| From 48a4ff1c7bb5a32d2e396b03132d20d552c0eca7 Mon Sep 17 00:00:00 2001 |
| From: Alan Stern <stern@rowland.harvard.edu> |
| Date: Tue, 12 Dec 2017 14:25:13 -0500 |
| Subject: USB: core: prevent malicious bNumInterfaces overflow |
| |
| From: Alan Stern <stern@rowland.harvard.edu> |
| |
| commit 48a4ff1c7bb5a32d2e396b03132d20d552c0eca7 upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/core/config.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/usb/core/config.c |
| +++ b/drivers/usb/core/config.c |
| @@ -450,6 +450,9 @@ static int usb_parse_configuration(struc |
| 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) { |
| @@ -463,7 +466,6 @@ static int usb_parse_configuration(struc |
| 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", |