| From d3c731564e09b6c2ebefcd1344743a91a237d6dc Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= <mirq-linux@rere.qmqm.pl> |
| Date: Wed, 12 Aug 2020 03:31:36 +0200 |
| Subject: [PATCH] regulator: plug of_node leak in regulator_register()'s error |
| path |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit d3c731564e09b6c2ebefcd1344743a91a237d6dc upstream. |
| |
| By calling device_initialize() earlier and noting that kfree(NULL) is |
| ok, we can save a bit of code in error handling and plug of_node leak. |
| Fixed commit already did part of the work. |
| |
| Fixes: 9177514ce349 ("regulator: fix memory leak on error path of regulator_register()") |
| Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> |
| Reviewed-by: Vladimir Zapolskiy <vz@mleia.com> |
| Acked-by: Vladimir Zapolskiy <vz@mleia.com> |
| Cc: stable@vger.kernel.org |
| Link: https://lore.kernel.org/r/f5035b1b4d40745e66bacd571bbbb5e4644d21a1.1597195321.git.mirq-linux@rere.qmqm.pl |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| |
| diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c |
| index 9f4944dad3a1..1561f7555fc6 100644 |
| --- a/drivers/regulator/core.c |
| +++ b/drivers/regulator/core.c |
| @@ -5167,6 +5167,7 @@ regulator_register(const struct regulator_desc *regulator_desc, |
| ret = -ENOMEM; |
| goto rinse; |
| } |
| + device_initialize(&rdev->dev); |
| |
| /* |
| * Duplicate the config so the driver could override it after |
| @@ -5174,9 +5175,8 @@ regulator_register(const struct regulator_desc *regulator_desc, |
| */ |
| config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL); |
| if (config == NULL) { |
| - kfree(rdev); |
| ret = -ENOMEM; |
| - goto rinse; |
| + goto clean; |
| } |
| |
| init_data = regulator_of_get_init_data(dev, regulator_desc, config, |
| @@ -5188,10 +5188,8 @@ regulator_register(const struct regulator_desc *regulator_desc, |
| * from a gpio extender or something else. |
| */ |
| if (PTR_ERR(init_data) == -EPROBE_DEFER) { |
| - kfree(config); |
| - kfree(rdev); |
| ret = -EPROBE_DEFER; |
| - goto rinse; |
| + goto clean; |
| } |
| |
| /* |
| @@ -5244,7 +5242,6 @@ regulator_register(const struct regulator_desc *regulator_desc, |
| } |
| |
| /* register with sysfs */ |
| - device_initialize(&rdev->dev); |
| rdev->dev.class = ®ulator_class; |
| rdev->dev.parent = dev; |
| dev_set_name(&rdev->dev, "regulator.%lu", |
| @@ -5322,13 +5319,11 @@ regulator_register(const struct regulator_desc *regulator_desc, |
| mutex_lock(®ulator_list_mutex); |
| regulator_ena_gpio_free(rdev); |
| mutex_unlock(®ulator_list_mutex); |
| - put_device(&rdev->dev); |
| - rdev = NULL; |
| clean: |
| if (dangling_of_gpiod) |
| gpiod_put(config->ena_gpiod); |
| - kfree(rdev); |
| kfree(config); |
| + put_device(&rdev->dev); |
| rinse: |
| if (dangling_cfg_gpiod) |
| gpiod_put(cfg->ena_gpiod); |
| -- |
| 2.27.0 |
| |