|
|
@@ -0,0 +1,61 @@
|
|
|
+From f6d2cb561402c3b6d3627c0eb89e009b503d9067 Mon Sep 17 00:00:00 2001
|
|
|
+From: Chris Dickens <[email protected]>
|
|
|
+Date: Sun, 13 Dec 2020 15:49:19 -0800
|
|
|
+Subject: [PATCH] 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 <[email protected]>
|
|
|
+---
|
|
|
+ libusb/os/linux_usbfs.c | 12 ++++++++----
|
|
|
+ libusb/version_nano.h | 2 +-
|
|
|
+ 2 files changed, 9 insertions(+), 5 deletions(-)
|
|
|
+
|
|
|
+--- a/libusb/os/linux_usbfs.c
|
|
|
++++ b/libusb/os/linux_usbfs.c
|
|
|
+@@ -641,7 +641,12 @@ static int seek_to_next_config(struct li
|
|
|
+ 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(stru
|
|
|
+ }
|
|
|
+
|
|
|
+ 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(stru
|
|
|
+ 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;
|
|
|
+--- a/libusb/version_nano.h
|
|
|
++++ b/libusb/version_nano.h
|
|
|
+@@ -1 +1 @@
|
|
|
+-#define LIBUSB_NANO 11585
|
|
|
++#define LIBUSB_NANO 11586
|