From: Greg Kroah-Hartman Date: Wed, 26 Feb 2020 09:43:02 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.215~73 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0bf45118f249838e5f63dc8259b0ea70282a2885;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch staging-rtl8188eu-fix-potential-security-hole.patch staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch staging-rtl8723bs-fix-potential-security-hole.patch usb-fix-novation-sourcecontrol-xl-after-suspend.patch usb-host-xhci-update-event-ring-dequeue-pointer-on-purpose.patch usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch usb-uas-fix-a-plug-unplug-racing.patch --- diff --git a/queue-4.14/series b/queue-4.14/series index 815737f003c..81b07317dde 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -178,3 +178,12 @@ staging-android-ashmem-disallow-ashmem-memory-from-being-remapped.patch staging-vt6656-fix-sign-of-rx_dbm-to-bb_pre_ed_rssi.patch xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch +usb-host-xhci-update-event-ring-dequeue-pointer-on-purpose.patch +usb-uas-fix-a-plug-unplug-racing.patch +usb-fix-novation-sourcecontrol-xl-after-suspend.patch +usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch +usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch +staging-rtl8188eu-fix-potential-security-hole.patch +staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch +staging-rtl8723bs-fix-potential-security-hole.patch +staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch diff --git a/queue-4.14/staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch b/queue-4.14/staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch new file mode 100644 index 00000000000..702d0020361 --- /dev/null +++ b/queue-4.14/staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch @@ -0,0 +1,38 @@ +From 4ddf8ab8d15ddbc52eefb44eb64e38466ce1f70f Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:32 -0600 +Subject: staging: rtl8188eu: Fix potential overuse of kernel memory + +From: Larry Finger + +commit 4ddf8ab8d15ddbc52eefb44eb64e38466ce1f70f upstream. + +In routine wpa_supplicant_ioctl(), the user-controlled p->length is +checked to be at least the size of struct ieee_param size, but the code +does not detect the case where p->length is greater than the size +of the struct, thus a malicious user could be wasting kernel memory. +Fixes commit a2c60d42d97c ("Add files for new driver - part 16"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes commit a2c60d42d97c ("Add files for new driver - part 16"). +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-4-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +@@ -2051,7 +2051,7 @@ static int wpa_supplicant_ioctl(struct n + struct ieee_param *param; + uint ret = 0; + +- if (p->length < sizeof(struct ieee_param) || !p->pointer) { ++ if (!p->pointer || p->length != sizeof(struct ieee_param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-4.14/staging-rtl8188eu-fix-potential-security-hole.patch b/queue-4.14/staging-rtl8188eu-fix-potential-security-hole.patch new file mode 100644 index 00000000000..88a39369899 --- /dev/null +++ b/queue-4.14/staging-rtl8188eu-fix-potential-security-hole.patch @@ -0,0 +1,40 @@ +From 499c405b2b80bb3a04425ba3541d20305e014d3e Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:30 -0600 +Subject: staging: rtl8188eu: Fix potential security hole + +From: Larry Finger + +commit 499c405b2b80bb3a04425ba3541d20305e014d3e upstream. + +In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed +to be at least the size of struct ieee_param size, but this assumption is +never checked. This could result in out-of-bounds read/write on kernel +heap in case a p->length less than the size of struct ieee_param is +specified by the user. If p->length is allowed to be greater than the size +of the struct, then a malicious user could be wasting kernel memory. +Fixes commit a2c60d42d97c ("Add files for new driver - part 16"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes: a2c60d42d97c ("staging: r8188eu: Add files for new driver - part 16") +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-2-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +@@ -2856,7 +2856,7 @@ static int rtw_hostapd_ioctl(struct net_ + goto out; + } + +- if (!p->pointer) { ++ if (!p->pointer || p->length != sizeof(struct ieee_param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-4.14/staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch b/queue-4.14/staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch new file mode 100644 index 00000000000..a7da6d95c22 --- /dev/null +++ b/queue-4.14/staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch @@ -0,0 +1,38 @@ +From 23954cb078febfc63a755301fe77e06bccdb4d2a Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:33 -0600 +Subject: staging: rtl8723bs: Fix potential overuse of kernel memory + +From: Larry Finger + +commit 23954cb078febfc63a755301fe77e06bccdb4d2a upstream. + +In routine wpa_supplicant_ioctl(), the user-controlled p->length is +checked to be at least the size of struct ieee_param size, but the code +does not detect the case where p->length is greater than the size +of the struct, thus a malicious user could be wasting kernel memory. +Fixes commit 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes: 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver"). +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-5-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +@@ -3495,7 +3495,7 @@ static int wpa_supplicant_ioctl(struct n + + /* down(&ieee->wx_sem); */ + +- if (p->length < sizeof(struct ieee_param) || !p->pointer) { ++ if (!p->pointer || p->length != sizeof(struct ieee_param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-4.14/staging-rtl8723bs-fix-potential-security-hole.patch b/queue-4.14/staging-rtl8723bs-fix-potential-security-hole.patch new file mode 100644 index 00000000000..cef37c159f7 --- /dev/null +++ b/queue-4.14/staging-rtl8723bs-fix-potential-security-hole.patch @@ -0,0 +1,40 @@ +From ac33597c0c0d1d819dccfe001bcd0acef7107e7c Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:31 -0600 +Subject: staging: rtl8723bs: Fix potential security hole + +From: Larry Finger + +commit ac33597c0c0d1d819dccfe001bcd0acef7107e7c upstream. + +In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed +to be at least the size of struct ieee_param size, but this assumption is +never checked. This could result in out-of-bounds read/write on kernel +heap in case a p->length less than the size of struct ieee_param is +specified by the user. If p->length is allowed to be greater than the size +of the struct, then a malicious user could be wasting kernel memory. +Fixes commit 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver"). +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-3-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +@@ -4340,7 +4340,7 @@ static int rtw_hostapd_ioctl(struct net_ + + + /* if (p->length < sizeof(struct ieee_param) || !p->pointer) { */ +- if (!p->pointer) { ++ if (!p->pointer || p->length != sizeof(*param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-4.14/usb-fix-novation-sourcecontrol-xl-after-suspend.patch b/queue-4.14/usb-fix-novation-sourcecontrol-xl-after-suspend.patch new file mode 100644 index 00000000000..083e8d31067 --- /dev/null +++ b/queue-4.14/usb-fix-novation-sourcecontrol-xl-after-suspend.patch @@ -0,0 +1,33 @@ +From b692056db8ecc7f452b934f016c17348282b7699 Mon Sep 17 00:00:00 2001 +From: Richard Dodd +Date: Wed, 12 Feb 2020 14:22:18 +0000 +Subject: USB: Fix novation SourceControl XL after suspend + +From: Richard Dodd + +commit b692056db8ecc7f452b934f016c17348282b7699 upstream. + +Currently, the SourceControl will stay in power-down mode after resuming +from suspend. This patch resets the device after suspend to power it up. + +Signed-off-by: Richard Dodd +Cc: stable +Link: https://lore.kernel.org/r/20200212142220.36892-1-richard.o.dodd@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -291,6 +291,9 @@ static const struct usb_device_id usb_qu + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* novation SoundControl XL */ ++ { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + { } /* terminating entry must be last */ + }; + diff --git a/queue-4.14/usb-host-xhci-update-event-ring-dequeue-pointer-on-purpose.patch b/queue-4.14/usb-host-xhci-update-event-ring-dequeue-pointer-on-purpose.patch new file mode 100644 index 00000000000..190970d53eb --- /dev/null +++ b/queue-4.14/usb-host-xhci-update-event-ring-dequeue-pointer-on-purpose.patch @@ -0,0 +1,116 @@ +From dc0ffbea5729a3abafa577ebfce87f18b79e294b Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Fri, 15 Nov 2019 18:50:00 +0200 +Subject: usb: host: xhci: update event ring dequeue pointer on purpose + +From: Peter Chen + +commit dc0ffbea5729a3abafa577ebfce87f18b79e294b upstream. + +On some situations, the software handles TRB events slower +than adding TRBs, then xhci_handle_event can't return zero +long time, the xHC will consider the event ring is full, +and trigger "Event Ring Full" error, but in fact, the software +has already finished lots of events, just no chance to +update ERDP (event ring dequeue pointer). + +In this commit, we force update ERDP if half of TRBS_PER_SEGMENT +events have handled to avoid "Event Ring Full" error. + +Signed-off-by: Peter Chen +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/1573836603-10871-2-git-send-email-mathias.nyman@linux.intel.com +Signed-off-by: Fabio Estevam +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 60 ++++++++++++++++++++++++++++++------------- + 1 file changed, 43 insertions(+), 17 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2759,6 +2759,42 @@ static int xhci_handle_event(struct xhci + } + + /* ++ * Update Event Ring Dequeue Pointer: ++ * - When all events have finished ++ * - To avoid "Event Ring Full Error" condition ++ */ ++static void xhci_update_erst_dequeue(struct xhci_hcd *xhci, ++ union xhci_trb *event_ring_deq) ++{ ++ u64 temp_64; ++ dma_addr_t deq; ++ ++ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); ++ /* If necessary, update the HW's version of the event ring deq ptr. */ ++ if (event_ring_deq != xhci->event_ring->dequeue) { ++ deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, ++ xhci->event_ring->dequeue); ++ if (deq == 0) ++ xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n"); ++ /* ++ * Per 4.9.4, Software writes to the ERDP register shall ++ * always advance the Event Ring Dequeue Pointer value. ++ */ ++ if ((temp_64 & (u64) ~ERST_PTR_MASK) == ++ ((u64) deq & (u64) ~ERST_PTR_MASK)) ++ return; ++ ++ /* Update HC event ring dequeue pointer */ ++ temp_64 &= ERST_PTR_MASK; ++ temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK); ++ } ++ ++ /* Clear the event handler busy flag (RW1C) */ ++ temp_64 |= ERST_EHB; ++ xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue); ++} ++ ++/* + * xHCI spec says we can get an interrupt, and if the HC has an error condition, + * we might get bad data out of the event ring. Section 4.10.2.7 has a list of + * indicators of an event TRB error, but we check the status *first* to be safe. +@@ -2769,9 +2805,9 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd + union xhci_trb *event_ring_deq; + irqreturn_t ret = IRQ_NONE; + unsigned long flags; +- dma_addr_t deq; + u64 temp_64; + u32 status; ++ int event_loop = 0; + + spin_lock_irqsave(&xhci->lock, flags); + /* Check if the xHC generated the interrupt, or the irq is shared */ +@@ -2825,24 +2861,14 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd + /* FIXME this should be a delayed service routine + * that clears the EHB. + */ +- while (xhci_handle_event(xhci) > 0) {} +- +- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); +- /* If necessary, update the HW's version of the event ring deq ptr. */ +- if (event_ring_deq != xhci->event_ring->dequeue) { +- deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, +- xhci->event_ring->dequeue); +- if (deq == 0) +- xhci_warn(xhci, "WARN something wrong with SW event " +- "ring dequeue ptr.\n"); +- /* Update HC event ring dequeue pointer */ +- temp_64 &= ERST_PTR_MASK; +- temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK); ++ while (xhci_handle_event(xhci) > 0) { ++ if (event_loop++ < TRBS_PER_SEGMENT / 2) ++ continue; ++ xhci_update_erst_dequeue(xhci, event_ring_deq); ++ event_loop = 0; + } + +- /* Clear the event handler busy flag (RW1C); event ring is empty. */ +- temp_64 |= ERST_EHB; +- xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue); ++ xhci_update_erst_dequeue(xhci, event_ring_deq); + ret = IRQ_HANDLED; + + out: diff --git a/queue-4.14/usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch b/queue-4.14/usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch new file mode 100644 index 00000000000..88129502337 --- /dev/null +++ b/queue-4.14/usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch @@ -0,0 +1,84 @@ +From 8099f58f1ecddf4f374f4828a3dff8397c7cbd74 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 31 Jan 2020 10:39:26 -0500 +Subject: USB: hub: Don't record a connect-change event during reset-resume + +From: Alan Stern + +commit 8099f58f1ecddf4f374f4828a3dff8397c7cbd74 upstream. + +Paul Zimmerman reports that his USB Bluetooth adapter sometimes +crashes following system resume, when it receives a +Get-Device-Descriptor request while it is busy doing something else. + +Such a request was added by commit a4f55d8b8c14 ("usb: hub: Check +device descriptor before resusciation"). It gets sent when the hub +driver's work thread checks whether a connect-change event on an +enabled port really indicates a new device has been connected, as +opposed to an old device momentarily disconnecting and then +reconnecting (which can happen with xHCI host controllers, since they +automatically enable connected ports). + +The same kind of thing occurs when a port's power session is lost +during system suspend. When the system wakes up it sees a +connect-change event on the port, and if the child device's +persist_enabled flag was set then hub_activate() sets the device's +reset_resume flag as well as the port's bit in hub->change_bits. The +reset-resume code then takes responsibility for checking that the same +device is still attached to the port, and it does this as part of the +device's resume pathway. By the time the hub driver's work thread +starts up again, the device has already been fully reinitialized and +is busy doing its own thing. There's no need for the work thread to +do the same check a second time, and in fact this unnecessary check is +what caused the problem that Paul observed. + +Note that performing the unnecessary check is not actually a bug. +Devices are supposed to be able to send descriptors back to the host +even when they are busy doing something else. The underlying cause of +Paul's problem lies in his Bluetooth adapter. Nevertheless, we +shouldn't perform the same check twice in a row -- and as a nice side +benefit, removing the extra check allows the Bluetooth adapter to work +more reliably. + +The work thread performs its check when it sees that the port's bit is +set in hub->change_bits. In this situation that bit is interpreted as +though a connect-change event had occurred on the port _after_ the +reset-resume, which is not what actually happened. + +One possible fix would be to make the reset-resume code clear the +port's bit in hub->change_bits. But it seems simpler to just avoid +setting the bit during hub_activate() in the first place. That's what +this patch does. + +(Proving that the patch is correct when CONFIG_PM is disabled requires +a little thought. In that setting hub_activate() will be called only +for initialization and resets, since there won't be any resumes or +reset-resumes. During initialization and hub resets the hub doesn't +have any child devices, and so this code path never gets executed.) + +Reported-and-tested-by: Paul Zimmerman +Signed-off-by: Alan Stern +Link: https://marc.info/?t=157949360700001&r=1&w=2 +CC: David Heinzelmann +CC: +Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2001311037460.1577-100000@iolanthe.rowland.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1189,11 +1189,6 @@ static void hub_activate(struct usb_hub + #ifdef CONFIG_PM + udev->reset_resume = 1; + #endif +- /* Don't set the change_bits when the device +- * was powered off. +- */ +- if (test_bit(port1, hub->power_bits)) +- set_bit(port1, hub->change_bits); + + } else { + /* The power session is gone; tell hub_wq */ diff --git a/queue-4.14/usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch b/queue-4.14/usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch new file mode 100644 index 00000000000..b115fcb1f64 --- /dev/null +++ b/queue-4.14/usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch @@ -0,0 +1,109 @@ +From 1208f9e1d758c991b0a46a1bd60c616b906bbe27 Mon Sep 17 00:00:00 2001 +From: Hardik Gajjar +Date: Thu, 6 Feb 2020 12:49:23 +0100 +Subject: USB: hub: Fix the broken detection of USB3 device in SMSC hub + +From: Hardik Gajjar + +commit 1208f9e1d758c991b0a46a1bd60c616b906bbe27 upstream. + +Renesas R-Car H3ULCB + Kingfisher Infotainment Board is either not able +to detect the USB3.0 mass storage devices or is detecting those as +USB2.0 high speed devices. + +The explanation given by Renesas is that, due to a HW issue, the XHCI +driver does not wake up after going to sleep on connecting a USB3.0 +device. + +In order to mitigate that, disable the auto-suspend feature +specifically for SMSC hubs from hub_probe() function, as a quirk. + +Renesas Kingfisher Infotainment Board has two USB3.0 ports (CN2) which +are connected via USB5534B 4-port SuperSpeed/Hi-Speed, low-power, +configurable hub controller. + +[1] SanDisk USB 3.0 device detected as USB-2.0 before the patch + [ 74.036390] usb 5-1.1: new high-speed USB device number 4 using xhci-hcd + [ 74.061598] usb 5-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00 + [ 74.069976] usb 5-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + [ 74.077303] usb 5-1.1: Product: Ultra + [ 74.080980] usb 5-1.1: Manufacturer: SanDisk + [ 74.085263] usb 5-1.1: SerialNumber: 4C530001110208116550 + +[2] SanDisk USB 3.0 device detected as USB-3.0 after the patch + [ 34.565078] usb 6-1.1: new SuperSpeed Gen 1 USB device number 3 using xhci-hcd + [ 34.588719] usb 6-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00 + [ 34.597098] usb 6-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + [ 34.604430] usb 6-1.1: Product: Ultra + [ 34.608110] usb 6-1.1: Manufacturer: SanDisk + [ 34.612397] usb 6-1.1: SerialNumber: 4C530001110208116550 + +Suggested-by: Alan Stern +Signed-off-by: Hardik Gajjar +Acked-by: Alan Stern +Tested-by: Eugeniu Rosca +Cc: stable +Link: https://lore.kernel.org/r/1580989763-32291-1-git-send-email-hgajjar@de.adit-jv.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 15 +++++++++++++++ + drivers/usb/core/hub.h | 1 + + 2 files changed, 16 insertions(+) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -36,7 +36,9 @@ + #include "otg_whitelist.h" + + #define USB_VENDOR_GENESYS_LOGIC 0x05e3 ++#define USB_VENDOR_SMSC 0x0424 + #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 ++#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02 + + /* Protect struct usb_device->state and ->children members + * Note: Both are also protected by ->dev.sem, except that ->state can +@@ -1680,6 +1682,10 @@ static void hub_disconnect(struct usb_in + kfree(hub->buffer); + + pm_suspend_ignore_children(&intf->dev, false); ++ ++ if (hub->quirk_disable_autosuspend) ++ usb_autopm_put_interface(intf); ++ + kref_put(&hub->kref, hub_release); + } + +@@ -1810,6 +1816,11 @@ static int hub_probe(struct usb_interfac + if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND) + hub->quirk_check_port_auto_suspend = 1; + ++ if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) { ++ hub->quirk_disable_autosuspend = 1; ++ usb_autopm_get_interface(intf); ++ } ++ + if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) + return 0; + +@@ -5288,6 +5299,10 @@ out_hdev_lock: + } + + static const struct usb_device_id hub_id_table[] = { ++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS, ++ .idVendor = USB_VENDOR_SMSC, ++ .bInterfaceClass = USB_CLASS_HUB, ++ .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_CLASS, + .idVendor = USB_VENDOR_GENESYS_LOGIC, +--- a/drivers/usb/core/hub.h ++++ b/drivers/usb/core/hub.h +@@ -69,6 +69,7 @@ struct usb_hub { + unsigned quiescing:1; + unsigned disconnected:1; + unsigned in_reset:1; ++ unsigned quirk_disable_autosuspend:1; + + unsigned quirk_check_port_auto_suspend:1; + diff --git a/queue-4.14/usb-uas-fix-a-plug-unplug-racing.patch b/queue-4.14/usb-uas-fix-a-plug-unplug-racing.patch new file mode 100644 index 00000000000..70088b006f5 --- /dev/null +++ b/queue-4.14/usb-uas-fix-a-plug-unplug-racing.patch @@ -0,0 +1,100 @@ +From 3e99862c05a9caa5a27969f41566b428696f5a9a Mon Sep 17 00:00:00 2001 +From: EJ Hsu +Date: Thu, 30 Jan 2020 01:25:06 -0800 +Subject: usb: uas: fix a plug & unplug racing + +From: EJ Hsu + +commit 3e99862c05a9caa5a27969f41566b428696f5a9a upstream. + +When a uas disk is plugged into an external hub, uas_probe() +will be called by the hub thread to do the probe. It will +first create a SCSI host and then do the scan for this host. +During the scan, it will probe the LUN using SCSI INQUERY command +which will be packed in the URB and submitted to uas disk. + +There might be a chance that this external hub with uas disk +attached is unplugged during the scan. In this case, uas driver +will fail to submit the URB (due to the NOTATTACHED state of uas +device) and try to put this SCSI command back to request queue +waiting for next chance to run. + +In normal case, this cycle will terminate when hub thread gets +disconnection event and calls into uas_disconnect() accordingly. +But in this case, uas_disconnect() will not be called because +hub thread of external hub gets stuck waiting for the completion +of this SCSI command. A deadlock happened. + +In this fix, uas will call scsi_scan_host() asynchronously to +avoid the blocking of hub thread. + +Signed-off-by: EJ Hsu +Acked-by: Oliver Neukum +Cc: stable +Link: https://lore.kernel.org/r/20200130092506.102760-1-ejh@nvidia.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -46,6 +46,7 @@ struct uas_dev_info { + struct scsi_cmnd *cmnd[MAX_CMNDS]; + spinlock_t lock; + struct work_struct work; ++ struct work_struct scan_work; /* for async scanning */ + }; + + enum { +@@ -115,6 +116,17 @@ out: + spin_unlock_irqrestore(&devinfo->lock, flags); + } + ++static void uas_scan_work(struct work_struct *work) ++{ ++ struct uas_dev_info *devinfo = ++ container_of(work, struct uas_dev_info, scan_work); ++ struct Scsi_Host *shost = usb_get_intfdata(devinfo->intf); ++ ++ dev_dbg(&devinfo->intf->dev, "starting scan\n"); ++ scsi_scan_host(shost); ++ dev_dbg(&devinfo->intf->dev, "scan complete\n"); ++} ++ + static void uas_add_work(struct uas_cmd_info *cmdinfo) + { + struct scsi_pointer *scp = (void *)cmdinfo; +@@ -989,6 +1001,7 @@ static int uas_probe(struct usb_interfac + init_usb_anchor(&devinfo->data_urbs); + spin_lock_init(&devinfo->lock); + INIT_WORK(&devinfo->work, uas_do_work); ++ INIT_WORK(&devinfo->scan_work, uas_scan_work); + + result = uas_configure_endpoints(devinfo); + if (result) +@@ -1005,7 +1018,9 @@ static int uas_probe(struct usb_interfac + if (result) + goto free_streams; + +- scsi_scan_host(shost); ++ /* Submit the delayed_work for SCSI-device scanning */ ++ schedule_work(&devinfo->scan_work); ++ + return result; + + free_streams: +@@ -1173,6 +1188,12 @@ static void uas_disconnect(struct usb_in + usb_kill_anchored_urbs(&devinfo->data_urbs); + uas_zap_pending(devinfo, DID_NO_CONNECT); + ++ /* ++ * Prevent SCSI scanning (if it hasn't started yet) ++ * or wait for the SCSI-scanning routine to stop. ++ */ ++ cancel_work_sync(&devinfo->scan_work); ++ + scsi_remove_host(shost); + uas_free_streams(devinfo); + scsi_host_put(shost);