Bug 78521

Summary: Missing NULL check of the return value of platform_device_add_data() in function pcf50633_probe()
Product: Drivers Reporter: RUC_Soft_Sec (rucsoftsec)
Component: OtherAssignee: drivers_other
Status: NEW ---    
Severity: normal CC: lee.jones, sameo, xerofoify
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.39 Subsystem:
Regression: No Bisected commit-id:

Description RUC_Soft_Sec 2014-06-20 12:37:54 UTC
In function pcf50633_probe() at drivers/mfd/pcf50633-core.c:254, the call to platform_device_add_data() at line 315 may return a NULL value, but its return value is never checked against NULL, and thus an invalid access error may be triggered.
The related code snippets in function pcf50633_probe() are as followings.
pcf50633_probe @ drivers/mfd/pcf50633-core.c:254
254 static int __devinit pcf50633_probe(struct i2c_client *client,
255                                 const struct i2c_device_id *ids)
256 {
257         struct pcf50633 *pcf;
    ...
305         for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
306                 struct platform_device *pdev;
307 
308                 pdev = platform_device_alloc("pcf50633-regltr", i);
309                 if (!pdev) {
310                         dev_err(pcf->dev, "Cannot create regulator %d\n", i);
311                         continue;
312                 }
313 
314                 pdev->dev.parent = pcf->dev;
315                 platform_device_add_data(pdev, &pdata->reg_init_data[i],
316                                         sizeof(pdata->reg_init_data[i]));
317                 pcf->regulator_pdev[i] = pdev;
318 
319                 platform_device_add(pdev);
320         }
    ...
334         return ret;
335 }

Generally, the return value of platform_device_add_data() shall be checked against NULL , like the following code snippets in function ce4100_spi_probe().
ce4100_spi_probe @ drivers/spi/pxa2xx_spi_pci.c:53
 53 static int __devinit ce4100_spi_probe(struct pci_dev *dev,
 54                 const struct pci_device_id *ent)
 55 {
 56         int ret;
 57         resource_size_t phys_beg;
    ...
 87         ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata));
 88         if (ret)
 89                 goto err_nomem;
 90 
 91         pdev->dev.parent = &dev->dev;
 92         pdev->dev.of_node = dev->dev.of_node;
 93         ssp = &spi_info->ssp;
 94         ssp->phys_base = pci_resource_start(dev, 0);
 95         ssp->mmio_base = ioremap(phys_beg, phys_len);
 96         if (!ssp->mmio_base) {
 97                 dev_err(&pdev->dev, "failed to ioremap() registers\n");
 98                 ret = -EIO;
 99                 goto err_nomem;
100         }
    ...
111         ret = platform_device_add(pdev);
112         if (ret)
113                 goto err_dev_add;
114 
115         return ret;
    ...
128         return ret;
129 }

Thak you!

RUC_Soft_Sec, supported by China.X.Orion
Comment 1 xerofoify 2014-06-21 03:17:33 UTC
if (platform_device_add_data(pdev, &pdata->reg_init_data[i],
					sizeof(pdata->reg_init_data[i])) < 0) {
			platform_device_put(pdev);
			dev_err(pcf->dev, "Out of memory for regulator parameters %d\n",i);
			continue;
		}
Seems to  fix around NULL pointer check you have sent. I am going to email the maintainers in order to tell then that this bug has a code fix as you don't 
seem to being to reply to these messages.
Nick