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;
                }

Reply via email to