|
@@ -1272,10 +1272,25 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
|
|
|
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 *mtd, loff_t to, size_t len,
|
|
|
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);
|
|
|
|