From: Greg Kroah-Hartman Date: Mon, 27 Jul 2026 15:57:34 +0000 (+0200) Subject: Bluetooth: btusb: Fix short read errors in btusb_qca_send_vendor_req() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cac43d360c928bc0cbbd18809632388265649761;p=thirdparty%2Fkernel%2Fstable.git Bluetooth: btusb: Fix short read errors in btusb_qca_send_vendor_req() 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 Signed-off-by: Greg Kroah-Hartman Signed-off-by: Luiz Augusto von Dentz --- diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 8f7ed469cac6..184e95c1625e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -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);