From: Naveen Kumar Chaudhary Date: Wed, 8 Jul 2026 14:33:04 +0000 (+0530) Subject: cmd: read: fix unsigned overflow bypassing range check X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1b8283bd3220e898d338fb98929f0b06ed63da84;p=thirdparty%2Fu-boot.git cmd: read: fix unsigned overflow bypassing range check The bounds check in do_rw() was written as: if (cnt + blk > limit) with cnt and blk declared as uint (unsigned int) and limit as ulong. C's usual arithmetic conversions are applied per binary operator, so "cnt + blk" is evaluated entirely in unsigned int and wraps modulo 2^32 before the result is widened for the comparison against limit. With cnt = 0xFFFFFFFF and blk = 1 the sum wraps to 0 and the guard passes, allowing blk_dread()/blk_dwrite() to be issued with a 4 GiB transfer count that runs past the partition (or, when no partition is selected, the entire device). Rewrite the check as two comparisons that do not overflow: if (blk > limit || cnt > limit - blk) The subtraction is performed in ulong (limit's type), so no truncation occurs, and the two sub-conditions cover both "start block past end" and "count would push us past end" failure modes. Signed-off-by: Naveen Kumar Chaudhary Reviewed-by: Simon Glass --- diff --git a/cmd/read.c b/cmd/read.c index 8e21f004423..efc255ce85d 100644 --- a/cmd/read.c +++ b/cmd/read.c @@ -46,7 +46,7 @@ do_rw(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) limit = ~0; } - if (cnt + blk > limit) { + if (blk > limit || cnt > limit - blk) { printf("%s out of range\n", cmdtp->name); unmap_sysmem(ptr); return 1;