]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Apr 2020 14:29:34 +0000 (16:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Apr 2020 14:29:34 +0000 (16:29 +0200)
added patches:
drivers-usb-core-don-t-disable-irqs-in-usb_sg_wait-during-urb-submit.patch
drivers-usb-core-minimize-irq-disabling-in-usb_sg_cancel.patch
fs-namespace.c-fix-mountpoint-reference-counter-race.patch
iio-xilinx-xadc-fix-adc-b-powerdown.patch
iio-xilinx-xadc-fix-clearing-interrupt-when-enabling-trigger.patch
iio-xilinx-xadc-fix-sequencer-configuration-for-aux-channels-in-simultaneous-mode.patch
usb-add-usb_quirk_delay_ctrl_msg-and-usb_quirk_delay_init-for-corsair-k70-rgb-rapidfire.patch
usb-core-fix-free-while-in-use-bug-in-the-usb-s-glibrary.patch
usb-hub-fix-handling-of-connect-changes-during-sleep.patch
usb-sisusbvga-change-port-variable-from-signed-to-unsigned.patch

queue-4.4/drivers-usb-core-don-t-disable-irqs-in-usb_sg_wait-during-urb-submit.patch [new file with mode: 0644]
queue-4.4/drivers-usb-core-minimize-irq-disabling-in-usb_sg_cancel.patch [new file with mode: 0644]
queue-4.4/fs-namespace.c-fix-mountpoint-reference-counter-race.patch [new file with mode: 0644]
queue-4.4/iio-xilinx-xadc-fix-adc-b-powerdown.patch [new file with mode: 0644]
queue-4.4/iio-xilinx-xadc-fix-clearing-interrupt-when-enabling-trigger.patch [new file with mode: 0644]
queue-4.4/iio-xilinx-xadc-fix-sequencer-configuration-for-aux-channels-in-simultaneous-mode.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/usb-add-usb_quirk_delay_ctrl_msg-and-usb_quirk_delay_init-for-corsair-k70-rgb-rapidfire.patch [new file with mode: 0644]
queue-4.4/usb-core-fix-free-while-in-use-bug-in-the-usb-s-glibrary.patch [new file with mode: 0644]
queue-4.4/usb-hub-fix-handling-of-connect-changes-during-sleep.patch [new file with mode: 0644]
queue-4.4/usb-sisusbvga-change-port-variable-from-signed-to-unsigned.patch [new file with mode: 0644]

diff --git a/queue-4.4/drivers-usb-core-don-t-disable-irqs-in-usb_sg_wait-during-urb-submit.patch b/queue-4.4/drivers-usb-core-don-t-disable-irqs-in-usb_sg_wait-during-urb-submit.patch
new file mode 100644 (file)
index 0000000..a824b7b
--- /dev/null
@@ -0,0 +1,79 @@
+From 98b74b0ee57af1bcb6e8b2e76e707a71c5ef8ec9 Mon Sep 17 00:00:00 2001
+From: David Mosberger <davidm@egauge.net>
+Date: Tue, 8 Mar 2016 14:42:48 -0700
+Subject: drivers: usb: core: Don't disable irqs in usb_sg_wait() during URB submit.
+
+From: David Mosberger <davidm@egauge.net>
+
+commit 98b74b0ee57af1bcb6e8b2e76e707a71c5ef8ec9 upstream.
+
+usb_submit_urb() may take quite long to execute.  For example, a
+single sg list may have 30 or more entries, possibly leading to that
+many calls to DMA-map pages.  This can cause interrupt latency of
+several hundred micro-seconds.
+
+Avoid the problem by releasing the io->lock spinlock and re-enabling
+interrupts before calling usb_submit_urb().  This opens races with
+usb_sg_cancel() and sg_complete().  Handle those races by using
+usb_block_urb() to stop URBs from being submitted after
+usb_sg_cancel() or sg_complete() with error.
+
+Note that usb_unlink_urb() is guaranteed to return -ENODEV if
+!io->urbs[i]->dev and since the -ENODEV case is already handled,
+we don't have to check for !io->urbs[i]->dev explicitly.
+
+Before this change, reading 512MB from an ext3 filesystem on a USB
+memory stick showed a throughput of 12 MB/s with about 500 missed
+deadlines.
+
+With this change, reading the same file gave the same throughput but
+only one or two missed deadlines.
+
+Signed-off-by: David Mosberger <davidm@egauge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/message.c |   15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -306,9 +306,10 @@ static void sg_complete(struct urb *urb)
+                */
+               spin_unlock(&io->lock);
+               for (i = 0, found = 0; i < io->entries; i++) {
+-                      if (!io->urbs[i] || !io->urbs[i]->dev)
++                      if (!io->urbs[i])
+                               continue;
+                       if (found) {
++                              usb_block_urb(io->urbs[i]);
+                               retval = usb_unlink_urb(io->urbs[i]);
+                               if (retval != -EINPROGRESS &&
+                                   retval != -ENODEV &&
+@@ -519,12 +520,10 @@ void usb_sg_wait(struct usb_sg_request *
+               int retval;
+               io->urbs[i]->dev = io->dev;
+-              retval = usb_submit_urb(io->urbs[i], GFP_ATOMIC);
+-
+-              /* after we submit, let completions or cancellations fire;
+-               * we handshake using io->status.
+-               */
+               spin_unlock_irq(&io->lock);
++
++              retval = usb_submit_urb(io->urbs[i], GFP_NOIO);
++
+               switch (retval) {
+                       /* maybe we retrying will recover */
+               case -ENXIO:    /* hc didn't queue this one */
+@@ -594,8 +593,8 @@ void usb_sg_cancel(struct usb_sg_request
+               for (i = 0; i < io->entries; i++) {
+                       int retval;
+-                      if (!io->urbs[i]->dev)
+-                              continue;
++                      usb_block_urb(io->urbs[i]);
++
+                       retval = usb_unlink_urb(io->urbs[i]);
+                       if (retval != -EINPROGRESS
+                                       && retval != -ENODEV
diff --git a/queue-4.4/drivers-usb-core-minimize-irq-disabling-in-usb_sg_cancel.patch b/queue-4.4/drivers-usb-core-minimize-irq-disabling-in-usb_sg_cancel.patch
new file mode 100644 (file)
index 0000000..3ea60a8
--- /dev/null
@@ -0,0 +1,71 @@
+From 5f2e5fb873e269fcb806165715d237f0de4ecf1d Mon Sep 17 00:00:00 2001
+From: David Mosberger <davidm@egauge.net>
+Date: Tue, 8 Mar 2016 14:42:49 -0700
+Subject: drivers: usb: core: Minimize irq disabling in usb_sg_cancel()
+
+From: David Mosberger <davidm@egauge.net>
+
+commit 5f2e5fb873e269fcb806165715d237f0de4ecf1d upstream.
+
+Restructure usb_sg_cancel() so we don't have to disable interrupts
+while cancelling the URBs.
+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: David Mosberger <davidm@egauge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/message.c |   37 +++++++++++++++++--------------------
+ 1 file changed, 17 insertions(+), 20 deletions(-)
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -581,31 +581,28 @@ EXPORT_SYMBOL_GPL(usb_sg_wait);
+ void usb_sg_cancel(struct usb_sg_request *io)
+ {
+       unsigned long flags;
++      int i, retval;
+       spin_lock_irqsave(&io->lock, flags);
++      if (io->status) {
++              spin_unlock_irqrestore(&io->lock, flags);
++              return;
++      }
++      /* shut everything down */
++      io->status = -ECONNRESET;
++      spin_unlock_irqrestore(&io->lock, flags);
+-      /* shut everything down, if it didn't already */
+-      if (!io->status) {
+-              int i;
+-
+-              io->status = -ECONNRESET;
+-              spin_unlock(&io->lock);
+-              for (i = 0; i < io->entries; i++) {
+-                      int retval;
+-
+-                      usb_block_urb(io->urbs[i]);
++      for (i = io->entries - 1; i >= 0; --i) {
++              usb_block_urb(io->urbs[i]);
+-                      retval = usb_unlink_urb(io->urbs[i]);
+-                      if (retval != -EINPROGRESS
+-                                      && retval != -ENODEV
+-                                      && retval != -EBUSY
+-                                      && retval != -EIDRM)
+-                              dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
+-                                      __func__, retval);
+-              }
+-              spin_lock(&io->lock);
++              retval = usb_unlink_urb(io->urbs[i]);
++              if (retval != -EINPROGRESS
++                  && retval != -ENODEV
++                  && retval != -EBUSY
++                  && retval != -EIDRM)
++                      dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
++                               __func__, retval);
+       }
+-      spin_unlock_irqrestore(&io->lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(usb_sg_cancel);
diff --git a/queue-4.4/fs-namespace.c-fix-mountpoint-reference-counter-race.patch b/queue-4.4/fs-namespace.c-fix-mountpoint-reference-counter-race.patch
new file mode 100644 (file)
index 0000000..c136fac
--- /dev/null
@@ -0,0 +1,49 @@
+From piotras@gmail.com  Mon Apr 27 16:05:30 2020
+From: piotras@gmail.com
+Date: Mon, 27 Apr 2020 11:34:12 +0100
+Subject: fs/namespace.c: fix mountpoint reference counter race
+To: greg@kroah.com
+Cc: Piotr Krysiuk <piotras@gmail.com>
+Message-ID: <20200427103412.19144-1-piotras@gmail.com>
+
+
+From: Piotr Krysiuk <piotras@gmail.com>
+
+A race condition between threads updating mountpoint reference counter
+affects longterm releases 4.4.220, 4.9.220, 4.14.177 and 4.19.118.
+
+The mountpoint reference counter corruption may occur when:
+* one thread increments m_count member of struct mountpoint
+  [under namespace_sem, but not holding mount_lock]
+    pivot_root()
+* another thread simultaneously decrements the same m_count
+  [under mount_lock, but not holding namespace_sem]
+    put_mountpoint()
+      unhash_mnt()
+        umount_mnt()
+          mntput_no_expire()
+
+To fix this race condition, grab mount_lock before updating m_count in
+pivot_root().
+
+Reference: CVE-2020-12114
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Piotr Krysiuk <piotras@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namespace.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -3161,8 +3161,8 @@ SYSCALL_DEFINE2(pivot_root, const char _
+       /* make certain new is below the root */
+       if (!is_path_reachable(new_mnt, new.dentry, &root))
+               goto out4;
+-      root_mp->m_count++; /* pin it so it won't go away */
+       lock_mount_hash();
++      root_mp->m_count++; /* pin it so it won't go away */
+       detach_mnt(new_mnt, &parent_path);
+       detach_mnt(root_mnt, &root_parent);
+       if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
diff --git a/queue-4.4/iio-xilinx-xadc-fix-adc-b-powerdown.patch b/queue-4.4/iio-xilinx-xadc-fix-adc-b-powerdown.patch
new file mode 100644 (file)
index 0000000..0f34ea7
--- /dev/null
@@ -0,0 +1,42 @@
+From e44ec7794d88f918805d700240211a9ec05ed89d Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Fri, 3 Apr 2020 15:27:13 +0200
+Subject: iio: xilinx-xadc: Fix ADC-B powerdown
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit e44ec7794d88f918805d700240211a9ec05ed89d upstream.
+
+The check for shutting down the second ADC is inverted. This causes it to
+be powered down when it should be enabled. As a result channels that are
+supposed to be handled by the second ADC return invalid conversion results.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver")
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/xilinx-xadc-core.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/adc/xilinx-xadc-core.c
++++ b/drivers/iio/adc/xilinx-xadc-core.c
+@@ -709,13 +709,14 @@ static int xadc_power_adc_b(struct xadc
+ {
+       uint16_t val;
++      /* Powerdown the ADC-B when it is not needed. */
+       switch (seq_mode) {
+       case XADC_CONF1_SEQ_SIMULTANEOUS:
+       case XADC_CONF1_SEQ_INDEPENDENT:
+-              val = XADC_CONF2_PD_ADC_B;
++              val = 0;
+               break;
+       default:
+-              val = 0;
++              val = XADC_CONF2_PD_ADC_B;
+               break;
+       }
diff --git a/queue-4.4/iio-xilinx-xadc-fix-clearing-interrupt-when-enabling-trigger.patch b/queue-4.4/iio-xilinx-xadc-fix-clearing-interrupt-when-enabling-trigger.patch
new file mode 100644 (file)
index 0000000..27d2c5c
--- /dev/null
@@ -0,0 +1,42 @@
+From f954b098fbac4d183219ce5b42d76d6df2aed50a Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Fri, 3 Apr 2020 15:27:14 +0200
+Subject: iio: xilinx-xadc: Fix clearing interrupt when enabling trigger
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit f954b098fbac4d183219ce5b42d76d6df2aed50a upstream.
+
+When enabling the trigger and unmasking the end-of-sequence (EOS) interrupt
+the EOS interrupt should be cleared from the status register. Otherwise it
+is possible that it was still set from a previous capture. If that is the
+case the interrupt would fire immediately even though no conversion has
+been done yet and stale data is being read from the device.
+
+The old code only clears the interrupt if the interrupt was previously
+unmasked. Which does not make much sense since the interrupt is always
+masked at this point and in addition masking the interrupt does not clear
+the interrupt from the status register. So the clearing needs to be done
+unconditionally.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver")
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/xilinx-xadc-core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/xilinx-xadc-core.c
++++ b/drivers/iio/adc/xilinx-xadc-core.c
+@@ -660,7 +660,7 @@ static int xadc_trigger_set_state(struct
+       spin_lock_irqsave(&xadc->lock, flags);
+       xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val);
+-      xadc_write_reg(xadc, XADC_AXI_REG_IPISR, val & XADC_AXI_INT_EOS);
++      xadc_write_reg(xadc, XADC_AXI_REG_IPISR, XADC_AXI_INT_EOS);
+       if (state)
+               val |= XADC_AXI_INT_EOS;
+       else
diff --git a/queue-4.4/iio-xilinx-xadc-fix-sequencer-configuration-for-aux-channels-in-simultaneous-mode.patch b/queue-4.4/iio-xilinx-xadc-fix-sequencer-configuration-for-aux-channels-in-simultaneous-mode.patch
new file mode 100644 (file)
index 0000000..689c505
--- /dev/null
@@ -0,0 +1,58 @@
+From 8bef455c8b1694547ee59e8b1939205ed9d901a6 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Fri, 3 Apr 2020 15:27:15 +0200
+Subject: iio: xilinx-xadc: Fix sequencer configuration for aux channels in simultaneous mode
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit 8bef455c8b1694547ee59e8b1939205ed9d901a6 upstream.
+
+The XADC has two internal ADCs. Depending on the mode it is operating in
+either one or both of them are used. The device manual calls this
+continuous (one ADC) and simultaneous (both ADCs) mode.
+
+The meaning of the sequencing register for the aux channels changes
+depending on the mode.
+
+In continuous mode each bit corresponds to one of the 16 aux channels. And
+the single ADC will convert them one by one in order.
+
+In simultaneous mode the aux channels are split into two groups the first 8
+channels are assigned to the first ADC and the other 8 channels to the
+second ADC. The upper 8 bits of the sequencing register are unused and the
+lower 8 bits control both ADCs. This means a bit needs to be set if either
+the corresponding channel from the first group or the second group (or
+both) are set.
+
+Currently the driver does not have the special handling required for
+simultaneous mode. Add it.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver")
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/xilinx-xadc-core.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/iio/adc/xilinx-xadc-core.c
++++ b/drivers/iio/adc/xilinx-xadc-core.c
+@@ -785,6 +785,16 @@ static int xadc_preenable(struct iio_dev
+       if (ret)
+               goto err;
++      /*
++       * In simultaneous mode the upper and lower aux channels are samples at
++       * the same time. In this mode the upper 8 bits in the sequencer
++       * register are don't care and the lower 8 bits control two channels
++       * each. As such we must set the bit if either the channel in the lower
++       * group or the upper group is enabled.
++       */
++      if (seq_mode == XADC_CONF1_SEQ_SIMULTANEOUS)
++              scan_mask = ((scan_mask >> 8) | scan_mask) & 0xff0000;
++
+       ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(1), scan_mask >> 16);
+       if (ret)
+               goto err;
index 752b7184f9fed994139d78e5b426ddbfb206e5e1..6b05e87dfd246c39c7e32bf7e253e229bd987861 100644 (file)
@@ -23,3 +23,13 @@ tcp-cache-line-align-max_tcp_header.patch
 team-fix-hang-in-team_mode_get.patch
 xfrm-always-set-xfrm_transformed-in-xfrm-4-6-_output_finish.patch
 alsa-hda-remove-asus-rog-zenith-from-the-blacklist.patch
+iio-xilinx-xadc-fix-adc-b-powerdown.patch
+iio-xilinx-xadc-fix-clearing-interrupt-when-enabling-trigger.patch
+iio-xilinx-xadc-fix-sequencer-configuration-for-aux-channels-in-simultaneous-mode.patch
+fs-namespace.c-fix-mountpoint-reference-counter-race.patch
+usb-sisusbvga-change-port-variable-from-signed-to-unsigned.patch
+usb-add-usb_quirk_delay_ctrl_msg-and-usb_quirk_delay_init-for-corsair-k70-rgb-rapidfire.patch
+drivers-usb-core-don-t-disable-irqs-in-usb_sg_wait-during-urb-submit.patch
+drivers-usb-core-minimize-irq-disabling-in-usb_sg_cancel.patch
+usb-core-fix-free-while-in-use-bug-in-the-usb-s-glibrary.patch
+usb-hub-fix-handling-of-connect-changes-during-sleep.patch
diff --git a/queue-4.4/usb-add-usb_quirk_delay_ctrl_msg-and-usb_quirk_delay_init-for-corsair-k70-rgb-rapidfire.patch b/queue-4.4/usb-add-usb_quirk_delay_ctrl_msg-and-usb_quirk_delay_init-for-corsair-k70-rgb-rapidfire.patch
new file mode 100644 (file)
index 0000000..0cd552e
--- /dev/null
@@ -0,0 +1,35 @@
+From be34a5854b4606bd7a160ad3cb43415d623596c7 Mon Sep 17 00:00:00 2001
+From: Jonathan Cox <jonathan@jdcox.net>
+Date: Fri, 10 Apr 2020 14:24:27 -0700
+Subject: USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 RGB RAPIDFIRE
+
+From: Jonathan Cox <jonathan@jdcox.net>
+
+commit be34a5854b4606bd7a160ad3cb43415d623596c7 upstream.
+
+The Corsair K70 RGB RAPIDFIRE needs the USB_QUIRK_DELAY_INIT and
+USB_QUIRK_DELAY_CTRL_MSG to function or it will randomly not
+respond on boot, just like other Corsair keyboards
+
+Signed-off-by: Jonathan Cox <jonathan@jdcox.net>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200410212427.2886-1-jonathan@jdcox.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -272,6 +272,10 @@ static const struct usb_device_id usb_qu
+       /* Corsair K70 LUX */
+       { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
++      /* Corsair K70 RGB RAPDIFIRE */
++      { USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT |
++        USB_QUIRK_DELAY_CTRL_MSG },
++
+       /* MIDI keyboard WORLDE MINI */
+       { USB_DEVICE(0x1c75, 0x0204), .driver_info =
+                       USB_QUIRK_CONFIG_INTF_STRINGS },
diff --git a/queue-4.4/usb-core-fix-free-while-in-use-bug-in-the-usb-s-glibrary.patch b/queue-4.4/usb-core-fix-free-while-in-use-bug-in-the-usb-s-glibrary.patch
new file mode 100644 (file)
index 0000000..f7a4e1b
--- /dev/null
@@ -0,0 +1,90 @@
+From 056ad39ee9253873522f6469c3364964a322912b Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Sat, 28 Mar 2020 16:18:11 -0400
+Subject: USB: core: Fix free-while-in-use bug in the USB S-Glibrary
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 056ad39ee9253873522f6469c3364964a322912b upstream.
+
+FuzzUSB (a variant of syzkaller) found a free-while-still-in-use bug
+in the USB scatter-gather library:
+
+BUG: KASAN: use-after-free in atomic_read
+include/asm-generic/atomic-instrumented.h:26 [inline]
+BUG: KASAN: use-after-free in usb_hcd_unlink_urb+0x5f/0x170
+drivers/usb/core/hcd.c:1607
+Read of size 4 at addr ffff888065379610 by task kworker/u4:1/27
+
+CPU: 1 PID: 27 Comm: kworker/u4:1 Not tainted 5.5.11 #2
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+1.10.2-1ubuntu1 04/01/2014
+Workqueue: scsi_tmf_2 scmd_eh_abort_handler
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0xce/0x128 lib/dump_stack.c:118
+ print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374
+ __kasan_report+0x153/0x1cb mm/kasan/report.c:506
+ kasan_report+0x12/0x20 mm/kasan/common.c:639
+ check_memory_region_inline mm/kasan/generic.c:185 [inline]
+ check_memory_region+0x152/0x1b0 mm/kasan/generic.c:192
+ __kasan_check_read+0x11/0x20 mm/kasan/common.c:95
+ atomic_read include/asm-generic/atomic-instrumented.h:26 [inline]
+ usb_hcd_unlink_urb+0x5f/0x170 drivers/usb/core/hcd.c:1607
+ usb_unlink_urb+0x72/0xb0 drivers/usb/core/urb.c:657
+ usb_sg_cancel+0x14e/0x290 drivers/usb/core/message.c:602
+ usb_stor_stop_transport+0x5e/0xa0 drivers/usb/storage/transport.c:937
+
+This bug occurs when cancellation of the S-G transfer races with
+transfer completion.  When that happens, usb_sg_cancel() may continue
+to access the transfer's URBs after usb_sg_wait() has freed them.
+
+The bug is caused by the fact that usb_sg_cancel() does not take any
+sort of reference to the transfer, and so there is nothing to prevent
+the URBs from being deallocated while the routine is trying to use
+them.  The fix is to take such a reference by incrementing the
+transfer's io->count field while the cancellation is in progres and
+decrementing it afterward.  The transfer's URBs are not deallocated
+until io->complete is triggered, which happens when io->count reaches
+zero.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: Kyungtae Kim <kt0755@gmail.com>
+CC: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2003281615140.14837-100000@netrider.rowland.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/message.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -584,12 +584,13 @@ void usb_sg_cancel(struct usb_sg_request
+       int i, retval;
+       spin_lock_irqsave(&io->lock, flags);
+-      if (io->status) {
++      if (io->status || io->count == 0) {
+               spin_unlock_irqrestore(&io->lock, flags);
+               return;
+       }
+       /* shut everything down */
+       io->status = -ECONNRESET;
++      io->count++;            /* Keep the request alive until we're done */
+       spin_unlock_irqrestore(&io->lock, flags);
+       for (i = io->entries - 1; i >= 0; --i) {
+@@ -603,6 +604,12 @@ void usb_sg_cancel(struct usb_sg_request
+                       dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
+                                __func__, retval);
+       }
++
++      spin_lock_irqsave(&io->lock, flags);
++      io->count--;
++      if (!io->count)
++              complete(&io->complete);
++      spin_unlock_irqrestore(&io->lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(usb_sg_cancel);
diff --git a/queue-4.4/usb-hub-fix-handling-of-connect-changes-during-sleep.patch b/queue-4.4/usb-hub-fix-handling-of-connect-changes-during-sleep.patch
new file mode 100644 (file)
index 0000000..3529f3a
--- /dev/null
@@ -0,0 +1,78 @@
+From 9f952e26295d977dbfc6fedeaf8c4f112c818d37 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 22 Apr 2020 16:09:51 -0400
+Subject: USB: hub: Fix handling of connect changes during sleep
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 9f952e26295d977dbfc6fedeaf8c4f112c818d37 upstream.
+
+Commit 8099f58f1ecd ("USB: hub: Don't record a connect-change event
+during reset-resume") wasn't very well conceived.  The problem it
+tried to fix was that if a connect-change event occurred while the
+system was asleep (such as a device disconnecting itself from the bus
+when it is suspended and then reconnecting when it resumes)
+requiring a reset-resume during the system wakeup transition, the hub
+port's change_bit entry would remain set afterward.  This would cause
+the hub driver to believe another connect-change event had occurred
+after the reset-resume, which was wrong and would lead the driver to
+send unnecessary requests to the device (which could interfere with a
+firmware update).
+
+The commit tried to fix this by not setting the change_bit during the
+wakeup.  But this was the wrong thing to do; it means that when a
+device is unplugged while the system is asleep, the hub driver doesn't
+realize anything has happened: The change_bit flag which would tell it
+to handle the disconnect event is clear.
+
+The commit needs to be reverted and the problem fixed in a different
+way.  Fortunately an alternative solution was noted in the commit's
+Changelog: We can continue to set the change_bit entry in
+hub_activate() but then clear it when a reset-resume occurs.  That way
+the the hub driver will see the change_bit when a device is
+disconnected but won't see it when the device is still present.
+
+That's what this patch does.
+
+Reported-and-tested-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Fixes: 8099f58f1ecd ("USB: hub: Don't record a connect-change event during reset-resume")
+Tested-by: Paul Zimmerman <pauldzim@gmail.com>
+CC: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2004221602480.11262-100000@iolanthe.rowland.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1175,6 +1175,11 @@ static void hub_activate(struct usb_hub
+ #ifdef CONFIG_PM
+                       udev->reset_resume = 1;
+ #endif
++                      /* Don't set the change_bits when the device
++                       * was powered off.
++                       */
++                      if (test_bit(port1, hub->power_bits))
++                              set_bit(port1, hub->change_bits);
+               } else {
+                       /* The power session is gone; tell hub_wq */
+@@ -2939,6 +2944,15 @@ static int check_port_resume_type(struct
+               if (portchange & USB_PORT_STAT_C_ENABLE)
+                       usb_clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_ENABLE);
++
++              /*
++               * Whatever made this reset-resume necessary may have
++               * turned on the port1 bit in hub->change_bits.  But after
++               * a successful reset-resume we want the bit to be clear;
++               * if it was on it would indicate that something happened
++               * following the reset-resume.
++               */
++              clear_bit(port1, hub->change_bits);
+       }
+       return status;
diff --git a/queue-4.4/usb-sisusbvga-change-port-variable-from-signed-to-unsigned.patch b/queue-4.4/usb-sisusbvga-change-port-variable-from-signed-to-unsigned.patch
new file mode 100644 (file)
index 0000000..aa57228
--- /dev/null
@@ -0,0 +1,130 @@
+From 2df7405f79ce1674d73c2786fe1a8727c905d65b Mon Sep 17 00:00:00 2001
+From: Changming Liu <liu.changm@northeastern.edu>
+Date: Mon, 20 Apr 2020 23:41:25 -0400
+Subject: USB: sisusbvga: Change port variable from signed to unsigned
+
+From: Changming Liu <liu.changm@northeastern.edu>
+
+commit 2df7405f79ce1674d73c2786fe1a8727c905d65b upstream.
+
+Change a bunch of arguments of wrapper functions which pass signed
+integer to an unsigned integer which might cause undefined behaviors
+when sign integer overflow.
+
+Signed-off-by: Changming Liu <liu.changm@northeastern.edu>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/BL0PR06MB45482D71EA822D75A0E60A2EE5D50@BL0PR06MB4548.namprd06.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/sisusbvga/sisusb.c      |   20 ++++++++++----------
+ drivers/usb/misc/sisusbvga/sisusb_init.h |   14 +++++++-------
+ 2 files changed, 17 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/misc/sisusbvga/sisusb.c
++++ b/drivers/usb/misc/sisusbvga/sisusb.c
+@@ -1243,20 +1243,20 @@ static int sisusb_read_mem_bulk(struct s
+ #ifdef INCL_SISUSB_CON
+ int
+-sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data)
++sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data)
+ {
+       return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
+ }
+ int
+-sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data)
++sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 *data)
+ {
+       return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
+ }
+ #endif
+ int
+-sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data)
++sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 data)
+ {
+       int ret;
+       ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index);
+@@ -1265,7 +1265,7 @@ sisusb_setidxreg(struct sisusb_usb_data
+ }
+ int
+-sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data)
++sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 *data)
+ {
+       int ret;
+       ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index);
+@@ -1274,7 +1274,7 @@ sisusb_getidxreg(struct sisusb_usb_data
+ }
+ int
+-sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
++sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx,
+                                                       u8 myand, u8 myor)
+ {
+       int ret;
+@@ -1289,7 +1289,7 @@ sisusb_setidxregandor(struct sisusb_usb_
+ }
+ static int
+-sisusb_setidxregmask(struct sisusb_usb_data *sisusb, int port, u8 idx,
++sisusb_setidxregmask(struct sisusb_usb_data *sisusb, u32 port, u8 idx,
+                                                       u8 data, u8 mask)
+ {
+       int ret;
+@@ -1303,13 +1303,13 @@ sisusb_setidxregmask(struct sisusb_usb_d
+ }
+ int
+-sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor)
++sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 myor)
+ {
+       return(sisusb_setidxregandor(sisusb, port, index, 0xff, myor));
+ }
+ int
+-sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand)
++sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 myand)
+ {
+       return(sisusb_setidxregandor(sisusb, port, idx, myand, 0x00));
+ }
+@@ -2849,8 +2849,8 @@ static int
+ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
+                                                       unsigned long arg)
+ {
+-      int     retval, port, length;
+-      u32     address;
++      int     retval, length;
++      u32     port, address;
+       /* All our commands require the device
+        * to be initialized.
+--- a/drivers/usb/misc/sisusbvga/sisusb_init.h
++++ b/drivers/usb/misc/sisusbvga/sisusb_init.h
+@@ -811,17 +811,17 @@ static const struct SiS_VCLKData SiSUSB_
+ int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+ int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
+-extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data);
+-extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 * data);
+-extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
++extern int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data);
++extern int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 * data);
++extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
+                           u8 index, u8 data);
+-extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
++extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
+                           u8 index, u8 * data);
+-extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port,
++extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port,
+                                u8 idx, u8 myand, u8 myor);
+-extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port,
++extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
+                             u8 index, u8 myor);
+-extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port,
++extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
+                              u8 idx, u8 myand);
+ void sisusb_delete(struct kref *kref);