mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
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 <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
0cc4b5649a
commit
cac43d360c
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user