[PATCH mtd-utils] libmtd: do not ignore non-zero eraseblock size when MTD_NO_ERASE is set

Enrico Jorns ejo at pengutronix.de
Fri Aug 19 05:32:13 PDT 2022


In 54d68799, mtd->eb_cnt was enforced to be '1' if MTD_NO_ERASE is set.
This was done with the aim of preventing divisions by zero.

However, even if MTD_NO_ERASE is set, mtd->eb_size (eraseblock size) can
still be set to a non-zero value which would not cause a division by
zero.

Instead, enforcing an eraseblock count of '1' here even leads to
inconsistent eraseblock counting in mtd-utils and lets for example a
'flash_erase' on an mtdnand device fail:

| # flash_erase /dev/mtd0 0 0
| Erasing 32768 Kibyte @ 0 --  0 % complete libmtd: error!: bad eraseblock number 255, mtd0 has 1 eraseblocks
| flash_erase: error!: /dev/mtd0: MTD Erase entire chip failureTrying one by one each sector.
|              error 22 (Invalid argument)
| Erasing 128 Kibyte @ 0 --  0 % complete libmtd: error!: bad eraseblock number 1, mtd0 has 1 eraseblocks
| flash_erase: error!: /dev/mtd0: MTD get bad block failed
|              error 22 (Invalid argument)

Also mtdinfo would look inconsistent (eraseblock size vs amount):

| # mtdinfo /dev/mtd0
| mtd0
| Name:                           mtdram test device
| Type:                           ram
| Eraseblock size:                131072 bytes, 128.0 KiB
| Amount of eraseblocks:          1 (33554432 bytes, 32.0 MiB)
| Minimum input/output unit size: 1 byte
| Sub-page size:                  1 byte
| Character device major/minor:   90:0
| Bad blocks are allowed:         false
| Device is writable:             true

Fix this by enforcing mtd->eb_cnt to be '1' only when mtd->eb_size is
actually zero and would lead to a division by zero otherwise.

Fixes: 54d68799 ("libmtd: avoid divide by zero")

Signed-off-by: Enrico Jorns <ejo at pengutronix.de>
---
 lib/libmtd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libmtd.c b/lib/libmtd.c
index a363e56..4aee947 100644
--- a/lib/libmtd.c
+++ b/lib/libmtd.c
@@ -792,7 +792,7 @@ int mtd_get_dev_info1(libmtd_t desc, int mtd_num, struct mtd_dev_info *mtd)
 		return -1;
 	mtd->writable = !!(ret & MTD_WRITEABLE);
 
-	if (ret & MTD_NO_ERASE)
+	if ((ret & MTD_NO_ERASE) && (mtd->eb_size == 0))
 		mtd->eb_cnt = 1;
 	else
 		mtd->eb_cnt = mtd->size / mtd->eb_size;
-- 
2.35.1




More information about the linux-mtd mailing list