Core: Avoid short read failures on broken descriptors
authorPeter Stuge <peter@stuge.se>
Tue, 30 Oct 2012 00:11:41 +0000 (00:11 +0000)
committerPete Batard <pete@akeo.ie>
Sun, 25 Nov 2012 00:27:42 +0000 (00:27 +0000)
* See http://marc.info/?t=135132844600001&r=1&w=2

libusb/descriptor.c
libusb/os/linux_usbfs.c
libusb/version_nano.h

index 0c5f51f..f3a4132 100644 (file)
@@ -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",
index 5093745..3d79bb1 100644 (file)
@@ -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;
index 7ecb4f7..6c90c70 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10586
+#define LIBUSB_NANO 10587