summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stuge <peter@stuge.se>2012-10-30 00:11:41 +0000
committerPete Batard <pete@akeo.ie>2012-11-25 00:27:42 +0000
commit5e479f1821d3294fb1cc70c5867c69eca2551de7 (patch)
treed0c19c46b65a7e88c9ff5589f98e104698ff4f0f
parent66db81a41cd64e638795f1da117e912e14d76f7c (diff)
downloadlibusb-5e479f1821d3294fb1cc70c5867c69eca2551de7.tar.gz
Core: Avoid short read failures on broken descriptors
* See http://marc.info/?t=135132844600001&r=1&w=2
-rw-r--r--libusb/descriptor.c14
-rw-r--r--libusb/os/linux_usbfs.c3
-rw-r--r--libusb/version_nano.h2
3 files changed, 16 insertions, 3 deletions
diff --git a/libusb/descriptor.c b/libusb/descriptor.c
index 0c5f51f..f3a4132 100644
--- a/libusb/descriptor.c
+++ b/libusb/descriptor.c
@@ -229,6 +229,12 @@ static int parse_interface(libusb_context *ctx,
header.bLength);
r = LIBUSB_ERROR_IO;
goto err;
+ } else if (header.bLength > size) {
+ usbi_warn(ctx, "invalid descriptor of length %d",
+ header.bLength);
+ /* The remaining bytes are bogus, but at least
+ * one interface is OK, so let's continue. */
+ break;
}
/* If we find another "proper" descriptor then we're done */
@@ -371,6 +377,14 @@ static int parse_configuration(struct libusb_context *ctx,
while (size >= DESC_HEADER_LENGTH) {
usbi_parse_descriptor(buffer, "bb", &header, 0);
+ /* If we've parsed at least one config descriptor then
+ * let's return that. */
+ if (header.bLength > size && i) {
+ usbi_warn(ctx, "invalid descriptor length of %d",
+ header.bLength);
+ return size;
+ }
+
if ((header.bLength > size) ||
(header.bLength < DESC_HEADER_LENGTH)) {
usbi_err(ctx, "invalid descriptor length of %d",
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 5093745..3d79bb1 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -690,7 +690,7 @@ static int sysfs_get_active_config_descriptor(struct libusb_device *dev,
r = LIBUSB_ERROR_NOT_FOUND;
} else if (r < len - sizeof(tmp)) {
usbi_err(DEVICE_CTX(dev), "short read %d/%d", r, len);
- r = LIBUSB_ERROR_IO;
+ r = 0;
}
} else {
r = 0;
@@ -740,7 +740,6 @@ static int get_config_descriptor(struct libusb_context *ctx, int fd,
return LIBUSB_ERROR_IO;
} else if (r < len) {
usbi_err(ctx, "short output read %d/%d", r, len);
- return LIBUSB_ERROR_IO;
}
return 0;
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 7ecb4f7..6c90c70 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10586
+#define LIBUSB_NANO 10587