windows: Fix off-by-one error in HID backend for devices without report IDs

When the windows HID backend is used for interrupt or bulk transfers on
USB-HID compliant devices which don't use HID report IDs, the current
code properly adds a zero prefix byte for report ID 0x00 before an OUT
transfer, and properly strips the leading zero prefix byte from buffers
received by IN transfers. Length of transmitted data is increased by +1
accordingly to account for the extra prefix byte.

However, on transfer completion the length of sent or received data is
not adjusted back again by one. This leads to misreporting of effective
transfer length for both OUT and IN transfers, reporting one byte too
much. It also causes a memcpy for IN transfers which copies one byte of
data too much into the client provided target buffer
transfer_priv->hid_dest, appending an extra zero byte at the end and
thereby writing one byte past the size of the client target buffer. This
could lead to memory corruption or a access violation if the client
application is unlucky.

This commit fixes the problem by detecting this type of HID transfers
and adjusting the effective length of the transfer down one byte.

The fix has been successfully tested with a Griffin PowerMate USB-HID
device that doesn't support report IDs, performing interrupt transfers
from/to the device.

Closes #1217

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
This commit is contained in:
Mario Kleiner
2022-11-15 07:07:22 +01:00
committed by Tormod Volden
parent bed8d3034e
commit 69e4ee63c9
2 changed files with 4 additions and 1 deletions

View File

@@ -4242,12 +4242,15 @@ static enum libusb_transfer_status hid_copy_transfer_data(int sub_api, struct us
}
if (transfer_priv->hid_buffer[0] == 0) {
length--;
memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer + 1, length);
} else {
memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, length);
}
}
transfer_priv->hid_dest = NULL;
} else if ((length > 0) && (transfer_priv->hid_buffer[0] == 0)) {
length--;
}
// For write, we just need to free the hid buffer
safe_free(transfer_priv->hid_buffer);

View File

@@ -1 +1 @@
#define LIBUSB_NANO 11750
#define LIBUSB_NANO 11751