diff options
author | Mario Kleiner <mario.kleiner.de@gmail.com> | 2022-11-15 07:07:22 +0100 |
---|---|---|
committer | Tormod Volden <debian.tormod@gmail.com> | 2022-12-19 21:49:50 +0100 |
commit | 69e4ee63c97f48728fc12292d4674cd609af61e9 (patch) | |
tree | 4abb0cb2407a92805f103b20d5d5c12c0e794cd7 | |
parent | bed8d3034eac74a6e1ba123b5c270ea63cb6cf1a (diff) | |
download | libusb-69e4ee63c97f48728fc12292d4674cd609af61e9.tar.gz |
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>
-rw-r--r-- | libusb/os/windows_winusb.c | 3 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
2 files changed, 4 insertions, 1 deletions
diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index f8c84f7..3e3f0b4 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -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); diff --git a/libusb/version_nano.h b/libusb/version_nano.h index c9efb6d..fe58632 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11750 +#define LIBUSB_NANO 11751 |