| From 2515fc01cd1ace14aa49f56258e73974ef4ef0b6 Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Mon, 1 Jun 2020 15:39:47 +0200 |
| Subject: [PATCH] leds: lm3533: fix use-after-free on unbind |
| |
| commit d584221e683bbd173738603b83a315f27d27d043 upstream. |
| |
| Several MFD child drivers register their class devices directly under |
| the parent device. This means you cannot blindly do devres conversions |
| so that deregistration ends up being tied to the parent device, |
| something which leads to use-after-free on driver unbind when the class |
| device is released while still being registered. |
| |
| Fixes: 50154e29e5cc ("leds: lm3533: Use devm_led_classdev_register") |
| Cc: stable <stable@vger.kernel.org> # 4.6 |
| Cc: Amitoj Kaur Chawla <amitoj1606@gmail.com> |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| Signed-off-by: Pavel Machek <pavel@ucw.cz> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c |
| index 9504ad405aef..b3edee703193 100644 |
| --- a/drivers/leds/leds-lm3533.c |
| +++ b/drivers/leds/leds-lm3533.c |
| @@ -694,7 +694,7 @@ static int lm3533_led_probe(struct platform_device *pdev) |
| |
| platform_set_drvdata(pdev, led); |
| |
| - ret = devm_led_classdev_register(pdev->dev.parent, &led->cdev); |
| + ret = led_classdev_register(pdev->dev.parent, &led->cdev); |
| if (ret) { |
| dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id); |
| return ret; |
| @@ -704,13 +704,18 @@ static int lm3533_led_probe(struct platform_device *pdev) |
| |
| ret = lm3533_led_setup(led, pdata); |
| if (ret) |
| - return ret; |
| + goto err_deregister; |
| |
| ret = lm3533_ctrlbank_enable(&led->cb); |
| if (ret) |
| - return ret; |
| + goto err_deregister; |
| |
| return 0; |
| + |
| +err_deregister: |
| + led_classdev_unregister(&led->cdev); |
| + |
| + return ret; |
| } |
| |
| static int lm3533_led_remove(struct platform_device *pdev) |
| @@ -720,6 +725,7 @@ static int lm3533_led_remove(struct platform_device *pdev) |
| dev_dbg(&pdev->dev, "%s\n", __func__); |
| |
| lm3533_ctrlbank_disable(&led->cb); |
| + led_classdev_unregister(&led->cdev); |
| |
| return 0; |
| } |
| -- |
| 2.27.0 |
| |