[PATCH v2 1/2] mtd: slram: remove failed entries from the device list
From: Ruoyu Wang
Date: Tue Jun 09 2026 - 04:59:13 EST
register_device() links a new slram_mtdlist entry before allocating all
of the state needed by the entry. If a later allocation, memremap(), or
mtd_device_register() fails, the partially initialized entry remains on
the global list. A later cleanup can then dereference or free invalid
state from that failed entry.
Unwind the partially initialized entry and clear the list tail on each
failure path after the entry has been linked.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Ruoyu Wang <ruoyuw560@xxxxxxxxx>
---
drivers/mtd/devices/slram.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 69cb63d99f573..48c2bc6b65eec 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -129,6 +129,7 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
static int register_device(char *name, unsigned long start, unsigned long length)
{
slram_mtd_list_t **curmtd;
+ int ret = -ENOMEM;
curmtd = &slram_mtdlist;
while (*curmtd) {
@@ -155,14 +156,15 @@ static int register_device(char *name, unsigned long start, unsigned long length
if (!(*curmtd)->mtdinfo) {
E("slram: Cannot allocate new MTD device.\n");
- return(-ENOMEM);
+ goto err_free_list;
}
if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
memremap(start, length,
MEMREMAP_WB | MEMREMAP_WT | MEMREMAP_WC))) {
E("slram: memremap failed\n");
- return -EIO;
+ ret = -EIO;
+ goto err_free_priv;
}
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end =
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start + length;
@@ -183,10 +185,8 @@ static int register_device(char *name, unsigned long start, unsigned long length
if (mtd_device_register((*curmtd)->mtdinfo, NULL, 0)) {
E("slram: Failed to register new device\n");
- memunmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start);
- kfree((*curmtd)->mtdinfo->priv);
- kfree((*curmtd)->mtdinfo);
- return(-EAGAIN);
+ ret = -EAGAIN;
+ goto err_unmap;
}
T("slram: Registered device %s from %luKiB to %luKiB\n", name,
(start / 1024), ((start + length) / 1024));
@@ -194,6 +194,16 @@ static int register_device(char *name, unsigned long start, unsigned long length
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
return(0);
+
+err_unmap:
+ memunmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start);
+err_free_priv:
+ kfree((*curmtd)->mtdinfo->priv);
+err_free_list:
+ kfree((*curmtd)->mtdinfo);
+ kfree(*curmtd);
+ *curmtd = NULL;
+ return ret;
}
static void unregister_devices(void)
--
2.51.0