[PATCH] extcon: usb-gpio: Use devm_delayed_work_autocancel() for detect work

Fan Wu <[email protected]>
Newsgroups org.kernel.vger.stable,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The id/vbus threaded IRQ handler re-arms the detect delayed work on every
edge. cancel_delayed_work_sync() in ->remove() runs before the IRQs are
freed by devm, so an IRQ firing in between can re-arm the work and run it
after info is freed, leading to a use-after-free. The same window exists on
probe-error paths.

Use devm_delayed_work_autocancel() so devm LIFO order frees the IRQs before
the work is cancelled, on every path. Drop the now-redundant cancel from
->remove(). This matches the other extcon drivers.

This issue was found by an in-house static analysis tool.
Compile-tested only; runtime testing is appreciated.

Fixes: e52817faae35 ("extcon: usb-gpio: Introduce gpio usb extcon driver")
Cc: [email protected]
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <[email protected]>
---
 drivers/extcon/extcon-usb-gpio.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c
index 5e8ad21ad206..4cc42f102098 100644
--- a/drivers/extcon/extcon-usb-gpio.c
+++ b/drivers/extcon/extcon-usb-gpio.c
@@ -6,6 +6,7 @@
  * Author: Roger Quadros <[email protected]>
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/extcon-provider.h>
 #include <linux/gpio/consumer.h>
 #include <linux/init.h>
@@ -146,7 +147,10 @@ static int usb_extcon_probe(struct platform_device *pdev)
 	if (ret < 0)
 		info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEBOUNCE_MS);
 
-	INIT_DELAYED_WORK(&info->wq_detcable, usb_extcon_detect_cable);
+	ret = devm_delayed_work_autocancel(dev, &info->wq_detcable,
+					   usb_extcon_detect_cable);
+	if (ret)
+		return ret;
 
 	if (info->id_gpiod) {
 		info->id_irq = gpiod_to_irq(info->id_gpiod);
@@ -195,9 +199,6 @@ static int usb_extcon_probe(struct platform_device *pdev)
 
 static void usb_extcon_remove(struct platform_device *pdev)
 {
-	struct usb_extcon_info *info = platform_get_drvdata(pdev);
-
-	cancel_delayed_work_sync(&info->wq_detcable);
 	device_init_wakeup(&pdev->dev, false);
 }
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.