[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;
 		}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.