mtd: fix memory leak in mtd_dataflash
Fix a potential memory leak in mtd_dataflash driver. The private data that is allocated when registering a DataFlash device with the MTD subsystem is not released if an error occurs when add_mtd_partitions() or add_mtd_device() is called. Fix this by adding an error path. The memory is already released during a remove. Also, add a dev_set_drvdata(&spi->dev, NULL) before the kfree() so that the spi device does not reference invalid data. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
committed by
David Woodhouse
parent
f54d633637
commit
d4702669b0
@@ -636,6 +636,7 @@ add_dataflash_otp(struct spi_device *spi, char *name,
|
|||||||
struct mtd_info *device;
|
struct mtd_info *device;
|
||||||
struct flash_platform_data *pdata = spi->dev.platform_data;
|
struct flash_platform_data *pdata = spi->dev.platform_data;
|
||||||
char *otp_tag = "";
|
char *otp_tag = "";
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
priv = kzalloc(sizeof *priv, GFP_KERNEL);
|
priv = kzalloc(sizeof *priv, GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
@@ -693,13 +694,23 @@ add_dataflash_otp(struct spi_device *spi, char *name,
|
|||||||
|
|
||||||
if (nr_parts > 0) {
|
if (nr_parts > 0) {
|
||||||
priv->partitioned = 1;
|
priv->partitioned = 1;
|
||||||
return add_mtd_partitions(device, parts, nr_parts);
|
err = add_mtd_partitions(device, parts, nr_parts);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
} else if (pdata && pdata->nr_parts)
|
} else if (pdata && pdata->nr_parts)
|
||||||
dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
|
dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
|
||||||
pdata->nr_parts, device->name);
|
pdata->nr_parts, device->name);
|
||||||
|
|
||||||
return add_mtd_device(device) == 1 ? -ENODEV : 0;
|
if (add_mtd_device(device) == 1)
|
||||||
|
err = -ENODEV;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (!err)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev_set_drvdata(&spi->dev, NULL);
|
||||||
|
kfree(priv);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int __devinit
|
static inline int __devinit
|
||||||
@@ -932,8 +943,10 @@ static int __devexit dataflash_remove(struct spi_device *spi)
|
|||||||
status = del_mtd_partitions(&flash->mtd);
|
status = del_mtd_partitions(&flash->mtd);
|
||||||
else
|
else
|
||||||
status = del_mtd_device(&flash->mtd);
|
status = del_mtd_device(&flash->mtd);
|
||||||
if (status == 0)
|
if (status == 0) {
|
||||||
|
dev_set_drvdata(&spi->dev, NULL);
|
||||||
kfree(flash);
|
kfree(flash);
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user