gpiolib: free device name on error path to fix kmemleak
authorQuanyang Wang <quanyang.wang@windriver.com>
Fri, 29 Jan 2021 08:19:17 +0000 (16:19 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Feb 2021 08:29:16 +0000 (09:29 +0100)
commit c351bb64cbe67029c68dea3adbec1b9508c6ff0f upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpio/gpiolib.c

index 4ad3c4b276dcf720c6936f557f76cd308e7f5796..7e17d4edccb12b2dc098de75f4fc6ccdd26963b0 100644 (file)
@@ -602,7 +602,11 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
                ret = gdev->id;
                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);
        dev_set_drvdata(&gdev->dev, gdev);
        if (gc->parent && gc->parent->driver)
@@ -616,7 +620,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
        gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
        if (!gdev->descs) {
                ret = -ENOMEM;
-               goto err_free_ida;
+               goto err_free_dev_name;
        }
 
        if (gc->ngpio == 0) {
@@ -767,6 +771,8 @@ err_free_label:
        kfree_const(gdev->label);
 err_free_descs:
        kfree(gdev->descs);
+err_free_dev_name:
+       kfree(dev_name(&gdev->dev));
 err_free_ida:
        ida_free(&gpio_ida, gdev->id);
 err_free_gdev: