From c5b600a3c05b1a7a110d558df935a8fc8a471c79 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 4 Jun 2026 08:37:37 +0200 Subject: [PATCH] Bluetooth: btusb: fix use-after-free on marvell probe failure Make sure to stop any TX URBs submitted during Marvell OOB wakeup configuration on later probe failures to avoid use-after-free in the completion callback. This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths. Link: https://sashiko.dev/#/patchset/20260402092704.2346710-1-johan%40kernel.org Fixes: a4ccc9e33d2f ("Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup") Cc: stable@vger.kernel.org # 4.11 Cc: Rajat Jain Signed-off-by: Johan Hovold Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btusb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c181e1a3eb3e..669fb3ebde4c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -4237,7 +4237,7 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_INTEL_COMBINED) { err = btintel_configure_setup(hdev, btusb_driver.name); if (err) - goto out_free_dev; + goto err_kill_tx_urbs; /* Transport specific configuration */ hdev->send = btusb_send_frame_intel; @@ -4401,7 +4401,7 @@ static int btusb_probe(struct usb_interface *intf, err = usb_set_interface(data->udev, 0, 0); if (err < 0) { BT_ERR("failed to set interface 0, alt 0 %d", err); - goto out_free_dev; + goto err_kill_tx_urbs; } } @@ -4409,7 +4409,7 @@ static int btusb_probe(struct usb_interface *intf, err = usb_driver_claim_interface(&btusb_driver, data->isoc, data); if (err < 0) - goto out_free_dev; + goto err_kill_tx_urbs; } if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && data->diag) { @@ -4445,6 +4445,8 @@ static int btusb_probe(struct usb_interface *intf, usb_set_intfdata(data->isoc, NULL); usb_driver_release_interface(&btusb_driver, data->isoc); } +err_kill_tx_urbs: + usb_kill_anchored_urbs(&data->tx_anchor); out_free_dev: if (data->reset_gpio) gpiod_put(data->reset_gpio);