From: Greg Kroah-Hartman Date: Mon, 9 Oct 2017 12:03:01 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.75~34 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cbe3437dd1e9379e1afab7692b998e8b162b6661;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: usb-fix-out-of-bounds-in-usb_set_configuration.patch usb-increase-quirk-delay-for-usb-devices.patch usb-uas-fix-bug-in-handling-of-alternate-settings.patch xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch --- diff --git a/queue-3.18/series b/queue-3.18/series index 0d1f09e746b..f038eaf3ce9 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -9,3 +9,7 @@ usb-pci-quirks.c-corrected-timeout-values-used-in-handshake.patch usb-dummy-hcd-fix-connection-failures-wrong-speed.patch usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch usb-devio-don-t-corrupt-user-memory.patch +usb-uas-fix-bug-in-handling-of-alternate-settings.patch +usb-increase-quirk-delay-for-usb-devices.patch +usb-fix-out-of-bounds-in-usb_set_configuration.patch +xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch diff --git a/queue-3.18/usb-fix-out-of-bounds-in-usb_set_configuration.patch b/queue-3.18/usb-fix-out-of-bounds-in-usb_set_configuration.patch new file mode 100644 index 00000000000..7b7a0ce85f6 --- /dev/null +++ b/queue-3.18/usb-fix-out-of-bounds-in-usb_set_configuration.patch @@ -0,0 +1,67 @@ +From bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Tue, 19 Sep 2017 15:07:17 +0200 +Subject: USB: fix out-of-bounds in usb_set_configuration + +From: Greg Kroah-Hartman + +commit bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb upstream. + +Andrey Konovalov reported a possible out-of-bounds problem for a USB interface +association descriptor. He writes: + It seems there's no proper size check of a USB_DT_INTERFACE_ASSOCIATION + descriptor. It's only checked that the size is >= 2 in + usb_parse_configuration(), so find_iad() might do out-of-bounds access + to intf_assoc->bInterfaceCount. + +And he's right, we don't check for crazy descriptors of this type very well, so +resolve this problem. Yet another issue found by syzkaller... + +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 14 +++++++++++--- + include/uapi/linux/usb/ch9.h | 1 + + 2 files changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -538,15 +538,23 @@ static int usb_parse_configuration(struc + + } else if (header->bDescriptorType == + USB_DT_INTERFACE_ASSOCIATION) { ++ struct usb_interface_assoc_descriptor *d; ++ ++ d = (struct usb_interface_assoc_descriptor *)header; ++ if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { ++ dev_warn(ddev, ++ "config %d has an invalid interface association descriptor of length %d, skipping\n", ++ cfgno, d->bLength); ++ continue; ++ } ++ + if (iad_num == USB_MAXIADS) { + dev_warn(ddev, "found more Interface " + "Association Descriptors " + "than allocated for in " + "configuration %d\n", cfgno); + } else { +- config->intf_assoc[iad_num] = +- (struct usb_interface_assoc_descriptor +- *)header; ++ config->intf_assoc[iad_num] = d; + iad_num++; + } + +--- a/include/uapi/linux/usb/ch9.h ++++ b/include/uapi/linux/usb/ch9.h +@@ -705,6 +705,7 @@ struct usb_interface_assoc_descriptor { + __u8 iFunction; + } __attribute__ ((packed)); + ++#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8 + + /*-------------------------------------------------------------------------*/ + diff --git a/queue-3.18/usb-increase-quirk-delay-for-usb-devices.patch b/queue-3.18/usb-increase-quirk-delay-for-usb-devices.patch new file mode 100644 index 00000000000..5bf362bcdf0 --- /dev/null +++ b/queue-3.18/usb-increase-quirk-delay-for-usb-devices.patch @@ -0,0 +1,52 @@ +From b2a542bbb3081dbd64acc8929c140d196664c406 Mon Sep 17 00:00:00 2001 +From: Dmitry Fleytman +Date: Tue, 5 Sep 2017 11:40:56 +0300 +Subject: usb: Increase quirk delay for USB devices + +From: Dmitry Fleytman + +commit b2a542bbb3081dbd64acc8929c140d196664c406 upstream. + +Commit e0429362ab15 +("usb: Add device quirk for Logitech HD Pro Webcams C920 and C930e") +introduced quirk to workaround an issue with some Logitech webcams. + +The workaround is introducing delay for some USB operations. + +According to our testing, delay introduced by original commit +is not long enough and in rare cases we still see issues described +by the aforementioned commit. + +This patch increases delays introduced by original commit. +Having this patch applied we do not see those problems anymore. + +Signed-off-by: Dmitry Fleytman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 2 +- + drivers/usb/core/hub.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -747,7 +747,7 @@ int usb_get_configuration(struct usb_dev + } + + if (dev->quirks & USB_QUIRK_DELAY_INIT) +- msleep(100); ++ msleep(200); + + result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, + bigbuffer, length); +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4719,7 +4719,7 @@ static void hub_port_connect(struct usb_ + goto loop; + + if (udev->quirks & USB_QUIRK_DELAY_INIT) +- msleep(1000); ++ msleep(2000); + + /* consecutive bus-powered hubs aren't reliable; they can + * violate the voltage drop budget. if the new child has diff --git a/queue-3.18/usb-uas-fix-bug-in-handling-of-alternate-settings.patch b/queue-3.18/usb-uas-fix-bug-in-handling-of-alternate-settings.patch new file mode 100644 index 00000000000..642422586f6 --- /dev/null +++ b/queue-3.18/usb-uas-fix-bug-in-handling-of-alternate-settings.patch @@ -0,0 +1,103 @@ +From 786de92b3cb26012d3d0f00ee37adf14527f35c4 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 22 Sep 2017 11:56:49 -0400 +Subject: USB: uas: fix bug in handling of alternate settings + +From: Alan Stern + +commit 786de92b3cb26012d3d0f00ee37adf14527f35c4 upstream. + +The uas driver has a subtle bug in the way it handles alternate +settings. The uas_find_uas_alt_setting() routine returns an +altsetting value (the bAlternateSetting number in the descriptor), but +uas_use_uas_driver() then treats that value as an index to the +intf->altsetting array, which it isn't. + +Normally this doesn't cause any problems because the various +alternate settings have bAlternateSetting values 0, 1, 2, ..., so the +value is equal to the index in the array. But this is not guaranteed, +and Andrey Konovalov used the syzkaller fuzzer with KASAN to get a +slab-out-of-bounds error by violating this assumption. + +This patch fixes the bug by making uas_find_uas_alt_setting() return a +pointer to the altsetting entry rather than either the value or the +index. Pointers are less subject to misinterpretation. + +Signed-off-by: Alan Stern +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas-detect.h | 15 ++++++++------- + drivers/usb/storage/uas.c | 10 +++++----- + 2 files changed, 13 insertions(+), 12 deletions(-) + +--- a/drivers/usb/storage/uas-detect.h ++++ b/drivers/usb/storage/uas-detect.h +@@ -9,7 +9,8 @@ static int uas_is_interface(struct usb_h + intf->desc.bInterfaceProtocol == USB_PR_UAS); + } + +-static int uas_find_uas_alt_setting(struct usb_interface *intf) ++static struct usb_host_interface *uas_find_uas_alt_setting( ++ struct usb_interface *intf) + { + int i; + +@@ -17,10 +18,10 @@ static int uas_find_uas_alt_setting(stru + struct usb_host_interface *alt = &intf->altsetting[i]; + + if (uas_is_interface(alt)) +- return alt->desc.bAlternateSetting; ++ return alt; + } + +- return -ENODEV; ++ return NULL; + } + + static int uas_find_endpoints(struct usb_host_interface *alt, +@@ -58,14 +59,14 @@ static int uas_use_uas_driver(struct usb + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + unsigned long flags = id->driver_info; +- int r, alt; +- ++ struct usb_host_interface *alt; ++ int r; + + alt = uas_find_uas_alt_setting(intf); +- if (alt < 0) ++ if (!alt) + return 0; + +- r = uas_find_endpoints(&intf->altsetting[alt], eps); ++ r = uas_find_endpoints(alt, eps); + if (r < 0) + return 0; + +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -866,14 +866,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids); + static int uas_switch_interface(struct usb_device *udev, + struct usb_interface *intf) + { +- int alt; ++ struct usb_host_interface *alt; + + alt = uas_find_uas_alt_setting(intf); +- if (alt < 0) +- return alt; ++ if (!alt) ++ return -ENODEV; + +- return usb_set_interface(udev, +- intf->altsetting[0].desc.bInterfaceNumber, alt); ++ return usb_set_interface(udev, alt->desc.bInterfaceNumber, ++ alt->desc.bAlternateSetting); + } + + static int uas_configure_endpoints(struct uas_dev_info *devinfo) diff --git a/queue-3.18/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch b/queue-3.18/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch new file mode 100644 index 00000000000..c3db3aafe1f --- /dev/null +++ b/queue-3.18/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch @@ -0,0 +1,34 @@ +From 5a838a13c9b4e5dd188b7a6eaeb894e9358ead0c Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 18 Sep 2017 17:39:13 +0300 +Subject: xhci: fix finding correct bus_state structure for USB 3.1 hosts + +From: Mathias Nyman + +commit 5a838a13c9b4e5dd188b7a6eaeb894e9358ead0c upstream. + +xhci driver keeps a bus_state structure for each hcd (usb2 and usb3) + +The structure is picked based on hcd speed, but driver only compared +for HCD_USB3 speed, returning the wrong bus_state for HCD_USB31 hosts. + +This caused null pointer dereference errors in bus_resume function. + +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1434,7 +1434,7 @@ struct xhci_bus_state { + + static inline unsigned int hcd_index(struct usb_hcd *hcd) + { +- if (hcd->speed == HCD_USB3) ++ if (hcd->speed >= HCD_USB3) + return 0; + else + return 1;