OSDN Git Service

USB: core: prevent malicious bNumInterfaces overflow
authorAlan Stern <stern@rowland.harvard.edu>
Tue, 12 Dec 2017 19:25:13 +0000 (14:25 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Dec 2017 11:28:43 +0000 (12:28 +0100)
A malicious USB device with crafted descriptors can cause the kernel
to access unallocated memory by setting the bNumInterfaces value too
high in a configuration descriptor.  Although the value is adjusted
during parsing, this adjustment is skipped in one of the error return
paths.

This patch prevents the problem by setting bNumInterfaces to 0
initially.  The existing code already sets it to the proper value
after parsing is complete.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/config.c

index 55b198b..78e92d2 100644 (file)
@@ -555,6 +555,9 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
        unsigned iad_num = 0;
 
        memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+       nintf = nintf_orig = config->desc.bNumInterfaces;
+       config->desc.bNumInterfaces = 0;        // Adjusted later
+
        if (config->desc.bDescriptorType != USB_DT_CONFIG ||
            config->desc.bLength < USB_DT_CONFIG_SIZE ||
            config->desc.bLength > size) {
@@ -568,7 +571,6 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
        buffer += config->desc.bLength;
        size -= config->desc.bLength;
 
-       nintf = nintf_orig = config->desc.bNumInterfaces;
        if (nintf > USB_MAXINTERFACES) {
                dev_warn(ddev, "config %d has too many interfaces: %d, "
                    "using maximum allowed: %d\n",