[PATCH] dm-verity: fix buffer overflow in FEC calculation
Mikulas Patocka <[email protected]>
| Newsgroups | dev.linux.lists.dm-devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Sami I used Claude to search for bugs in dm-verity and it found this. The bug is real, the buffer "lambda" in lib/reed_solomon/decode_rs.c can overflow. Claude proposed this fix. I'd like to ask you (as you wrote the dm-verity FEC code) to review this patch. It seems that we can also redice the size of fio->erasures to DM_VERITY_FEC_MAX_ROOTS entries. Mikulas if (neras && *neras <= v->fec->roots) fio->erasures[(*neras)++] = i; This allows *neras to reach roots + 1 (the post-increment pushes it past roots). This value is then passed as no_eras to decode_rs8(). Inside the RS decoder (lib/reed_solomon/decode_rs.c:113-121), the erasure locator polynomial loop writes lambda[j] where j can reach nroots + 1 — one element past the end of lambda[] (which is sized nroots + 1, valid indices 0..nroots). The out-of-bounds write lands on syn[0], corrupting the syndrome buffer. Signed-off-by: Mikulas Patocka <[email protected]> Assisted-by: Claude:claude-opus-4-6 Cc: [email protected] Fixes: a739ff3f543a ("dm verity: add support for forward error correction") --- drivers/md/dm-verity-fec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Index: linux-2.6/drivers/md/dm-verity-fec.c =================================================================== --- linux-2.6.orig/drivers/md/dm-verity-fec.c 2026-07-01 13:38:45.000000000 +0200 +++ linux-2.6/drivers/md/dm-verity-fec.c 2026-07-01 13:52:19.000000000 +0200 @@ -220,7 +220,7 @@ static int fec_read_bufs(struct dm_verit PTR_ERR(bbuf)); /* assume the block is corrupted */ - if (neras && *neras <= v->fec->roots) + if (neras && *neras < v->fec->roots) fio->erasures[(*neras)++] = i; continue; @@ -238,7 +238,7 @@ static int fec_read_bufs(struct dm_verit * skip if we have already found the theoretical * maximum number (i.e. fec->roots) of erasures */ - if (neras && *neras <= v->fec->roots && + if (neras && *neras < v->fec->roots && fec_is_erasure(v, io, want_digest, bbuf)) fio->erasures[(*neras)++] = i; }