]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 7 Dec 2017 12:20:31 +0000 (13:20 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 7 Dec 2017 12:20:31 +0000 (13:20 +0100)
added patches:
usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch
usb-host-fix-incorrect-updating-of-offset.patch
usb-hub-cycle-hub-power-when-initialization-fails.patch
usb-increase-usbfs-transfer-limit.patch
usb-usbfs-filter-flags-passed-in-from-user-space.patch

queue-3.18/series
queue-3.18/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch [new file with mode: 0644]
queue-3.18/usb-host-fix-incorrect-updating-of-offset.patch [new file with mode: 0644]
queue-3.18/usb-hub-cycle-hub-power-when-initialization-fails.patch [new file with mode: 0644]
queue-3.18/usb-increase-usbfs-transfer-limit.patch [new file with mode: 0644]
queue-3.18/usb-usbfs-filter-flags-passed-in-from-user-space.patch [new file with mode: 0644]

index 0d75f9c061cce7134cabaf2d0dc33b43877fe711..a51bf0f9e00f7c945a53825614962ecb35bd4c3f 100644 (file)
@@ -19,3 +19,8 @@ ima-fix-hash-algorithm-initialization.patch
 uas-always-apply-us_fl_no_ata_1x-quirk-to-seagate-devices.patch
 usb-quirks-add-no-lpm-quirk-for-ky-688-usb-3.1-type-c-hub.patch
 serial-8250_pci-add-amazon-pci-serial-device-id.patch
+usb-hub-cycle-hub-power-when-initialization-fails.patch
+usb-increase-usbfs-transfer-limit.patch
+usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch
+usb-usbfs-filter-flags-passed-in-from-user-space.patch
+usb-host-fix-incorrect-updating-of-offset.patch
diff --git a/queue-3.18/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch b/queue-3.18/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch
new file mode 100644 (file)
index 0000000..533ef26
--- /dev/null
@@ -0,0 +1,52 @@
+From 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Fri, 22 Sep 2017 23:43:25 +0300
+Subject: USB: devio: Prevent integer overflow in proc_do_submiturb()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 upstream.
+
+There used to be an integer overflow check in proc_do_submiturb() but
+we removed it.  It turns out that it's still required.  The
+uurb->buffer_length variable is a signed integer and it's controlled by
+the user.  It can lead to an integer overflow when we do:
+
+       num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE);
+
+If we strip away the macro then that line looks like this:
+
+       num_sgs = (uurb->buffer_length + USB_SG_SIZE - 1) / USB_SG_SIZE;
+                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+It's the first addition which can overflow.
+
+Fixes: 1129d270cbfb ("USB: Increase usbfs transfer limit")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/devio.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -118,6 +118,9 @@ module_param(usbfs_memory_mb, uint, 0644
+ MODULE_PARM_DESC(usbfs_memory_mb,
+               "maximum MB allowed for usbfs buffers (0 = no limit)");
++/* Hard limit, necessary to avoid arithmetic overflow */
++#define USBFS_XFER_MAX         (UINT_MAX / 2 - 1000000)
++
+ static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */
+ /* Check whether it's okay to allocate more memory for a transfer */
+@@ -1295,6 +1298,8 @@ static int proc_do_submiturb(struct usb_
+                               USBDEVFS_URB_ZERO_PACKET |
+                               USBDEVFS_URB_NO_INTERRUPT))
+               return -EINVAL;
++      if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX)
++              return -EINVAL;
+       if (uurb->buffer_length > 0 && !uurb->buffer)
+               return -EINVAL;
+       if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
diff --git a/queue-3.18/usb-host-fix-incorrect-updating-of-offset.patch b/queue-3.18/usb-host-fix-incorrect-updating-of-offset.patch
new file mode 100644 (file)
index 0000000..abf1b87
--- /dev/null
@@ -0,0 +1,37 @@
+From 1d5a31582ef046d3b233f0da1a68ae26519b2f0a Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 7 Nov 2017 16:45:04 +0000
+Subject: usb: host: fix incorrect updating of offset
+
+From: Colin Ian King <colin.king@canonical.com>
+
+commit 1d5a31582ef046d3b233f0da1a68ae26519b2f0a upstream.
+
+The variable temp is incorrectly being updated, instead it should
+be offset otherwise the loop just reads the same capability value
+and loops forever.  Thanks to Alan Stern for pointing out the
+correct fix to my original fix.  Fix also cleans up clang warning:
+
+drivers/usb/host/ehci-dbg.c:840:4: warning: Value stored to 'temp'
+is never read
+
+Fixes: d49d43174400 ("USB: misc ehci updates")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-dbg.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ehci-dbg.c
++++ b/drivers/usb/host/ehci-dbg.c
+@@ -850,7 +850,7 @@ static ssize_t fill_registers_buffer(str
+                       default:                /* unknown */
+                               break;
+                       }
+-                      temp = (cap >> 8) & 0xff;
++                      offset = (cap >> 8) & 0xff;
+               }
+       }
+ #endif
diff --git a/queue-3.18/usb-hub-cycle-hub-power-when-initialization-fails.patch b/queue-3.18/usb-hub-cycle-hub-power-when-initialization-fails.patch
new file mode 100644 (file)
index 0000000..f9db665
--- /dev/null
@@ -0,0 +1,57 @@
+From 973593a960ddac0f14f0d8877d2d0abe0afda795 Mon Sep 17 00:00:00 2001
+From: Mike Looijmans <mike.looijmans@topic.nl>
+Date: Thu, 9 Nov 2017 13:16:46 +0100
+Subject: usb: hub: Cycle HUB power when initialization fails
+
+From: Mike Looijmans <mike.looijmans@topic.nl>
+
+commit 973593a960ddac0f14f0d8877d2d0abe0afda795 upstream.
+
+Sometimes the USB device gets confused about the state of the initialization and
+the connection fails. In particular, the device thinks that it's already set up
+and running while the host thinks the device still needs to be configured. To
+work around this issue, power-cycle the hub's output to issue a sort of "reset"
+to the device. This makes the device restart its state machine and then the
+initialization succeeds.
+
+This fixes problems where the kernel reports a list of errors like this:
+
+usb 1-1.3: device not accepting address 19, error -71
+
+The end result is a non-functioning device. After this patch, the sequence
+becomes like this:
+
+usb 1-1.3: new high-speed USB device number 18 using ci_hdrc
+usb 1-1.3: device not accepting address 18, error -71
+usb 1-1.3: new high-speed USB device number 19 using ci_hdrc
+usb 1-1.3: device not accepting address 19, error -71
+usb 1-1-port3: attempt power cycle
+usb 1-1.3: new high-speed USB device number 21 using ci_hdrc
+usb-storage 1-1.3:1.2: USB Mass Storage device detected
+
+Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -4816,6 +4816,15 @@ loop:
+               usb_put_dev(udev);
+               if ((status == -ENOTCONN) || (status == -ENOTSUPP))
+                       break;
++
++              /* When halfway through our retry count, power-cycle the port */
++              if (i == (SET_CONFIG_TRIES / 2) - 1) {
++                      dev_info(&port_dev->dev, "attempt power cycle\n");
++                      usb_hub_set_port_power(hdev, hub, port1, false);
++                      msleep(2 * hub_power_on_good_delay(hub));
++                      usb_hub_set_port_power(hdev, hub, port1, true);
++                      msleep(hub_power_on_good_delay(hub));
++              }
+       }
+       if (hub->hdev->parent ||
+                       !hcd->driver->port_handed_over ||
diff --git a/queue-3.18/usb-increase-usbfs-transfer-limit.patch b/queue-3.18/usb-increase-usbfs-transfer-limit.patch
new file mode 100644 (file)
index 0000000..2bebe82
--- /dev/null
@@ -0,0 +1,100 @@
+From 1129d270cbfbb7e2b1ec3dede4a13930bdd10e41 Mon Sep 17 00:00:00 2001
+From: Mateusz Berezecki <mateuszb@fastmail.fm>
+Date: Wed, 21 Dec 2016 09:19:14 -0800
+Subject: USB: Increase usbfs transfer limit
+
+From: Mateusz Berezecki <mateuszb@fastmail.fm>
+
+commit 1129d270cbfbb7e2b1ec3dede4a13930bdd10e41 upstream.
+
+Promote a variable keeping track of USB transfer memory usage to a
+wider data type and allow for higher bandwidth transfers from a large
+number of USB devices connected to a single host.
+
+Signed-off-by: Mateusz Berezecki <mateuszb@fastmail.fm>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/devio.c |   43 ++++++++++++++++---------------------------
+ 1 file changed, 16 insertions(+), 27 deletions(-)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -113,42 +113,35 @@ enum snoop_when {
+ #define USB_DEVICE_DEV                MKDEV(USB_DEVICE_MAJOR, 0)
+ /* Limit on the total amount of memory we can allocate for transfers */
+-static unsigned usbfs_memory_mb = 16;
++static u32 usbfs_memory_mb = 16;
+ module_param(usbfs_memory_mb, uint, 0644);
+ MODULE_PARM_DESC(usbfs_memory_mb,
+               "maximum MB allowed for usbfs buffers (0 = no limit)");
+-/* Hard limit, necessary to avoid arithmetic overflow */
+-#define USBFS_XFER_MAX                (UINT_MAX / 2 - 1000000)
+-
+-static atomic_t usbfs_memory_usage;   /* Total memory currently allocated */
++static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */
+ /* Check whether it's okay to allocate more memory for a transfer */
+-static int usbfs_increase_memory_usage(unsigned amount)
++static int usbfs_increase_memory_usage(u64 amount)
+ {
+-      unsigned lim;
++      u64 lim;
+-      /*
+-       * Convert usbfs_memory_mb to bytes, avoiding overflows.
+-       * 0 means use the hard limit (effectively unlimited).
+-       */
+       lim = ACCESS_ONCE(usbfs_memory_mb);
+-      if (lim == 0 || lim > (USBFS_XFER_MAX >> 20))
+-              lim = USBFS_XFER_MAX;
+-      else
+-              lim <<= 20;
++      lim <<= 20;
+-      atomic_add(amount, &usbfs_memory_usage);
+-      if (atomic_read(&usbfs_memory_usage) <= lim)
+-              return 0;
+-      atomic_sub(amount, &usbfs_memory_usage);
+-      return -ENOMEM;
++      atomic64_add(amount, &usbfs_memory_usage);
++
++      if (lim > 0 && atomic64_read(&usbfs_memory_usage) > lim) {
++              atomic64_sub(amount, &usbfs_memory_usage);
++              return -ENOMEM;
++      }
++
++      return 0;
+ }
+ /* Memory for a transfer is being deallocated */
+-static void usbfs_decrease_memory_usage(unsigned amount)
++static void usbfs_decrease_memory_usage(u64 amount)
+ {
+-      atomic_sub(amount, &usbfs_memory_usage);
++      atomic64_sub(amount, &usbfs_memory_usage);
+ }
+ static int connected(struct usb_dev_state *ps)
+@@ -1077,7 +1070,7 @@ static int proc_bulk(struct usb_dev_stat
+       if (!usb_maxpacket(dev, pipe, !(bulk.ep & USB_DIR_IN)))
+               return -EINVAL;
+       len1 = bulk.len;
+-      if (len1 >= USBFS_XFER_MAX)
++      if (len1 >= (INT_MAX - sizeof(struct urb)))
+               return -EINVAL;
+       ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb));
+       if (ret)
+@@ -1420,10 +1413,6 @@ static int proc_do_submiturb(struct usb_
+               return -EINVAL;
+       }
+-      if (uurb->buffer_length >= USBFS_XFER_MAX) {
+-              ret = -EINVAL;
+-              goto error;
+-      }
+       if (uurb->buffer_length > 0 &&
+                       !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
+                               uurb->buffer, uurb->buffer_length)) {
diff --git a/queue-3.18/usb-usbfs-filter-flags-passed-in-from-user-space.patch b/queue-3.18/usb-usbfs-filter-flags-passed-in-from-user-space.patch
new file mode 100644 (file)
index 0000000..9d2d132
--- /dev/null
@@ -0,0 +1,47 @@
+From 446f666da9f019ce2ffd03800995487e79a91462 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 23 Nov 2017 16:39:52 +0100
+Subject: USB: usbfs: Filter flags passed in from user space
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 446f666da9f019ce2ffd03800995487e79a91462 upstream.
+
+USBDEVFS_URB_ISO_ASAP must be accepted only for ISO endpoints.
+Improve sanity checking.
+
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/devio.c |   14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -1290,14 +1290,18 @@ static int proc_do_submiturb(struct usb_
+       int number_of_packets = 0;
+       unsigned int stream_id = 0;
+       void *buf;
+-
+-      if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP |
+-                              USBDEVFS_URB_SHORT_NOT_OK |
++      unsigned long mask =    USBDEVFS_URB_SHORT_NOT_OK |
+                               USBDEVFS_URB_BULK_CONTINUATION |
+                               USBDEVFS_URB_NO_FSBR |
+                               USBDEVFS_URB_ZERO_PACKET |
+-                              USBDEVFS_URB_NO_INTERRUPT))
+-              return -EINVAL;
++                              USBDEVFS_URB_NO_INTERRUPT;
++      /* USBDEVFS_URB_ISO_ASAP is a special case */
++      if (uurb->type == USBDEVFS_URB_TYPE_ISO)
++              mask |= USBDEVFS_URB_ISO_ASAP;
++
++      if (uurb->flags & ~mask)
++                      return -EINVAL;
++
+       if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX)
+               return -EINVAL;
+       if (uurb->buffer_length > 0 && !uurb->buffer)