]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Dec 2017 12:02:01 +0000 (13:02 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Dec 2017 12:02:01 +0000 (13:02 +0100)
added patches:
autofs-fix-careless-error-in-recent-commit.patch
bluetooth-btusb-driver-to-enable-the-usb-wakeup-feature.patch
ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch
dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch
eeprom-at24-change-nvmem-stride-to-1.patch
ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch
ext4-fix-fdatasync-2-after-fallocate-2-operation.patch
nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch
sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch
tracing-allocate-mask_str-buffer-dynamically.patch
usb-core-prevent-malicious-bnuminterfaces-overflow.patch
usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch
usb-xhci-fix-tds-for-mtk-xhci1.1.patch
usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch
usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch
usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch
xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch

18 files changed:
queue-4.9/autofs-fix-careless-error-in-recent-commit.patch [new file with mode: 0644]
queue-4.9/bluetooth-btusb-driver-to-enable-the-usb-wakeup-feature.patch [new file with mode: 0644]
queue-4.9/ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch [new file with mode: 0644]
queue-4.9/dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch [new file with mode: 0644]
queue-4.9/eeprom-at24-change-nvmem-stride-to-1.patch [new file with mode: 0644]
queue-4.9/ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch [new file with mode: 0644]
queue-4.9/ext4-fix-fdatasync-2-after-fallocate-2-operation.patch [new file with mode: 0644]
queue-4.9/nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch [new file with mode: 0644]
queue-4.9/sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/tracing-allocate-mask_str-buffer-dynamically.patch [new file with mode: 0644]
queue-4.9/usb-core-prevent-malicious-bnuminterfaces-overflow.patch [new file with mode: 0644]
queue-4.9/usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch [new file with mode: 0644]
queue-4.9/usb-xhci-fix-tds-for-mtk-xhci1.1.patch [new file with mode: 0644]
queue-4.9/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch [new file with mode: 0644]
queue-4.9/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch [new file with mode: 0644]
queue-4.9/usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch [new file with mode: 0644]
queue-4.9/xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch [new file with mode: 0644]

diff --git a/queue-4.9/autofs-fix-careless-error-in-recent-commit.patch b/queue-4.9/autofs-fix-careless-error-in-recent-commit.patch
new file mode 100644 (file)
index 0000000..f80878b
--- /dev/null
@@ -0,0 +1,36 @@
+From 302ec300ef8a545a7fc7f667e5fd743b091c2eeb Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Thu, 14 Dec 2017 15:32:38 -0800
+Subject: autofs: fix careless error in recent commit
+
+From: NeilBrown <neilb@suse.com>
+
+commit 302ec300ef8a545a7fc7f667e5fd743b091c2eeb upstream.
+
+Commit ecc0c469f277 ("autofs: don't fail mount for transient error") was
+meant to replace an 'if' with a 'switch', but instead added the 'switch'
+leaving the case in place.
+
+Link: http://lkml.kernel.org/r/87zi6wstmw.fsf@notabene.neil.brown.name
+Fixes: ecc0c469f277 ("autofs: don't fail mount for transient error")
+Reported-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: NeilBrown <neilb@suse.com>
+Cc: Ian Kent <raven@themaw.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/autofs4/waitq.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/fs/autofs4/waitq.c
++++ b/fs/autofs4/waitq.c
+@@ -176,7 +176,6 @@ static void autofs4_notify_daemon(struct
+       mutex_unlock(&sbi->wq_mutex);
+-      if (autofs4_write(sbi, pipe, &pkt, pktsz))
+       switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) {
+       case 0:
+               break;
diff --git a/queue-4.9/bluetooth-btusb-driver-to-enable-the-usb-wakeup-feature.patch b/queue-4.9/bluetooth-btusb-driver-to-enable-the-usb-wakeup-feature.patch
new file mode 100644 (file)
index 0000000..a49ded6
--- /dev/null
@@ -0,0 +1,57 @@
+From a0085f2510e8976614ad8f766b209448b385492f Mon Sep 17 00:00:00 2001
+From: Sukumar Ghorai <sukumar.ghorai@intel.com>
+Date: Wed, 16 Aug 2017 14:46:55 -0700
+Subject: Bluetooth: btusb: driver to enable the usb-wakeup feature
+
+From: Sukumar Ghorai <sukumar.ghorai@intel.com>
+
+commit a0085f2510e8976614ad8f766b209448b385492f upstream.
+
+BT-Controller connected as platform non-root-hub device and
+usb-driver initialize such device with wakeup disabled,
+Ref. usb_new_device().
+
+At present wakeup-capability get enabled by hid-input device from usb
+function driver(e.g. BT HID device) at runtime. Again some functional
+driver does not set usb-wakeup capability(e.g LE HID device implement
+as HID-over-GATT), and can't wakeup the host on USB.
+
+Most of the device operation (such as mass storage) initiated from host
+(except HID) and USB wakeup aligned with host resume procedure. For BT
+device, usb-wakeup capability need to enable form btusc driver as a
+generic solution for multiple profile use case and required for USB remote
+wakeup (in-bus wakeup) while host is suspended. Also usb-wakeup feature
+need to enable/disable with HCI interface up and down.
+
+Signed-off-by: Sukumar Ghorai <sukumar.ghorai@intel.com>
+Signed-off-by: Amit K Bag <amit.k.bag@intel.com>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/bluetooth/btusb.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -1059,6 +1059,10 @@ static int btusb_open(struct hci_dev *hd
+       }
+       data->intf->needs_remote_wakeup = 1;
++      /* device specific wakeup source enabled and required for USB
++       * remote wakeup while host is suspended
++       */
++      device_wakeup_enable(&data->udev->dev);
+       if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
+               goto done;
+@@ -1122,6 +1126,7 @@ static int btusb_close(struct hci_dev *h
+               goto failed;
+       data->intf->needs_remote_wakeup = 0;
++      device_wakeup_disable(&data->udev->dev);
+       usb_autopm_put_interface(data->intf);
+ failed:
diff --git a/queue-4.9/ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch b/queue-4.9/ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch
new file mode 100644 (file)
index 0000000..e6d93c6
--- /dev/null
@@ -0,0 +1,85 @@
+From 040d786032bf59002d374b86d75b04d97624005c Mon Sep 17 00:00:00 2001
+From: "Yan, Zheng" <zyan@redhat.com>
+Date: Thu, 30 Nov 2017 11:59:22 +0800
+Subject: ceph: drop negative child dentries before try pruning inode's alias
+
+From: Yan, Zheng <zyan@redhat.com>
+
+commit 040d786032bf59002d374b86d75b04d97624005c upstream.
+
+Negative child dentry holds reference on inode's alias, it makes
+d_prune_aliases() do nothing.
+
+Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ceph/mds_client.c |   42 ++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 38 insertions(+), 4 deletions(-)
+
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -1396,6 +1396,29 @@ static int __close_session(struct ceph_m
+       return request_close_session(mdsc, session);
+ }
++static bool drop_negative_children(struct dentry *dentry)
++{
++      struct dentry *child;
++      bool all_negative = true;
++
++      if (!d_is_dir(dentry))
++              goto out;
++
++      spin_lock(&dentry->d_lock);
++      list_for_each_entry(child, &dentry->d_subdirs, d_child) {
++              if (d_really_is_positive(child)) {
++                      all_negative = false;
++                      break;
++              }
++      }
++      spin_unlock(&dentry->d_lock);
++
++      if (all_negative)
++              shrink_dcache_parent(dentry);
++out:
++      return all_negative;
++}
++
+ /*
+  * Trim old(er) caps.
+  *
+@@ -1441,16 +1464,27 @@ static int trim_caps_cb(struct inode *in
+       if ((used | wanted) & ~oissued & mine)
+               goto out;   /* we need these caps */
+-      session->s_trim_caps--;
+       if (oissued) {
+               /* we aren't the only cap.. just remove us */
+               __ceph_remove_cap(cap, true);
++              session->s_trim_caps--;
+       } else {
++              struct dentry *dentry;
+               /* try dropping referring dentries */
+               spin_unlock(&ci->i_ceph_lock);
+-              d_prune_aliases(inode);
+-              dout("trim_caps_cb %p cap %p  pruned, count now %d\n",
+-                   inode, cap, atomic_read(&inode->i_count));
++              dentry = d_find_any_alias(inode);
++              if (dentry && drop_negative_children(dentry)) {
++                      int count;
++                      dput(dentry);
++                      d_prune_aliases(inode);
++                      count = atomic_read(&inode->i_count);
++                      if (count == 1)
++                              session->s_trim_caps--;
++                      dout("trim_caps_cb %p cap %p pruned, count now %d\n",
++                           inode, cap, count);
++              } else {
++                      dput(dentry);
++              }
+               return 0;
+       }
diff --git a/queue-4.9/dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch b/queue-4.9/dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch
new file mode 100644 (file)
index 0000000..6866c2c
--- /dev/null
@@ -0,0 +1,159 @@
+From 6f6a23a213be51728502b88741ba6a10cda2441d Mon Sep 17 00:00:00 2001
+From: Adam Wallis <awallis@codeaurora.org>
+Date: Mon, 27 Nov 2017 10:45:01 -0500
+Subject: dmaengine: dmatest: move callback wait queue to thread context
+
+From: Adam Wallis <awallis@codeaurora.org>
+
+commit 6f6a23a213be51728502b88741ba6a10cda2441d upstream.
+
+Commit adfa543e7314 ("dmatest: don't use set_freezable_with_signal()")
+introduced a bug (that is in fact documented by the patch commit text)
+that leaves behind a dangling pointer. Since the done_wait structure is
+allocated on the stack, future invocations to the DMATEST can produce
+undesirable results (e.g., corrupted spinlocks).
+
+Commit a9df21e34b42 ("dmaengine: dmatest: warn user when dma test times
+out") attempted to WARN the user that the stack was likely corrupted but
+did not fix the actual issue.
+
+This patch fixes the issue by pushing the wait queue and callback
+structs into the the thread structure. If a failure occurs due to time,
+dmaengine_terminate_all will force the callback to safely call
+wake_up_all() without possibility of using a freed pointer.
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=197605
+Fixes: adfa543e7314 ("dmatest: don't use set_freezable_with_signal()")
+Reviewed-by: Sinan Kaya <okaya@codeaurora.org>
+Suggested-by: Shunyong Yang <shunyong.yang@hxt-semitech.com>
+Signed-off-by: Adam Wallis <awallis@codeaurora.org>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/dmatest.c |   55 ++++++++++++++++++++++++++++----------------------
+ 1 file changed, 31 insertions(+), 24 deletions(-)
+
+--- a/drivers/dma/dmatest.c
++++ b/drivers/dma/dmatest.c
+@@ -158,6 +158,12 @@ MODULE_PARM_DESC(run, "Run the test (def
+ #define PATTERN_OVERWRITE     0x20
+ #define PATTERN_COUNT_MASK    0x1f
++/* poor man's completion - we want to use wait_event_freezable() on it */
++struct dmatest_done {
++      bool                    done;
++      wait_queue_head_t       *wait;
++};
++
+ struct dmatest_thread {
+       struct list_head        node;
+       struct dmatest_info     *info;
+@@ -166,6 +172,8 @@ struct dmatest_thread {
+       u8                      **srcs;
+       u8                      **dsts;
+       enum dma_transaction_type type;
++      wait_queue_head_t done_wait;
++      struct dmatest_done test_done;
+       bool                    done;
+ };
+@@ -326,18 +334,25 @@ static unsigned int dmatest_verify(u8 **
+       return error_count;
+ }
+-/* poor man's completion - we want to use wait_event_freezable() on it */
+-struct dmatest_done {
+-      bool                    done;
+-      wait_queue_head_t       *wait;
+-};
+ static void dmatest_callback(void *arg)
+ {
+       struct dmatest_done *done = arg;
+-
+-      done->done = true;
+-      wake_up_all(done->wait);
++      struct dmatest_thread *thread =
++              container_of(arg, struct dmatest_thread, done_wait);
++      if (!thread->done) {
++              done->done = true;
++              wake_up_all(done->wait);
++      } else {
++              /*
++               * If thread->done, it means that this callback occurred
++               * after the parent thread has cleaned up. This can
++               * happen in the case that driver doesn't implement
++               * the terminate_all() functionality and a dma operation
++               * did not occur within the timeout period
++               */
++              WARN(1, "dmatest: Kernel memory may be corrupted!!\n");
++      }
+ }
+ static unsigned int min_odd(unsigned int x, unsigned int y)
+@@ -408,9 +423,8 @@ static unsigned long long dmatest_KBs(s6
+  */
+ static int dmatest_func(void *data)
+ {
+-      DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait);
+       struct dmatest_thread   *thread = data;
+-      struct dmatest_done     done = { .wait = &done_wait };
++      struct dmatest_done     *done = &thread->test_done;
+       struct dmatest_info     *info;
+       struct dmatest_params   *params;
+       struct dma_chan         *chan;
+@@ -637,9 +651,9 @@ static int dmatest_func(void *data)
+                       continue;
+               }
+-              done.done = false;
++              done->done = false;
+               tx->callback = dmatest_callback;
+-              tx->callback_param = &done;
++              tx->callback_param = done;
+               cookie = tx->tx_submit(tx);
+               if (dma_submit_error(cookie)) {
+@@ -652,21 +666,12 @@ static int dmatest_func(void *data)
+               }
+               dma_async_issue_pending(chan);
+-              wait_event_freezable_timeout(done_wait, done.done,
++              wait_event_freezable_timeout(thread->done_wait, done->done,
+                                            msecs_to_jiffies(params->timeout));
+               status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
+-              if (!done.done) {
+-                      /*
+-                       * We're leaving the timed out dma operation with
+-                       * dangling pointer to done_wait.  To make this
+-                       * correct, we'll need to allocate wait_done for
+-                       * each test iteration and perform "who's gonna
+-                       * free it this time?" dancing.  For now, just
+-                       * leave it dangling.
+-                       */
+-                      WARN(1, "dmatest: Kernel stack may be corrupted!!\n");
++              if (!done->done) {
+                       dmaengine_unmap_put(um);
+                       result("test timed out", total_tests, src_off, dst_off,
+                              len, 0);
+@@ -747,7 +752,7 @@ err_thread_type:
+               dmatest_KBs(runtime, total_len), ret);
+       /* terminate all transfers on specified channels */
+-      if (ret)
++      if (ret || failed_tests)
+               dmaengine_terminate_all(chan);
+       thread->done = true;
+@@ -807,6 +812,8 @@ static int dmatest_add_threads(struct dm
+               thread->info = info;
+               thread->chan = dtc->chan;
+               thread->type = type;
++              thread->test_done.wait = &thread->done_wait;
++              init_waitqueue_head(&thread->done_wait);
+               smp_wmb();
+               thread->task = kthread_create(dmatest_func, thread, "%s-%s%u",
+                               dma_chan_name(chan), op, i);
diff --git a/queue-4.9/eeprom-at24-change-nvmem-stride-to-1.patch b/queue-4.9/eeprom-at24-change-nvmem-stride-to-1.patch
new file mode 100644 (file)
index 0000000..c8e1a7c
--- /dev/null
@@ -0,0 +1,34 @@
+From 7f6d2ecd3d7acaf205ea7b3e96f9ffc55b92298b Mon Sep 17 00:00:00 2001
+From: David Lechner <david@lechnology.com>
+Date: Sun, 3 Dec 2017 19:54:41 -0600
+Subject: eeprom: at24: change nvmem stride to 1
+
+From: David Lechner <david@lechnology.com>
+
+commit 7f6d2ecd3d7acaf205ea7b3e96f9ffc55b92298b upstream.
+
+Trying to read the MAC address from an eeprom that has an offset that
+is not a multiple of 4 causes an error currently.
+
+Fix it by changing the nvmem stride to 1.
+
+Signed-off-by: David Lechner <david@lechnology.com>
+[Bartosz: tweaked the commit message]
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/eeprom/at24.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/eeprom/at24.c
++++ b/drivers/misc/eeprom/at24.c
+@@ -783,7 +783,7 @@ static int at24_probe(struct i2c_client
+       at24->nvmem_config.reg_read = at24_read;
+       at24->nvmem_config.reg_write = at24_write;
+       at24->nvmem_config.priv = at24;
+-      at24->nvmem_config.stride = 4;
++      at24->nvmem_config.stride = 1;
+       at24->nvmem_config.word_size = 1;
+       at24->nvmem_config.size = chip.byte_len;
diff --git a/queue-4.9/ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch b/queue-4.9/ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch
new file mode 100644 (file)
index 0000000..58f42f8
--- /dev/null
@@ -0,0 +1,57 @@
+From 9d5afec6b8bd46d6ed821aa1579634437f58ef1f Mon Sep 17 00:00:00 2001
+From: Chandan Rajendra <chandan@linux.vnet.ibm.com>
+Date: Mon, 11 Dec 2017 15:00:57 -0500
+Subject: ext4: fix crash when a directory's i_size is too small
+
+From: Chandan Rajendra <chandan@linux.vnet.ibm.com>
+
+commit 9d5afec6b8bd46d6ed821aa1579634437f58ef1f upstream.
+
+On a ppc64 machine, when mounting a fuzzed ext2 image (generated by
+fsfuzzer) the following call trace is seen,
+
+VFS: brelse: Trying to free free buffer
+WARNING: CPU: 1 PID: 6913 at /root/repos/linux/fs/buffer.c:1165 .__brelse.part.6+0x24/0x40
+.__brelse.part.6+0x20/0x40 (unreliable)
+.ext4_find_entry+0x384/0x4f0
+.ext4_lookup+0x84/0x250
+.lookup_slow+0xdc/0x230
+.walk_component+0x268/0x400
+.path_lookupat+0xec/0x2d0
+.filename_lookup+0x9c/0x1d0
+.vfs_statx+0x98/0x140
+.SyS_newfstatat+0x48/0x80
+system_call+0x58/0x6c
+
+This happens because the directory that ext4_find_entry() looks up has
+inode->i_size that is less than the block size of the filesystem. This
+causes 'nblocks' to have a value of zero. ext4_bread_batch() ends up not
+reading any of the directory file's blocks. This renders the entries in
+bh_use[] array to continue to have garbage data. buffer_uptodate() on
+bh_use[0] can then return a zero value upon which brelse() function is
+invoked.
+
+This commit fixes the bug by returning -ENOENT when the directory file
+has no associated blocks.
+
+Reported-by: Abdul Haleem <abdhalee@linux.vnet.ibm.com>
+Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/namei.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1417,6 +1417,10 @@ static struct buffer_head * ext4_find_en
+                              "falling back\n"));
+       }
+       nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
++      if (!nblocks) {
++              ret = NULL;
++              goto cleanup_and_exit;
++      }
+       start = EXT4_I(dir)->i_dir_start_lookup;
+       if (start >= nblocks)
+               start = 0;
diff --git a/queue-4.9/ext4-fix-fdatasync-2-after-fallocate-2-operation.patch b/queue-4.9/ext4-fix-fdatasync-2-after-fallocate-2-operation.patch
new file mode 100644 (file)
index 0000000..57d5092
--- /dev/null
@@ -0,0 +1,43 @@
+From c894aa97577e47d3066b27b32499ecf899bfa8b0 Mon Sep 17 00:00:00 2001
+From: Eryu Guan <eguan@redhat.com>
+Date: Sun, 3 Dec 2017 22:52:51 -0500
+Subject: ext4: fix fdatasync(2) after fallocate(2) operation
+
+From: Eryu Guan <eguan@redhat.com>
+
+commit c894aa97577e47d3066b27b32499ecf899bfa8b0 upstream.
+
+Currently, fallocate(2) with KEEP_SIZE followed by a fdatasync(2)
+then crash, we'll see wrong allocated block number (stat -c %b), the
+blocks allocated beyond EOF are all lost. fstests generic/468
+exposes this bug.
+
+Commit 67a7d5f561f4 ("ext4: fix fdatasync(2) after extent
+manipulation operations") fixed all the other extent manipulation
+operation paths such as hole punch, zero range, collapse range etc.,
+but forgot the fallocate case.
+
+So similarly, fix it by recording the correct journal tid in ext4
+inode in fallocate(2) path, so that ext4_sync_file() will wait for
+the right tid to be committed on fdatasync(2).
+
+This addresses the test failure in xfstests test generic/468.
+
+Signed-off-by: Eryu Guan <eguan@redhat.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/extents.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -4731,6 +4731,7 @@ retry:
+                                                   EXT4_INODE_EOFBLOCKS);
+               }
+               ext4_mark_inode_dirty(handle, inode);
++              ext4_update_inode_fsync_trans(handle, inode, 1);
+               ret2 = ext4_journal_stop(handle);
+               if (ret2)
+                       break;
diff --git a/queue-4.9/nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch b/queue-4.9/nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch
new file mode 100644 (file)
index 0000000..607c997
--- /dev/null
@@ -0,0 +1,66 @@
+From dc4fd9ab01ab379ae5af522b3efd4187a7c30a31 Mon Sep 17 00:00:00 2001
+From: Scott Mayhew <smayhew@redhat.com>
+Date: Fri, 8 Dec 2017 16:00:12 -0500
+Subject: nfs: don't wait on commit in nfs_commit_inode() if there were no commit requests
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+commit dc4fd9ab01ab379ae5af522b3efd4187a7c30a31 upstream.
+
+If there were no commit requests, then nfs_commit_inode() should not
+wait on the commit or mark the inode dirty, otherwise the following
+BUG_ON can be triggered:
+
+[ 1917.130762] kernel BUG at fs/inode.c:578!
+[ 1917.130766] Oops: Exception in kernel mode, sig: 5 [#1]
+[ 1917.130768] SMP NR_CPUS=2048 NUMA pSeries
+[ 1917.130772] Modules linked in: iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi blocklayoutdriver rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache sunrpc sg nx_crypto pseries_rng ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic crct10dif_common ibmvscsi scsi_transport_srp ibmveth scsi_tgt dm_mirror dm_region_hash dm_log dm_mod
+[ 1917.130805] CPU: 2 PID: 14923 Comm: umount.nfs4 Tainted: G               ------------ T 3.10.0-768.el7.ppc64 #1
+[ 1917.130810] task: c0000005ecd88040 ti: c00000004cea0000 task.ti: c00000004cea0000
+[ 1917.130813] NIP: c000000000354178 LR: c000000000354160 CTR: c00000000012db80
+[ 1917.130816] REGS: c00000004cea3720 TRAP: 0700   Tainted: G               ------------ T  (3.10.0-768.el7.ppc64)
+[ 1917.130820] MSR: 8000000100029032 <SF,EE,ME,IR,DR,RI>  CR: 22002822  XER: 20000000
+[ 1917.130828] CFAR: c00000000011f594 SOFTE: 1
+GPR00: c000000000354160 c00000004cea39a0 c0000000014c4700 c0000000018cc750
+GPR04: 000000000000c750 80c0000000000000 0600000000000000 04eeb76bea749a03
+GPR08: 0000000000000034 c0000000018cc758 0000000000000001 d000000005e619e8
+GPR12: c00000000012db80 c000000007b31200 0000000000000000 0000000000000000
+GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
+GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
+GPR24: 0000000000000000 c000000000dfc3ec 0000000000000000 c0000005eefc02c0
+GPR28: d0000000079dbd50 c0000005b94a02c0 c0000005b94a0250 c0000005b94a01c8
+[ 1917.130867] NIP [c000000000354178] .evict+0x1c8/0x350
+[ 1917.130871] LR [c000000000354160] .evict+0x1b0/0x350
+[ 1917.130873] Call Trace:
+[ 1917.130876] [c00000004cea39a0] [c000000000354160] .evict+0x1b0/0x350 (unreliable)
+[ 1917.130880] [c00000004cea3a30] [c0000000003558cc] .evict_inodes+0x13c/0x270
+[ 1917.130884] [c00000004cea3af0] [c000000000327d20] .kill_anon_super+0x70/0x1e0
+[ 1917.130896] [c00000004cea3b80] [d000000005e43e30] .nfs_kill_super+0x20/0x60 [nfs]
+[ 1917.130900] [c00000004cea3c00] [c000000000328a20] .deactivate_locked_super+0xa0/0x1b0
+[ 1917.130903] [c00000004cea3c80] [c00000000035ba54] .cleanup_mnt+0xd4/0x180
+[ 1917.130907] [c00000004cea3d10] [c000000000119034] .task_work_run+0x114/0x150
+[ 1917.130912] [c00000004cea3db0] [c00000000001ba6c] .do_notify_resume+0xcc/0x100
+[ 1917.130916] [c00000004cea3e30] [c00000000000a7b0] .ret_from_except_lite+0x5c/0x60
+[ 1917.130919] Instruction dump:
+[ 1917.130921] 7fc3f378 486734b5 60000000 387f00a0 38800003 4bdcb365 60000000 e95f00a0
+[ 1917.130927] 694a0060 7d4a0074 794ad182 694a0001 <0b0a0000> 892d02a4 2f890000 40de0134
+
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/write.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1859,6 +1859,8 @@ int nfs_commit_inode(struct inode *inode
+       if (res)
+               error = nfs_generic_commit_list(inode, &head, how, &cinfo);
+       nfs_commit_end(cinfo.mds);
++      if (res == 0)
++              return res;
+       if (error < 0)
+               goto out_error;
+       if (!may_wait)
diff --git a/queue-4.9/sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch b/queue-4.9/sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch
new file mode 100644 (file)
index 0000000..a1413a2
--- /dev/null
@@ -0,0 +1,82 @@
+From f73c52a5bcd1710994e53fbccc378c42b97a06b6 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Sat, 2 Dec 2017 13:04:54 -0500
+Subject: sched/rt: Do not pull from current CPU if only one CPU to pull
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit f73c52a5bcd1710994e53fbccc378c42b97a06b6 upstream.
+
+Daniel Wagner reported a crash on the BeagleBone Black SoC.
+
+This is a single CPU architecture, and does not have a functional
+arch_send_call_function_single_ipi() implementation which can crash
+the kernel if that is called.
+
+As it only has one CPU, it shouldn't be called, but if the kernel is
+compiled for SMP, the push/pull RT scheduling logic now calls it for
+irq_work if the one CPU is overloaded, it can use that function to call
+itself and crash the kernel.
+
+Ideally, we should disable the SCHED_FEAT(RT_PUSH_IPI) if the system
+only has a single CPU. But SCHED_FEAT is a constant if sched debugging
+is turned off. Another fix can also be used, and this should also help
+with normal SMP machines. That is, do not initiate the pull code if
+there's only one RT overloaded CPU, and that CPU happens to be the
+current CPU that is scheduling in a lower priority task.
+
+Even on a system with many CPUs, if there's many RT tasks waiting to
+run on a single CPU, and that CPU schedules in another RT task of lower
+priority, it will initiate the PULL logic in case there's a higher
+priority RT task on another CPU that is waiting to run. But if there is
+no other CPU with waiting RT tasks, it will initiate the RT pull logic
+on itself (as it still has RT tasks waiting to run). This is a wasted
+effort.
+
+Not only does this help with SMP code where the current CPU is the only
+one with RT overloaded tasks, it should also solve the issue that
+Daniel encountered, because it will prevent the PULL logic from
+executing, as there's only one CPU on the system, and the check added
+here will cause it to exit the RT pull code.
+
+Reported-by: Daniel Wagner <wagi@monom.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-rt-users <linux-rt-users@vger.kernel.org>
+Fixes: 4bdced5c9 ("sched/rt: Simplify the IPI based RT balancing logic")
+Link: http://lkml.kernel.org/r/20171202130454.4cbbfe8d@vmware.local.home
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/rt.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -2022,8 +2022,9 @@ static void pull_rt_task(struct rq *this
+       bool resched = false;
+       struct task_struct *p;
+       struct rq *src_rq;
++      int rt_overload_count = rt_overloaded(this_rq);
+-      if (likely(!rt_overloaded(this_rq)))
++      if (likely(!rt_overload_count))
+               return;
+       /*
+@@ -2032,6 +2033,11 @@ static void pull_rt_task(struct rq *this
+        */
+       smp_rmb();
++      /* If we are the only overloaded CPU do nothing */
++      if (rt_overload_count == 1 &&
++          cpumask_test_cpu(this_rq->cpu, this_rq->rd->rto_mask))
++              return;
++
+ #ifdef HAVE_RT_PUSH_IPI
+       if (sched_feat(RT_PUSH_IPI)) {
+               tell_cpu_to_push(this_rq);
index fd9bd8ec5b5210d61e48d401dce905f41761f1c5..6295f860144d06bc22146ebbdc849323d146acc1 100644 (file)
@@ -2,3 +2,20 @@ mfd-fsl-imx25-clean-up-irq-settings-during-removal.patch
 crypto-rsa-fix-buffer-overread-when-stripping-leading-zeroes.patch
 crypto-hmac-require-that-the-underlying-hash-algorithm-is-unkeyed.patch
 crypto-salsa20-fix-blkcipher_walk-api-usage.patch
+autofs-fix-careless-error-in-recent-commit.patch
+tracing-allocate-mask_str-buffer-dynamically.patch
+usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch
+usb-core-prevent-malicious-bnuminterfaces-overflow.patch
+usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch
+usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch
+usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch
+ceph-drop-negative-child-dentries-before-try-pruning-inode-s-alias.patch
+usb-xhci-fix-tds-for-mtk-xhci1.1.patch
+bluetooth-btusb-driver-to-enable-the-usb-wakeup-feature.patch
+xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch
+nfs-don-t-wait-on-commit-in-nfs_commit_inode-if-there-were-no-commit-requests.patch
+sched-rt-do-not-pull-from-current-cpu-if-only-one-cpu-to-pull.patch
+eeprom-at24-change-nvmem-stride-to-1.patch
+dmaengine-dmatest-move-callback-wait-queue-to-thread-context.patch
+ext4-fix-fdatasync-2-after-fallocate-2-operation.patch
+ext4-fix-crash-when-a-directory-s-i_size-is-too-small.patch
diff --git a/queue-4.9/tracing-allocate-mask_str-buffer-dynamically.patch b/queue-4.9/tracing-allocate-mask_str-buffer-dynamically.patch
new file mode 100644 (file)
index 0000000..bb1a148
--- /dev/null
@@ -0,0 +1,97 @@
+From 90e406f96f630c07d631a021fd4af10aac913e77 Mon Sep 17 00:00:00 2001
+From: Changbin Du <changbin.du@intel.com>
+Date: Thu, 30 Nov 2017 11:39:43 +0800
+Subject: tracing: Allocate mask_str buffer dynamically
+
+From: Changbin Du <changbin.du@intel.com>
+
+commit 90e406f96f630c07d631a021fd4af10aac913e77 upstream.
+
+The default NR_CPUS can be very large, but actual possible nr_cpu_ids
+usually is very small. For my x86 distribution, the NR_CPUS is 8192 and
+nr_cpu_ids is 4. About 2 pages are wasted.
+
+Most machines don't have so many CPUs, so define a array with NR_CPUS
+just wastes memory. So let's allocate the buffer dynamically when need.
+
+With this change, the mutext tracing_cpumask_update_lock also can be
+removed now, which was used to protect mask_str.
+
+Link: http://lkml.kernel.org/r/1512013183-19107-1-git-send-email-changbin.du@intel.com
+
+Fixes: 36dfe9252bd4c ("ftrace: make use of tracing_cpumask")
+Signed-off-by: Changbin Du <changbin.du@intel.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace.c |   29 +++++++++--------------------
+ 1 file changed, 9 insertions(+), 20 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -3727,37 +3727,30 @@ static const struct file_operations show
+       .llseek         = seq_lseek,
+ };
+-/*
+- * The tracer itself will not take this lock, but still we want
+- * to provide a consistent cpumask to user-space:
+- */
+-static DEFINE_MUTEX(tracing_cpumask_update_lock);
+-
+-/*
+- * Temporary storage for the character representation of the
+- * CPU bitmask (and one more byte for the newline):
+- */
+-static char mask_str[NR_CPUS + 1];
+-
+ static ssize_t
+ tracing_cpumask_read(struct file *filp, char __user *ubuf,
+                    size_t count, loff_t *ppos)
+ {
+       struct trace_array *tr = file_inode(filp)->i_private;
++      char *mask_str;
+       int len;
+-      mutex_lock(&tracing_cpumask_update_lock);
++      len = snprintf(NULL, 0, "%*pb\n",
++                     cpumask_pr_args(tr->tracing_cpumask)) + 1;
++      mask_str = kmalloc(len, GFP_KERNEL);
++      if (!mask_str)
++              return -ENOMEM;
+-      len = snprintf(mask_str, count, "%*pb\n",
++      len = snprintf(mask_str, len, "%*pb\n",
+                      cpumask_pr_args(tr->tracing_cpumask));
+       if (len >= count) {
+               count = -EINVAL;
+               goto out_err;
+       }
+-      count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1);
++      count = simple_read_from_buffer(ubuf, count, ppos, mask_str, len);
+ out_err:
+-      mutex_unlock(&tracing_cpumask_update_lock);
++      kfree(mask_str);
+       return count;
+ }
+@@ -3777,8 +3770,6 @@ tracing_cpumask_write(struct file *filp,
+       if (err)
+               goto err_unlock;
+-      mutex_lock(&tracing_cpumask_update_lock);
+-
+       local_irq_disable();
+       arch_spin_lock(&tr->max_lock);
+       for_each_tracing_cpu(cpu) {
+@@ -3801,8 +3792,6 @@ tracing_cpumask_write(struct file *filp,
+       local_irq_enable();
+       cpumask_copy(tr->tracing_cpumask, tracing_cpumask_new);
+-
+-      mutex_unlock(&tracing_cpumask_update_lock);
+       free_cpumask_var(tracing_cpumask_new);
+       return count;
diff --git a/queue-4.9/usb-core-prevent-malicious-bnuminterfaces-overflow.patch b/queue-4.9/usb-core-prevent-malicious-bnuminterfaces-overflow.patch
new file mode 100644 (file)
index 0000000..6797f2e
--- /dev/null
@@ -0,0 +1,47 @@
+From 48a4ff1c7bb5a32d2e396b03132d20d552c0eca7 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 12 Dec 2017 14:25:13 -0500
+Subject: USB: core: prevent malicious bNumInterfaces overflow
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 48a4ff1c7bb5a32d2e396b03132d20d552c0eca7 upstream.
+
+A malicious USB device with crafted descriptors can cause the kernel
+to access unallocated memory by setting the bNumInterfaces value too
+high in a configuration descriptor.  Although the value is adjusted
+during parsing, this adjustment is skipped in one of the error return
+paths.
+
+This patch prevents the problem by setting bNumInterfaces to 0
+initially.  The existing code already sets it to the proper value
+after parsing is complete.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -550,6 +550,9 @@ static int usb_parse_configuration(struc
+       unsigned iad_num = 0;
+       memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
++      nintf = nintf_orig = config->desc.bNumInterfaces;
++      config->desc.bNumInterfaces = 0;        // Adjusted later
++
+       if (config->desc.bDescriptorType != USB_DT_CONFIG ||
+           config->desc.bLength < USB_DT_CONFIG_SIZE ||
+           config->desc.bLength > size) {
+@@ -563,7 +566,6 @@ static int usb_parse_configuration(struc
+       buffer += config->desc.bLength;
+       size -= config->desc.bLength;
+-      nintf = nintf_orig = config->desc.bNumInterfaces;
+       if (nintf > USB_MAXINTERFACES) {
+               dev_warn(ddev, "config %d has too many interfaces: %d, "
+                   "using maximum allowed: %d\n",
diff --git a/queue-4.9/usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch b/queue-4.9/usb-uas-and-storage-add-us_fl_broken_fua-for-another-jmicron-jms567-id.patch
new file mode 100644 (file)
index 0000000..2a07024
--- /dev/null
@@ -0,0 +1,65 @@
+From 62354454625741f0569c2cbe45b2d192f8fd258e Mon Sep 17 00:00:00 2001
+From: David Kozub <zub@linux.fjfi.cvut.cz>
+Date: Tue, 5 Dec 2017 22:40:04 +0100
+Subject: USB: uas and storage: Add US_FL_BROKEN_FUA for another JMicron JMS567 ID
+
+From: David Kozub <zub@linux.fjfi.cvut.cz>
+
+commit 62354454625741f0569c2cbe45b2d192f8fd258e upstream.
+
+There is another JMS567-based USB3 UAS enclosure (152d:0578) that fails
+with the following error:
+
+[sda] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
+[sda] tag#0 Sense Key : Illegal Request [current]
+[sda] tag#0 Add. Sense: Invalid field in cdb
+
+The issue occurs both with UAS (occasionally) and mass storage
+(immediately after mounting a FS on a disk in the enclosure).
+
+Enabling US_FL_BROKEN_FUA quirk solves this issue.
+
+This patch adds an UNUSUAL_DEV with US_FL_BROKEN_FUA for the enclosure
+for both UAS and mass storage.
+
+Signed-off-by: David Kozub <zub@linux.fjfi.cvut.cz>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/unusual_devs.h |    7 +++++++
+ drivers/usb/storage/unusual_uas.h  |    7 +++++++
+ 2 files changed, 14 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -2113,6 +2113,13 @@ UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BROKEN_FUA ),
++/* Reported by David Kozub <zub@linux.fjfi.cvut.cz> */
++UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
++              "JMicron",
++              "JMS567",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_BROKEN_FUA),
++
+ /*
+  * Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+  * JMicron responds to USN and several other SCSI ioctls with a
+--- a/drivers/usb/storage/unusual_uas.h
++++ b/drivers/usb/storage/unusual_uas.h
+@@ -142,6 +142,13 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x99
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),
++/* Reported-by: David Kozub <zub@linux.fjfi.cvut.cz> */
++UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
++              "JMicron",
++              "JMS567",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_BROKEN_FUA),
++
+ /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
+ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
+               "VIA",
diff --git a/queue-4.9/usb-xhci-fix-tds-for-mtk-xhci1.1.patch b/queue-4.9/usb-xhci-fix-tds-for-mtk-xhci1.1.patch
new file mode 100644 (file)
index 0000000..abaefbb
--- /dev/null
@@ -0,0 +1,47 @@
+From 72b663a99c074a8d073e7ecdae446cfb024ef551 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 8 Dec 2017 18:10:06 +0200
+Subject: usb: xhci: fix TDS for MTK xHCI1.1
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+commit 72b663a99c074a8d073e7ecdae446cfb024ef551 upstream.
+
+For MTK's xHCI 1.0 or latter, TD size is the number of max
+packet sized packets remaining in the TD, not including
+this TRB (following spec).
+
+For MTK's xHCI 0.96 and older, TD size is the number of max
+packet sized packets remaining in the TD, including this TRB
+(not following spec).
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3132,7 +3132,7 @@ static u32 xhci_td_remainder(struct xhci
+ {
+       u32 maxp, total_packet_count;
+-      /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */
++      /* MTK xHCI 0.96 contains some features from 1.0 */
+       if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST))
+               return ((td_total_len - transferred) >> 10);
+@@ -3141,8 +3141,8 @@ static u32 xhci_td_remainder(struct xhci
+           trb_buff_len == td_total_len)
+               return 0;
+-      /* for MTK xHCI, TD size doesn't include this TRB */
+-      if (xhci->quirks & XHCI_MTK_HOST)
++      /* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */
++      if ((xhci->quirks & XHCI_MTK_HOST) && (xhci->hci_version < 0x100))
+               trb_buff_len = 0;
+       maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
diff --git a/queue-4.9/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch b/queue-4.9/usbip-fix-stub_rx-get_pipe-to-validate-endpoint-number.patch
new file mode 100644 (file)
index 0000000..ae59a2f
--- /dev/null
@@ -0,0 +1,71 @@
+From 635f545a7e8be7596b9b2b6a43cab6bbd5a88e43 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <shuahkh@osg.samsung.com>
+Date: Thu, 7 Dec 2017 14:16:47 -0700
+Subject: usbip: fix stub_rx: get_pipe() to validate endpoint number
+
+From: Shuah Khan <shuahkh@osg.samsung.com>
+
+commit 635f545a7e8be7596b9b2b6a43cab6bbd5a88e43 upstream.
+
+get_pipe() routine doesn't validate the input endpoint number
+and uses to reference ep_in and ep_out arrays. Invalid endpoint
+number can trigger BUG(). Range check the epnum and returning
+error instead of calling BUG().
+
+Change caller stub_recv_cmd_submit() to handle the get_pipe()
+error return.
+
+Reported-by: Secunia Research <vuln@secunia.com>
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_rx.c |   18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/usbip/stub_rx.c
++++ b/drivers/usb/usbip/stub_rx.c
+@@ -342,15 +342,15 @@ static int get_pipe(struct stub_device *
+       struct usb_host_endpoint *ep;
+       struct usb_endpoint_descriptor *epd = NULL;
++      if (epnum < 0 || epnum > 15)
++              goto err_ret;
++
+       if (dir == USBIP_DIR_IN)
+               ep = udev->ep_in[epnum & 0x7f];
+       else
+               ep = udev->ep_out[epnum & 0x7f];
+-      if (!ep) {
+-              dev_err(&sdev->udev->dev, "no such endpoint?, %d\n",
+-                      epnum);
+-              BUG();
+-      }
++      if (!ep)
++              goto err_ret;
+       epd = &ep->desc;
+       if (usb_endpoint_xfer_control(epd)) {
+@@ -381,9 +381,10 @@ static int get_pipe(struct stub_device *
+                       return usb_rcvisocpipe(udev, epnum);
+       }
++err_ret:
+       /* NOT REACHED */
+-      dev_err(&sdev->udev->dev, "get pipe, epnum %d\n", epnum);
+-      return 0;
++      dev_err(&sdev->udev->dev, "get pipe() invalid epnum %d\n", epnum);
++      return -1;
+ }
+ static void masking_bogus_flags(struct urb *urb)
+@@ -449,6 +450,9 @@ static void stub_recv_cmd_submit(struct
+       struct usb_device *udev = sdev->udev;
+       int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
++      if (pipe == -1)
++              return;
++
+       priv = stub_priv_alloc(sdev, pdu);
+       if (!priv)
+               return;
diff --git a/queue-4.9/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch b/queue-4.9/usbip-fix-stub_rx-harden-cmd_submit-path-to-handle-malicious-input.patch
new file mode 100644 (file)
index 0000000..e0c7cb9
--- /dev/null
@@ -0,0 +1,106 @@
+From c6688ef9f29762e65bce325ef4acd6c675806366 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <shuahkh@osg.samsung.com>
+Date: Thu, 7 Dec 2017 14:16:48 -0700
+Subject: usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input
+
+From: Shuah Khan <shuahkh@osg.samsung.com>
+
+commit c6688ef9f29762e65bce325ef4acd6c675806366 upstream.
+
+Harden CMD_SUBMIT path to handle malicious input that could trigger
+large memory allocations. Add checks to validate transfer_buffer_length
+and number_of_packets to protect against bad input requesting for
+unbounded memory allocations. Validate early in get_pipe() and return
+failure.
+
+Reported-by: Secunia Research <vuln@secunia.com>
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_rx.c |   35 +++++++++++++++++++++++++++++++----
+ 1 file changed, 31 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/usbip/stub_rx.c
++++ b/drivers/usb/usbip/stub_rx.c
+@@ -336,11 +336,13 @@ static struct stub_priv *stub_priv_alloc
+       return priv;
+ }
+-static int get_pipe(struct stub_device *sdev, int epnum, int dir)
++static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu)
+ {
+       struct usb_device *udev = sdev->udev;
+       struct usb_host_endpoint *ep;
+       struct usb_endpoint_descriptor *epd = NULL;
++      int epnum = pdu->base.ep;
++      int dir = pdu->base.direction;
+       if (epnum < 0 || epnum > 15)
+               goto err_ret;
+@@ -353,6 +355,15 @@ static int get_pipe(struct stub_device *
+               goto err_ret;
+       epd = &ep->desc;
++
++      /* validate transfer_buffer_length */
++      if (pdu->u.cmd_submit.transfer_buffer_length > INT_MAX) {
++              dev_err(&sdev->udev->dev,
++                      "CMD_SUBMIT: -EMSGSIZE transfer_buffer_length %d\n",
++                      pdu->u.cmd_submit.transfer_buffer_length);
++              return -1;
++      }
++
+       if (usb_endpoint_xfer_control(epd)) {
+               if (dir == USBIP_DIR_OUT)
+                       return usb_sndctrlpipe(udev, epnum);
+@@ -375,6 +386,21 @@ static int get_pipe(struct stub_device *
+       }
+       if (usb_endpoint_xfer_isoc(epd)) {
++              /* validate packet size and number of packets */
++              unsigned int maxp, packets, bytes;
++
++              maxp = usb_endpoint_maxp(epd);
++              maxp *= usb_endpoint_maxp_mult(epd);
++              bytes = pdu->u.cmd_submit.transfer_buffer_length;
++              packets = DIV_ROUND_UP(bytes, maxp);
++
++              if (pdu->u.cmd_submit.number_of_packets < 0 ||
++                  pdu->u.cmd_submit.number_of_packets > packets) {
++                      dev_err(&sdev->udev->dev,
++                              "CMD_SUBMIT: isoc invalid num packets %d\n",
++                              pdu->u.cmd_submit.number_of_packets);
++                      return -1;
++              }
+               if (dir == USBIP_DIR_OUT)
+                       return usb_sndisocpipe(udev, epnum);
+               else
+@@ -383,7 +409,7 @@ static int get_pipe(struct stub_device *
+ err_ret:
+       /* NOT REACHED */
+-      dev_err(&sdev->udev->dev, "get pipe() invalid epnum %d\n", epnum);
++      dev_err(&sdev->udev->dev, "CMD_SUBMIT: invalid epnum %d\n", epnum);
+       return -1;
+ }
+@@ -448,7 +474,7 @@ static void stub_recv_cmd_submit(struct
+       struct stub_priv *priv;
+       struct usbip_device *ud = &sdev->ud;
+       struct usb_device *udev = sdev->udev;
+-      int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
++      int pipe = get_pipe(sdev, pdu);
+       if (pipe == -1)
+               return;
+@@ -470,7 +496,8 @@ static void stub_recv_cmd_submit(struct
+       }
+       /* allocate urb transfer buffer, if needed */
+-      if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
++      if (pdu->u.cmd_submit.transfer_buffer_length > 0 &&
++          pdu->u.cmd_submit.transfer_buffer_length <= INT_MAX) {
+               priv->urb->transfer_buffer =
+                       kzalloc(pdu->u.cmd_submit.transfer_buffer_length,
+                               GFP_KERNEL);
diff --git a/queue-4.9/usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch b/queue-4.9/usbip-fix-stub_send_ret_submit-vulnerability-to-null-transfer_buffer.patch
new file mode 100644 (file)
index 0000000..9a2c705
--- /dev/null
@@ -0,0 +1,38 @@
+From be6123df1ea8f01ee2f896a16c2b7be3e4557a5a Mon Sep 17 00:00:00 2001
+From: Shuah Khan <shuahkh@osg.samsung.com>
+Date: Thu, 7 Dec 2017 14:16:50 -0700
+Subject: usbip: fix stub_send_ret_submit() vulnerability to null transfer_buffer
+
+From: Shuah Khan <shuahkh@osg.samsung.com>
+
+commit be6123df1ea8f01ee2f896a16c2b7be3e4557a5a upstream.
+
+stub_send_ret_submit() handles urb with a potential null transfer_buffer,
+when it replays a packet with potential malicious data that could contain
+a null buffer. Add a check for the condition when actual_length > 0 and
+transfer_buffer is null.
+
+Reported-by: Secunia Research <vuln@secunia.com>
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_tx.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/usbip/stub_tx.c
++++ b/drivers/usb/usbip/stub_tx.c
+@@ -181,6 +181,13 @@ static int stub_send_ret_submit(struct s
+               memset(&pdu_header, 0, sizeof(pdu_header));
+               memset(&msg, 0, sizeof(msg));
++              if (urb->actual_length > 0 && !urb->transfer_buffer) {
++                      dev_err(&sdev->udev->dev,
++                              "urb: actual_length %d transfer_buffer null\n",
++                              urb->actual_length);
++                      return -1;
++              }
++
+               if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
+                       iovnum = 2 + urb->number_of_packets;
+               else
diff --git a/queue-4.9/xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch b/queue-4.9/xhci-don-t-add-a-virt_dev-to-the-devs-array-before-it-s-fully-allocated.patch
new file mode 100644 (file)
index 0000000..1c00958
--- /dev/null
@@ -0,0 +1,62 @@
+From 5d9b70f7d52eb14bb37861c663bae44de9521c35 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 8 Dec 2017 18:10:05 +0200
+Subject: xhci: Don't add a virt_dev to the devs array before it's fully allocated
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 5d9b70f7d52eb14bb37861c663bae44de9521c35 upstream.
+
+Avoid null pointer dereference if some function is walking through the
+devs array accessing members of a new virt_dev that is mid allocation.
+
+Add the virt_dev to xhci->devs[i] _after_ the virt_device and all its
+members are properly allocated.
+
+issue found by KASAN: null-ptr-deref in xhci_find_slot_id_by_port
+
+"Quick analysis suggests that xhci_alloc_virt_device() is not mutex
+protected. If so, there is a time frame where xhci->devs[slot_id] is set
+but not fully initialized. Specifically, xhci->devs[i]->udev can be NULL."
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1032,10 +1032,9 @@ int xhci_alloc_virt_device(struct xhci_h
+               return 0;
+       }
+-      xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags);
+-      if (!xhci->devs[slot_id])
++      dev = kzalloc(sizeof(*dev), flags);
++      if (!dev)
+               return 0;
+-      dev = xhci->devs[slot_id];
+       /* Allocate the (output) device context that will be used in the HC. */
+       dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags);
+@@ -1083,9 +1082,17 @@ int xhci_alloc_virt_device(struct xhci_h
+                &xhci->dcbaa->dev_context_ptrs[slot_id],
+                le64_to_cpu(xhci->dcbaa->dev_context_ptrs[slot_id]));
++      xhci->devs[slot_id] = dev;
++
+       return 1;
+ fail:
+-      xhci_free_virt_device(xhci, slot_id);
++
++      if (dev->in_ctx)
++              xhci_free_container_ctx(xhci, dev->in_ctx);
++      if (dev->out_ctx)
++              xhci_free_container_ctx(xhci, dev->out_ctx);
++      kfree(dev);
++
+       return 0;
+ }