Commit d4702669 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by David Woodhouse

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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent f54d6336
...@@ -636,6 +636,7 @@ add_dataflash_otp(struct spi_device *spi, char *name, ...@@ -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, ...@@ -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) ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment