summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorFan Wu <fanwu01@zju.edu.cn>2026-03-03 10:33:44 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-03-25 13:05:50 +0300
commit9c6159d5b72d5fc265cce5da04f27d730b552e69 (patch)
treef80c3d4fe2d8d8ae814274f69589a334b4cc9f9c /drivers/usb
parent4ee3062bf2c9a722afef429826e8607eaf3fc6a0 (diff)
downloadlinux-9c6159d5b72d5fc265cce5da04f27d730b552e69.tar.xz
usb: renesas_usbhs: fix use-after-free in ISR during device removal
commit 3cbc242b88c607f55da3d0d0d336b49bf1e20412 upstream. In usbhs_remove(), the driver frees resources (including the pipe array) while the interrupt handler (usbhs_interrupt) is still registered. If an interrupt fires after usbhs_pipe_remove() but before the driver is fully unbound, the ISR may access freed memory, causing a use-after-free. Fix this by calling devm_free_irq() before freeing resources. This ensures the interrupt handler is both disabled and synchronized (waits for any running ISR to complete) before usbhs_pipe_remove() is called. Fixes: f1407d5c6624 ("usb: renesas_usbhs: Add Renesas USBHS common code") Cc: stable <stable@kernel.org> Suggested-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Fan Wu <fanwu01@zju.edu.cn> Link: https://patch.msgid.link/20260303073344.34577-1-fanwu01@zju.edu.cn Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/renesas_usbhs/common.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index 2978e869ac8f..4fdc1d0c2451 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -800,6 +800,15 @@ static void usbhs_remove(struct platform_device *pdev)
usbhs_platform_call(priv, hardware_exit, pdev);
reset_control_assert(priv->rsts);
+
+ /*
+ * Explicitly free the IRQ to ensure the interrupt handler is
+ * disabled and synchronized before freeing resources.
+ * devm_free_irq() calls free_irq() which waits for any running
+ * ISR to complete, preventing UAF.
+ */
+ devm_free_irq(&pdev->dev, priv->irq, priv);
+
usbhs_mod_remove(priv);
usbhs_fifo_remove(priv);
usbhs_pipe_remove(priv);