| From 623e2a995d156e115c91f56a3ec691bdc333df8b Mon Sep 17 00:00:00 2001 |
| From: Chris Dickens <christopher.a.dickens@gmail.com> |
| Date: Sun, 13 Dec 2020 15:49:19 -0800 |
| Subject: [PATCH 1/1] linux_usbfs: Fix parsing of descriptors for |
| multi-configuration devices |
| |
| Commit e2be556bd2 ("linux_usbfs: Parse config descriptors during device |
| initialization") introduced a regression for devices with multiple |
| configurations. The logic that verifies the reported length of the |
| configuration descriptors failed to count the length of the |
| configuration descriptor itself and would truncate the actual length by |
| 9 bytes, leading to a parsing error for subsequent descriptors. |
| |
| Closes #825 |
| |
| Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com> |
| (cherry picked from commit f6d2cb561402c3b6d3627c0eb89e009b503d9067) |
| Signed-off-by: John Keeping <john@metanate.com> |
| --- |
| libusb/os/linux_usbfs.c | 12 ++++++++---- |
| 1 file changed, 8 insertions(+), 4 deletions(-) |
| |
| diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c |
| index fb2ed53..4d2dc8d 100644 |
| --- a/libusb/os/linux_usbfs.c |
| +++ b/libusb/os/linux_usbfs.c |
| @@ -641,7 +641,12 @@ static int seek_to_next_config(struct libusb_context *ctx, |
| uint8_t *buffer, size_t len) |
| { |
| struct usbi_descriptor_header *header; |
| - int offset = 0; |
| + int offset; |
| + |
| + /* Start seeking past the config descriptor */ |
| + offset = LIBUSB_DT_CONFIG_SIZE; |
| + buffer += LIBUSB_DT_CONFIG_SIZE; |
| + len -= LIBUSB_DT_CONFIG_SIZE; |
| |
| while (len > 0) { |
| if (len < 2) { |
| @@ -718,7 +723,7 @@ static int parse_config_descriptors(struct libusb_device *dev) |
| } |
| |
| if (priv->sysfs_dir) { |
| - /* |
| + /* |
| * In sysfs wTotalLength is ignored, instead the kernel returns a |
| * config descriptor with verified bLength fields, with descriptors |
| * with an invalid bLength removed. |
| @@ -727,8 +732,7 @@ static int parse_config_descriptors(struct libusb_device *dev) |
| int offset; |
| |
| if (num_configs > 1 && idx < num_configs - 1) { |
| - offset = seek_to_next_config(ctx, buffer + LIBUSB_DT_CONFIG_SIZE, |
| - remaining - LIBUSB_DT_CONFIG_SIZE); |
| + offset = seek_to_next_config(ctx, buffer, remaining); |
| if (offset < 0) |
| return offset; |
| sysfs_config_len = (uint16_t)offset; |
| -- |
| 2.30.1 |
| |