gpiolib: free device name on error path to fix kmemleak

In gpiochip_add_data_with_key, we should check the return value of
dev_set_name to ensure that device name is allocated successfully
and then add a label on the error path to free device name to fix
kmemleak as below:

unreferenced object 0xc2d6fc40 (size 64):
  comm "kworker/0:1", pid 16, jiffies 4294937425 (age 65.120s)
  hex dump (first 32 bytes):
    67 70 69 6f 63 68 69 70 30 00 1a c0 54 63 1a c0  gpiochip0...Tc..
    0c ed 84 c0 48 ed 84 c0 3c ee 84 c0 10 00 00 00  ....H...<.......
  backtrace:
    [<962810f7>] kobject_set_name_vargs+0x2c/0xa0
    [<f50797e6>] dev_set_name+0x2c/0x5c
    [<94abbca9>] gpiochip_add_data_with_key+0xfc/0xce8
    [<5c4193e0>] omap_gpio_probe+0x33c/0x68c
    [<3402f137>] platform_probe+0x58/0xb8
    [<7421e210>] really_probe+0xec/0x3b4
    [<000f8ada>] driver_probe_device+0x58/0xb4
    [<67e0f7f7>] bus_for_each_drv+0x80/0xd0
    [<4de545dc>] __device_attach+0xe8/0x15c
    [<2e4431e7>] bus_probe_device+0x84/0x8c
    [<c18b1de9>] device_add+0x384/0x7c0
    [<5aff2995>] of_platform_device_create_pdata+0x8c/0xb8
    [<061c3483>] of_platform_bus_create+0x198/0x230
    [<5ee6d42a>] of_platform_populate+0x60/0xb8
    [<2647300f>] sysc_probe+0xd18/0x135c
    [<3402f137>] platform_probe+0x58/0xb8

Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com>
Cc: stable@vger.kernel.org
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This commit is contained in:
Quanyang Wang 2021-01-29 16:19:17 +08:00 committed by Bartosz Golaszewski
parent 03a58ea590
commit c351bb64cb
1 changed files with 8 additions and 2 deletions

View File

@ -603,7 +603,11 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gdev->id; ret = gdev->id;
goto err_free_gdev; goto err_free_gdev;
} }
dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
if (ret)
goto err_free_ida;
device_initialize(&gdev->dev); device_initialize(&gdev->dev);
dev_set_drvdata(&gdev->dev, gdev); dev_set_drvdata(&gdev->dev, gdev);
if (gc->parent && gc->parent->driver) if (gc->parent && gc->parent->driver)
@ -617,7 +621,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL); gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
if (!gdev->descs) { if (!gdev->descs) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_free_ida; goto err_free_dev_name;
} }
if (gc->ngpio == 0) { if (gc->ngpio == 0) {
@ -768,6 +772,8 @@ err_free_label:
kfree_const(gdev->label); kfree_const(gdev->label);
err_free_descs: err_free_descs:
kfree(gdev->descs); kfree(gdev->descs);
err_free_dev_name:
kfree(dev_name(&gdev->dev));
err_free_ida: err_free_ida:
ida_free(&gpio_ida, gdev->id); ida_free(&gpio_ida, gdev->id);
err_free_gdev: err_free_gdev: