diff options
author | Nishka Dasgupta <nishkadg.linux@gmail.com> | 2019-07-11 10:54:05 +0300 |
---|---|---|
committer | Jacek Anaszewski <jacek.anaszewski@gmail.com> | 2019-07-22 21:35:00 +0300 |
commit | 730f693d79da8130c8ac18d1083cdb333fd8d7c8 (patch) | |
tree | 701e8edcad8a8ad5bfce430dc7557e68ecc13786 /drivers/leds/leds-max77650.c | |
parent | 533016c870a8d0cc01478ed9e780a46e830b3b22 (diff) | |
download | linux-730f693d79da8130c8ac18d1083cdb333fd8d7c8.tar.xz |
leds: max77650: Add of_node_put() before return
Each iteration of for_each_child_of_node puts the previous node, but in
the case of a return from the middle of the loop, there is no put, thus
causing a memory leak.
Hence create a new label, err_node_put, which puts the previous node and
returns variable rv. Modify the mid-loop return statements to instead
store the return value in rv and jump to err_node_put.
Issue found with Coccinelle.
Signed-off-by: Nishka Dasgupta <nishkadg.linux@gmail.com>
Reviewed-by: Dan Murphy <dmurphy@ti.com>
Acked-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Diffstat (limited to 'drivers/leds/leds-max77650.c')
-rw-r--r-- | drivers/leds/leds-max77650.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/leds/leds-max77650.c b/drivers/leds/leds-max77650.c index 150421387534..04738324b3e6 100644 --- a/drivers/leds/leds-max77650.c +++ b/drivers/leds/leds-max77650.c @@ -91,8 +91,10 @@ static int max77650_led_probe(struct platform_device *pdev) for_each_child_of_node(of_node, child) { rv = of_property_read_u32(child, "reg", ®); - if (rv || reg >= MAX77650_LED_NUM_LEDS) - return -EINVAL; + if (rv || reg >= MAX77650_LED_NUM_LEDS) { + rv = -EINVAL; + goto err_node_put; + } led = &leds[reg]; led->map = map; @@ -107,8 +109,10 @@ static int max77650_led_probe(struct platform_device *pdev) } else { led->cdev.name = devm_kasprintf(dev, GFP_KERNEL, "max77650:%s", label); - if (!led->cdev.name) - return -ENOMEM; + if (!led->cdev.name) { + rv = -ENOMEM; + goto err_node_put; + } } of_property_read_string(child, "linux,default-trigger", @@ -116,20 +120,23 @@ static int max77650_led_probe(struct platform_device *pdev) rv = devm_of_led_classdev_register(dev, child, &led->cdev); if (rv) - return rv; + goto err_node_put; rv = regmap_write(map, led->regA, MAX77650_LED_A_DEFAULT); if (rv) - return rv; + goto err_node_put; rv = regmap_write(map, led->regB, MAX77650_LED_B_DEFAULT); if (rv) - return rv; + goto err_node_put; } return regmap_write(map, MAX77650_REG_CNFG_LED_TOP, MAX77650_LED_TOP_DEFAULT); +err_node_put: + of_node_put(child); + return rv; } static struct platform_driver max77650_led_driver = { |