[PATCH] mtd: rawnand: nandsim: validate overridesize before shifting

James Hilliard james.hilliard1 at gmail.com
Sun Nov 8 13:01:38 PST 2026


The size overflow check shifts by overridesize before validating it, so
values at least 64 already cause an invalid shift. Smaller values can
pass that check but exceed the width of the later eraseblock-count shift.

Use check_shl_overflow() to calculate the unsigned eraseblock count and
reject values that cannot be represented. Derive the byte size by
multiplying the two 32-bit quantities in 64-bit arithmetic.

Fixes: a5ac8aeb2900 ("[MTD] nandsim: enhance nandsim to allow arbitrary NAND size")
Cc: stable at vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
 drivers/mtd/nand/raw/nandsim.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
index fe968037f75a..6716eafb4b00 100644
--- a/drivers/mtd/nand/raw/nandsim.c
+++ b/drivers/mtd/nand/raw/nandsim.c
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/overflow.h>
 #include <linux/vmalloc.h>
 #include <linux/math64.h>
 #include <linux/slab.h>
@@ -2341,21 +2342,21 @@ static int __init ns_init_module(void)
 	}
 
 	if (overridesize) {
-		uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize;
 		struct nand_memory_organization *memorg;
+		unsigned int eraseblocks;
 		u64 targetsize;
 
 		memorg = nanddev_get_memorg(&chip->base);
 
-		if (new_size >> overridesize != nsmtd->erasesize) {
+		if (check_shl_overflow(1U, overridesize, &eraseblocks)) {
 			NS_ERR("overridesize is too big\n");
 			ret = -EINVAL;
 			goto cleanup_nand;
 		}
 
 		/* N.B. This relies on nand_scan not doing anything with the size before we change it */
-		nsmtd->size = new_size;
-		memorg->eraseblocks_per_lun = 1 << overridesize;
+		nsmtd->size = (u64)nsmtd->erasesize * eraseblocks;
+		memorg->eraseblocks_per_lun = eraseblocks;
 		targetsize = nanddev_target_size(&chip->base);
 		chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1;
 		chip->pagemask = (targetsize >> chip->page_shift) - 1;

---
base-commit: 30daaf3e7897b4a8d9b72e5b0c86dd6e2a4d7d85
change-id: 20261107-submit-nandsim-overridesize-bound-v1-1c83cbe80469

Best regards,
--  
James Hilliard <james.hilliard1 at gmail.com>




More information about the linux-mtd mailing list