[PATCH] mtd: nand: bbt: clamp GENMASK high bit to word boundary
From: Daniel Golle
Date: Sat Apr 11 2026 - 20:06:19 EST
When a BBT entry straddles an unsigned long boundary, the GENMASK in
nanddev_bbt_set_block_status() can potentially overflow because
offs + bits_per_block - 1 can theoretically exceed BITS_PER_LONG - 1.
Clamp the high bit so only bits within the current word are masked.
The cross-word portion is already handled by the pos[1] block below.
Discovered by UBSAN: shift-out-of-bounds in
drivers/mtd/nand/bbt.c:116:13
shift exponent 18446744073709551614 is too large for 64-bit type
'long unsigned int'
Fixes: 9c3736a3de21 ("mtd: nand: Add core infrastructure to deal with NAND devices")
Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx>
---
drivers/mtd/nand/bbt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/bbt.c b/drivers/mtd/nand/bbt.c
index db4f93a903e48..dfe4a6a991c15 100644
--- a/drivers/mtd/nand/bbt.c
+++ b/drivers/mtd/nand/bbt.c
@@ -113,7 +113,8 @@ int nanddev_bbt_set_block_status(struct nand_device *nand, unsigned int entry,
if (entry >= nanddev_neraseblocks(nand))
return -ERANGE;
- pos[0] &= ~GENMASK(offs + bits_per_block - 1, offs);
+ pos[0] &= ~GENMASK(min(offs + bits_per_block - 1,
+ BITS_PER_LONG - 1), offs);
pos[0] |= val << offs;
if (bits_per_block + offs > BITS_PER_LONG) {
--
2.53.0