Skip to contentSkip to conversation

Correctly validate out-of-band offset and length

PATCH Applied Adrian Hunter 2 participants 2 messages Jan 31, 2007 – Feb 9, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Correctly validate out-of-band offset and length

Add checks to ensure that out-of-band reads and writes are not attempted with an invalid offset or length. Specifically, the offset must be less than the size of oob for a page and the length must not go beyond the size of the device. Additionally the checks must adjust for auto-placement (MTD_OOB_AUTO) of oob data.

---
drivers/mtd/nand/nand_base.c | 46 +++++++++++++++++++++++++++++++++++++----

1 files changed, 41 insertions(+), 5 deletions(-)
drivers/mtd/nand/nand_base.c +0 -0
index dfe56e0..c13d664 100644
@@ -1272,10 +1272,25 @@ static int nand_do_read_oob(struct mtd_i
	DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
	      (unsigned long long)from, readlen);

- if (ops->mode == MTD_OOB_RAW)
- len = mtd->oobsize;
- else
+ if (ops->mode == MTD_OOB_AUTO)

		len = chip->ecc.layout->oobavail;

+ else
+ len = mtd->oobsize;
+
+ if (unlikely(ops->ooboffs >= len)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ "Attempt to start read outside oob\n");
+ return -EINVAL;
+ }
+
+ /* Do not allow reads past end of device */
+ if (unlikely(from >= mtd->size ||
+ ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
+ (from >> chip->page_shift)) * len)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ "Attempt read beyond end of device\n");
+ return -EINVAL;
+ }

	chipnr = (int)(from >> chip->chip_shift);
	chip->select_chip(mtd, chipnr);

@@ -1742,19 +1757,40 @@ static int nand_write(struct mtd_info *m static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
- int chipnr, page, status;
+ int chipnr, page, status, len;

	struct nand_chip *chip = mtd->priv;

	DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
	      (unsigned int)to, (int)ops->ooblen);

+ if (ops->mode == MTD_OOB_AUTO)
+ len = chip->ecc.layout->oobavail;
+ else
+ len = mtd->oobsize;
+

	/* Do not allow write past end of page */
-	if ((ops->ooboffs + ops->ooblen) > mtd->oobsize) {
+	if ((ops->ooboffs + ops->ooblen) > len) {
		DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
		      "Attempt to write past end of page\n");
		return -EINVAL;
	}

+ if (unlikely(ops->ooboffs >= len)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ "Attempt to start write outside oob\n");
+ return -EINVAL;
+ }
+
+ /* Do not allow reads past end of device */
+ if (unlikely(to >= mtd->size ||
+ ops->ooboffs + ops->ooblen >
+ ((mtd->size >> chip->page_shift) -
+ (to >> chip->page_shift)) * len)) {
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ "Attempt write beyond end of device\n");
+ return -EINVAL;
+ }
+

	chipnr = (int)(to >> chip->chip_shift);
	chip->select_chip(mtd, chipnr);
Signature · 1 line
1.4.3
#1 lore raw
Quoted 8 lines · Adrian Hunter

Add checks to ensure that out-of-band reads and writes are not attempted with an invalid offset or length. Specifically, the offset must be less than the size of oob for a page and the length must not go beyond the size of the device. Additionally the checks must adjust for auto-placement (MTD_OOB_AUTO) of oob data.

Applied; thanks.

Signature · 1 line
dwmw2