]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Bluetooth: btusb: reorder cleanup in btusb_disconnect to avoid UAF
authorRaphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
Wed, 5 Nov 2025 19:28:41 +0000 (14:28 -0500)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 10 Nov 2025 21:07:01 +0000 (16:07 -0500)
There is a KASAN: slab-use-after-free read in btusb_disconnect().
Calling "usb_driver_release_interface(&btusb_driver, data->intf)" will
free the btusb data associated with the interface. The same data is
then used later in the function, hence the UAF.

Fix by moving the accesses to btusb data to before the data is free'd.

Reported-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2fc81b50a4f8263a159b
Tested-by: syzbot+2fc81b50a4f8263a159b@syzkaller.appspotmail.com
Fixes: fd913ef7ce619 ("Bluetooth: btusb: Add out-of-band wakeup support")
Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btusb.c

index 5e9ebf0c53125e46e21d8fc8666411990e7333c2..a722446ec73dd88b5fb09ff4a7fd271ac06e705e 100644 (file)
@@ -4361,6 +4361,11 @@ static void btusb_disconnect(struct usb_interface *intf)
 
        hci_unregister_dev(hdev);
 
+       if (data->oob_wake_irq)
+               device_init_wakeup(&data->udev->dev, false);
+       if (data->reset_gpio)
+               gpiod_put(data->reset_gpio);
+
        if (intf == data->intf) {
                if (data->isoc)
                        usb_driver_release_interface(&btusb_driver, data->isoc);
@@ -4371,17 +4376,11 @@ static void btusb_disconnect(struct usb_interface *intf)
                        usb_driver_release_interface(&btusb_driver, data->diag);
                usb_driver_release_interface(&btusb_driver, data->intf);
        } else if (intf == data->diag) {
-               usb_driver_release_interface(&btusb_driver, data->intf);
                if (data->isoc)
                        usb_driver_release_interface(&btusb_driver, data->isoc);
+               usb_driver_release_interface(&btusb_driver, data->intf);
        }
 
-       if (data->oob_wake_irq)
-               device_init_wakeup(&data->udev->dev, false);
-
-       if (data->reset_gpio)
-               gpiod_put(data->reset_gpio);
-
        hci_free_dev(hdev);
 }