mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] mtd: inftl: validate MediaHeader partition geometry before allocating tables
@ 2026-09-02 12:40 henrymei
  2026-09-03  8:04 ` Miquel Raynal
  0 siblings, 1 reply; 4+ messages in thread
From: henrymei @ 2026-09-02 12:40 UTC (permalink / raw)
  To: linux-mtd
  Cc: miquel.raynal, richard, vigneshr, linux-kernel, Aohan Mei,
	TencentOS Corvus AI, stable

From: Aohan Mei <henrymei@tencent.com>

find_boot_record() trusts the on-flash INFTL MediaHeader partition
fields without validating their relationship to each other or to the
device geometry.

The sanity check

	if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits)

is evaluated in unsigned 32-bit arithmetic.  With lastUnit < firstUnit
the subtraction wraps to a huge value and the check passes.  Control
then reaches:

	inftl->nb_boot_blocks = ip->firstUnit;    /* loop bound */
	inftl->nb_blocks      = ip->lastUnit + 1; /* table size */

so PUtable/VUtable are allocated with lastUnit + 1 entries while the
boot-block marking loop writes firstUnit u16 entries:

	for (i = 0; i < inftl->nb_boot_blocks; i++)
		inftl->PUtable[i] = BLOCK_RESERVED;

A crafted MediaHeader (e.g. firstUnit=7000, lastUnit=3) turns a
kmalloc_array(4, 2) 8-byte allocation into a ~14 KB out-of-bounds
write:

	BUG: KASAN: slab-out-of-bounds in find_boot_record
	Write of size 2 ... 0 bytes to the right of allocated 8-byte region

The MediaHeader unit itself is also marked through PUtable[block]
without verifying that block lies within the described extent.

Reject inconsistent partition geometry (lastUnit < firstUnit, or
lastUnit beyond the device) as each partition entry is scanned, and
reject a boot record that lies outside the extent of the selected
partition.  The existing virtualUnits check then subtracts values
that can no longer underflow.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Assisted-by: CodeBuddy:Kimi-K3
Signed-off-by: Aohan Mei <henrymei@tencent.com>
---
 drivers/mtd/inftlmount.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 87e246a6f488..b0f01db95280 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -192,6 +192,23 @@ static int find_boot_record(struct INFTLrecord *inftl)
 				 ip->lastUnit, ip->flags,
 				 ip->spareUnits);
 
+			/*
+			 * Reject inconsistent partition geometry before it is
+			 * used: lastUnit < firstUnit would make the
+			 * (lastUnit - firstUnit + 1) check below underflow,
+			 * and lastUnit must stay within the device as it later
+			 * bounds the PUtable/VUtable allocations.
+			 */
+			if (ip->lastUnit < ip->firstUnit ||
+			    ip->lastUnit >= inftl->nb_blocks) {
+				pr_warn("INFTL: Media Header "
+					"Partition %d sanity check failed:\n"
+					"        firstUnit %d lastUnit %d "
+					"(nb_blocks %d)\n",
+					i, ip->firstUnit, ip->lastUnit,
+					inftl->nb_blocks);
+				return -1;
+			}
 			if (ip->Reserved0 != ip->firstUnit) {
 				struct erase_info *instr = &inftl->instr;
 
@@ -233,6 +250,18 @@ static int find_boot_record(struct INFTLrecord *inftl)
 			return -1;
 		}
 
+		/*
+		 * The boot record unit must lie within the described
+		 * extent; it is later marked through PUtable[block].
+		 */
+		if (block > ip->lastUnit) {
+			pr_warn("INFTL: Media Header "
+				"Partition %d sanity check failed:\n"
+				"        boot record unit %d beyond "
+				"lastUnit %d\n",
+				i, block, ip->lastUnit);
+			return -1;
+		}
 		inftl->nb_boot_blocks = ip->firstUnit;
 		inftl->numvunits = ip->virtualUnits;
 		if (inftl->numvunits > (inftl->nb_blocks -
-- 
2.43.7


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-03 10:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-02 12:40 [PATCH] mtd: inftl: validate MediaHeader partition geometry before allocating tables henrymei
2026-09-03  8:04 ` Miquel Raynal
2026-09-03  9:43   ` 林佳鹏
2026-09-03 10:01     ` Miquel Raynal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®