summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/spi-nor
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2017-09-12 15:10:35 +0200
committerBoris Brezillon <boris.brezillon@free-electrons.com>2017-09-18 09:53:27 +0200
commitb8f3911610529ba531b99d1e109c7a40fb071f0a (patch)
treec39be062e14d0b719e9ed49d29fcc265c4e909b0 /drivers/mtd/spi-nor
parent2bd6bf03f4c1c59381d62c61d03f6cc3fe71f66e (diff)
downloadlinux-b8f3911610529ba531b99d1e109c7a40fb071f0a.tar.bz2
mtd: spi-nor: Check consistency of the memory size extracted from the SFDP
One field of the flash parameter table contains information about the flash device size. Most of the time the data extracted from this field is valid, but sometimes the BFPT section of the SFDP table is corrupted or invalid and this field is set to 0xffffffff, thus resulting in an integer overflow when setting params->size. Since NOR devices are anayway always smaller than 2^64 bytes, we can easily stop the BFPT parsing if the size reported in this table is invalid. Fixes: f384b352cbf0 ("mtd: spi-nor: parse Serial Flash Discoverable Parameters (SFDP) tables") Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.com>
Diffstat (limited to 'drivers/mtd/spi-nor')
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index cf1d4a15e10a..4425b0283725 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2127,6 +2127,15 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
params->size = bfpt.dwords[BFPT_DWORD(2)];
if (params->size & BIT(31)) {
params->size &= ~BIT(31);
+
+ /*
+ * Prevent overflows on params->size. Anyway, a NOR of 2^64
+ * bits is unlikely to exist so this error probably means
+ * the BFPT we are reading is corrupted/wrong.
+ */
+ if (params->size > 63)
+ return -EINVAL;
+
params->size = 1ULL << params->size;
} else {
params->size++;