wlcore: fix usage of platform_device_add_data()
PATCH 1/1 wlcore: fix usage of platform_device_add_data()
Coverity CID 986698 reports leakage of struct wlcore_platdev_data in the probe functions of both the SPI/SDIO interfaces. The structure passed to platform_device_add_data() is dynamically allocated and only freed in the error paths, however, platform_device_add_data() adds a copy of the platform specific data to the device. Move the temporary struct that is kmemdup'ed to the stack. This issue exists since afb43e6d (wlcore: remove if_ops from platform_data).
---
Applies against v3.15-rc2 as well as branch master in tree git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git and is compile tested only.
--- drivers/net/wireless/ti/wlcore/sdio.c | 28 +++++++++++----------------- drivers/net/wireless/ti/wlcore/spi.c | 23 +++++++++-------------- 2 files changed, 20 insertions(+), 31 deletions(-)
drivers/net/wireless/ti/wlcore/sdio.c +11 -17
@@ -217,7 +217,7 @@ static struct wl1271_if_operations sdio_ops = {static int wl1271_probe (struct sdio_func *func,const struct sdio_device_id *id) { -struct wlcore_platdev_data *pdev_data; +struct wlcore_platdev_data pdev_data;struct wl12xx_sdio_glue *glue;struct resource res[1 ];mmc_pm_flag_t mmcflags;
@@ -228,16 +228,13 @@ static int wl1271_probe(struct sdio_func *func,if (func->num !=0x02 )return -ENODEV ; - pdev_data =kzalloc (sizeof (*pdev_data),GFP_KERNEL ); -if (!pdev_data) - goto out; - - pdev_data->if_ops = &sdio_ops; +memset (&pdev_data,0x00 ,sizeof (pdev_data)); + pdev_data.if_ops = &sdio_ops; glue =kzalloc (sizeof (*glue),GFP_KERNEL );if (!glue) {dev_err (&func->dev,"can't allocate glue\n" ); - goto out_free_pdev_data; + goto out; } glue->dev = &func->dev;
@@ -248,9 +245,9 @@ static int wl1271_probe(struct sdio_func *func,/* Use block mode for transferring over one block size of data */ func->card->quirks |=MMC_QUIRK_BLKSZ_FOR_BYTE_MODE ; - pdev_data->pdata =wl12xx_get_platform_data (); -if (IS_ERR (pdev_data->pdata)) { - ret =PTR_ERR (pdev_data->pdata); + pdev_data.pdata =wl12xx_get_platform_data (); +if (IS_ERR (pdev_data.pdata)) { + ret =PTR_ERR (pdev_data.pdata);dev_err (glue->dev,"missing wlan platform data: %d\n" , ret); goto out_free_glue; }
@@ -260,7 +257,7 @@ static int wl1271_probe(struct sdio_func *func,dev_dbg (glue->dev,"sdio PM caps = 0x%x\n" , mmcflags);if (mmcflags &MMC_PM_KEEP_POWER ) - pdev_data->pdata->pwr_in_suspend = true; + pdev_data.pdata->pwr_in_suspend = true;sdio_set_drvdata (func, glue);
@@ -289,7 +286,7 @@ static int wl1271_probe(struct sdio_func *func,memset (res,0x00 ,sizeof (res)); - res[0 ].start = pdev_data->pdata->irq; + res[0 ].start = pdev_data.pdata->irq; res[0 ].flags =IORESOURCE_IRQ ; res[0 ].name ="irq" ;
@@ -299,8 +296,8 @@ static int wl1271_probe(struct sdio_func *func, goto out_dev_put; } - ret =platform_device_add_data (glue->core, pdev_data, -sizeof (*pdev_data)); + ret =platform_device_add_data (glue->core, &pdev_data, +sizeof (pdev_data));if (ret) {dev_err (glue->dev,"can't add platform data\n" ); goto out_dev_put;
@@ -319,9 +316,6 @@ out_dev_put: out_free_glue:kfree (glue); -out_free_pdev_data: -kfree (pdev_data); - out:return ret; }
drivers/net/wireless/ti/wlcore/spi.c +9 -14
@@ -327,27 +327,25 @@ static struct wl1271_if_operations spi_ops = {static int wl1271_probe (struct spi_device *spi) {struct wl12xx_spi_glue *glue; -struct wlcore_platdev_data *pdev_data; +struct wlcore_platdev_data pdev_data;struct resource res[1 ];int ret = -ENOMEM ; - pdev_data =kzalloc (sizeof (*pdev_data),GFP_KERNEL ); -if (!pdev_data) - goto out; +memset (&pdev_data,0x00 ,sizeof (pdev_data)); - pdev_data->pdata =dev_get_platdata (&spi->dev); -if (!pdev_data->pdata) { + pdev_data.pdata =dev_get_platdata (&spi->dev); +if (!pdev_data.pdata) {dev_err (&spi->dev,"no platform data\n" ); ret = -ENODEV ; - goto out_free_pdev_data; + goto out; } - pdev_data->if_ops = &spi_ops; + pdev_data.if_ops = &spi_ops; glue =kzalloc (sizeof (*glue),GFP_KERNEL );if (!glue) {dev_err (&spi->dev,"can't allocate glue\n" ); - goto out_free_pdev_data; + goto out; } glue->dev = &spi->dev;
@@ -385,8 +383,8 @@ static int wl1271_probe(struct spi_device *spi) goto out_dev_put; } - ret =platform_device_add_data (glue->core, pdev_data, -sizeof (*pdev_data)); + ret =platform_device_add_data (glue->core, &pdev_data, +sizeof (pdev_data));if (ret) {dev_err (glue->dev,"can't add platform data\n" ); goto out_dev_put;
@@ -406,9 +404,6 @@ out_dev_put: out_free_glue:kfree (glue); -out_free_pdev_data: -kfree (pdev_data); - out:return ret; }
Signature · 1 line
1.9.1
PATCH RESEND 1/1 wlcore: fix usage of platform_device_add_data()
Coverity CID 986698 reports leakage of struct wlcore_platdev_data in the probe functions of both the SPI/SDIO interfaces. The structure passed to platform_device_add_data() is dynamically allocated and only freed in the error paths, however, platform_device_add_data() adds a copy of the platform specific data to the device. Move the temporary struct that is kmemdup'ed to the stack. This issue exists since afb43e6d (wlcore: remove if_ops from platform_data).
---
Applies against v3.15-rc2 as well as branch master in tree git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git and is compile tested only.
Resend with updated mail address: Luciano Coelho <[email protected]>
--- drivers/net/wireless/ti/wlcore/sdio.c | 28 +++++++++++----------------- drivers/net/wireless/ti/wlcore/spi.c | 23 +++++++++-------------- 2 files changed, 20 insertions(+), 31 deletions(-)
drivers/net/wireless/ti/wlcore/sdio.c +11 -17
@@ -217,7 +217,7 @@ static struct wl1271_if_operations sdio_ops = {static int wl1271_probe (struct sdio_func *func,const struct sdio_device_id *id) { -struct wlcore_platdev_data *pdev_data; +struct wlcore_platdev_data pdev_data;struct wl12xx_sdio_glue *glue;struct resource res[1 ];mmc_pm_flag_t mmcflags;
@@ -228,16 +228,13 @@ static int wl1271_probe(struct sdio_func *func,if (func->num !=0x02 )return -ENODEV ; - pdev_data =kzalloc (sizeof (*pdev_data),GFP_KERNEL ); -if (!pdev_data) - goto out; - - pdev_data->if_ops = &sdio_ops; +memset (&pdev_data,0x00 ,sizeof (pdev_data)); + pdev_data.if_ops = &sdio_ops; glue =kzalloc (sizeof (*glue),GFP_KERNEL );if (!glue) {dev_err (&func->dev,"can't allocate glue\n" ); - goto out_free_pdev_data; + goto out; } glue->dev = &func->dev;
@@ -248,9 +245,9 @@ static int wl1271_probe(struct sdio_func *func,/* Use block mode for transferring over one block size of data */ func->card->quirks |=MMC_QUIRK_BLKSZ_FOR_BYTE_MODE ; - pdev_data->pdata =wl12xx_get_platform_data (); -if (IS_ERR (pdev_data->pdata)) { - ret =PTR_ERR (pdev_data->pdata); + pdev_data.pdata =wl12xx_get_platform_data (); +if (IS_ERR (pdev_data.pdata)) { + ret =PTR_ERR (pdev_data.pdata);dev_err (glue->dev,"missing wlan platform data: %d\n" , ret); goto out_free_glue; }
@@ -260,7 +257,7 @@ static int wl1271_probe(struct sdio_func *func,dev_dbg (glue->dev,"sdio PM caps = 0x%x\n" , mmcflags);if (mmcflags &MMC_PM_KEEP_POWER ) - pdev_data->pdata->pwr_in_suspend = true; + pdev_data.pdata->pwr_in_suspend = true;sdio_set_drvdata (func, glue);
@@ -289,7 +286,7 @@ static int wl1271_probe(struct sdio_func *func,memset (res,0x00 ,sizeof (res)); - res[0 ].start = pdev_data->pdata->irq; + res[0 ].start = pdev_data.pdata->irq; res[0 ].flags =IORESOURCE_IRQ ; res[0 ].name ="irq" ;
@@ -299,8 +296,8 @@ static int wl1271_probe(struct sdio_func *func, goto out_dev_put; } - ret =platform_device_add_data (glue->core, pdev_data, -sizeof (*pdev_data)); + ret =platform_device_add_data (glue->core, &pdev_data, +sizeof (pdev_data));if (ret) {dev_err (glue->dev,"can't add platform data\n" ); goto out_dev_put;
@@ -319,9 +316,6 @@ out_dev_put: out_free_glue:kfree (glue); -out_free_pdev_data: -kfree (pdev_data); - out:return ret; }
drivers/net/wireless/ti/wlcore/spi.c +9 -14
@@ -327,27 +327,25 @@ static struct wl1271_if_operations spi_ops = {static int wl1271_probe (struct spi_device *spi) {struct wl12xx_spi_glue *glue; -struct wlcore_platdev_data *pdev_data; +struct wlcore_platdev_data pdev_data;struct resource res[1 ];int ret = -ENOMEM ; - pdev_data =kzalloc (sizeof (*pdev_data),GFP_KERNEL ); -if (!pdev_data) - goto out; +memset (&pdev_data,0x00 ,sizeof (pdev_data)); - pdev_data->pdata =dev_get_platdata (&spi->dev); -if (!pdev_data->pdata) { + pdev_data.pdata =dev_get_platdata (&spi->dev); +if (!pdev_data.pdata) {dev_err (&spi->dev,"no platform data\n" ); ret = -ENODEV ; - goto out_free_pdev_data; + goto out; } - pdev_data->if_ops = &spi_ops; + pdev_data.if_ops = &spi_ops; glue =kzalloc (sizeof (*glue),GFP_KERNEL );if (!glue) {dev_err (&spi->dev,"can't allocate glue\n" ); - goto out_free_pdev_data; + goto out; } glue->dev = &spi->dev;
@@ -385,8 +383,8 @@ static int wl1271_probe(struct spi_device *spi) goto out_dev_put; } - ret =platform_device_add_data (glue->core, pdev_data, -sizeof (*pdev_data)); + ret =platform_device_add_data (glue->core, &pdev_data, +sizeof (pdev_data));if (ret) {dev_err (glue->dev,"can't add platform data\n" ); goto out_dev_put;
@@ -406,9 +404,6 @@ out_dev_put: out_free_glue:kfree (glue); -out_free_pdev_data: -kfree (pdev_data); - out:return ret; }
Signature · 1 line
1.9.1