From 5e479f1821d3294fb1cc70c5867c69eca2551de7 Mon Sep 17 00:00:00 2001 From: Peter Stuge Date: Tue, 30 Oct 2012 00:11:41 +0000 Subject: [PATCH] Core: Avoid short read failures on broken descriptors * See http://marc.info/?t=135132844600001&r=1&w=2 --- libusb/descriptor.c | 14 ++++++++++++++ libusb/os/linux_usbfs.c | 3 +-- libusb/version_nano.h | 2 +- 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 -- 2.7.4