* [PATCH] mtd: rawnand: sunxi: reject invalid ECC step sizes
@ 2026-08-11 6:06 James Hilliard
0 siblings, 0 replies; only message in thread
From: James Hilliard @ 2026-08-11 6:06 UTC (permalink / raw)
To: linux-mtd, linux-sunxi
Cc: James Hilliard, stable, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Richard Genoud, Geert Uytterhoeven, Boris Brezillon,
linux-arm-kernel, linux-kernel
ECC maximization forces a 1024-byte ECC step and divides the
available OOB bytes by the number of steps. A NAND with a smaller
page therefore produces zero steps and a division by zero.
An explicitly configured ECC step which is larger than, or does not
divide, the page also produces an unusable step count before the NAND
core can diagnose the configuration.
Validate the step size at both points where the driver derives the
number of sectors and reject invalid geometries.
Fixes: 4796d8655915 ("mtd: nand: sunxi: Support ECC maximization")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/mtd/nand/raw/sunxi_nand.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index 45ccbce91551..ad314c0e30b2 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -2032,6 +2032,15 @@ static void sunxi_nand_detach_chip(struct nand_chip *nand)
sunxi_nand->user_data_bytes = NULL;
}
+static int sunxi_nfc_ecc_steps(struct mtd_info *mtd, unsigned int step_size)
+{
+ if (!step_size || mtd->writesize < step_size ||
+ mtd->writesize % step_size)
+ return -EINVAL;
+
+ return mtd->writesize / step_size;
+}
+
static int sunxi_nfc_maximize_user_data(struct nand_chip *nand, uint32_t oobsize,
int ecc_bytes, int nsectors)
{
@@ -2078,7 +2087,9 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand,
int bytes = mtd->oobsize;
ecc->size = 1024;
- nsectors = mtd->writesize / ecc->size;
+ nsectors = sunxi_nfc_ecc_steps(mtd, ecc->size);
+ if (nsectors < 0)
+ return nsectors;
if (!nfc->caps->reg_user_data_len) {
/*
@@ -2163,7 +2174,9 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand,
/* HW ECC always work with even numbers of ECC bytes */
ecc->bytes = ALIGN(ecc->bytes, 2);
- nsectors = mtd->writesize / ecc->size;
+ nsectors = sunxi_nfc_ecc_steps(mtd, ecc->size);
+ if (nsectors < 0)
+ return nsectors;
/*
* The rationale for variable data length is to prioritize maximum ECC
--
2.53.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-11 6:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 6:06 [PATCH] mtd: rawnand: sunxi: reject invalid ECC step sizes James Hilliard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox