]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Jun 2019 08:20:23 +0000 (10:20 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Jun 2019 08:20:23 +0000 (10:20 +0200)
added patches:
btrfs-fix-race-updating-log-root-item-during-fsync.patch
include-linux-bitops.h-sanitize-rotate-primitives.patch
media-smsusb-better-handle-optional-alignment.patch
media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch
media-usb-siano-fix-general-protection-fault-in-smsusb.patch
scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch
scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch
sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch
usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch
usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch
usb-rio500-fix-memory-leak-in-close-after-disconnect.patch
usb-rio500-refuse-more-than-one-device-at-a-time.patch
usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch
usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch
xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch

16 files changed:
queue-4.4/btrfs-fix-race-updating-log-root-item-during-fsync.patch [new file with mode: 0644]
queue-4.4/include-linux-bitops.h-sanitize-rotate-primitives.patch [new file with mode: 0644]
queue-4.4/media-smsusb-better-handle-optional-alignment.patch [new file with mode: 0644]
queue-4.4/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch [new file with mode: 0644]
queue-4.4/media-usb-siano-fix-general-protection-fault-in-smsusb.patch [new file with mode: 0644]
queue-4.4/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch [new file with mode: 0644]
queue-4.4/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch [new file with mode: 0644]
queue-4.4/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch [new file with mode: 0644]
queue-4.4/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch [new file with mode: 0644]
queue-4.4/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch [new file with mode: 0644]
queue-4.4/usb-rio500-refuse-more-than-one-device-at-a-time.patch [new file with mode: 0644]
queue-4.4/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch [new file with mode: 0644]
queue-4.4/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch [new file with mode: 0644]
queue-4.4/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch [new file with mode: 0644]

diff --git a/queue-4.4/btrfs-fix-race-updating-log-root-item-during-fsync.patch b/queue-4.4/btrfs-fix-race-updating-log-root-item-during-fsync.patch
new file mode 100644 (file)
index 0000000..e637515
--- /dev/null
@@ -0,0 +1,125 @@
+From 06989c799f04810f6876900d4760c0edda369cf7 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 15 May 2019 16:03:17 +0100
+Subject: Btrfs: fix race updating log root item during fsync
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 06989c799f04810f6876900d4760c0edda369cf7 upstream.
+
+When syncing the log, the final phase of a fsync operation, we need to
+either create a log root's item or update the existing item in the log
+tree of log roots, and that depends on the current value of the log
+root's log_transid - if it's 1 we need to create the log root item,
+otherwise it must exist already and we update it. Since there is no
+synchronization between updating the log_transid and checking it for
+deciding whether the log root's item needs to be created or updated, we
+end up with a tiny race window that results in attempts to update the
+item to fail because the item was not yet created:
+
+              CPU 1                                    CPU 2
+
+  btrfs_sync_log()
+
+    lock root->log_mutex
+
+    set log root's log_transid to 1
+
+    unlock root->log_mutex
+
+                                               btrfs_sync_log()
+
+                                                 lock root->log_mutex
+
+                                                 sets log root's
+                                                 log_transid to 2
+
+                                                 unlock root->log_mutex
+
+    update_log_root()
+
+      sees log root's log_transid
+      with a value of 2
+
+        calls btrfs_update_root(),
+        which fails with -EUCLEAN
+        and causes transaction abort
+
+Until recently the race lead to a BUG_ON at btrfs_update_root(), but after
+the recent commit 7ac1e464c4d47 ("btrfs: Don't panic when we can't find a
+root key") we just abort the current transaction.
+
+A sample trace of the BUG_ON() on a SLE12 kernel:
+
+  ------------[ cut here ]------------
+  kernel BUG at ../fs/btrfs/root-tree.c:157!
+  Oops: Exception in kernel mode, sig: 5 [#1]
+  SMP NR_CPUS=2048 NUMA pSeries
+  (...)
+  Supported: Yes, External
+  CPU: 78 PID: 76303 Comm: rtas_errd Tainted: G                 X 4.4.156-94.57-default #1
+  task: c00000ffa906d010 ti: c00000ff42b08000 task.ti: c00000ff42b08000
+  NIP: d000000036ae5cdc LR: d000000036ae5cd8 CTR: 0000000000000000
+  REGS: c00000ff42b0b860 TRAP: 0700   Tainted: G                 X  (4.4.156-94.57-default)
+  MSR: 8000000002029033 <SF,VEC,EE,ME,IR,DR,RI,LE>  CR: 22444484  XER: 20000000
+  CFAR: d000000036aba66c SOFTE: 1
+  GPR00: d000000036ae5cd8 c00000ff42b0bae0 d000000036bda220 0000000000000054
+  GPR04: 0000000000000001 0000000000000000 c00007ffff8d37c8 0000000000000000
+  GPR08: c000000000e19c00 0000000000000000 0000000000000000 3736343438312079
+  GPR12: 3930373337303434 c000000007a3a800 00000000007fffff 0000000000000023
+  GPR16: c00000ffa9d26028 c00000ffa9d261f8 0000000000000010 c00000ffa9d2ab28
+  GPR20: c00000ff42b0bc48 0000000000000001 c00000ff9f0d9888 0000000000000001
+  GPR24: c00000ffa9d26000 c00000ffa9d261e8 c00000ffa9d2a800 c00000ff9f0d9888
+  GPR28: c00000ffa9d26028 c00000ffa9d2aa98 0000000000000001 c00000ffa98f5b20
+  NIP [d000000036ae5cdc] btrfs_update_root+0x25c/0x4e0 [btrfs]
+  LR [d000000036ae5cd8] btrfs_update_root+0x258/0x4e0 [btrfs]
+  Call Trace:
+  [c00000ff42b0bae0] [d000000036ae5cd8] btrfs_update_root+0x258/0x4e0 [btrfs] (unreliable)
+  [c00000ff42b0bba0] [d000000036b53610] btrfs_sync_log+0x2d0/0xc60 [btrfs]
+  [c00000ff42b0bce0] [d000000036b1785c] btrfs_sync_file+0x44c/0x4e0 [btrfs]
+  [c00000ff42b0bd80] [c00000000032e300] vfs_fsync_range+0x70/0x120
+  [c00000ff42b0bdd0] [c00000000032e44c] do_fsync+0x5c/0xb0
+  [c00000ff42b0be10] [c00000000032e8dc] SyS_fdatasync+0x2c/0x40
+  [c00000ff42b0be30] [c000000000009488] system_call+0x3c/0x100
+  Instruction dump:
+  7f43d378 4bffebb9 60000000 88d90008 3d220000 e8b90000 3b390009 e87a01f0
+  e8898e08 e8f90000 4bfd48e5 60000000 <0fe00000> e95b0060 39200004 394a0ea0
+  ---[ end trace 8f2dc8f919cabab8 ]---
+
+So fix this by doing the check of log_transid and updating or creating the
+log root's item while holding the root's log_mutex.
+
+Fixes: 7237f1833601d ("Btrfs: fix tree logs parallel sync")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -2809,6 +2809,12 @@ int btrfs_sync_log(struct btrfs_trans_ha
+       log->log_transid = root->log_transid;
+       root->log_start_pid = 0;
+       /*
++       * Update or create log root item under the root's log_mutex to prevent
++       * races with concurrent log syncs that can lead to failure to update
++       * log root item because it was not created yet.
++       */
++      ret = update_log_root(trans, log);
++      /*
+        * IO has been started, blocks of the log tree have WRITTEN flag set
+        * in their headers. new modifications of the log will be written to
+        * new positions. so it's safe to allow log writers to go in.
+@@ -2827,8 +2833,6 @@ int btrfs_sync_log(struct btrfs_trans_ha
+       mutex_unlock(&log_root_tree->log_mutex);
+-      ret = update_log_root(trans, log);
+-
+       mutex_lock(&log_root_tree->log_mutex);
+       if (atomic_dec_and_test(&log_root_tree->log_writers)) {
+               /*
diff --git a/queue-4.4/include-linux-bitops.h-sanitize-rotate-primitives.patch b/queue-4.4/include-linux-bitops.h-sanitize-rotate-primitives.patch
new file mode 100644 (file)
index 0000000..4aa1c6e
--- /dev/null
@@ -0,0 +1,133 @@
+From ef4d6f6b275c498f8e5626c99dbeefdc5027f843 Mon Sep 17 00:00:00 2001
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Date: Tue, 14 May 2019 15:43:27 -0700
+Subject: include/linux/bitops.h: sanitize rotate primitives
+
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+
+commit ef4d6f6b275c498f8e5626c99dbeefdc5027f843 upstream.
+
+The ror32 implementation (word >> shift) | (word << (32 - shift) has
+undefined behaviour if shift is outside the [1, 31] range.  Similarly
+for the 64 bit variants.  Most callers pass a compile-time constant
+(naturally in that range), but there's an UBSAN report that these may
+actually be called with a shift count of 0.
+
+Instead of special-casing that, we can make them DTRT for all values of
+shift while also avoiding UB.  For some reason, this was already partly
+done for rol32 (which was well-defined for [0, 31]).  gcc 8 recognizes
+these patterns as rotates, so for example
+
+  __u32 rol32(__u32 word, unsigned int shift)
+  {
+       return (word << (shift & 31)) | (word >> ((-shift) & 31));
+  }
+
+compiles to
+
+0000000000000020 <rol32>:
+  20:   89 f8                   mov    %edi,%eax
+  22:   89 f1                   mov    %esi,%ecx
+  24:   d3 c0                   rol    %cl,%eax
+  26:   c3                      retq
+
+Older compilers unfortunately do not do as well, but this only affects
+the small minority of users that don't pass constants.
+
+Due to integer promotions, ro[lr]8 were already well-defined for shifts
+in [0, 8], and ro[lr]16 were mostly well-defined for shifts in [0, 16]
+(only mostly - u16 gets promoted to _signed_ int, so if bit 15 is set,
+word << 16 is undefined).  For consistency, update those as well.
+
+Link: http://lkml.kernel.org/r/20190410211906.2190-1-linux@rasmusvillemoes.dk
+Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Reported-by: Ido Schimmel <idosch@mellanox.com>
+Tested-by: Ido Schimmel <idosch@mellanox.com>
+Reviewed-by: Will Deacon <will.deacon@arm.com>
+Cc: Vadim Pasternak <vadimp@mellanox.com>
+Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
+Cc: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Cc: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/bitops.h |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -68,7 +68,7 @@ static __always_inline unsigned long hwe
+  */
+ static inline __u64 rol64(__u64 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> (64 - shift));
++      return (word << (shift & 63)) | (word >> ((-shift) & 63));
+ }
+ /**
+@@ -78,7 +78,7 @@ static inline __u64 rol64(__u64 word, un
+  */
+ static inline __u64 ror64(__u64 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (64 - shift));
++      return (word >> (shift & 63)) | (word << ((-shift) & 63));
+ }
+ /**
+@@ -88,7 +88,7 @@ static inline __u64 ror64(__u64 word, un
+  */
+ static inline __u32 rol32(__u32 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> ((-shift) & 31));
++      return (word << (shift & 31)) | (word >> ((-shift) & 31));
+ }
+ /**
+@@ -98,7 +98,7 @@ static inline __u32 rol32(__u32 word, un
+  */
+ static inline __u32 ror32(__u32 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (32 - shift));
++      return (word >> (shift & 31)) | (word << ((-shift) & 31));
+ }
+ /**
+@@ -108,7 +108,7 @@ static inline __u32 ror32(__u32 word, un
+  */
+ static inline __u16 rol16(__u16 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> (16 - shift));
++      return (word << (shift & 15)) | (word >> ((-shift) & 15));
+ }
+ /**
+@@ -118,7 +118,7 @@ static inline __u16 rol16(__u16 word, un
+  */
+ static inline __u16 ror16(__u16 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (16 - shift));
++      return (word >> (shift & 15)) | (word << ((-shift) & 15));
+ }
+ /**
+@@ -128,7 +128,7 @@ static inline __u16 ror16(__u16 word, un
+  */
+ static inline __u8 rol8(__u8 word, unsigned int shift)
+ {
+-      return (word << shift) | (word >> (8 - shift));
++      return (word << (shift & 7)) | (word >> ((-shift) & 7));
+ }
+ /**
+@@ -138,7 +138,7 @@ static inline __u8 rol8(__u8 word, unsig
+  */
+ static inline __u8 ror8(__u8 word, unsigned int shift)
+ {
+-      return (word >> shift) | (word << (8 - shift));
++      return (word >> (shift & 7)) | (word << ((-shift) & 7));
+ }
+ /**
diff --git a/queue-4.4/media-smsusb-better-handle-optional-alignment.patch b/queue-4.4/media-smsusb-better-handle-optional-alignment.patch
new file mode 100644 (file)
index 0000000..410fd3d
--- /dev/null
@@ -0,0 +1,72 @@
+From a47686636d84eaec5c9c6e84bd5f96bed34d526d Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Date: Fri, 24 May 2019 10:59:43 -0400
+Subject: media: smsusb: better handle optional alignment
+
+From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+
+commit a47686636d84eaec5c9c6e84bd5f96bed34d526d upstream.
+
+Most Siano devices require an alignment for the response.
+
+Changeset f3be52b0056a ("media: usb: siano: Fix general protection fault in smsusb")
+changed the logic with gets such aligment, but it now produces a
+sparce warning:
+
+drivers/media/usb/siano/smsusb.c: In function 'smsusb_init_device':
+drivers/media/usb/siano/smsusb.c:447:37: warning: 'in_maxp' may be used uninitialized in this function [-Wmaybe-uninitialized]
+  447 |   dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr);
+      |                             ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The sparse message itself is bogus, but a broken (or fake) USB
+eeprom could produce a negative value for response_alignment.
+
+So, change the code in order to check if the result is not
+negative.
+
+Fixes: 31e0456de5be ("media: usb: siano: Fix general protection fault in smsusb")
+CC: <stable@vger.kernel.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/siano/smsusb.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -391,7 +391,7 @@ static int smsusb_init_device(struct usb
+       struct smsusb_device_t *dev;
+       void *mdev;
+       int i, rc;
+-      int in_maxp = 0;
++      int align = 0;
+       /* create device object */
+       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
+@@ -409,14 +409,14 @@ static int smsusb_init_device(struct usb
+               if (desc->bEndpointAddress & USB_DIR_IN) {
+                       dev->in_ep = desc->bEndpointAddress;
+-                      in_maxp = usb_endpoint_maxp(desc);
++                      align = usb_endpoint_maxp(desc) - sizeof(struct sms_msg_hdr);
+               } else {
+                       dev->out_ep = desc->bEndpointAddress;
+               }
+       }
+       pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep);
+-      if (!dev->in_ep || !dev->out_ep) {      /* Missing endpoints? */
++      if (!dev->in_ep || !dev->out_ep || align < 0) {  /* Missing endpoints? */
+               smsusb_term_device(intf);
+               return -ENODEV;
+       }
+@@ -435,7 +435,7 @@ static int smsusb_init_device(struct usb
+               /* fall-thru */
+       default:
+               dev->buffer_size = USB2_BUFFER_SIZE;
+-              dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr);
++              dev->response_alignment = align;
+               params.flags |= SMS_DEVICE_FAMILY2;
+               break;
diff --git a/queue-4.4/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch b/queue-4.4/media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch
new file mode 100644 (file)
index 0000000..f9ebae2
--- /dev/null
@@ -0,0 +1,33 @@
+From 45457c01171fd1488a7000d1751c06ed8560ee38 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 21 May 2019 11:38:07 -0400
+Subject: media: usb: siano: Fix false-positive "uninitialized variable" warning
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 45457c01171fd1488a7000d1751c06ed8560ee38 upstream.
+
+GCC complains about an apparently uninitialized variable recently
+added to smsusb_init_device().  It's a false positive, but to silence
+the warning this patch adds a trivial initialization.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: kbuild test robot <lkp@intel.com>
+CC: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/siano/smsusb.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -391,7 +391,7 @@ static int smsusb_init_device(struct usb
+       struct smsusb_device_t *dev;
+       void *mdev;
+       int i, rc;
+-      int in_maxp;
++      int in_maxp = 0;
+       /* create device object */
+       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
diff --git a/queue-4.4/media-usb-siano-fix-general-protection-fault-in-smsusb.patch b/queue-4.4/media-usb-siano-fix-general-protection-fault-in-smsusb.patch
new file mode 100644 (file)
index 0000000..74f31da
--- /dev/null
@@ -0,0 +1,90 @@
+From 31e0456de5be379b10fea0fa94a681057114a96e Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 7 May 2019 12:39:47 -0400
+Subject: media: usb: siano: Fix general protection fault in smsusb
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 31e0456de5be379b10fea0fa94a681057114a96e upstream.
+
+The syzkaller USB fuzzer found a general-protection-fault bug in the
+smsusb part of the Siano DVB driver.  The fault occurs during probe
+because the driver assumes without checking that the device has both
+IN and OUT endpoints and the IN endpoint is ep1.
+
+By slightly rearranging the driver's initialization code, we can make
+the appropriate checks early on and thus avoid the problem.  If the
+expected endpoints aren't present, the new code safely returns -ENODEV
+from the probe routine.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: syzbot+53f029db71c19a47325a@syzkaller.appspotmail.com
+CC: <stable@vger.kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/siano/smsusb.c |   33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+--- a/drivers/media/usb/siano/smsusb.c
++++ b/drivers/media/usb/siano/smsusb.c
+@@ -391,6 +391,7 @@ static int smsusb_init_device(struct usb
+       struct smsusb_device_t *dev;
+       void *mdev;
+       int i, rc;
++      int in_maxp;
+       /* create device object */
+       dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
+@@ -402,6 +403,24 @@ static int smsusb_init_device(struct usb
+       dev->udev = interface_to_usbdev(intf);
+       dev->state = SMSUSB_DISCONNECTED;
++      for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
++              struct usb_endpoint_descriptor *desc =
++                              &intf->cur_altsetting->endpoint[i].desc;
++
++              if (desc->bEndpointAddress & USB_DIR_IN) {
++                      dev->in_ep = desc->bEndpointAddress;
++                      in_maxp = usb_endpoint_maxp(desc);
++              } else {
++                      dev->out_ep = desc->bEndpointAddress;
++              }
++      }
++
++      pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep);
++      if (!dev->in_ep || !dev->out_ep) {      /* Missing endpoints? */
++              smsusb_term_device(intf);
++              return -ENODEV;
++      }
++
+       params.device_type = sms_get_board(board_id)->type;
+       switch (params.device_type) {
+@@ -416,24 +435,12 @@ static int smsusb_init_device(struct usb
+               /* fall-thru */
+       default:
+               dev->buffer_size = USB2_BUFFER_SIZE;
+-              dev->response_alignment =
+-                  le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
+-                  sizeof(struct sms_msg_hdr);
++              dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr);
+               params.flags |= SMS_DEVICE_FAMILY2;
+               break;
+       }
+-      for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+-              if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN)
+-                      dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
+-              else
+-                      dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
+-      }
+-
+-      pr_debug("in_ep = %02x, out_ep = %02x\n",
+-              dev->in_ep, dev->out_ep);
+-
+       params.device = &dev->udev->dev;
+       params.buffer_size = dev->buffer_size;
+       params.num_buffers = MAX_BUFFERS;
diff --git a/queue-4.4/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch b/queue-4.4/scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch
new file mode 100644 (file)
index 0000000..bc1d9ac
--- /dev/null
@@ -0,0 +1,35 @@
+From d27e5e07f9c49bf2a6a4ef254ce531c1b4fb5a38 Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.ibm.com>
+Date: Thu, 23 May 2019 15:23:45 +0200
+Subject: scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove
+
+From: Steffen Maier <maier@linux.ibm.com>
+
+commit d27e5e07f9c49bf2a6a4ef254ce531c1b4fb5a38 upstream.
+
+With this early return due to zfcp_unit child(ren), we don't use the
+zfcp_port reference from the earlier zfcp_get_port_by_wwpn() anymore and
+need to put it.
+
+Signed-off-by: Steffen Maier <maier@linux.ibm.com>
+Fixes: d99b601b6338 ("[SCSI] zfcp: restore refcount check on port_remove")
+Cc: <stable@vger.kernel.org> #3.7+
+Reviewed-by: Jens Remus <jremus@linux.ibm.com>
+Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_sysfs.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/s390/scsi/zfcp_sysfs.c
++++ b/drivers/s390/scsi/zfcp_sysfs.c
+@@ -263,6 +263,7 @@ static ssize_t zfcp_sysfs_port_remove_st
+       if (atomic_read(&port->units) > 0) {
+               retval = -EBUSY;
+               mutex_unlock(&zfcp_sysfs_port_units_mutex);
++              put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
+               goto out;
+       }
+       /* port is about to be removed, so no more unit_add */
diff --git a/queue-4.4/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch b/queue-4.4/scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch
new file mode 100644 (file)
index 0000000..79d613b
--- /dev/null
@@ -0,0 +1,186 @@
+From ef4021fe5fd77ced0323cede27979d80a56211ca Mon Sep 17 00:00:00 2001
+From: Steffen Maier <maier@linux.ibm.com>
+Date: Thu, 23 May 2019 15:23:46 +0200
+Subject: scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs)
+
+From: Steffen Maier <maier@linux.ibm.com>
+
+commit ef4021fe5fd77ced0323cede27979d80a56211ca upstream.
+
+When the user tries to remove a zfcp port via sysfs, we only rejected it if
+there are zfcp unit children under the port. With purely automatically
+scanned LUNs there are no zfcp units but only SCSI devices. In such cases,
+the port_remove erroneously continued. We close the port and this
+implicitly closes all LUNs under the port. The SCSI devices survive with
+their private zfcp_scsi_dev still holding a reference to the "removed"
+zfcp_port (still allocated but invisible in sysfs) [zfcp_get_port_by_wwpn
+in zfcp_scsi_slave_alloc]. This is not a problem as long as the fc_rport
+stays blocked. Once (auto) port scan brings back the removed port, we
+unblock its fc_rport again by design.  However, there is no mechanism that
+would recover (open) the LUNs under the port (no "ersfs_3" without
+zfcp_unit [zfcp_erp_strategy_followup_success]).  Any pending or new I/O to
+such LUN leads to repeated:
+
+  Done: NEEDS_RETRY Result: hostbyte=DID_IMM_RETRY driverbyte=DRIVER_OK
+
+See also v4.10 commit 6f2ce1c6af37 ("scsi: zfcp: fix rport unblock race
+with LUN recovery"). Even a manual LUN recovery
+(echo 0 > /sys/bus/scsi/devices/H:C:T:L/zfcp_failed)
+does not help, as the LUN links to the old "removed" port which remains
+to lack ZFCP_STATUS_COMMON_RUNNING [zfcp_erp_required_act].
+The only workaround is to first ensure that the fc_rport is blocked
+(e.g. port_remove again in case it was re-discovered by (auto) port scan),
+then delete the SCSI devices, and finally re-discover by (auto) port scan.
+The port scan includes an fc_rport unblock, which in turn triggers
+a new scan on the scsi target to freshly get new pure auto scan LUNs.
+
+Fix this by rejecting port_remove also if there are SCSI devices
+(even without any zfcp_unit) under this port. Re-use mechanics from v3.7
+commit d99b601b6338 ("[SCSI] zfcp: restore refcount check on port_remove").
+However, we have to give up zfcp_sysfs_port_units_mutex earlier in unit_add
+to prevent a deadlock with scsi_host scan taking shost->scan_mutex first
+and then zfcp_sysfs_port_units_mutex now in our zfcp_scsi_slave_alloc().
+
+Signed-off-by: Steffen Maier <maier@linux.ibm.com>
+Fixes: b62a8d9b45b9 ("[SCSI] zfcp: Use SCSI device data zfcp scsi dev instead of zfcp unit")
+Fixes: f8210e34887e ("[SCSI] zfcp: Allow midlayer to scan for LUNs when running in NPIV mode")
+Cc: <stable@vger.kernel.org> #2.6.37+
+Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/scsi/zfcp_ext.h   |    1 
+ drivers/s390/scsi/zfcp_scsi.c  |    9 ++++++
+ drivers/s390/scsi/zfcp_sysfs.c |   54 ++++++++++++++++++++++++++++++++++++-----
+ drivers/s390/scsi/zfcp_unit.c  |    8 +++++-
+ 4 files changed, 65 insertions(+), 7 deletions(-)
+
+--- a/drivers/s390/scsi/zfcp_ext.h
++++ b/drivers/s390/scsi/zfcp_ext.h
+@@ -161,6 +161,7 @@ extern const struct attribute_group *zfc
+ extern struct mutex zfcp_sysfs_port_units_mutex;
+ extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
+ extern struct device_attribute *zfcp_sysfs_shost_attrs[];
++bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port);
+ /* zfcp_unit.c */
+ extern int zfcp_unit_add(struct zfcp_port *, u64);
+--- a/drivers/s390/scsi/zfcp_scsi.c
++++ b/drivers/s390/scsi/zfcp_scsi.c
+@@ -124,6 +124,15 @@ static int zfcp_scsi_slave_alloc(struct
+       zfcp_sdev->erp_action.port = port;
++      mutex_lock(&zfcp_sysfs_port_units_mutex);
++      if (zfcp_sysfs_port_is_removing(port)) {
++              /* port is already gone */
++              mutex_unlock(&zfcp_sysfs_port_units_mutex);
++              put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
++              return -ENXIO;
++      }
++      mutex_unlock(&zfcp_sysfs_port_units_mutex);
++
+       unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev));
+       if (unit)
+               put_device(&unit->dev);
+--- a/drivers/s390/scsi/zfcp_sysfs.c
++++ b/drivers/s390/scsi/zfcp_sysfs.c
+@@ -237,6 +237,53 @@ static ZFCP_DEV_ATTR(adapter, port_resca
+ DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);
++static void zfcp_sysfs_port_set_removing(struct zfcp_port *const port)
++{
++      lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
++      atomic_set(&port->units, -1);
++}
++
++bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port)
++{
++      lockdep_assert_held(&zfcp_sysfs_port_units_mutex);
++      return atomic_read(&port->units) == -1;
++}
++
++static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port)
++{
++      struct zfcp_adapter *const adapter = port->adapter;
++      unsigned long flags;
++      struct scsi_device *sdev;
++      bool in_use = true;
++
++      mutex_lock(&zfcp_sysfs_port_units_mutex);
++      if (atomic_read(&port->units) > 0)
++              goto unlock_port_units_mutex; /* zfcp_unit(s) under port */
++
++      spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
++      __shost_for_each_device(sdev, adapter->scsi_host) {
++              const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
++
++              if (sdev->sdev_state == SDEV_DEL ||
++                  sdev->sdev_state == SDEV_CANCEL)
++                      continue;
++              if (zsdev->port != port)
++                      continue;
++              /* alive scsi_device under port of interest */
++              goto unlock_host_lock;
++      }
++
++      /* port is about to be removed, so no more unit_add or slave_alloc */
++      zfcp_sysfs_port_set_removing(port);
++      in_use = false;
++
++unlock_host_lock:
++      spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags);
++unlock_port_units_mutex:
++      mutex_unlock(&zfcp_sysfs_port_units_mutex);
++      return in_use;
++}
++
+ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
+                                           struct device_attribute *attr,
+                                           const char *buf, size_t count)
+@@ -259,16 +306,11 @@ static ssize_t zfcp_sysfs_port_remove_st
+       else
+               retval = 0;
+-      mutex_lock(&zfcp_sysfs_port_units_mutex);
+-      if (atomic_read(&port->units) > 0) {
++      if (zfcp_sysfs_port_in_use(port)) {
+               retval = -EBUSY;
+-              mutex_unlock(&zfcp_sysfs_port_units_mutex);
+               put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */
+               goto out;
+       }
+-      /* port is about to be removed, so no more unit_add */
+-      atomic_set(&port->units, -1);
+-      mutex_unlock(&zfcp_sysfs_port_units_mutex);
+       write_lock_irq(&adapter->port_list_lock);
+       list_del(&port->list);
+--- a/drivers/s390/scsi/zfcp_unit.c
++++ b/drivers/s390/scsi/zfcp_unit.c
+@@ -122,7 +122,7 @@ int zfcp_unit_add(struct zfcp_port *port
+       int retval = 0;
+       mutex_lock(&zfcp_sysfs_port_units_mutex);
+-      if (atomic_read(&port->units) == -1) {
++      if (zfcp_sysfs_port_is_removing(port)) {
+               /* port is already gone */
+               retval = -ENODEV;
+               goto out;
+@@ -166,8 +166,14 @@ int zfcp_unit_add(struct zfcp_port *port
+       write_lock_irq(&port->unit_list_lock);
+       list_add_tail(&unit->list, &port->unit_list);
+       write_unlock_irq(&port->unit_list_lock);
++      /*
++       * lock order: shost->scan_mutex before zfcp_sysfs_port_units_mutex
++       * due to      zfcp_unit_scsi_scan() => zfcp_scsi_slave_alloc()
++       */
++      mutex_unlock(&zfcp_sysfs_port_units_mutex);
+       zfcp_unit_scsi_scan(unit);
++      return retval;
+ out:
+       mutex_unlock(&zfcp_sysfs_port_units_mutex);
index d67b6193c91eeef49bd0b0aa4df86219d784eadc..2193f1ccf9ef189d751ccb89dee53429035e9ff6 100644 (file)
@@ -189,3 +189,18 @@ crypto-vmx-ghash-do-nosimd-fallback-manually.patch
 xen-pciback-don-t-disable-pci_command-on-pci-device-reset.patch
 revert-tipc-fix-modprobe-tipc-failed-after-switch-order-of-device-registration.patch
 tipc-fix-modprobe-tipc-failed-after-switch-order-of-device-registration-v2.patch
+sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch
+include-linux-bitops.h-sanitize-rotate-primitives.patch
+xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch
+usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch
+usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch
+usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch
+usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch
+usb-rio500-refuse-more-than-one-device-at-a-time.patch
+usb-rio500-fix-memory-leak-in-close-after-disconnect.patch
+media-usb-siano-fix-general-protection-fault-in-smsusb.patch
+media-usb-siano-fix-false-positive-uninitialized-variable-warning.patch
+media-smsusb-better-handle-optional-alignment.patch
+scsi-zfcp-fix-missing-zfcp_port-reference-put-on-ebusy-from-port_remove.patch
+scsi-zfcp-fix-to-prevent-port_remove-with-pure-auto-scan-luns-only-sdevs.patch
+btrfs-fix-race-updating-log-root-item-during-fsync.patch
diff --git a/queue-4.4/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch b/queue-4.4/sparc64-fix-regression-in-non-hypervisor-tlb-flush-xcall.patch
new file mode 100644 (file)
index 0000000..6eedac2
--- /dev/null
@@ -0,0 +1,47 @@
+From d3c976c14ad8af421134c428b0a89ff8dd3bd8f8 Mon Sep 17 00:00:00 2001
+From: James Clarke <jrtc27@jrtc27.com>
+Date: Wed, 29 May 2019 22:31:31 +0100
+Subject: sparc64: Fix regression in non-hypervisor TLB flush xcall
+
+From: James Clarke <jrtc27@jrtc27.com>
+
+commit d3c976c14ad8af421134c428b0a89ff8dd3bd8f8 upstream.
+
+Previously, %g2 would end up with the value PAGE_SIZE, but after the
+commit mentioned below it ends up with the value 1 due to being reused
+for a different purpose. We need it to be PAGE_SIZE as we use it to step
+through pages in our demap loop, otherwise we set different flags in the
+low 12 bits of the address written to, thereby doing things other than a
+nucleus page flush.
+
+Fixes: a74ad5e660a9 ("sparc64: Handle extremely large kernel TLB range flushes more gracefully.")
+Reported-by: Meelis Roos <mroos@linux.ee>
+Tested-by: Meelis Roos <mroos@linux.ee>
+Signed-off-by: James Clarke <jrtc27@jrtc27.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/sparc/mm/ultra.S |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/mm/ultra.S
++++ b/arch/sparc/mm/ultra.S
+@@ -586,7 +586,7 @@ xcall_flush_tlb_kernel_range:      /* 44 insn
+       sub             %g7, %g1, %g3
+       srlx            %g3, 18, %g2
+       brnz,pn         %g2, 2f
+-       add            %g2, 1, %g2
++       sethi          %hi(PAGE_SIZE), %g2
+       sub             %g3, %g2, %g3
+       or              %g1, 0x20, %g1          ! Nucleus
+ 1:    stxa            %g0, [%g1 + %g3] ASI_DMMU_DEMAP
+@@ -750,7 +750,7 @@ __cheetah_xcall_flush_tlb_kernel_range:
+       sub             %g7, %g1, %g3
+       srlx            %g3, 18, %g2
+       brnz,pn         %g2, 2f
+-       add            %g2, 1, %g2
++       sethi          %hi(PAGE_SIZE), %g2
+       sub             %g3, %g2, %g3
+       or              %g1, 0x20, %g1          ! Nucleus
+ 1:    stxa            %g0, [%g1 + %g3] ASI_DMMU_DEMAP
diff --git a/queue-4.4/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch b/queue-4.4/usb-add-lpm-quirk-for-surface-dock-gige-adapter.patch
new file mode 100644 (file)
index 0000000..bb5cd0e
--- /dev/null
@@ -0,0 +1,37 @@
+From ea261113385ac0a71c2838185f39e8452d54b152 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Thu, 16 May 2019 17:08:31 +0200
+Subject: USB: Add LPM quirk for Surface Dock GigE adapter
+
+From: Maximilian Luz <luzmaximilian@gmail.com>
+
+commit ea261113385ac0a71c2838185f39e8452d54b152 upstream.
+
+Without USB_QUIRK_NO_LPM ethernet will not work and rtl8152 will
+complain with
+
+    r8152 <device...>: Stop submitting intr, status -71
+
+Adding the quirk resolves this. As the dock is externally powered, this
+should not have any drawbacks.
+
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -64,6 +64,9 @@ static const struct usb_device_id usb_qu
+       /* Microsoft LifeCam-VX700 v2.0 */
+       { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
++      /* Microsoft Surface Dock Ethernet (RTL8153 GigE) */
++      { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM },
++
+       /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
+       { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/queue-4.4/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch b/queue-4.4/usb-fix-slab-out-of-bounds-write-in-usb_get_bos_descriptor.patch
new file mode 100644 (file)
index 0000000..55e5624
--- /dev/null
@@ -0,0 +1,38 @@
+From a03ff54460817c76105f81f3aa8ef655759ccc9a Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 13 May 2019 13:14:29 -0400
+Subject: USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit a03ff54460817c76105f81f3aa8ef655759ccc9a upstream.
+
+The syzkaller USB fuzzer found a slab-out-of-bounds write bug in the
+USB core, caused by a failure to check the actual size of a BOS
+descriptor.  This patch adds a check to make sure the descriptor is at
+least as large as it is supposed to be, so that the code doesn't
+inadvertently access memory beyond the end of the allocated region
+when assigning to dev->bos->desc->bNumDeviceCaps later on.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: syzbot+71f1e64501a309fcc012@syzkaller.appspotmail.com
+CC: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -902,8 +902,8 @@ int usb_get_bos_descriptor(struct usb_de
+       /* Get BOS descriptor */
+       ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE);
+-      if (ret < USB_DT_BOS_SIZE) {
+-              dev_err(ddev, "unable to get BOS descriptor\n");
++      if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) {
++              dev_err(ddev, "unable to get BOS descriptor or descriptor too short\n");
+               if (ret >= 0)
+                       ret = -ENOMSG;
+               kfree(bos);
diff --git a/queue-4.4/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch b/queue-4.4/usb-rio500-fix-memory-leak-in-close-after-disconnect.patch
new file mode 100644 (file)
index 0000000..ac32e9d
--- /dev/null
@@ -0,0 +1,47 @@
+From e0feb73428b69322dd5caae90b0207de369b5575 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 9 May 2019 11:30:59 +0200
+Subject: USB: rio500: fix memory leak in close after disconnect
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit e0feb73428b69322dd5caae90b0207de369b5575 upstream.
+
+If a disconnected device is closed, rio_close() must free
+the buffers.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/rio500.c |   17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/rio500.c
++++ b/drivers/usb/misc/rio500.c
+@@ -103,9 +103,22 @@ static int close_rio(struct inode *inode
+ {
+       struct rio_usb_data *rio = &rio_instance;
+-      rio->isopen = 0;
++      /* against disconnect() */
++      mutex_lock(&rio500_mutex);
++      mutex_lock(&(rio->lock));
+-      dev_info(&rio->rio_dev->dev, "Rio closed.\n");
++      rio->isopen = 0;
++      if (!rio->present) {
++              /* cleanup has been delayed */
++              kfree(rio->ibuf);
++              kfree(rio->obuf);
++              rio->ibuf = NULL;
++              rio->obuf = NULL;
++      } else {
++              dev_info(&rio->rio_dev->dev, "Rio closed.\n");
++      }
++      mutex_unlock(&(rio->lock));
++      mutex_unlock(&rio500_mutex);
+       return 0;
+ }
diff --git a/queue-4.4/usb-rio500-refuse-more-than-one-device-at-a-time.patch b/queue-4.4/usb-rio500-refuse-more-than-one-device-at-a-time.patch
new file mode 100644 (file)
index 0000000..eec3f33
--- /dev/null
@@ -0,0 +1,83 @@
+From 3864d33943b4a76c6e64616280e98d2410b1190f Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 9 May 2019 11:30:58 +0200
+Subject: USB: rio500: refuse more than one device at a time
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 3864d33943b4a76c6e64616280e98d2410b1190f upstream.
+
+This driver is using a global variable. It cannot handle more than
+one device at a time. The issue has been existing since the dawn
+of the driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Reported-by: syzbot+35f04d136fc975a70da4@syzkaller.appspotmail.com
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/rio500.c |   24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/misc/rio500.c
++++ b/drivers/usb/misc/rio500.c
+@@ -464,15 +464,23 @@ static int probe_rio(struct usb_interfac
+ {
+       struct usb_device *dev = interface_to_usbdev(intf);
+       struct rio_usb_data *rio = &rio_instance;
+-      int retval;
++      int retval = 0;
+-      dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
++      mutex_lock(&rio500_mutex);
++      if (rio->present) {
++              dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum);
++              retval = -EBUSY;
++              goto bail_out;
++      } else {
++              dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
++      }
+       retval = usb_register_dev(intf, &usb_rio_class);
+       if (retval) {
+               dev_err(&dev->dev,
+                       "Not able to get a minor for this device.\n");
+-              return -ENOMEM;
++              retval = -ENOMEM;
++              goto bail_out;
+       }
+       rio->rio_dev = dev;
+@@ -481,7 +489,8 @@ static int probe_rio(struct usb_interfac
+               dev_err(&dev->dev,
+                       "probe_rio: Not enough memory for the output buffer\n");
+               usb_deregister_dev(intf, &usb_rio_class);
+-              return -ENOMEM;
++              retval = -ENOMEM;
++              goto bail_out;
+       }
+       dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
+@@ -490,7 +499,8 @@ static int probe_rio(struct usb_interfac
+                       "probe_rio: Not enough memory for the input buffer\n");
+               usb_deregister_dev(intf, &usb_rio_class);
+               kfree(rio->obuf);
+-              return -ENOMEM;
++              retval = -ENOMEM;
++              goto bail_out;
+       }
+       dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
+@@ -498,8 +508,10 @@ static int probe_rio(struct usb_interfac
+       usb_set_intfdata (intf, rio);
+       rio->present = 1;
++bail_out:
++      mutex_unlock(&rio500_mutex);
+-      return 0;
++      return retval;
+ }
+ static void disconnect_rio(struct usb_interface *intf)
diff --git a/queue-4.4/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch b/queue-4.4/usb-sisusbvga-fix-oops-in-error-path-of-sisusb_probe.patch
new file mode 100644 (file)
index 0000000..22cbc11
--- /dev/null
@@ -0,0 +1,55 @@
+From 9a5729f68d3a82786aea110b1bfe610be318f80a Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 9 May 2019 14:41:50 +0200
+Subject: USB: sisusbvga: fix oops in error path of sisusb_probe
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 9a5729f68d3a82786aea110b1bfe610be318f80a upstream.
+
+The pointer used to log a failure of usb_register_dev() must
+be set before the error is logged.
+
+v2: fix that minor is not available before registration
+
+Signed-off-by: oliver Neukum <oneukum@suse.com>
+Reported-by: syzbot+a0cbdbd6d169020c8959@syzkaller.appspotmail.com
+Fixes: 7b5cd5fefbe02 ("USB: SisUSB2VGA: Convert printk to dev_* macros")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/sisusbvga/sisusb.c |   15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/misc/sisusbvga/sisusb.c
++++ b/drivers/usb/misc/sisusbvga/sisusb.c
+@@ -3103,6 +3103,13 @@ static int sisusb_probe(struct usb_inter
+       mutex_init(&(sisusb->lock));
++      sisusb->sisusb_dev = dev;
++      sisusb->vrambase   = SISUSB_PCI_MEMBASE;
++      sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
++      sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
++      sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
++      /* Everything else is zero */
++
+       /* Register device */
+       retval = usb_register_dev(intf, &usb_sisusb_class);
+       if (retval) {
+@@ -3112,13 +3119,7 @@ static int sisusb_probe(struct usb_inter
+               goto error_1;
+       }
+-      sisusb->sisusb_dev = dev;
+-      sisusb->minor      = intf->minor;
+-      sisusb->vrambase   = SISUSB_PCI_MEMBASE;
+-      sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
+-      sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
+-      sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
+-      /* Everything else is zero */
++      sisusb->minor = intf->minor;
+       /* Allocate buffers */
+       sisusb->ibufsize = SISUSB_IBUF_SIZE;
diff --git a/queue-4.4/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch b/queue-4.4/usb-xhci-avoid-null-pointer-deref-when-bos-field-is-null.patch
new file mode 100644 (file)
index 0000000..200e75c
--- /dev/null
@@ -0,0 +1,106 @@
+From 7aa1bb2ffd84d6b9b5f546b079bb15cd0ab6e76e Mon Sep 17 00:00:00 2001
+From: Carsten Schmid <carsten_schmid@mentor.com>
+Date: Wed, 22 May 2019 14:33:59 +0300
+Subject: usb: xhci: avoid null pointer deref when bos field is NULL
+
+From: Carsten Schmid <carsten_schmid@mentor.com>
+
+commit 7aa1bb2ffd84d6b9b5f546b079bb15cd0ab6e76e upstream.
+
+With defective USB sticks we see the following error happen:
+usb 1-3: new high-speed USB device number 6 using xhci_hcd
+usb 1-3: device descriptor read/64, error -71
+usb 1-3: device descriptor read/64, error -71
+usb 1-3: new high-speed USB device number 7 using xhci_hcd
+usb 1-3: device descriptor read/64, error -71
+usb 1-3: unable to get BOS descriptor set
+usb 1-3: New USB device found, idVendor=0781, idProduct=5581
+usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
+...
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
+
+This comes from the following place:
+[ 1660.215380] IP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd]
+[ 1660.222092] PGD 0 P4D 0
+[ 1660.224918] Oops: 0000 [#1] PREEMPT SMP NOPTI
+[ 1660.425520] CPU: 1 PID: 38 Comm: kworker/1:1 Tainted: P     U  W  O    4.14.67-apl #1
+[ 1660.434277] Workqueue: usb_hub_wq hub_event [usbcore]
+[ 1660.439918] task: ffffa295b6ae4c80 task.stack: ffffad4580150000
+[ 1660.446532] RIP: 0010:xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd]
+[ 1660.453821] RSP: 0018:ffffad4580153c70 EFLAGS: 00010046
+[ 1660.459655] RAX: 0000000000000000 RBX: ffffa295b4d7c000 RCX: 0000000000000002
+[ 1660.467625] RDX: 0000000000000002 RSI: ffffffff984a55b2 RDI: ffffffff984a55b2
+[ 1660.475586] RBP: ffffad4580153cc8 R08: 0000000000d6520a R09: 0000000000000001
+[ 1660.483556] R10: ffffad4580a004a0 R11: 0000000000000286 R12: ffffa295b4d7c000
+[ 1660.491525] R13: 0000000000010648 R14: ffffa295a84e1800 R15: 0000000000000000
+[ 1660.499494] FS:  0000000000000000(0000) GS:ffffa295bfc80000(0000) knlGS:0000000000000000
+[ 1660.508530] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1660.514947] CR2: 0000000000000008 CR3: 000000025a114000 CR4: 00000000003406a0
+[ 1660.522917] Call Trace:
+[ 1660.525657]  usb_set_usb2_hardware_lpm+0x3d/0x70 [usbcore]
+[ 1660.531792]  usb_disable_device+0x242/0x260 [usbcore]
+[ 1660.537439]  usb_disconnect+0xc1/0x2b0 [usbcore]
+[ 1660.542600]  hub_event+0x596/0x18f0 [usbcore]
+[ 1660.547467]  ? trace_preempt_on+0xdf/0x100
+[ 1660.552040]  ? process_one_work+0x1c1/0x410
+[ 1660.556708]  process_one_work+0x1d2/0x410
+[ 1660.561184]  ? preempt_count_add.part.3+0x21/0x60
+[ 1660.566436]  worker_thread+0x2d/0x3f0
+[ 1660.570522]  kthread+0x122/0x140
+[ 1660.574123]  ? process_one_work+0x410/0x410
+[ 1660.578792]  ? kthread_create_on_node+0x60/0x60
+[ 1660.583849]  ret_from_fork+0x3a/0x50
+[ 1660.587839] Code: 00 49 89 c3 49 8b 84 24 50 16 00 00 8d 4a ff 48 8d 04 c8 48 89 ca 4c 8b 10 45 8b 6a 04 48 8b 00 48 89 45 c0 49 8b 86 80 03 00 00 <48> 8b 40 08 8b 40 03 0f 1f 44 00 00 45 85 ff 0f 84 81 01 00 00
+[ 1660.608980] RIP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd] RSP: ffffad4580153c70
+[ 1660.617921] CR2: 0000000000000008
+
+Tracking this down shows that udev->bos is NULL in the following code:
+(xhci.c, in xhci_set_usb2_hardware_lpm)
+       field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);  <<<<<<< here
+
+       xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
+                       enable ? "enable" : "disable", port_num + 1);
+
+       if (enable) {
+               /* Host supports BESL timeout instead of HIRD */
+               if (udev->usb2_hw_lpm_besl_capable) {
+                       /* if device doesn't have a preferred BESL value use a
+                        * default one which works with mixed HIRD and BESL
+                        * systems. See XHCI_DEFAULT_BESL definition in xhci.h
+                        */
+                       if ((field & USB_BESL_SUPPORT) &&
+                           (field & USB_BESL_BASELINE_VALID))
+                               hird = USB_GET_BESL_BASELINE(field);
+                       else
+                               hird = udev->l1_params.besl;
+
+The failing case is when disabling LPM. So it is sufficient to avoid
+access to udev->bos by moving the instruction into the "enable" clause.
+
+Cc: Stable <stable@vger.kernel.org>
+Signed-off-by: Carsten Schmid <carsten_schmid@mentor.com>
+Signed-off-by: Mathias Nyman <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
+@@ -4191,7 +4191,6 @@ int xhci_set_usb2_hardware_lpm(struct us
+       pm_addr = port_array[port_num] + PORTPMSC;
+       pm_val = readl(pm_addr);
+       hlpm_addr = port_array[port_num] + PORTHLPMC;
+-      field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
+       xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
+                       enable ? "enable" : "disable", port_num + 1);
+@@ -4203,6 +4202,7 @@ int xhci_set_usb2_hardware_lpm(struct us
+                        * default one which works with mixed HIRD and BESL
+                        * systems. See XHCI_DEFAULT_BESL definition in xhci.h
+                        */
++                      field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
+                       if ((field & USB_BESL_SUPPORT) &&
+                           (field & USB_BESL_BASELINE_VALID))
+                               hird = USB_GET_BESL_BASELINE(field);
diff --git a/queue-4.4/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch b/queue-4.4/xhci-convert-xhci_handshake-to-use-readl_poll_timeout_atomic.patch
new file mode 100644 (file)
index 0000000..ff9ff1a
--- /dev/null
@@ -0,0 +1,76 @@
+From f7fac17ca925faa03fc5eb854c081a24075f8bad Mon Sep 17 00:00:00 2001
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+Date: Wed, 22 May 2019 14:34:01 +0300
+Subject: xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic()
+
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+
+commit f7fac17ca925faa03fc5eb854c081a24075f8bad upstream.
+
+Xhci_handshake() implements the algorithm already captured by
+readl_poll_timeout_atomic(). Convert the former to use the latter to
+avoid repetition.
+
+Turned out this patch also fixes a bug on the AMD Stoneyridge platform
+where usleep(1) sometimes takes over 10ms.
+This means a 5 second timeout can easily take over 15 seconds which will
+trigger the watchdog and reboot the system.
+
+[Add info about patch fixing a bug to commit message -Mathias]
+Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
+Tested-by: Raul E Rangel <rrangel@chromium.org>
+Reviewed-by: Raul E Rangel <rrangel@chromium.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |   22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -21,6 +21,7 @@
+  */
+ #include <linux/pci.h>
++#include <linux/iopoll.h>
+ #include <linux/irq.h>
+ #include <linux/log2.h>
+ #include <linux/module.h>
+@@ -46,7 +47,6 @@ static unsigned int quirks;
+ module_param(quirks, uint, S_IRUGO);
+ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
+-/* TODO: copied from ehci-hcd.c - can this be refactored? */
+ /*
+  * xhci_handshake - spin reading hc until handshake completes or fails
+  * @ptr: address of hc register to be read
+@@ -63,18 +63,16 @@ MODULE_PARM_DESC(quirks, "Bit flags for
+ int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
+ {
+       u32     result;
++      int     ret;
+-      do {
+-              result = readl(ptr);
+-              if (result == ~(u32)0)          /* card removed */
+-                      return -ENODEV;
+-              result &= mask;
+-              if (result == done)
+-                      return 0;
+-              udelay(1);
+-              usec--;
+-      } while (usec > 0);
+-      return -ETIMEDOUT;
++      ret = readl_poll_timeout_atomic(ptr, result,
++                                      (result & mask) == done ||
++                                      result == U32_MAX,
++                                      1, usec);
++      if (result == U32_MAX)          /* card removed */
++              return -ENODEV;
++
++      return ret;
+ }
+ /*