Skip to content

Commit

Permalink
Fixed buffer overincrement 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.
  • Loading branch information
seanm committed May 13, 2024
1 parent 498e406 commit d12e64a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 7 deletions.
17 changes: 10 additions & 7 deletions libusb/descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,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 @@ -1356,12 +1356,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 @@ -1372,10 +1372,13 @@ static int parse_iad_array(struct libusb_context *ctx,
iad[i].iFunction = buffer[7];
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

0 comments on commit d12e64a

Please sign in to comment.