Skip to content

Commit

Permalink
descriptor: Avoid buffer over-increment in parse_iad_array function
Browse files Browse the repository at this point in the history
The first iteration of this loop was safe because the beginning of the
function checked that `size` is at least LIBUSB_DT_CONFIG_SIZE (9) bytes
long.

But for subsequent iterations, it could advance the pointer too far
(which is undefined behaviour) depending on the content of the buffer
itself.

Closes #1460
  • Loading branch information
seanm authored and tormodvolden committed May 28, 2024
1 parent 678c812 commit 916c740
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 7 deletions.
15 changes: 9 additions & 6 deletions libusb/descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -1329,7 +1329,7 @@ static int parse_iad_array(struct libusb_context *ctx,
while (consumed < size) {
header.bLength = buf[0];
header.bDescriptorType = buf[1];
if (header.bLength < 2) {
if (header.bLength < DESC_HEADER_LENGTH) {
usbi_err(ctx, "invalid descriptor bLength %d",
header.bLength);
return LIBUSB_ERROR_IO;
Expand All @@ -1354,12 +1354,12 @@ static int parse_iad_array(struct libusb_context *ctx,
iad_array->iad = iad;

/* Second pass: Iterate through desc list, fill IAD structures */
consumed = 0;
int remaining = size;
i = 0;
while (consumed < size) {
do {
header.bLength = buffer[0];
header.bDescriptorType = buffer[1];
if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION) {
if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION && (remaining >= LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE)) {
iad[i].bLength = buffer[0];
iad[i].bDescriptorType = buffer[1];
iad[i].bFirstInterface = buffer[2];
Expand All @@ -1371,9 +1371,12 @@ static int parse_iad_array(struct libusb_context *ctx,
i++;
}

remaining -= header.bLength;
if (remaining < DESC_HEADER_LENGTH) {
break;
}
buffer += header.bLength;
consumed += header.bLength;
}
} while (1);
}

return LIBUSB_SUCCESS;
Expand Down
1 change: 1 addition & 0 deletions libusb/libusb.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ enum libusb_descriptor_type {
#define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE 6
#define LIBUSB_DT_BOS_SIZE 5
#define LIBUSB_DT_DEVICE_CAPABILITY_SIZE 3
#define LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE 8

/* BOS descriptor sizes */
#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7
Expand Down
2 changes: 1 addition & 1 deletion libusb/version_nano.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define LIBUSB_NANO 11911
#define LIBUSB_NANO 11912

0 comments on commit 916c740

Please sign in to comment.