[PATCH 2/2] mtd: spi-nor: sfdp: check the length of the SCCR map

From: HyeongJun An

Date: Sat Jul 18 2026 - 21:09:32 EST


spi_nor_parse_sccr() sizes its bounce buffer from the length the flash
reports in the SFDP parameter header, then reads DWORD22 out of it:

len = sccr_header->length * sizeof(*dwords);
dwords = kmalloc(len, GFP_KERNEL);
...
if (FIELD_GET(SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE,
dwords[SFDP_DWORD(22)]))

Nothing checks that the table actually has 22 DWORDs. The length is a
u8 the flash supplies, so a device advertising the SCCR map with a
shorter length makes the read run past the allocation: with a length of
one the buffer is four bytes and dwords[SFDP_DWORD(22)] reads
eighty-four bytes beyond it. A length of zero is worse, as kmalloc()
then returns ZERO_SIZE_PTR rather than an error and the read of
dwords[SFDP_DWORD(1)] dereferences it.

Reject a table shorter than the highest DWORD the parser reads, the way
spi_nor_parse_4bait() already does with SFDP_4BAIT_DWORD_MAX. Failing
an optional parameter table is not fatal: spi_nor_parse_sfdp() warns and
carries on with the data gathered so far.

spi_nor_parse_sccr_mc() does not need the same check. It derives the
number of dice from the length it allocated with, so its highest index
stays inside the buffer, and a length below two leaves its loop empty.

Fixes: 7ab8b810757a ("mtd: spi-nor: sfdp: Add support for SCCR map for multi-chip device")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: HyeongJun An <sammiee5311@xxxxxxxxx>
---
drivers/mtd/spi-nor/sfdp.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index d3d85b5d1b4a..6c9db103a29a 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -1266,6 +1266,7 @@ static int spi_nor_parse_profile1(struct spi_nor *nor,
}

#define SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE BIT(31)
+#define SFDP_SCCR_DWORD_MAX 22

/**
* spi_nor_parse_sccr() - Parse the Status, Control and Configuration Register
@@ -1284,6 +1285,9 @@ static int spi_nor_parse_sccr(struct spi_nor *nor,
size_t len;
int ret;

+ if (sccr_header->length < SFDP_SCCR_DWORD_MAX)
+ return -EINVAL;
+
len = sccr_header->length * sizeof(*dwords);
dwords = kmalloc(len, GFP_KERNEL);
if (!dwords)
--
2.43.0