]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Bluetooth: btusb: revert use of devm_kzalloc in btusb
authorRaphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
Wed, 10 Dec 2025 16:02:28 +0000 (11:02 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Jan 2026 12:09:56 +0000 (13:09 +0100)
[ Upstream commit 252714f1e8bdd542025b16321c790458014d6880 ]

This reverts commit 98921dbd00c4e ("Bluetooth: Use devm_kzalloc in
btusb.c file").

In btusb_probe(), we use devm_kzalloc() to allocate the btusb data. This
ties the lifetime of all the btusb data to the binding of a driver to
one interface, INTF. In a driver that binds to other interfaces, ISOC
and DIAG, this is an accident waiting to happen.

The issue is revealed in btusb_disconnect(), where calling
usb_driver_release_interface(&btusb_driver, data->intf) will have devm
free the data that is also being used by the other interfaces of the
driver that may not be released yet.

To fix this, revert the use of devm and go back to freeing memory
explicitly.

Fixes: 98921dbd00c4e ("Bluetooth: Use devm_kzalloc in btusb.c file")
Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/bluetooth/btusb.c

index 95483a8d7b1e93f5d6fc64cc21581cf6e200c8c9..c447e2e9417b38646b067663a5e87bef56b7e146 100644 (file)
@@ -3788,7 +3788,7 @@ static int btusb_probe(struct usb_interface *intf,
                        return -ENODEV;
        }
 
-       data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -3811,8 +3811,10 @@ static int btusb_probe(struct usb_interface *intf,
                }
        }
 
-       if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep)
+       if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
+               kfree(data);
                return -ENODEV;
+       }
 
        if (id->driver_info & BTUSB_AMP) {
                data->cmdreq_type = USB_TYPE_CLASS | 0x01;
@@ -3855,8 +3857,10 @@ static int btusb_probe(struct usb_interface *intf,
        data->recv_acl = hci_recv_frame;
 
        hdev = hci_alloc_dev_priv(priv_size);
-       if (!hdev)
+       if (!hdev) {
+               kfree(data);
                return -ENOMEM;
+       }
 
        hdev->bus = HCI_USB;
        hci_set_drvdata(hdev, data);
@@ -4104,6 +4108,7 @@ out_free_dev:
        if (data->reset_gpio)
                gpiod_put(data->reset_gpio);
        hci_free_dev(hdev);
+       kfree(data);
        return err;
 }
 
@@ -4149,6 +4154,7 @@ static void btusb_disconnect(struct usb_interface *intf)
        }
 
        hci_free_dev(hdev);
+       kfree(data);
 }
 
 #ifdef CONFIG_PM