]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2019 14:25:40 +0000 (16:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2019 14:25:40 +0000 (16:25 +0200)
added patches:
serial-uartlite-fix-exit-path-null-pointer.patch
usb-adutux-fix-null-derefs-on-disconnect.patch
usb-adutux-fix-use-after-free-on-disconnect.patch
usb-adutux-fix-use-after-free-on-release.patch
usb-adutux-remove-redundant-variable-minor.patch
usb-chaoskey-fix-use-after-free-on-release.patch
usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch
usb-iowarrior-fix-use-after-free-after-driver-unbind.patch
usb-iowarrior-fix-use-after-free-on-disconnect.patch
usb-iowarrior-fix-use-after-free-on-release.patch
usb-ldusb-fix-null-derefs-on-driver-unbind.patch
usb-legousbtower-fix-deadlock-on-disconnect.patch
usb-legousbtower-fix-open-after-failed-reset-request.patch
usb-legousbtower-fix-potential-null-deref-on-disconnect.patch
usb-legousbtower-fix-slab-info-leak-at-probe.patch
usb-legousbtower-fix-use-after-free-on-release.patch
usb-microtek-fix-info-leak-at-probe.patch
usb-renesas_usbhs-gadget-do-not-discard-queues-in-usb_ep_set_-halt-wedge.patch
usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch
usb-serial-fix-runtime-pm-after-driver-unbind.patch
usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch
usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch
usb-serial-option-add-support-for-cinterion-cls8-devices.patch
usb-serial-option-add-telit-fn980-compositions.patch
usb-usb-skeleton-fix-null-deref-on-disconnect.patch
usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch
usb-usblcd-fix-i-o-after-disconnect.patch
usb-usblp-fix-runtime-pm-after-driver-unbind.patch
usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch
xhci-check-all-endpoints-for-lpm-timeout.patch
xhci-fix-false-warning-message-about-wrong-bounce-buffer-write-length.patch
xhci-increase-sts_save-timeout-in-xhci_suspend.patch
xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too-long.patch

34 files changed:
queue-4.14/serial-uartlite-fix-exit-path-null-pointer.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/usb-adutux-fix-null-derefs-on-disconnect.patch [new file with mode: 0644]
queue-4.14/usb-adutux-fix-use-after-free-on-disconnect.patch [new file with mode: 0644]
queue-4.14/usb-adutux-fix-use-after-free-on-release.patch [new file with mode: 0644]
queue-4.14/usb-adutux-remove-redundant-variable-minor.patch [new file with mode: 0644]
queue-4.14/usb-chaoskey-fix-use-after-free-on-release.patch [new file with mode: 0644]
queue-4.14/usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch [new file with mode: 0644]
queue-4.14/usb-iowarrior-fix-use-after-free-after-driver-unbind.patch [new file with mode: 0644]
queue-4.14/usb-iowarrior-fix-use-after-free-on-disconnect.patch [new file with mode: 0644]
queue-4.14/usb-iowarrior-fix-use-after-free-on-release.patch [new file with mode: 0644]
queue-4.14/usb-ldusb-fix-null-derefs-on-driver-unbind.patch [new file with mode: 0644]
queue-4.14/usb-legousbtower-fix-deadlock-on-disconnect.patch [new file with mode: 0644]
queue-4.14/usb-legousbtower-fix-open-after-failed-reset-request.patch [new file with mode: 0644]
queue-4.14/usb-legousbtower-fix-potential-null-deref-on-disconnect.patch [new file with mode: 0644]
queue-4.14/usb-legousbtower-fix-slab-info-leak-at-probe.patch [new file with mode: 0644]
queue-4.14/usb-legousbtower-fix-use-after-free-on-release.patch [new file with mode: 0644]
queue-4.14/usb-microtek-fix-info-leak-at-probe.patch [new file with mode: 0644]
queue-4.14/usb-renesas_usbhs-gadget-do-not-discard-queues-in-usb_ep_set_-halt-wedge.patch [new file with mode: 0644]
queue-4.14/usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch [new file with mode: 0644]
queue-4.14/usb-serial-fix-runtime-pm-after-driver-unbind.patch [new file with mode: 0644]
queue-4.14/usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch [new file with mode: 0644]
queue-4.14/usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch [new file with mode: 0644]
queue-4.14/usb-serial-option-add-support-for-cinterion-cls8-devices.patch [new file with mode: 0644]
queue-4.14/usb-serial-option-add-telit-fn980-compositions.patch [new file with mode: 0644]
queue-4.14/usb-usb-skeleton-fix-null-deref-on-disconnect.patch [new file with mode: 0644]
queue-4.14/usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch [new file with mode: 0644]
queue-4.14/usb-usblcd-fix-i-o-after-disconnect.patch [new file with mode: 0644]
queue-4.14/usb-usblp-fix-runtime-pm-after-driver-unbind.patch [new file with mode: 0644]
queue-4.14/usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch [new file with mode: 0644]
queue-4.14/xhci-check-all-endpoints-for-lpm-timeout.patch [new file with mode: 0644]
queue-4.14/xhci-fix-false-warning-message-about-wrong-bounce-buffer-write-length.patch [new file with mode: 0644]
queue-4.14/xhci-increase-sts_save-timeout-in-xhci_suspend.patch [new file with mode: 0644]
queue-4.14/xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too-long.patch [new file with mode: 0644]

diff --git a/queue-4.14/serial-uartlite-fix-exit-path-null-pointer.patch b/queue-4.14/serial-uartlite-fix-exit-path-null-pointer.patch
new file mode 100644 (file)
index 0000000..66931a5
--- /dev/null
@@ -0,0 +1,43 @@
+From a553add0846f355a28ed4e81134012e4a1e280c2 Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Mon, 16 Sep 2019 16:12:23 -0700
+Subject: serial: uartlite: fix exit path null pointer
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+commit a553add0846f355a28ed4e81134012e4a1e280c2 upstream.
+
+Call uart_unregister_driver() conditionally instead of
+unconditionally, only if it has been previously registered.
+
+This uses driver.state, just as the sh-sci.c driver does.
+
+Fixes this null pointer dereference in tty_unregister_driver(),
+since the 'driver' argument is null:
+
+  general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI
+  RIP: 0010:tty_unregister_driver+0x25/0x1d0
+
+Fixes: 238b8721a554 ("[PATCH] serial uartlite driver")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: stable <stable@vger.kernel.org>
+Cc: Peter Korsgaard <jacmet@sunsite.dk>
+Link: https://lore.kernel.org/r/9c8e6581-6fcc-a595-0897-4d90f5d710df@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/uartlite.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/uartlite.c
++++ b/drivers/tty/serial/uartlite.c
+@@ -746,7 +746,8 @@ err_uart:
+ static void __exit ulite_exit(void)
+ {
+       platform_driver_unregister(&ulite_platform_driver);
+-      uart_unregister_driver(&ulite_uart_driver);
++      if (ulite_uart_driver.state)
++              uart_unregister_driver(&ulite_uart_driver);
+ }
+ module_init(ulite_init);
index 617fe8a6600f2bbe1aab5d67d849bb7f0deecd1f..c961d37472dde0bf2f7756cbe0a7cb4d294c3f67 100644 (file)
@@ -3,3 +3,36 @@ f2fs-use-einval-for-superblock-with-invalid-magic.patch
 usb-rio500-remove-rio-500-kernel-driver.patch
 usb-yurex-don-t-retry-on-unexpected-errors.patch
 usb-yurex-fix-null-derefs-on-disconnect.patch
+usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch
+usb-usb-skeleton-fix-null-deref-on-disconnect.patch
+xhci-fix-false-warning-message-about-wrong-bounce-buffer-write-length.patch
+xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too-long.patch
+xhci-check-all-endpoints-for-lpm-timeout.patch
+usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch
+xhci-increase-sts_save-timeout-in-xhci_suspend.patch
+usb-adutux-remove-redundant-variable-minor.patch
+usb-adutux-fix-use-after-free-on-disconnect.patch
+usb-adutux-fix-null-derefs-on-disconnect.patch
+usb-adutux-fix-use-after-free-on-release.patch
+usb-iowarrior-fix-use-after-free-on-disconnect.patch
+usb-iowarrior-fix-use-after-free-on-release.patch
+usb-iowarrior-fix-use-after-free-after-driver-unbind.patch
+usb-usblp-fix-runtime-pm-after-driver-unbind.patch
+usb-chaoskey-fix-use-after-free-on-release.patch
+usb-ldusb-fix-null-derefs-on-driver-unbind.patch
+serial-uartlite-fix-exit-path-null-pointer.patch
+usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch
+usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch
+usb-serial-option-add-telit-fn980-compositions.patch
+usb-serial-option-add-support-for-cinterion-cls8-devices.patch
+usb-serial-fix-runtime-pm-after-driver-unbind.patch
+usb-usblcd-fix-i-o-after-disconnect.patch
+usb-microtek-fix-info-leak-at-probe.patch
+usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch
+usb-renesas_usbhs-gadget-do-not-discard-queues-in-usb_ep_set_-halt-wedge.patch
+usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch
+usb-legousbtower-fix-slab-info-leak-at-probe.patch
+usb-legousbtower-fix-deadlock-on-disconnect.patch
+usb-legousbtower-fix-potential-null-deref-on-disconnect.patch
+usb-legousbtower-fix-open-after-failed-reset-request.patch
+usb-legousbtower-fix-use-after-free-on-release.patch
diff --git a/queue-4.14/usb-adutux-fix-null-derefs-on-disconnect.patch b/queue-4.14/usb-adutux-fix-null-derefs-on-disconnect.patch
new file mode 100644 (file)
index 0000000..fffc1cb
--- /dev/null
@@ -0,0 +1,109 @@
+From b2fa7baee744fde746c17bc1860b9c6f5c2eebb7 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 25 Sep 2019 11:29:13 +0200
+Subject: USB: adutux: fix NULL-derefs on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b2fa7baee744fde746c17bc1860b9c6f5c2eebb7 upstream.
+
+The driver was using its struct usb_device pointer as an inverted
+disconnected flag, but was setting it to NULL before making sure all
+completion handlers had run. This could lead to a NULL-pointer
+dereference in a number of dev_dbg statements in the completion handlers
+which relies on said pointer.
+
+The pointer was also dereferenced unconditionally in a dev_dbg statement
+release() something which would lead to a NULL-deref whenever a device
+was disconnected before the final character-device close if debugging
+was enabled.
+
+Fix this by unconditionally stopping all I/O and preventing
+resubmissions by poisoning the interrupt URBs at disconnect and using a
+dedicated disconnected flag.
+
+This also makes sure that all I/O has completed by the time the
+disconnect callback returns.
+
+Fixes: 1ef37c6047fe ("USB: adutux: remove custom debug macro and module parameter")
+Fixes: 66d4bc30d128 ("USB: adutux: remove custom debug macro")
+Cc: stable <stable@vger.kernel.org>     # 3.12
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190925092913.8608-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c |   16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -79,6 +79,7 @@ struct adu_device {
+       char                    serial_number[8];
+       int                     open_count; /* number of times this port has been opened */
++      unsigned long           disconnected:1;
+       char            *read_buffer_primary;
+       int                     read_buffer_length;
+@@ -120,7 +121,7 @@ static void adu_abort_transfers(struct a
+ {
+       unsigned long flags;
+-      if (dev->udev == NULL)
++      if (dev->disconnected)
+               return;
+       /* shutdown transfer */
+@@ -243,7 +244,7 @@ static int adu_open(struct inode *inode,
+       }
+       dev = usb_get_intfdata(interface);
+-      if (!dev || !dev->udev) {
++      if (!dev) {
+               retval = -ENODEV;
+               goto exit_no_device;
+       }
+@@ -326,7 +327,7 @@ static int adu_release(struct inode *ino
+       }
+       adu_release_internal(dev);
+-      if (dev->udev == NULL) {
++      if (dev->disconnected) {
+               /* the device was unplugged before the file was released */
+               if (!dev->open_count)   /* ... and we're the last user */
+                       adu_delete(dev);
+@@ -355,7 +356,7 @@ static ssize_t adu_read(struct file *fil
+               return -ERESTARTSYS;
+       /* verify that the device wasn't unplugged */
+-      if (dev->udev == NULL) {
++      if (dev->disconnected) {
+               retval = -ENODEV;
+               pr_err("No device or device unplugged %d\n", retval);
+               goto exit;
+@@ -520,7 +521,7 @@ static ssize_t adu_write(struct file *fi
+               goto exit_nolock;
+       /* verify that the device wasn't unplugged */
+-      if (dev->udev == NULL) {
++      if (dev->disconnected) {
+               retval = -ENODEV;
+               pr_err("No device or device unplugged %d\n", retval);
+               goto exit;
+@@ -766,11 +767,14 @@ static void adu_disconnect(struct usb_in
+       usb_deregister_dev(interface, &adu_class);
++      usb_poison_urb(dev->interrupt_in_urb);
++      usb_poison_urb(dev->interrupt_out_urb);
++
+       mutex_lock(&adutux_mutex);
+       usb_set_intfdata(interface, NULL);
+       mutex_lock(&dev->mtx);  /* not interruptible */
+-      dev->udev = NULL;       /* poison */
++      dev->disconnected = 1;
+       mutex_unlock(&dev->mtx);
+       /* if the device is not opened, then we clean up right now */
diff --git a/queue-4.14/usb-adutux-fix-use-after-free-on-disconnect.patch b/queue-4.14/usb-adutux-fix-use-after-free-on-disconnect.patch
new file mode 100644 (file)
index 0000000..bf6482a
--- /dev/null
@@ -0,0 +1,52 @@
+From 44efc269db7929f6275a1fa927ef082e533ecde0 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 25 Sep 2019 11:29:12 +0200
+Subject: USB: adutux: fix use-after-free on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 44efc269db7929f6275a1fa927ef082e533ecde0 upstream.
+
+The driver was clearing its struct usb_device pointer, which it used as
+an inverted disconnected flag, before deregistering the character device
+and without serialising against racing release().
+
+This could lead to a use-after-free if a racing release() callback
+observes the cleared pointer and frees the driver data before
+disconnect() is finished with it.
+
+This could also lead to NULL-pointer dereferences in a racing open().
+
+Fixes: f08812d5eb8f ("USB: FIx locks and urb->status in adutux (updated)")
+Cc: stable <stable@vger.kernel.org>     # 2.6.24
+Reported-by: syzbot+0243cb250a51eeefb8cc@syzkaller.appspotmail.com
+Tested-by: syzbot+0243cb250a51eeefb8cc@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190925092913.8608-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -764,14 +764,15 @@ static void adu_disconnect(struct usb_in
+       dev = usb_get_intfdata(interface);
+-      mutex_lock(&dev->mtx);  /* not interruptible */
+-      dev->udev = NULL;       /* poison */
+       usb_deregister_dev(interface, &adu_class);
+-      mutex_unlock(&dev->mtx);
+       mutex_lock(&adutux_mutex);
+       usb_set_intfdata(interface, NULL);
++      mutex_lock(&dev->mtx);  /* not interruptible */
++      dev->udev = NULL;       /* poison */
++      mutex_unlock(&dev->mtx);
++
+       /* if the device is not opened, then we clean up right now */
+       if (!dev->open_count)
+               adu_delete(dev);
diff --git a/queue-4.14/usb-adutux-fix-use-after-free-on-release.patch b/queue-4.14/usb-adutux-fix-use-after-free-on-release.patch
new file mode 100644 (file)
index 0000000..6ae7ed0
--- /dev/null
@@ -0,0 +1,43 @@
+From 123a0f125fa3d2104043697baa62899d9e549272 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:44 +0200
+Subject: USB: adutux: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 123a0f125fa3d2104043697baa62899d9e549272 upstream.
+
+The driver was accessing its struct usb_device in its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever the device was disconnected while the character
+device was still open.
+
+Fixes: 66d4bc30d128 ("USB: adutux: remove custom debug macro")
+Cc: stable <stable@vger.kernel.org>     # 3.12
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -151,6 +151,7 @@ static void adu_delete(struct adu_device
+       kfree(dev->read_buffer_secondary);
+       kfree(dev->interrupt_in_buffer);
+       kfree(dev->interrupt_out_buffer);
++      usb_put_dev(dev->udev);
+       kfree(dev);
+ }
+@@ -666,7 +667,7 @@ static int adu_probe(struct usb_interfac
+       mutex_init(&dev->mtx);
+       spin_lock_init(&dev->buflock);
+-      dev->udev = udev;
++      dev->udev = usb_get_dev(udev);
+       init_waitqueue_head(&dev->read_wait);
+       init_waitqueue_head(&dev->write_wait);
diff --git a/queue-4.14/usb-adutux-remove-redundant-variable-minor.patch b/queue-4.14/usb-adutux-remove-redundant-variable-minor.patch
new file mode 100644 (file)
index 0000000..fb00795
--- /dev/null
@@ -0,0 +1,38 @@
+From 8444efc4a052332d643ed5c8aebcca148c7de032 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 7 Nov 2017 11:45:27 +0000
+Subject: USB: adutux: remove redundant variable minor
+
+From: Colin Ian King <colin.king@canonical.com>
+
+commit 8444efc4a052332d643ed5c8aebcca148c7de032 upstream.
+
+Variable minor is being assigned but never read, hence it is redundant
+and can be removed. Cleans up clang warning:
+
+drivers/usb/misc/adutux.c:770:2: warning: Value stored to 'minor' is
+never read
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -761,13 +761,11 @@ error:
+ static void adu_disconnect(struct usb_interface *interface)
+ {
+       struct adu_device *dev;
+-      int minor;
+       dev = usb_get_intfdata(interface);
+       mutex_lock(&dev->mtx);  /* not interruptible */
+       dev->udev = NULL;       /* poison */
+-      minor = dev->minor;
+       usb_deregister_dev(interface, &adu_class);
+       mutex_unlock(&dev->mtx);
diff --git a/queue-4.14/usb-chaoskey-fix-use-after-free-on-release.patch b/queue-4.14/usb-chaoskey-fix-use-after-free-on-release.patch
new file mode 100644 (file)
index 0000000..8264496
--- /dev/null
@@ -0,0 +1,52 @@
+From 93ddb1f56ae102f14f9e46a9a9c8017faa970003 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:45 +0200
+Subject: USB: chaoskey: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 93ddb1f56ae102f14f9e46a9a9c8017faa970003 upstream.
+
+The driver was accessing its struct usb_interface in its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever the device was disconnected while the character
+device was still open.
+
+Fixes: 66e3e591891d ("usb: Add driver for Altus Metrum ChaosKey device (v2)")
+Cc: stable <stable@vger.kernel.org>     # 4.1
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/chaoskey.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -106,6 +106,7 @@ static void chaoskey_free(struct chaoske
+               usb_free_urb(dev->urb);
+               kfree(dev->name);
+               kfree(dev->buf);
++              usb_put_intf(dev->interface);
+               kfree(dev);
+       }
+ }
+@@ -153,6 +154,8 @@ static int chaoskey_probe(struct usb_int
+       if (dev == NULL)
+               goto out;
++      dev->interface = usb_get_intf(interface);
++
+       dev->buf = kmalloc(size, GFP_KERNEL);
+       if (dev->buf == NULL)
+@@ -186,8 +189,6 @@ static int chaoskey_probe(struct usb_int
+               strcat(dev->name, udev->serial);
+       }
+-      dev->interface = interface;
+-
+       dev->in_ep = in_ep;
+       if (le16_to_cpu(udev->descriptor.idVendor) != ALEA_VENDOR_ID)
diff --git a/queue-4.14/usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch b/queue-4.14/usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch
new file mode 100644 (file)
index 0000000..acd6369
--- /dev/null
@@ -0,0 +1,48 @@
+From 2636d49b64671d3d90ecc4daf971b58df3956519 Mon Sep 17 00:00:00 2001
+From: "Jacky.Cao@sony.com" <Jacky.Cao@sony.com>
+Date: Thu, 5 Sep 2019 04:11:57 +0000
+Subject: USB: dummy-hcd: fix power budget for SuperSpeed mode
+
+From: Jacky.Cao@sony.com <Jacky.Cao@sony.com>
+
+commit 2636d49b64671d3d90ecc4daf971b58df3956519 upstream.
+
+The power budget for SuperSpeed mode should be 900 mA
+according to USB specification, so set the power budget
+to 900mA for dummy_start_ss which is only used for
+SuperSpeed mode.
+
+If the max power consumption of SuperSpeed device is
+larger than 500 mA, insufficient available bus power
+error happens in usb_choose_configuration function
+when the device connects to dummy hcd.
+
+Signed-off-by: Jacky Cao <Jacky.Cao@sony.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/16EA1F625E922C43B00B9D82250220500871CDE5@APYOKXMS108.ap.sony.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/udc/dummy_hcd.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -50,6 +50,7 @@
+ #define DRIVER_VERSION        "02 May 2005"
+ #define POWER_BUDGET  500     /* in mA; use 8 for low-power port testing */
++#define POWER_BUDGET_3        900     /* in mA */
+ static const char     driver_name[] = "dummy_hcd";
+ static const char     driver_desc[] = "USB Host+Gadget Emulator";
+@@ -2439,7 +2440,7 @@ static int dummy_start_ss(struct dummy_h
+       dum_hcd->rh_state = DUMMY_RH_RUNNING;
+       dum_hcd->stream_en_ep = 0;
+       INIT_LIST_HEAD(&dum_hcd->urbp_list);
+-      dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET;
++      dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET_3;
+       dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING;
+       dummy_hcd_to_hcd(dum_hcd)->uses_new_polling = 1;
+ #ifdef CONFIG_USB_OTG
diff --git a/queue-4.14/usb-iowarrior-fix-use-after-free-after-driver-unbind.patch b/queue-4.14/usb-iowarrior-fix-use-after-free-after-driver-unbind.patch
new file mode 100644 (file)
index 0000000..3c8b8e3
--- /dev/null
@@ -0,0 +1,63 @@
+From b5f8d46867ca233d773408ffbe691a8062ed718f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 12:48:43 +0200
+Subject: USB: iowarrior: fix use-after-free after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b5f8d46867ca233d773408ffbe691a8062ed718f upstream.
+
+Make sure to stop also the asynchronous write URBs on disconnect() to
+avoid use-after-free in the completion handler after driver unbind.
+
+Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.")
+Cc: stable <stable@vger.kernel.org>    # 2.6.21: 51a2f077c44e ("USB: introduce usb_anchor")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009104846.5925-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/iowarrior.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -87,6 +87,7 @@ struct iowarrior {
+       char chip_serial[9];            /* the serial number string of the chip connected */
+       int report_size;                /* number of bytes in a report */
+       u16 product_id;
++      struct usb_anchor submitted;
+ };
+ /*--------------*/
+@@ -428,11 +429,13 @@ static ssize_t iowarrior_write(struct fi
+                       retval = -EFAULT;
+                       goto error;
+               }
++              usb_anchor_urb(int_out_urb, &dev->submitted);
+               retval = usb_submit_urb(int_out_urb, GFP_KERNEL);
+               if (retval) {
+                       dev_dbg(&dev->interface->dev,
+                               "submit error %d for urb nr.%d\n",
+                               retval, atomic_read(&dev->write_busy));
++                      usb_unanchor_urb(int_out_urb);
+                       goto error;
+               }
+               /* submit was ok */
+@@ -774,6 +777,8 @@ static int iowarrior_probe(struct usb_in
+       iface_desc = interface->cur_altsetting;
+       dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
++      init_usb_anchor(&dev->submitted);
++
+       res = usb_find_last_int_in_endpoint(iface_desc, &dev->int_in_endpoint);
+       if (res) {
+               dev_err(&interface->dev, "no interrupt-in endpoint found\n");
+@@ -889,6 +894,7 @@ static void iowarrior_disconnect(struct
+                  Deleting the device is postponed until close() was called.
+                */
+               usb_kill_urb(dev->int_in_urb);
++              usb_kill_anchored_urbs(&dev->submitted);
+               wake_up_interruptible(&dev->read_wait);
+               wake_up_interruptible(&dev->write_wait);
+               mutex_unlock(&dev->mutex);
diff --git a/queue-4.14/usb-iowarrior-fix-use-after-free-on-disconnect.patch b/queue-4.14/usb-iowarrior-fix-use-after-free-on-disconnect.patch
new file mode 100644 (file)
index 0000000..1f75386
--- /dev/null
@@ -0,0 +1,63 @@
+From edc4746f253d907d048de680a621e121517f484b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 12:48:41 +0200
+Subject: USB: iowarrior: fix use-after-free on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit edc4746f253d907d048de680a621e121517f484b upstream.
+
+A recent fix addressing a deadlock on disconnect introduced a new bug
+by moving the present flag out of the critical section protected by the
+driver-data mutex. This could lead to a racing release() freeing the
+driver data before disconnect() is done with it.
+
+Due to insufficient locking a related use-after-free could be triggered
+also before the above mentioned commit. Specifically, the driver needs
+to hold the driver-data mutex also while checking the opened flag at
+disconnect().
+
+Fixes: c468a8aa790e ("usb: iowarrior: fix deadlock on disconnect")
+Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.")
+Cc: stable <stable@vger.kernel.org>    # 2.6.21
+Reported-by: syzbot+0761012cebf7bdb38137@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009104846.5925-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/iowarrior.c |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -870,8 +870,6 @@ static void iowarrior_disconnect(struct
+       dev = usb_get_intfdata(interface);
+       mutex_lock(&iowarrior_open_disc_lock);
+       usb_set_intfdata(interface, NULL);
+-      /* prevent device read, write and ioctl */
+-      dev->present = 0;
+       minor = dev->minor;
+       mutex_unlock(&iowarrior_open_disc_lock);
+@@ -882,8 +880,7 @@ static void iowarrior_disconnect(struct
+       mutex_lock(&dev->mutex);
+       /* prevent device read, write and ioctl */
+-
+-      mutex_unlock(&dev->mutex);
++      dev->present = 0;
+       if (dev->opened) {
+               /* There is a process that holds a filedescriptor to the device ,
+@@ -893,8 +890,10 @@ static void iowarrior_disconnect(struct
+               usb_kill_urb(dev->int_in_urb);
+               wake_up_interruptible(&dev->read_wait);
+               wake_up_interruptible(&dev->write_wait);
++              mutex_unlock(&dev->mutex);
+       } else {
+               /* no process is using the device, cleanup now */
++              mutex_unlock(&dev->mutex);
+               iowarrior_delete(dev);
+       }
diff --git a/queue-4.14/usb-iowarrior-fix-use-after-free-on-release.patch b/queue-4.14/usb-iowarrior-fix-use-after-free-on-release.patch
new file mode 100644 (file)
index 0000000..476df1c
--- /dev/null
@@ -0,0 +1,43 @@
+From 80cd5479b525093a56ef768553045741af61b250 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 12:48:42 +0200
+Subject: USB: iowarrior: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 80cd5479b525093a56ef768553045741af61b250 upstream.
+
+The driver was accessing its struct usb_interface from its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever debugging was enabled and the device was
+disconnected while its character device was open.
+
+Fixes: 549e83500b80 ("USB: iowarrior: Convert local dbg macro to dev_dbg")
+Cc: stable <stable@vger.kernel.org>     # 3.16
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009104846.5925-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/iowarrior.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -246,6 +246,7 @@ static inline void iowarrior_delete(stru
+       kfree(dev->int_in_buffer);
+       usb_free_urb(dev->int_in_urb);
+       kfree(dev->read_queue);
++      usb_put_intf(dev->interface);
+       kfree(dev);
+ }
+@@ -768,7 +769,7 @@ static int iowarrior_probe(struct usb_in
+       init_waitqueue_head(&dev->write_wait);
+       dev->udev = udev;
+-      dev->interface = interface;
++      dev->interface = usb_get_intf(interface);
+       iface_desc = interface->cur_altsetting;
+       dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
diff --git a/queue-4.14/usb-ldusb-fix-null-derefs-on-driver-unbind.patch b/queue-4.14/usb-ldusb-fix-null-derefs-on-driver-unbind.patch
new file mode 100644 (file)
index 0000000..a6ebdd1
--- /dev/null
@@ -0,0 +1,130 @@
+From 58ecf131e74620305175a7aa103f81350bb37570 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:46 +0200
+Subject: USB: ldusb: fix NULL-derefs on driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 58ecf131e74620305175a7aa103f81350bb37570 upstream.
+
+The driver was using its struct usb_interface pointer as an inverted
+disconnected flag, but was setting it to NULL before making sure all
+completion handlers had run. This could lead to a NULL-pointer
+dereference in a number of dev_dbg, dev_warn and dev_err statements in
+the completion handlers which relies on said pointer.
+
+Fix this by unconditionally stopping all I/O and preventing
+resubmissions by poisoning the interrupt URBs at disconnect and using a
+dedicated disconnected flag.
+
+This also makes sure that all I/O has completed by the time the
+disconnect callback returns.
+
+Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver")
+Cc: stable <stable@vger.kernel.org>     # 2.6.13
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/ldusb.c |   24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/misc/ldusb.c
++++ b/drivers/usb/misc/ldusb.c
+@@ -157,6 +157,7 @@ MODULE_PARM_DESC(min_interrupt_out_inter
+ struct ld_usb {
+       struct mutex            mutex;          /* locks this structure */
+       struct usb_interface    *intf;          /* save off the usb interface pointer */
++      unsigned long           disconnected:1;
+       int                     open_count;     /* number of times this port has been opened */
+@@ -196,12 +197,10 @@ static void ld_usb_abort_transfers(struc
+       /* shutdown transfer */
+       if (dev->interrupt_in_running) {
+               dev->interrupt_in_running = 0;
+-              if (dev->intf)
+-                      usb_kill_urb(dev->interrupt_in_urb);
++              usb_kill_urb(dev->interrupt_in_urb);
+       }
+       if (dev->interrupt_out_busy)
+-              if (dev->intf)
+-                      usb_kill_urb(dev->interrupt_out_urb);
++              usb_kill_urb(dev->interrupt_out_urb);
+ }
+ /**
+@@ -209,8 +208,6 @@ static void ld_usb_abort_transfers(struc
+  */
+ static void ld_usb_delete(struct ld_usb *dev)
+ {
+-      ld_usb_abort_transfers(dev);
+-
+       /* free data structures */
+       usb_free_urb(dev->interrupt_in_urb);
+       usb_free_urb(dev->interrupt_out_urb);
+@@ -266,7 +263,7 @@ static void ld_usb_interrupt_in_callback
+ resubmit:
+       /* resubmit if we're still running */
+-      if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) {
++      if (dev->interrupt_in_running && !dev->buffer_overflow) {
+               retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
+               if (retval) {
+                       dev_err(&dev->intf->dev,
+@@ -395,7 +392,7 @@ static int ld_usb_release(struct inode *
+               retval = -ENODEV;
+               goto unlock_exit;
+       }
+-      if (dev->intf == NULL) {
++      if (dev->disconnected) {
+               /* the device was unplugged before the file was released */
+               mutex_unlock(&dev->mutex);
+               /* unlock here as ld_usb_delete frees dev */
+@@ -426,7 +423,7 @@ static unsigned int ld_usb_poll(struct f
+       dev = file->private_data;
+-      if (!dev->intf)
++      if (dev->disconnected)
+               return POLLERR | POLLHUP;
+       poll_wait(file, &dev->read_wait, wait);
+@@ -465,7 +462,7 @@ static ssize_t ld_usb_read(struct file *
+       }
+       /* verify that the device wasn't unplugged */
+-      if (dev->intf == NULL) {
++      if (dev->disconnected) {
+               retval = -ENODEV;
+               printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
+               goto unlock_exit;
+@@ -545,7 +542,7 @@ static ssize_t ld_usb_write(struct file
+       }
+       /* verify that the device wasn't unplugged */
+-      if (dev->intf == NULL) {
++      if (dev->disconnected) {
+               retval = -ENODEV;
+               printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
+               goto unlock_exit;
+@@ -762,6 +759,9 @@ static void ld_usb_disconnect(struct usb
+       /* give back our minor */
+       usb_deregister_dev(intf, &ld_usb_class);
++      usb_poison_urb(dev->interrupt_in_urb);
++      usb_poison_urb(dev->interrupt_out_urb);
++
+       mutex_lock(&dev->mutex);
+       /* if the device is not opened, then we clean up right now */
+@@ -769,7 +769,7 @@ static void ld_usb_disconnect(struct usb
+               mutex_unlock(&dev->mutex);
+               ld_usb_delete(dev);
+       } else {
+-              dev->intf = NULL;
++              dev->disconnected = 1;
+               /* wake up pollers */
+               wake_up_interruptible_all(&dev->read_wait);
+               wake_up_interruptible_all(&dev->write_wait);
diff --git a/queue-4.14/usb-legousbtower-fix-deadlock-on-disconnect.patch b/queue-4.14/usb-legousbtower-fix-deadlock-on-disconnect.patch
new file mode 100644 (file)
index 0000000..b60b279
--- /dev/null
@@ -0,0 +1,125 @@
+From 33a7813219f208f4952ece60ee255fd983272dec Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:37 +0200
+Subject: USB: legousbtower: fix deadlock on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 33a7813219f208f4952ece60ee255fd983272dec upstream.
+
+Fix a potential deadlock if disconnect races with open.
+
+Since commit d4ead16f50f9 ("USB: prevent char device open/deregister
+race") core holds an rw-semaphore while open is called and when
+releasing the minor number during deregistration. This can lead to an
+ABBA deadlock if a driver takes a lock in open which it also holds
+during deregistration.
+
+This effectively reverts commit 78663ecc344b ("USB: disconnect open race
+in legousbtower") which needlessly introduced this issue after a generic
+fix for this race had been added to core by commit d4ead16f50f9 ("USB:
+prevent char device open/deregister race").
+
+Fixes: 78663ecc344b ("USB: disconnect open race in legousbtower")
+Cc: stable <stable@vger.kernel.org>    # 2.6.24
+Reported-by: syzbot+f9549f5ee8a5416f0b95@syzkaller.appspotmail.com
+Tested-by: syzbot+f9549f5ee8a5416f0b95@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c |   19 ++-----------------
+ 1 file changed, 2 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -183,7 +183,6 @@ static const struct usb_device_id tower_
+ };
+ MODULE_DEVICE_TABLE (usb, tower_table);
+-static DEFINE_MUTEX(open_disc_mutex);
+ #define LEGO_USB_TOWER_MINOR_BASE     160
+@@ -336,18 +335,14 @@ static int tower_open (struct inode *ino
+               goto exit;
+       }
+-      mutex_lock(&open_disc_mutex);
+       dev = usb_get_intfdata(interface);
+-
+       if (!dev) {
+-              mutex_unlock(&open_disc_mutex);
+               retval = -ENODEV;
+               goto exit;
+       }
+       /* lock this device */
+       if (mutex_lock_interruptible(&dev->lock)) {
+-              mutex_unlock(&open_disc_mutex);
+               retval = -ERESTARTSYS;
+               goto exit;
+       }
+@@ -355,12 +350,10 @@ static int tower_open (struct inode *ino
+       /* allow opening only once */
+       if (dev->open_count) {
+-              mutex_unlock(&open_disc_mutex);
+               retval = -EBUSY;
+               goto unlock_exit;
+       }
+       dev->open_count = 1;
+-      mutex_unlock(&open_disc_mutex);
+       /* reset the tower */
+       result = usb_control_msg (dev->udev,
+@@ -427,10 +420,9 @@ static int tower_release (struct inode *
+       if (dev == NULL) {
+               retval = -ENODEV;
+-              goto exit_nolock;
++              goto exit;
+       }
+-      mutex_lock(&open_disc_mutex);
+       if (mutex_lock_interruptible(&dev->lock)) {
+               retval = -ERESTARTSYS;
+               goto exit;
+@@ -460,10 +452,7 @@ static int tower_release (struct inode *
+ unlock_exit:
+       mutex_unlock(&dev->lock);
+-
+ exit:
+-      mutex_unlock(&open_disc_mutex);
+-exit_nolock:
+       return retval;
+ }
+@@ -915,7 +904,6 @@ static int tower_probe (struct usb_inter
+       if (retval) {
+               /* something prevented us from registering this driver */
+               dev_err(idev, "Not able to get a minor for this device.\n");
+-              usb_set_intfdata (interface, NULL);
+               goto error;
+       }
+       dev->minor = interface->minor;
+@@ -947,16 +935,13 @@ static void tower_disconnect (struct usb
+       int minor;
+       dev = usb_get_intfdata (interface);
+-      mutex_lock(&open_disc_mutex);
+-      usb_set_intfdata (interface, NULL);
+       minor = dev->minor;
+-      /* give back our minor */
++      /* give back our minor and prevent further open() */
+       usb_deregister_dev (interface, &tower_class);
+       mutex_lock(&dev->lock);
+-      mutex_unlock(&open_disc_mutex);
+       /* if the device is not opened, then we clean up right now */
+       if (!dev->open_count) {
diff --git a/queue-4.14/usb-legousbtower-fix-open-after-failed-reset-request.patch b/queue-4.14/usb-legousbtower-fix-open-after-failed-reset-request.patch
new file mode 100644 (file)
index 0000000..252ae6e
--- /dev/null
@@ -0,0 +1,51 @@
+From 0b074f6986751361ff442bc1127c1648567aa8d6 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:39 +0200
+Subject: USB: legousbtower: fix open after failed reset request
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 0b074f6986751361ff442bc1127c1648567aa8d6 upstream.
+
+The driver would return with a nonzero open count in case the reset
+control request failed. This would prevent any further attempts to open
+the char dev until the device was disconnected.
+
+Fix this by incrementing the open count only on successful open.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-5-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -352,7 +352,6 @@ static int tower_open (struct inode *ino
+               retval = -EBUSY;
+               goto unlock_exit;
+       }
+-      dev->open_count = 1;
+       /* reset the tower */
+       result = usb_control_msg (dev->udev,
+@@ -392,13 +391,14 @@ static int tower_open (struct inode *ino
+               dev_err(&dev->udev->dev,
+                       "Couldn't submit interrupt_in_urb %d\n", retval);
+               dev->interrupt_in_running = 0;
+-              dev->open_count = 0;
+               goto unlock_exit;
+       }
+       /* save device in the file's private structure */
+       file->private_data = dev;
++      dev->open_count = 1;
++
+ unlock_exit:
+       mutex_unlock(&dev->lock);
diff --git a/queue-4.14/usb-legousbtower-fix-potential-null-deref-on-disconnect.patch b/queue-4.14/usb-legousbtower-fix-potential-null-deref-on-disconnect.patch
new file mode 100644 (file)
index 0000000..ea53ed3
--- /dev/null
@@ -0,0 +1,140 @@
+From cd81e6fa8e033e7bcd59415b4a65672b4780030b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:38 +0200
+Subject: USB: legousbtower: fix potential NULL-deref on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit cd81e6fa8e033e7bcd59415b4a65672b4780030b upstream.
+
+The driver is using its struct usb_device pointer as an inverted
+disconnected flag, but was setting it to NULL before making sure all
+completion handlers had run. This could lead to a NULL-pointer
+dereference in a number of dev_dbg and dev_err statements in the
+completion handlers which relies on said pointer.
+
+Fix this by unconditionally stopping all I/O and preventing
+resubmissions by poisoning the interrupt URBs at disconnect and using a
+dedicated disconnected flag.
+
+This also makes sure that all I/O has completed by the time the
+disconnect callback returns.
+
+Fixes: 9d974b2a06e3 ("USB: legousbtower.c: remove err() usage")
+Fixes: fef526cae700 ("USB: legousbtower: remove custom debug macro")
+Fixes: 4dae99638097 ("USB: legotower: remove custom debug macro and module parameter")
+Cc: stable <stable@vger.kernel.org>     # 3.5
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c |   26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -194,6 +194,7 @@ struct lego_usb_tower {
+       unsigned char           minor;          /* the starting minor number for this device */
+       int                     open_count;     /* number of times this port has been opened */
++      unsigned long           disconnected:1;
+       char*                   read_buffer;
+       size_t                  read_buffer_length; /* this much came in */
+@@ -293,8 +294,6 @@ static inline void lego_usb_tower_debug_
+  */
+ static inline void tower_delete (struct lego_usb_tower *dev)
+ {
+-      tower_abort_transfers (dev);
+-
+       /* free data structures */
+       usb_free_urb(dev->interrupt_in_urb);
+       usb_free_urb(dev->interrupt_out_urb);
+@@ -434,7 +433,8 @@ static int tower_release (struct inode *
+               retval = -ENODEV;
+               goto unlock_exit;
+       }
+-      if (dev->udev == NULL) {
++
++      if (dev->disconnected) {
+               /* the device was unplugged before the file was released */
+               /* unlock here as tower_delete frees dev */
+@@ -470,10 +470,9 @@ static void tower_abort_transfers (struc
+       if (dev->interrupt_in_running) {
+               dev->interrupt_in_running = 0;
+               mb();
+-              if (dev->udev)
+-                      usb_kill_urb (dev->interrupt_in_urb);
++              usb_kill_urb(dev->interrupt_in_urb);
+       }
+-      if (dev->interrupt_out_busy && dev->udev)
++      if (dev->interrupt_out_busy)
+               usb_kill_urb(dev->interrupt_out_urb);
+ }
+@@ -509,7 +508,7 @@ static unsigned int tower_poll (struct f
+       dev = file->private_data;
+-      if (!dev->udev)
++      if (dev->disconnected)
+               return POLLERR | POLLHUP;
+       poll_wait(file, &dev->read_wait, wait);
+@@ -556,7 +555,7 @@ static ssize_t tower_read (struct file *
+       }
+       /* verify that the device wasn't unplugged */
+-      if (dev->udev == NULL) {
++      if (dev->disconnected) {
+               retval = -ENODEV;
+               pr_err("No device or device unplugged %d\n", retval);
+               goto unlock_exit;
+@@ -642,7 +641,7 @@ static ssize_t tower_write (struct file
+       }
+       /* verify that the device wasn't unplugged */
+-      if (dev->udev == NULL) {
++      if (dev->disconnected) {
+               retval = -ENODEV;
+               pr_err("No device or device unplugged %d\n", retval);
+               goto unlock_exit;
+@@ -751,7 +750,7 @@ static void tower_interrupt_in_callback
+ resubmit:
+       /* resubmit if we're still running */
+-      if (dev->interrupt_in_running && dev->udev) {
++      if (dev->interrupt_in_running) {
+               retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC);
+               if (retval)
+                       dev_err(&dev->udev->dev,
+@@ -816,6 +815,7 @@ static int tower_probe (struct usb_inter
+       dev->udev = udev;
+       dev->open_count = 0;
++      dev->disconnected = 0;
+       dev->read_buffer = NULL;
+       dev->read_buffer_length = 0;
+@@ -941,6 +941,10 @@ static void tower_disconnect (struct usb
+       /* give back our minor and prevent further open() */
+       usb_deregister_dev (interface, &tower_class);
++      /* stop I/O */
++      usb_poison_urb(dev->interrupt_in_urb);
++      usb_poison_urb(dev->interrupt_out_urb);
++
+       mutex_lock(&dev->lock);
+       /* if the device is not opened, then we clean up right now */
+@@ -948,7 +952,7 @@ static void tower_disconnect (struct usb
+               mutex_unlock(&dev->lock);
+               tower_delete (dev);
+       } else {
+-              dev->udev = NULL;
++              dev->disconnected = 1;
+               /* wake up pollers */
+               wake_up_interruptible_all(&dev->read_wait);
+               wake_up_interruptible_all(&dev->write_wait);
diff --git a/queue-4.14/usb-legousbtower-fix-slab-info-leak-at-probe.patch b/queue-4.14/usb-legousbtower-fix-slab-info-leak-at-probe.patch
new file mode 100644 (file)
index 0000000..3f3699a
--- /dev/null
@@ -0,0 +1,38 @@
+From 1d427be4a39defadda6dd8f4659bc17f7591740f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:36 +0200
+Subject: USB: legousbtower: fix slab info leak at probe
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 1d427be4a39defadda6dd8f4659bc17f7591740f upstream.
+
+Make sure to check for short transfers when retrieving the version
+information at probe to avoid leaking uninitialised slab data when
+logging it.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -894,8 +894,10 @@ static int tower_probe (struct usb_inter
+                                 get_version_reply,
+                                 sizeof(*get_version_reply),
+                                 1000);
+-      if (result < 0) {
+-              dev_err(idev, "LEGO USB Tower get version control request failed\n");
++      if (result < sizeof(*get_version_reply)) {
++              if (result >= 0)
++                      result = -EIO;
++              dev_err(idev, "get version request failed: %d\n", result);
+               retval = result;
+               goto error;
+       }
diff --git a/queue-4.14/usb-legousbtower-fix-use-after-free-on-release.patch b/queue-4.14/usb-legousbtower-fix-use-after-free-on-release.patch
new file mode 100644 (file)
index 0000000..87e9064
--- /dev/null
@@ -0,0 +1,43 @@
+From 726b55d0e22ca72c69c947af87785c830289ddbc Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:47 +0200
+Subject: USB: legousbtower: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 726b55d0e22ca72c69c947af87785c830289ddbc upstream.
+
+The driver was accessing its struct usb_device in its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever the device was disconnected while the character
+device was still open.
+
+Fixes: fef526cae700 ("USB: legousbtower: remove custom debug macro")
+Cc: stable <stable@vger.kernel.org>     # 3.12
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-5-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -300,6 +300,7 @@ static inline void tower_delete (struct
+       kfree (dev->read_buffer);
+       kfree (dev->interrupt_in_buffer);
+       kfree (dev->interrupt_out_buffer);
++      usb_put_dev(dev->udev);
+       kfree (dev);
+ }
+@@ -813,7 +814,7 @@ static int tower_probe (struct usb_inter
+       mutex_init(&dev->lock);
+-      dev->udev = udev;
++      dev->udev = usb_get_dev(udev);
+       dev->open_count = 0;
+       dev->disconnected = 0;
diff --git a/queue-4.14/usb-microtek-fix-info-leak-at-probe.patch b/queue-4.14/usb-microtek-fix-info-leak-at-probe.patch
new file mode 100644 (file)
index 0000000..07ed973
--- /dev/null
@@ -0,0 +1,38 @@
+From 177238c3d47d54b2ed8f0da7a4290db492f4a057 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 3 Oct 2019 09:09:31 +0200
+Subject: USB: microtek: fix info-leak at probe
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 177238c3d47d54b2ed8f0da7a4290db492f4a057 upstream.
+
+Add missing bulk-in endpoint sanity check to prevent uninitialised stack
+data from being reported to the system log and used as endpoint
+addresses.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reported-by: syzbot+5630ca7c3b2be5c9da5e@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20191003070931.17009-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/image/microtek.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/image/microtek.c
++++ b/drivers/usb/image/microtek.c
+@@ -720,6 +720,10 @@ static int mts_usb_probe(struct usb_inte
+       }
++      if (ep_in_current != &ep_in_set[2]) {
++              MTS_WARNING("couldn't find two input bulk endpoints. Bailing out.\n");
++              return -ENODEV;
++      }
+       if ( ep_out == -1 ) {
+               MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
diff --git a/queue-4.14/usb-renesas_usbhs-gadget-do-not-discard-queues-in-usb_ep_set_-halt-wedge.patch b/queue-4.14/usb-renesas_usbhs-gadget-do-not-discard-queues-in-usb_ep_set_-halt-wedge.patch
new file mode 100644 (file)
index 0000000..79b22a9
--- /dev/null
@@ -0,0 +1,36 @@
+From 1aae1394294cb71c6aa0bc904a94a7f2f1e75936 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 1 Oct 2019 19:10:32 +0900
+Subject: usb: renesas_usbhs: gadget: Do not discard queues in usb_ep_set_{halt,wedge}()
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit 1aae1394294cb71c6aa0bc904a94a7f2f1e75936 upstream.
+
+The commit 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area")
+had added a usbhsg_pipe_disable() calling into
+__usbhsg_ep_set_halt_wedge() accidentally. But, this driver should
+not call the usbhsg_pipe_disable() because the function discards
+all queues. So, this patch removes it.
+
+Fixes: 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area")
+Cc: <stable@vger.kernel.org> # v3.1+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/1569924633-322-2-git-send-email-yoshihiro.shimoda.uh@renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/renesas_usbhs/mod_gadget.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/usb/renesas_usbhs/mod_gadget.c
++++ b/drivers/usb/renesas_usbhs/mod_gadget.c
+@@ -730,8 +730,6 @@ static int __usbhsg_ep_set_halt_wedge(st
+       struct device *dev = usbhsg_gpriv_to_dev(gpriv);
+       unsigned long flags;
+-      usbhsg_pipe_disable(uep);
+-
+       dev_dbg(dev, "set halt %d (pipe %d)\n",
+               halt, usbhs_pipe_number(pipe));
diff --git a/queue-4.14/usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch b/queue-4.14/usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch
new file mode 100644 (file)
index 0000000..97e23a5
--- /dev/null
@@ -0,0 +1,137 @@
+From 4d599cd3a097a85a5c68a2c82b9a48cddf9953ec Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 1 Oct 2019 19:10:33 +0900
+Subject: usb: renesas_usbhs: gadget: Fix usb_ep_set_{halt,wedge}() behavior
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit 4d599cd3a097a85a5c68a2c82b9a48cddf9953ec upstream.
+
+According to usb_ep_set_halt()'s description,
+__usbhsg_ep_set_halt_wedge() should return -EAGAIN if the IN endpoint
+has any queue or data. Otherwise, this driver is possible to cause
+just STALL without sending a short packet data on g_mass_storage driver,
+and then a few resetting a device happens on a host side during
+a usb enumaration.
+
+Fixes: 2f98382dcdfe ("usb: renesas_usbhs: Add Renesas USBHS Gadget")
+Cc: <stable@vger.kernel.org> # v3.0+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/1569924633-322-3-git-send-email-yoshihiro.shimoda.uh@renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/renesas_usbhs/common.h     |    1 +
+ drivers/usb/renesas_usbhs/fifo.c       |    2 +-
+ drivers/usb/renesas_usbhs/fifo.h       |    1 +
+ drivers/usb/renesas_usbhs/mod_gadget.c |   16 +++++++++++++++-
+ drivers/usb/renesas_usbhs/pipe.c       |   15 +++++++++++++++
+ drivers/usb/renesas_usbhs/pipe.h       |    1 +
+ 6 files changed, 34 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/renesas_usbhs/common.h
++++ b/drivers/usb/renesas_usbhs/common.h
+@@ -213,6 +213,7 @@ struct usbhs_priv;
+ /* DCPCTR */
+ #define BSTS          (1 << 15)       /* Buffer Status */
+ #define SUREQ         (1 << 14)       /* Sending SETUP Token */
++#define INBUFM                (1 << 14)       /* (PIPEnCTR) Transfer Buffer Monitor */
+ #define CSSTS         (1 << 12)       /* CSSTS Status */
+ #define       ACLRM           (1 << 9)        /* Buffer Auto-Clear Mode */
+ #define SQCLR         (1 << 8)        /* Toggle Bit Clear */
+--- a/drivers/usb/renesas_usbhs/fifo.c
++++ b/drivers/usb/renesas_usbhs/fifo.c
+@@ -98,7 +98,7 @@ static void __usbhsf_pkt_del(struct usbh
+       list_del_init(&pkt->node);
+ }
+-static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
++struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
+ {
+       return list_first_entry_or_null(&pipe->list, struct usbhs_pkt, node);
+ }
+--- a/drivers/usb/renesas_usbhs/fifo.h
++++ b/drivers/usb/renesas_usbhs/fifo.h
+@@ -106,5 +106,6 @@ void usbhs_pkt_push(struct usbhs_pipe *p
+                   void *buf, int len, int zero, int sequence);
+ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt);
+ void usbhs_pkt_start(struct usbhs_pipe *pipe);
++struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe);
+ #endif /* RENESAS_USB_FIFO_H */
+--- a/drivers/usb/renesas_usbhs/mod_gadget.c
++++ b/drivers/usb/renesas_usbhs/mod_gadget.c
+@@ -729,6 +729,7 @@ static int __usbhsg_ep_set_halt_wedge(st
+       struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
+       struct device *dev = usbhsg_gpriv_to_dev(gpriv);
+       unsigned long flags;
++      int ret = 0;
+       dev_dbg(dev, "set halt %d (pipe %d)\n",
+               halt, usbhs_pipe_number(pipe));
+@@ -736,6 +737,18 @@ static int __usbhsg_ep_set_halt_wedge(st
+       /********************  spin lock ********************/
+       usbhs_lock(priv, flags);
++      /*
++       * According to usb_ep_set_halt()'s description, this function should
++       * return -EAGAIN if the IN endpoint has any queue or data. Note
++       * that the usbhs_pipe_is_dir_in() returns false if the pipe is an
++       * IN endpoint in the gadget mode.
++       */
++      if (!usbhs_pipe_is_dir_in(pipe) && (__usbhsf_pkt_get(pipe) ||
++          usbhs_pipe_contains_transmittable_data(pipe))) {
++              ret = -EAGAIN;
++              goto out;
++      }
++
+       if (halt)
+               usbhs_pipe_stall(pipe);
+       else
+@@ -746,10 +759,11 @@ static int __usbhsg_ep_set_halt_wedge(st
+       else
+               usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE);
++out:
+       usbhs_unlock(priv, flags);
+       /********************  spin unlock ******************/
+-      return 0;
++      return ret;
+ }
+ static int usbhsg_ep_set_halt(struct usb_ep *ep, int value)
+--- a/drivers/usb/renesas_usbhs/pipe.c
++++ b/drivers/usb/renesas_usbhs/pipe.c
+@@ -286,6 +286,21 @@ int usbhs_pipe_is_accessible(struct usbh
+       return -EBUSY;
+ }
++bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe)
++{
++      u16 val;
++
++      /* Do not support for DCP pipe */
++      if (usbhs_pipe_is_dcp(pipe))
++              return false;
++
++      val = usbhsp_pipectrl_get(pipe);
++      if (val & INBUFM)
++              return true;
++
++      return false;
++}
++
+ /*
+  *            PID ctrl
+  */
+--- a/drivers/usb/renesas_usbhs/pipe.h
++++ b/drivers/usb/renesas_usbhs/pipe.h
+@@ -90,6 +90,7 @@ void usbhs_pipe_init(struct usbhs_priv *
+ int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
+ void usbhs_pipe_clear(struct usbhs_pipe *pipe);
+ int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe);
++bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe);
+ void usbhs_pipe_enable(struct usbhs_pipe *pipe);
+ void usbhs_pipe_disable(struct usbhs_pipe *pipe);
+ void usbhs_pipe_stall(struct usbhs_pipe *pipe);
diff --git a/queue-4.14/usb-serial-fix-runtime-pm-after-driver-unbind.patch b/queue-4.14/usb-serial-fix-runtime-pm-after-driver-unbind.patch
new file mode 100644 (file)
index 0000000..119310d
--- /dev/null
@@ -0,0 +1,41 @@
+From d51bdb93ca7e71d7fb30a572c7b47ed0194bf3fe Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Oct 2019 10:49:07 +0200
+Subject: USB: serial: fix runtime PM after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit d51bdb93ca7e71d7fb30a572c7b47ed0194bf3fe upstream.
+
+Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate
+interface PM usage counter") USB drivers must always balance their
+runtime PM gets and puts, including when the driver has already been
+unbound from the interface.
+
+Leaving the interface with a positive PM usage counter would prevent a
+later bound driver from suspending the device.
+
+Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191001084908.2003-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/usb-serial.c |    5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -314,10 +314,7 @@ static void serial_cleanup(struct tty_st
+       serial = port->serial;
+       owner = serial->type->driver.owner;
+-      mutex_lock(&serial->disc_mutex);
+-      if (!serial->disconnected)
+-              usb_autopm_put_interface(serial->interface);
+-      mutex_unlock(&serial->disc_mutex);
++      usb_autopm_put_interface(serial->interface);
+       usb_serial_put(serial);
+       module_put(owner);
diff --git a/queue-4.14/usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch b/queue-4.14/usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch
new file mode 100644 (file)
index 0000000..45e9b6f
--- /dev/null
@@ -0,0 +1,65 @@
+From 357f16d9e0194cdbc36531ff88b453481560b76a Mon Sep 17 00:00:00 2001
+From: Beni Mahler <beni.mahler@gmx.net>
+Date: Thu, 5 Sep 2019 00:26:20 +0200
+Subject: USB: serial: ftdi_sio: add device IDs for Sienna and Echelon PL-20
+
+From: Beni Mahler <beni.mahler@gmx.net>
+
+commit 357f16d9e0194cdbc36531ff88b453481560b76a upstream.
+
+Both devices added here have a FTDI chip inside. The device from Echelon
+is called 'Network Interface' it is actually a LON network gateway.
+
+ ID 0403:8348 Future Technology Devices International, Ltd
+ https://www.eltako.com/fileadmin/downloads/de/datenblatt/Datenblatt_PL-SW-PROF.pdf
+
+ ID 0920:7500 Network Interface
+ https://www.echelon.com/products/u20-usb-network-interface
+
+Signed-off-by: Beni Mahler <beni.mahler@gmx.net>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c     |    3 +++
+ drivers/usb/serial/ftdi_sio_ids.h |    9 +++++++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1025,6 +1025,9 @@ static const struct usb_device_id id_tab
+       /* EZPrototypes devices */
+       { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) },
+       { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) },
++      /* Sienna devices */
++      { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) },
++      { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) },
+       { }                                     /* Terminating entry */
+ };
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -39,6 +39,9 @@
+ #define FTDI_LUMEL_PD12_PID   0x6002
++/* Sienna Serial Interface by Secyourit GmbH */
++#define FTDI_SIENNA_PID               0x8348
++
+ /* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */
+ #define CYBER_CORTEX_AV_PID   0x8698
+@@ -689,6 +692,12 @@
+ #define BANDB_ZZ_PROG1_USB_PID        0xBA02
+ /*
++ * Echelon USB Serial Interface
++ */
++#define ECHELON_VID           0x0920
++#define ECHELON_U20_PID               0x7500
++
++/*
+  * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI
+  */
+ #define INTREPID_VID          0x093C
diff --git a/queue-4.14/usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch b/queue-4.14/usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch
new file mode 100644 (file)
index 0000000..c11221a
--- /dev/null
@@ -0,0 +1,74 @@
+From 7d7e21fafdbc7fcf0854b877bd0975b487ed2717 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 3 Oct 2019 15:49:58 +0200
+Subject: USB: serial: keyspan: fix NULL-derefs on open() and write()
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 7d7e21fafdbc7fcf0854b877bd0975b487ed2717 upstream.
+
+Fix NULL-pointer dereferences on open() and write() which can be
+triggered by a malicious USB device.
+
+The current URB allocation helper would fail to initialise the newly
+allocated URB if the device has unexpected endpoint descriptors,
+something which could lead NULL-pointer dereferences in a number of
+open() and write() paths when accessing the URB. For example:
+
+       BUG: kernel NULL pointer dereference, address: 0000000000000000
+       ...
+       RIP: 0010:usb_clear_halt+0x11/0xc0
+       ...
+       Call Trace:
+        ? tty_port_open+0x4d/0xd0
+        keyspan_open+0x70/0x160 [keyspan]
+        serial_port_activate+0x5b/0x80 [usbserial]
+        tty_port_open+0x7b/0xd0
+        ? check_tty_count+0x43/0xa0
+        tty_open+0xf1/0x490
+
+       BUG: kernel NULL pointer dereference, address: 0000000000000000
+       ...
+       RIP: 0010:keyspan_write+0x14e/0x1f3 [keyspan]
+       ...
+       Call Trace:
+        serial_write+0x43/0xa0 [usbserial]
+        n_tty_write+0x1af/0x4f0
+        ? do_wait_intr_irq+0x80/0x80
+        ? process_echoes+0x60/0x60
+        tty_write+0x13f/0x2f0
+
+       BUG: kernel NULL pointer dereference, address: 0000000000000000
+       ...
+       RIP: 0010:keyspan_usa26_send_setup+0x298/0x305 [keyspan]
+       ...
+       Call Trace:
+        keyspan_open+0x10f/0x160 [keyspan]
+        serial_port_activate+0x5b/0x80 [usbserial]
+        tty_port_open+0x7b/0xd0
+        ? check_tty_count+0x43/0xa0
+        tty_open+0xf1/0x490
+
+Fixes: fdcba53e2d58 ("fix for bugzilla #7544 (keyspan USB-to-serial converter)")
+Cc: stable <stable@vger.kernel.org>    # 2.6.21
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/keyspan.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -1745,8 +1745,8 @@ static struct urb *keyspan_setup_urb(str
+       ep_desc = find_ep(serial, endpoint);
+       if (!ep_desc) {
+-              /* leak the urb, something's wrong and the callers don't care */
+-              return urb;
++              usb_free_urb(urb);
++              return NULL;
+       }
+       if (usb_endpoint_xfer_int(ep_desc)) {
+               ep_type_name = "INT";
diff --git a/queue-4.14/usb-serial-option-add-support-for-cinterion-cls8-devices.patch b/queue-4.14/usb-serial-option-add-support-for-cinterion-cls8-devices.patch
new file mode 100644 (file)
index 0000000..6916844
--- /dev/null
@@ -0,0 +1,65 @@
+From dfbac2f4da6a0c4a8f6b4d715a4077a7b8df53ad Mon Sep 17 00:00:00 2001
+From: Reinhard Speyerer <rspmn@arcor.de>
+Date: Thu, 3 Oct 2019 18:53:21 +0200
+Subject: USB: serial: option: add support for Cinterion CLS8 devices
+
+From: Reinhard Speyerer <rspmn@arcor.de>
+
+commit dfbac2f4da6a0c4a8f6b4d715a4077a7b8df53ad upstream.
+
+Add support for the serial ports of Cinterion CLS8 devices.
+
+T:  Bus=01 Lev=03 Prnt=05 Port=01 Cnt=02 Dev#= 25 Spd=480  MxCh= 0
+D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
+P:  Vendor=1e2d ProdID=00b0 Rev= 3.18
+S:  Manufacturer=GEMALTO
+S:  Product=USB Modem
+C:* #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
+E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E:  Ad=83(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
+E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E:  Ad=85(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
+E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E:  Ad=87(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
+E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
+E:  Ad=89(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
+E:  Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Signed-off-by: Reinhard Speyerer <rspmn@arcor.de>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -422,6 +422,7 @@ static void option_instat_callback(struc
+ #define CINTERION_PRODUCT_PH8_AUDIO           0x0083
+ #define CINTERION_PRODUCT_AHXX_2RMNET         0x0084
+ #define CINTERION_PRODUCT_AHXX_AUDIO          0x0085
++#define CINTERION_PRODUCT_CLS8                        0x00b0
+ /* Olivetti products */
+ #define OLIVETTI_VENDOR_ID                    0x0b3c
+@@ -1858,6 +1859,8 @@ static const struct usb_device_id option
+         .driver_info = RSVD(4) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) },
++      { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_CLS8, 0xff),
++        .driver_info = RSVD(0) | RSVD(4) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
diff --git a/queue-4.14/usb-serial-option-add-telit-fn980-compositions.patch b/queue-4.14/usb-serial-option-add-telit-fn980-compositions.patch
new file mode 100644 (file)
index 0000000..2baa2e7
--- /dev/null
@@ -0,0 +1,42 @@
+From 5eb3f4b87a0e7e949c976f32f296176a06d1a93b Mon Sep 17 00:00:00 2001
+From: Daniele Palmas <dnlplm@gmail.com>
+Date: Mon, 23 Sep 2019 12:23:28 +0200
+Subject: USB: serial: option: add Telit FN980 compositions
+
+From: Daniele Palmas <dnlplm@gmail.com>
+
+commit 5eb3f4b87a0e7e949c976f32f296176a06d1a93b upstream.
+
+This patch adds the following Telit FN980 compositions:
+
+0x1050: tty, adb, rmnet, tty, tty, tty, tty
+0x1051: tty, adb, mbim, tty, tty, tty, tty
+0x1052: rndis, tty, adb, tty, tty, tty, tty
+0x1053: tty, adb, ecm, tty, tty, tty, tty
+
+Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1157,6 +1157,14 @@ static const struct usb_device_id option
+         .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
+         .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
++      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1050, 0xff),    /* Telit FN980 (rmnet) */
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
++      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1051, 0xff),    /* Telit FN980 (MBIM) */
++        .driver_info = NCTRL(0) | RSVD(1) },
++      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1052, 0xff),    /* Telit FN980 (RNDIS) */
++        .driver_info = NCTRL(2) | RSVD(3) },
++      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1053, 0xff),    /* Telit FN980 (ECM) */
++        .driver_info = NCTRL(0) | RSVD(1) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
+         .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
diff --git a/queue-4.14/usb-usb-skeleton-fix-null-deref-on-disconnect.patch b/queue-4.14/usb-usb-skeleton-fix-null-deref-on-disconnect.patch
new file mode 100644 (file)
index 0000000..3822258
--- /dev/null
@@ -0,0 +1,70 @@
+From bed5ef230943863b9abf5eae226a20fad9a8ff71 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 19:09:42 +0200
+Subject: USB: usb-skeleton: fix NULL-deref on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit bed5ef230943863b9abf5eae226a20fad9a8ff71 upstream.
+
+The driver was using its struct usb_interface pointer as an inverted
+disconnected flag and was setting it to NULL before making sure all
+completion handlers had run. This could lead to NULL-pointer
+dereferences in the dev_err() statements in the completion handlers
+which relies on said pointer.
+
+Fix this by using a dedicated disconnected flag.
+
+Note that this is also addresses a NULL-pointer dereference at release()
+and a struct usb_interface reference leak introduced by a recent runtime
+PM fix, which depends on and should have been submitted together with
+this patch.
+
+Fixes: 4212cd74ca6f ("USB: usb-skeleton.c: remove err() usage")
+Fixes: 5c290a5e42c3 ("USB: usb-skeleton: fix runtime PM after driver unbind")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009170944.30057-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usb-skeleton.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/usb-skeleton.c
++++ b/drivers/usb/usb-skeleton.c
+@@ -63,6 +63,7 @@ struct usb_skel {
+       spinlock_t              err_lock;               /* lock for errors */
+       struct kref             kref;
+       struct mutex            io_mutex;               /* synchronize I/O with disconnect */
++      unsigned long           disconnected:1;
+       wait_queue_head_t       bulk_in_wait;           /* to wait for an ongoing read */
+ };
+ #define to_skel_dev(d) container_of(d, struct usb_skel, kref)
+@@ -239,7 +240,7 @@ static ssize_t skel_read(struct file *fi
+       if (rv < 0)
+               return rv;
+-      if (!dev->interface) {          /* disconnect() was called */
++      if (dev->disconnected) {                /* disconnect() was called */
+               rv = -ENODEV;
+               goto exit;
+       }
+@@ -420,7 +421,7 @@ static ssize_t skel_write(struct file *f
+       /* this lock makes sure we don't submit URBs to gone devices */
+       mutex_lock(&dev->io_mutex);
+-      if (!dev->interface) {          /* disconnect() was called */
++      if (dev->disconnected) {                /* disconnect() was called */
+               mutex_unlock(&dev->io_mutex);
+               retval = -ENODEV;
+               goto error;
+@@ -571,7 +572,7 @@ static void skel_disconnect(struct usb_i
+       /* prevent more I/O from starting */
+       mutex_lock(&dev->io_mutex);
+-      dev->interface = NULL;
++      dev->disconnected = 1;
+       mutex_unlock(&dev->io_mutex);
+       usb_kill_anchored_urbs(&dev->submitted);
diff --git a/queue-4.14/usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch b/queue-4.14/usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch
new file mode 100644 (file)
index 0000000..bfd0a05
--- /dev/null
@@ -0,0 +1,58 @@
+From 5c290a5e42c3387e82de86965784d30e6c5270fd Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Oct 2019 10:49:05 +0200
+Subject: USB: usb-skeleton: fix runtime PM after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5c290a5e42c3387e82de86965784d30e6c5270fd upstream.
+
+Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate
+interface PM usage counter") USB drivers must always balance their
+runtime PM gets and puts, including when the driver has already been
+unbound from the interface.
+
+Leaving the interface with a positive PM usage counter would prevent a
+later bound driver from suspending the device.
+
+Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191001084908.2003-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usb-skeleton.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/usb-skeleton.c
++++ b/drivers/usb/usb-skeleton.c
+@@ -75,6 +75,7 @@ static void skel_delete(struct kref *kre
+       struct usb_skel *dev = to_skel_dev(kref);
+       usb_free_urb(dev->bulk_in_urb);
++      usb_put_intf(dev->interface);
+       usb_put_dev(dev->udev);
+       kfree(dev->bulk_in_buffer);
+       kfree(dev);
+@@ -126,10 +127,7 @@ static int skel_release(struct inode *in
+               return -ENODEV;
+       /* allow the device to be autosuspended */
+-      mutex_lock(&dev->io_mutex);
+-      if (dev->interface)
+-              usb_autopm_put_interface(dev->interface);
+-      mutex_unlock(&dev->io_mutex);
++      usb_autopm_put_interface(dev->interface);
+       /* decrement the count on our device */
+       kref_put(&dev->kref, skel_delete);
+@@ -507,7 +505,7 @@ static int skel_probe(struct usb_interfa
+       init_waitqueue_head(&dev->bulk_in_wait);
+       dev->udev = usb_get_dev(interface_to_usbdev(interface));
+-      dev->interface = interface;
++      dev->interface = usb_get_intf(interface);
+       /* set up the endpoint information */
+       /* use only the first bulk-in and bulk-out endpoints */
diff --git a/queue-4.14/usb-usblcd-fix-i-o-after-disconnect.patch b/queue-4.14/usb-usblcd-fix-i-o-after-disconnect.patch
new file mode 100644 (file)
index 0000000..8142dd4
--- /dev/null
@@ -0,0 +1,128 @@
+From eb7f5a490c5edfe8126f64bc58b9ba2edef0a425 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 26 Sep 2019 11:12:25 +0200
+Subject: USB: usblcd: fix I/O after disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit eb7f5a490c5edfe8126f64bc58b9ba2edef0a425 upstream.
+
+Make sure to stop all I/O on disconnect by adding a disconnected flag
+which is used to prevent new I/O from being started and by stopping all
+ongoing I/O before returning.
+
+This also fixes a potential use-after-free on driver unbind in case the
+driver data is freed before the completion handler has run.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>    # 7bbe990c989e
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190926091228.24634-7-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/usblcd.c |   33 +++++++++++++++++++++++++++++++--
+ 1 file changed, 31 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/usblcd.c
++++ b/drivers/usb/misc/usblcd.c
+@@ -17,6 +17,7 @@
+ #include <linux/slab.h>
+ #include <linux/errno.h>
+ #include <linux/mutex.h>
++#include <linux/rwsem.h>
+ #include <linux/uaccess.h>
+ #include <linux/usb.h>
+@@ -56,6 +57,8 @@ struct usb_lcd {
+                                                          using up all RAM */
+       struct usb_anchor       submitted;              /* URBs to wait for
+                                                          before suspend */
++      struct rw_semaphore     io_rwsem;
++      unsigned long           disconnected:1;
+ };
+ #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref)
+@@ -141,6 +144,13 @@ static ssize_t lcd_read(struct file *fil
+       dev = file->private_data;
++      down_read(&dev->io_rwsem);
++
++      if (dev->disconnected) {
++              retval = -ENODEV;
++              goto out_up_io;
++      }
++
+       /* do a blocking bulk read to get data from the device */
+       retval = usb_bulk_msg(dev->udev,
+                             usb_rcvbulkpipe(dev->udev,
+@@ -157,6 +167,9 @@ static ssize_t lcd_read(struct file *fil
+                       retval = bytes_read;
+       }
++out_up_io:
++      up_read(&dev->io_rwsem);
++
+       return retval;
+ }
+@@ -236,11 +249,18 @@ static ssize_t lcd_write(struct file *fi
+       if (r < 0)
+               return -EINTR;
++      down_read(&dev->io_rwsem);
++
++      if (dev->disconnected) {
++              retval = -ENODEV;
++              goto err_up_io;
++      }
++
+       /* create a urb, and a buffer for it, and copy the data to the urb */
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!urb) {
+               retval = -ENOMEM;
+-              goto err_no_buf;
++              goto err_up_io;
+       }
+       buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL,
+@@ -277,6 +297,7 @@ static ssize_t lcd_write(struct file *fi
+          the USB core will eventually free it entirely */
+       usb_free_urb(urb);
++      up_read(&dev->io_rwsem);
+ exit:
+       return count;
+ error_unanchor:
+@@ -284,7 +305,8 @@ error_unanchor:
+ error:
+       usb_free_coherent(dev->udev, count, buf, urb->transfer_dma);
+       usb_free_urb(urb);
+-err_no_buf:
++err_up_io:
++      up_read(&dev->io_rwsem);
+       up(&dev->limit_sem);
+       return retval;
+ }
+@@ -324,6 +346,7 @@ static int lcd_probe(struct usb_interfac
+       kref_init(&dev->kref);
+       sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);
++      init_rwsem(&dev->io_rwsem);
+       init_usb_anchor(&dev->submitted);
+       dev->udev = usb_get_dev(interface_to_usbdev(interface));
+@@ -421,6 +444,12 @@ static void lcd_disconnect(struct usb_in
+       /* give back our minor */
+       usb_deregister_dev(interface, &lcd_class);
++      down_write(&dev->io_rwsem);
++      dev->disconnected = 1;
++      up_write(&dev->io_rwsem);
++
++      usb_kill_anchored_urbs(&dev->submitted);
++
+       /* decrement our usage count */
+       kref_put(&dev->kref, lcd_delete);
diff --git a/queue-4.14/usb-usblp-fix-runtime-pm-after-driver-unbind.patch b/queue-4.14/usb-usblp-fix-runtime-pm-after-driver-unbind.patch
new file mode 100644 (file)
index 0000000..7ca544c
--- /dev/null
@@ -0,0 +1,45 @@
+From 9a31535859bfd8d1c3ed391f5e9247cd87bb7909 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Oct 2019 10:49:06 +0200
+Subject: USB: usblp: fix runtime PM after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 9a31535859bfd8d1c3ed391f5e9247cd87bb7909 upstream.
+
+Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate
+interface PM usage counter") USB drivers must always balance their
+runtime PM gets and puts, including when the driver has already been
+unbound from the interface.
+
+Leaving the interface with a positive PM usage counter would prevent a
+later bound driver from suspending the device.
+
+Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191001084908.2003-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/usblp.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/class/usblp.c
++++ b/drivers/usb/class/usblp.c
+@@ -474,10 +474,12 @@ static int usblp_release(struct inode *i
+       mutex_lock(&usblp_mutex);
+       usblp->used = 0;
+-      if (usblp->present) {
++      if (usblp->present)
+               usblp_unlink_urbs(usblp);
+-              usb_autopm_put_interface(usblp->intf);
+-      } else          /* finish cleanup from disconnect */
++
++      usb_autopm_put_interface(usblp->intf);
++
++      if (!usblp->present)            /* finish cleanup from disconnect */
+               usblp_cleanup(usblp);
+       mutex_unlock(&usblp_mutex);
+       return 0;
diff --git a/queue-4.14/usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch b/queue-4.14/usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch
new file mode 100644 (file)
index 0000000..2e6769c
--- /dev/null
@@ -0,0 +1,45 @@
+From a70bcbc322837eda1ab5994d12db941dc9733a7d Mon Sep 17 00:00:00 2001
+From: Rick Tseng <rtseng@nvidia.com>
+Date: Fri, 4 Oct 2019 14:59:30 +0300
+Subject: usb: xhci: wait for CNR controller not ready bit in xhci resume
+
+From: Rick Tseng <rtseng@nvidia.com>
+
+commit a70bcbc322837eda1ab5994d12db941dc9733a7d upstream.
+
+NVIDIA 3.1 xHCI card would lose power when moving power state into D3Cold.
+Thus we need to wait for CNR bit to clear in xhci resume, just as in
+xhci init.
+
+[Minor changes to comment and commit message -Mathias]
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Rick Tseng <rtseng@nvidia.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-6-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1044,6 +1044,18 @@ int xhci_resume(struct xhci_hcd *xhci, b
+               hibernated = true;
+       if (!hibernated) {
++              /*
++               * Some controllers might lose power during suspend, so wait
++               * for controller not ready bit to clear, just as in xHC init.
++               */
++              retval = xhci_handshake(&xhci->op_regs->status,
++                                      STS_CNR, 0, 10 * 1000 * 1000);
++              if (retval) {
++                      xhci_warn(xhci, "Controller not ready at resume %d\n",
++                                retval);
++                      spin_unlock_irq(&xhci->lock);
++                      return retval;
++              }
+               /* step 1: restore register */
+               xhci_restore_registers(xhci);
+               /* step 2: initialize command ring buffer */
diff --git a/queue-4.14/xhci-check-all-endpoints-for-lpm-timeout.patch b/queue-4.14/xhci-check-all-endpoints-for-lpm-timeout.patch
new file mode 100644 (file)
index 0000000..5ac65e5
--- /dev/null
@@ -0,0 +1,46 @@
+From d500c63f80f2ea08ee300e57da5f2af1c13875f5 Mon Sep 17 00:00:00 2001
+From: Jan Schmidt <jan@centricular.com>
+Date: Fri, 4 Oct 2019 14:59:28 +0300
+Subject: xhci: Check all endpoints for LPM timeout
+
+From: Jan Schmidt <jan@centricular.com>
+
+commit d500c63f80f2ea08ee300e57da5f2af1c13875f5 upstream.
+
+If an endpoint is encountered that returns USB3_LPM_DEVICE_INITIATED, keep
+checking further endpoints, as there might be periodic endpoints later
+that return USB3_LPM_DISABLED due to shorter service intervals.
+
+Without this, the code can set too high a maximum-exit-latency and
+prevent the use of multiple USB3 cameras that should be able to work.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jan Schmidt <jan@centricular.com>
+Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-4-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4491,12 +4491,12 @@ static int xhci_update_timeout_for_endpo
+       alt_timeout = xhci_call_host_update_timeout_for_endpoint(xhci, udev,
+               desc, state, timeout);
+-      /* If we found we can't enable hub-initiated LPM, or
++      /* If we found we can't enable hub-initiated LPM, and
+        * the U1 or U2 exit latency was too high to allow
+-       * device-initiated LPM as well, just stop searching.
++       * device-initiated LPM as well, then we will disable LPM
++       * for this device, so stop searching any further.
+        */
+-      if (alt_timeout == USB3_LPM_DISABLED ||
+-                      alt_timeout == USB3_LPM_DEVICE_INITIATED) {
++      if (alt_timeout == USB3_LPM_DISABLED) {
+               *timeout = alt_timeout;
+               return -E2BIG;
+       }
diff --git a/queue-4.14/xhci-fix-false-warning-message-about-wrong-bounce-buffer-write-length.patch b/queue-4.14/xhci-fix-false-warning-message-about-wrong-bounce-buffer-write-length.patch
new file mode 100644 (file)
index 0000000..0abb7b0
--- /dev/null
@@ -0,0 +1,44 @@
+From c03101ff4f74bb30679c1a03d551ecbef1024bf6 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 4 Oct 2019 14:59:26 +0300
+Subject: xhci: Fix false warning message about wrong bounce buffer write length
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit c03101ff4f74bb30679c1a03d551ecbef1024bf6 upstream.
+
+The check printing out the "WARN Wrong bounce buffer write length:"
+uses incorrect values when comparing bytes written from scatterlist
+to bounce buffer. Actual copied lengths are fine.
+
+The used seg->bounce_len will be set to equal new_buf_len a few lines later
+in the code, but is incorrect when doing the comparison.
+
+The patch which added this false warning was backported to 4.8+ kernels
+so this should be backported as far as well.
+
+Cc: <stable@vger.kernel.org> # v4.8+
+Fixes: 597c56e372da ("xhci: update bounce buffer with correct sg num")
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-2-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3223,10 +3223,10 @@ static int xhci_align_td(struct xhci_hcd
+       if (usb_urb_dir_out(urb)) {
+               len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
+                                  seg->bounce_buf, new_buff_len, enqd_len);
+-              if (len != seg->bounce_len)
++              if (len != new_buff_len)
+                       xhci_warn(xhci,
+                               "WARN Wrong bounce buffer write length: %zu != %d\n",
+-                              len, seg->bounce_len);
++                              len, new_buff_len);
+               seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
+                                                max_pkt, DMA_TO_DEVICE);
+       } else {
diff --git a/queue-4.14/xhci-increase-sts_save-timeout-in-xhci_suspend.patch b/queue-4.14/xhci-increase-sts_save-timeout-in-xhci_suspend.patch
new file mode 100644 (file)
index 0000000..cb36a22
--- /dev/null
@@ -0,0 +1,41 @@
+From ac343366846a445bb81f0a0e8f16abb8bd5d5d88 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Fri, 4 Oct 2019 14:59:32 +0300
+Subject: xhci: Increase STS_SAVE timeout in xhci_suspend()
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit ac343366846a445bb81f0a0e8f16abb8bd5d5d88 upstream.
+
+After commit f7fac17ca925 ("xhci: Convert xhci_handshake() to use
+readl_poll_timeout_atomic()"), ASMedia xHCI may fail to suspend.
+
+Although the algorithms are essentially the same, the old max timeout is
+(usec + usec * time of doing readl()), and the new max timeout is just
+usec, which is much less than the old one.
+
+Increase the timeout to make ASMedia xHCI able to suspend again.
+
+BugLink: https://bugs.launchpad.net/bugs/1844021
+Fixes: f7fac17ca925 ("xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic()")
+Cc: <stable@vger.kernel.org> # v5.2+
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-8-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -968,7 +968,7 @@ int xhci_suspend(struct xhci_hcd *xhci,
+       writel(command, &xhci->op_regs->command);
+       xhci->broken_suspend = 0;
+       if (xhci_handshake(&xhci->op_regs->status,
+-                              STS_SAVE, 0, 10 * 1000)) {
++                              STS_SAVE, 0, 20 * 1000)) {
+       /*
+        * AMD SNPS xHC 3.0 occasionally does not clear the
+        * SSS bit of USBSTS and when driver tries to poll
diff --git a/queue-4.14/xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too-long.patch b/queue-4.14/xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too-long.patch
new file mode 100644 (file)
index 0000000..01fbeec
--- /dev/null
@@ -0,0 +1,47 @@
+From cd9d9491e835a845c1a98b8471f88d26285e0bb9 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 4 Oct 2019 14:59:27 +0300
+Subject: xhci: Prevent device initiated U1/U2 link pm if exit latency is too long
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit cd9d9491e835a845c1a98b8471f88d26285e0bb9 upstream.
+
+If host/hub initiated link pm is prevented by a driver flag we still must
+ensure that periodic endpoints have longer service intervals than link pm
+exit latency before allowing device initiated link pm.
+
+Fix this by continue walking and checking endpoint service interval if
+xhci_get_timeout_no_hub_lpm() returns anything else than USB3_LPM_DISABLED
+
+While at it fix the split line error message
+
+Tested-by: Jan Schmidt <jan@centricular.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-3-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4607,10 +4607,12 @@ static u16 xhci_calculate_lpm_timeout(st
+               if (intf->dev.driver) {
+                       driver = to_usb_driver(intf->dev.driver);
+                       if (driver && driver->disable_hub_initiated_lpm) {
+-                              dev_dbg(&udev->dev, "Hub-initiated %s disabled "
+-                                              "at request of driver %s\n",
+-                                              state_name, driver->name);
+-                              return xhci_get_timeout_no_hub_lpm(udev, state);
++                              dev_dbg(&udev->dev, "Hub-initiated %s disabled at request of driver %s\n",
++                                      state_name, driver->name);
++                              timeout = xhci_get_timeout_no_hub_lpm(udev,
++                                                                    state);
++                              if (timeout == USB3_LPM_DISABLED)
++                                      return timeout;
+                       }
+               }