From: "Michael Walle" <mwalle@kernel.org>
To: "HyeongJun An" <sammiee5311@gmail.com>,
"Pratyush Yadav" <pratyush@kernel.org>,
"Tudor Ambarus" <tudor.ambarus@linaro.org>,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
"Richard Weinberger" <richard@nod.at>,
"Vignesh Raghavendra" <vigneshr@ti.com>
Cc: "Takahiro Kuwano" <takahiro.kuwano@infineon.com>,
<linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
<stable@vger.kernel.org>
Subject: Re: [PATCH 1/2] mtd: spi-nor: sfdp: check the length of the xSPI Profile 1.0 table
Date: Mon, 20 Jul 2026 09:41:20 +0200 [thread overview]
Message-ID: <DK3893GFV1ZQ.3QF1WIWYGH5NH@kernel.org> (raw)
In-Reply-To: <20260719010820.1924739-2-sammiee5311@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 3003 bytes --]
On Sun Jul 19, 2026 at 3:08 AM CEST, HyeongJun An wrote:
> spi_nor_parse_profile1() sizes its bounce buffer from the length the
> flash reports in the SFDP parameter header, then indexes that buffer at
> fixed offsets:
>
> len = profile1_header->length * sizeof(*dwords);
> dwords = kmalloc(len, GFP_KERNEL);
> ...
> dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_166MHZ, dwords[SFDP_DWORD(5)]);
>
> The parser reads up to DWORD5, but never checks that the table is that
> long. The length is a u8 the flash supplies, so a device advertising
> the table 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(5)]
> reads sixteen bytes beyond it. A length of zero is worse, as kmalloc()
> then returns ZERO_SIZE_PTR rather than an error and the first access
> dereferences it.
>
> The bytes read out of bounds are not just discarded either, they end up
> as the dummy cycle count programmed for 8D-8D-8D fast reads.
>
> SFDP tables that do not match what the flash actually implements are
> common enough that this file already carries fixup hooks for them, and
> malformed SFDP has caused memory-safety bugs here before. See
> commit f0f0cfdc3a02 ("mtd: spi-nor: Fix shift-out-of-bounds in
> spi_nor_set_erase_type").
>
> 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.
Please be more precise. Best would be to describe the issue in your
own words.
> Fixes: fb27f198971a ("mtd: spi-nor: sfdp: parse xSPI Profile 1.0 table")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
> ---
> 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 4600983cb579..d3d85b5d1b4a 100644
> --- a/drivers/mtd/spi-nor/sfdp.c
> +++ b/drivers/mtd/spi-nor/sfdp.c
> @@ -1175,6 +1175,7 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,
> #define PROFILE1_DWORD5_DUMMY_166MHZ GENMASK(31, 27)
> #define PROFILE1_DWORD5_DUMMY_133MHZ GENMASK(21, 17)
> #define PROFILE1_DWORD5_DUMMY_100MHZ GENMASK(11, 7)
> +#define SFDP_PROFILE1_DWORD_MAX 5
>
> /**
> * spi_nor_parse_profile1() - parse the xSPI Profile 1.0 table
> @@ -1192,6 +1193,9 @@ static int spi_nor_parse_profile1(struct spi_nor *nor,
> int ret;
> u8 dummy, opcode;
>
> + if (profile1_header->length < SFDP_PROFILE1_DWORD_MAX)
> + return -EINVAL;
> +
I see that it's also use in the 4bait parsing, but I find it very
confusing to read. IMHO it should be SFDP_PROFILE1_DWORD_MIN.
-michael
> len = profile1_header->length * sizeof(*dwords);
> dwords = kmalloc(len, GFP_KERNEL);
> if (!dwords)
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]
[-- Attachment #2: Type: text/plain, Size: 144 bytes --]
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
WARNING: multiple messages have this Message-ID (diff)
From: "Michael Walle" <mwalle@kernel.org>
To: "HyeongJun An" <sammiee5311@gmail.com>,
"Pratyush Yadav" <pratyush@kernel.org>,
"Tudor Ambarus" <tudor.ambarus@linaro.org>,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
"Richard Weinberger" <richard@nod.at>,
"Vignesh Raghavendra" <vigneshr@ti.com>
Cc: "Takahiro Kuwano" <takahiro.kuwano@infineon.com>,
<linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
<stable@vger.kernel.org>
Subject: Re: [PATCH 1/2] mtd: spi-nor: sfdp: check the length of the xSPI Profile 1.0 table
Date: Mon, 20 Jul 2026 09:41:20 +0200 [thread overview]
Message-ID: <DK3893GFV1ZQ.3QF1WIWYGH5NH@kernel.org> (raw)
In-Reply-To: <20260719010820.1924739-2-sammiee5311@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3003 bytes --]
On Sun Jul 19, 2026 at 3:08 AM CEST, HyeongJun An wrote:
> spi_nor_parse_profile1() sizes its bounce buffer from the length the
> flash reports in the SFDP parameter header, then indexes that buffer at
> fixed offsets:
>
> len = profile1_header->length * sizeof(*dwords);
> dwords = kmalloc(len, GFP_KERNEL);
> ...
> dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_166MHZ, dwords[SFDP_DWORD(5)]);
>
> The parser reads up to DWORD5, but never checks that the table is that
> long. The length is a u8 the flash supplies, so a device advertising
> the table 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(5)]
> reads sixteen bytes beyond it. A length of zero is worse, as kmalloc()
> then returns ZERO_SIZE_PTR rather than an error and the first access
> dereferences it.
>
> The bytes read out of bounds are not just discarded either, they end up
> as the dummy cycle count programmed for 8D-8D-8D fast reads.
>
> SFDP tables that do not match what the flash actually implements are
> common enough that this file already carries fixup hooks for them, and
> malformed SFDP has caused memory-safety bugs here before. See
> commit f0f0cfdc3a02 ("mtd: spi-nor: Fix shift-out-of-bounds in
> spi_nor_set_erase_type").
>
> 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.
Please be more precise. Best would be to describe the issue in your
own words.
> Fixes: fb27f198971a ("mtd: spi-nor: sfdp: parse xSPI Profile 1.0 table")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
> ---
> 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 4600983cb579..d3d85b5d1b4a 100644
> --- a/drivers/mtd/spi-nor/sfdp.c
> +++ b/drivers/mtd/spi-nor/sfdp.c
> @@ -1175,6 +1175,7 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,
> #define PROFILE1_DWORD5_DUMMY_166MHZ GENMASK(31, 27)
> #define PROFILE1_DWORD5_DUMMY_133MHZ GENMASK(21, 17)
> #define PROFILE1_DWORD5_DUMMY_100MHZ GENMASK(11, 7)
> +#define SFDP_PROFILE1_DWORD_MAX 5
>
> /**
> * spi_nor_parse_profile1() - parse the xSPI Profile 1.0 table
> @@ -1192,6 +1193,9 @@ static int spi_nor_parse_profile1(struct spi_nor *nor,
> int ret;
> u8 dummy, opcode;
>
> + if (profile1_header->length < SFDP_PROFILE1_DWORD_MAX)
> + return -EINVAL;
> +
I see that it's also use in the 4bait parsing, but I find it very
confusing to read. IMHO it should be SFDP_PROFILE1_DWORD_MIN.
-michael
> len = profile1_header->length * sizeof(*dwords);
> dwords = kmalloc(len, GFP_KERNEL);
> if (!dwords)
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]
next prev parent reply other threads:[~2026-07-20 7:41 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-19 1:08 [PATCH 0/2] mtd: spi-nor: sfdp: bound two optional parameter tables HyeongJun An
2026-07-19 1:08 ` HyeongJun An
2026-07-19 1:08 ` [PATCH 1/2] mtd: spi-nor: sfdp: check the length of the xSPI Profile 1.0 table HyeongJun An
2026-07-19 1:08 ` HyeongJun An
2026-07-20 7:41 ` Michael Walle [this message]
2026-07-20 7:41 ` Michael Walle
2026-07-19 1:08 ` [PATCH 2/2] mtd: spi-nor: sfdp: check the length of the SCCR map HyeongJun An
2026-07-19 1:08 ` HyeongJun An
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DK3893GFV1ZQ.3QF1WIWYGH5NH@kernel.org \
--to=mwalle@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=miquel.raynal@bootlin.com \
--cc=pratyush@kernel.org \
--cc=richard@nod.at \
--cc=sammiee5311@gmail.com \
--cc=stable@vger.kernel.org \
--cc=takahiro.kuwano@infineon.com \
--cc=tudor.ambarus@linaro.org \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.