mtd_erase() calls mtd->_erase() without checking that the driver has
one, so a device which does not provide one will end in accessing
NULL pointer.

MTD_NO_ERASE flag exists, but nobody reads it yet.

Linux guards mtd_erase() with

        if (!mtd->erasesize || !master->_erase)
                return -ENOTSUPP;

so do the same in U-Boot, but with EOPNOTSUPP as the error code,
as checkpatch asks for ("ENOTSUPP is not a SUSV4 error code, prefer
EOPNOTSUPP").

Signed-off-by: Heiko Schocher <[email protected]>
---

Changes in v2:
- New patch. The SRAM driver of patch 3 has no erase, which the old
  mtd_erase() would have turned into a NULL pointer jump

 drivers/mtd/mtdcore.c | 3 +++
 drivers/mtd/mtdpart.c | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 3bfa5aebbc6..bde74510d4f 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -906,6 +906,9 @@ EXPORT_SYMBOL_GPL(__put_mtd_device);
 
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
+       if (!mtd->erasesize || !mtd->_erase)
+               return -EOPNOTSUPP;
+
        if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr)
                return -EINVAL;
        if (!(mtd->flags & MTD_WRITEABLE))
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index f3b7f1ee13c..a3003cf44b0 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -654,7 +654,8 @@ static struct mtd_info *allocate_partition(struct mtd_info 
*master,
                slave->_block_isbad = part_block_isbad;
        if (master->_block_markbad)
                slave->_block_markbad = part_block_markbad;
-       slave->_erase = part_erase;
+       if (master->_erase)
+               slave->_erase = part_erase;
        slave->parent = master;
        slave->offset = part->offset;
        INIT_LIST_HEAD(&slave->partitions);
-- 
2.55.0

Reply via email to