| From 96a923bca54d4468a889b13ab7e9c466db6d79a8 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 3 Jan 2025 23:18:26 +0900 |
| Subject: gpio: virtuser: fix missing lookup table cleanups |
| |
| From: Koichiro Den <koichiro.den@canonical.com> |
| |
| [ Upstream commit a619cba8c69c434258ff4101d463322cd63e1bdc ] |
| |
| When a virtuser device is created via configfs and the probe fails due |
| to an incorrect lookup table, the table is not removed. This prevents |
| subsequent probe attempts from succeeding, even if the issue is |
| corrected, unless the device is released. Additionally, cleanup is also |
| needed in the less likely case of platform_device_register_full() |
| failure. |
| |
| Besides, a consistent memory leak in lookup_table->dev_id was spotted |
| using kmemleak by toggling the live state between 0 and 1 with a correct |
| lookup table. |
| |
| Introduce gpio_virtuser_remove_lookup_table() as the counterpart to the |
| existing gpio_virtuser_make_lookup_table() and call it from all |
| necessary points to ensure proper cleanup. |
| |
| Fixes: 91581c4b3f29 ("gpio: virtuser: new virtual testing driver for the GPIO API") |
| Signed-off-by: Koichiro Den <koichiro.den@canonical.com> |
| Link: https://lore.kernel.org/r/20250103141829.430662-2-koichiro.den@canonical.com |
| Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpio/gpio-virtuser.c | 36 +++++++++++++++++++++++++----------- |
| 1 file changed, 25 insertions(+), 11 deletions(-) |
| |
| diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c |
| index 91b6352c957c..e89b1239b635 100644 |
| --- a/drivers/gpio/gpio-virtuser.c |
| +++ b/drivers/gpio/gpio-virtuser.c |
| @@ -1439,6 +1439,15 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev) |
| return 0; |
| } |
| |
| +static void |
| +gpio_virtuser_remove_lookup_table(struct gpio_virtuser_device *dev) |
| +{ |
| + gpiod_remove_lookup_table(dev->lookup_table); |
| + kfree(dev->lookup_table->dev_id); |
| + kfree(dev->lookup_table); |
| + dev->lookup_table = NULL; |
| +} |
| + |
| static struct fwnode_handle * |
| gpio_virtuser_make_device_swnode(struct gpio_virtuser_device *dev) |
| { |
| @@ -1487,10 +1496,8 @@ gpio_virtuser_device_activate(struct gpio_virtuser_device *dev) |
| pdevinfo.fwnode = swnode; |
| |
| ret = gpio_virtuser_make_lookup_table(dev); |
| - if (ret) { |
| - fwnode_remove_software_node(swnode); |
| - return ret; |
| - } |
| + if (ret) |
| + goto err_remove_swnode; |
| |
| reinit_completion(&dev->probe_completion); |
| dev->driver_bound = false; |
| @@ -1498,23 +1505,31 @@ gpio_virtuser_device_activate(struct gpio_virtuser_device *dev) |
| |
| pdev = platform_device_register_full(&pdevinfo); |
| if (IS_ERR(pdev)) { |
| + ret = PTR_ERR(pdev); |
| bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); |
| - fwnode_remove_software_node(swnode); |
| - return PTR_ERR(pdev); |
| + goto err_remove_lookup_table; |
| } |
| |
| wait_for_completion(&dev->probe_completion); |
| bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); |
| |
| if (!dev->driver_bound) { |
| - platform_device_unregister(pdev); |
| - fwnode_remove_software_node(swnode); |
| - return -ENXIO; |
| + ret = -ENXIO; |
| + goto err_unregister_pdev; |
| } |
| |
| dev->pdev = pdev; |
| |
| return 0; |
| + |
| +err_unregister_pdev: |
| + platform_device_unregister(pdev); |
| +err_remove_lookup_table: |
| + gpio_virtuser_remove_lookup_table(dev); |
| +err_remove_swnode: |
| + fwnode_remove_software_node(swnode); |
| + |
| + return ret; |
| } |
| |
| static void |
| @@ -1526,10 +1541,9 @@ gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev) |
| |
| swnode = dev_fwnode(&dev->pdev->dev); |
| platform_device_unregister(dev->pdev); |
| + gpio_virtuser_remove_lookup_table(dev); |
| fwnode_remove_software_node(swnode); |
| dev->pdev = NULL; |
| - gpiod_remove_lookup_table(dev->lookup_table); |
| - kfree(dev->lookup_table); |
| } |
| |
| static ssize_t |
| -- |
| 2.39.5 |
| |