]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Bluetooth: btusb: Fix short read errors in btusb_qca_send_vendor_req()
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jul 2026 15:57:34 +0000 (17:57 +0200)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 28 Jul 2026 20:13:48 +0000 (16:13 -0400)
If btusb_qca_send_vendor_req() gets a "short" read from a device, it
will accidentally treat that as a "real" read and populate the returned
value with some unknown and probably totally invalid data.

Fix this logic error up by calling usb_control_msg_recv() which
guarantees a "full" read happens, and then simplify the error checking
for when btusb_qca_send_vendor_req() is called.

Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btusb.c

index 8f7ed469cac6829a34f0f6f16231e83d25b13a8d..184e95c1625e57303d3c5083c30ccb15a2cb06ce 100644 (file)
@@ -3424,28 +3424,16 @@ static const char *qca_get_fw_subdirectory(const struct qca_version *ver)
 static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
                                     void *data, u16 size)
 {
-       int pipe, err;
-       u8 *buf;
-
-       buf = kmalloc(size, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
+       int err;
 
        /* Found some of USB hosts have IOT issues with ours so that we should
         * not wait until HCI layer is ready.
         */
-       pipe = usb_rcvctrlpipe(udev, 0);
-       err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN,
-                             0, 0, buf, size, USB_CTRL_GET_TIMEOUT);
-       if (err < 0) {
+       err = usb_control_msg_recv(udev, 0, request, USB_TYPE_VENDOR | USB_DIR_IN,
+                                  0, 0, data, size, USB_CTRL_GET_TIMEOUT,
+                                  GFP_KERNEL);
+       if (err)
                dev_err(&udev->dev, "Failed to access otp area (%d)", err);
-               goto done;
-       }
-
-       memcpy(data, buf, size);
-
-done:
-       kfree(buf);
 
        return err;
 }
@@ -3652,7 +3640,7 @@ static bool btusb_qca_need_patch(struct usb_device *udev)
        struct qca_version ver;
 
        if (btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
-                                     sizeof(ver)) < 0)
+                                     sizeof(ver)))
                return false;
        /* only low ROM versions need patches */
        return !(le32_to_cpu(ver.rom_version) & ~0xffffU);
@@ -3670,7 +3658,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
 
        err = btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
                                        sizeof(ver));
-       if (err < 0)
+       if (err)
                return err;
 
        ver_rom = le32_to_cpu(ver.rom_version);
@@ -3693,7 +3681,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
 
        err = btusb_qca_send_vendor_req(udev, QCA_CHECK_STATUS, &status,
                                        sizeof(status));
-       if (err < 0)
+       if (err)
                return err;
 
        if (!(status & QCA_PATCH_UPDATED)) {
@@ -3704,7 +3692,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
 
        err = btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
                                        sizeof(ver));
-       if (err < 0)
+       if (err)
                return err;
 
        btdata->qca_dump.fw_version = le32_to_cpu(ver.patch_version);