summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner.de@gmail.com>2022-11-15 07:07:22 +0100
committerTormod Volden <debian.tormod@gmail.com>2022-12-19 21:49:50 +0100
commit69e4ee63c97f48728fc12292d4674cd609af61e9 (patch)
tree4abb0cb2407a92805f103b20d5d5c12c0e794cd7
parentbed8d3034eac74a6e1ba123b5c270ea63cb6cf1a (diff)
downloadlibusb-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.c3
-rw-r--r--libusb/version_nano.h2
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