]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 16:07:04 +0000 (18:07 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 16:07:04 +0000 (18:07 +0200)
added patches:
dm-btree-fix-for-dm_btree_find_lowest_key.patch
dm-bufio-avoid-a-possible-abba-deadlock.patch
dm-space-map-disk-fix-some-book-keeping-in-the-disk-space-map.patch
dm-thin-metadata-call-precommit-before-saving-the-roots.patch
mwifiex-pcie-fix-cmd_buf-use-after-free-in-remove-reset.patch

queue-3.18/dm-btree-fix-for-dm_btree_find_lowest_key.patch [new file with mode: 0644]
queue-3.18/dm-bufio-avoid-a-possible-abba-deadlock.patch [new file with mode: 0644]
queue-3.18/dm-space-map-disk-fix-some-book-keeping-in-the-disk-space-map.patch [new file with mode: 0644]
queue-3.18/dm-thin-metadata-call-precommit-before-saving-the-roots.patch [new file with mode: 0644]
queue-3.18/mwifiex-pcie-fix-cmd_buf-use-after-free-in-remove-reset.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/dm-btree-fix-for-dm_btree_find_lowest_key.patch b/queue-3.18/dm-btree-fix-for-dm_btree_find_lowest_key.patch
new file mode 100644 (file)
index 0000000..ee37eb2
--- /dev/null
@@ -0,0 +1,46 @@
+From 7d1fedb6e96a960aa91e4ff70714c3fb09195a5a Mon Sep 17 00:00:00 2001
+From: Vinothkumar Raja <vinraja@cs.stonybrook.edu>
+Date: Thu, 6 Apr 2017 22:09:38 -0400
+Subject: dm btree: fix for dm_btree_find_lowest_key()
+
+From: Vinothkumar Raja <vinraja@cs.stonybrook.edu>
+
+commit 7d1fedb6e96a960aa91e4ff70714c3fb09195a5a upstream.
+
+dm_btree_find_lowest_key() is giving incorrect results.  find_key()
+traverses the btree correctly for finding the highest key, but there is
+an error in the way it traverses the btree for retrieving the lowest
+key.  dm_btree_find_lowest_key() fetches the first key of the rightmost
+block of the btree instead of fetching the first key from the leftmost
+block.
+
+Fix this by conditionally passing the correct parameter to value64()
+based on the @find_highest flag.
+
+Signed-off-by: Erez Zadok <ezk@fsl.cs.sunysb.edu>
+Signed-off-by: Vinothkumar Raja <vinraja@cs.stonybrook.edu>
+Signed-off-by: Nidhi Panpalia <npanpalia@cs.stonybrook.edu>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/persistent-data/dm-btree.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/persistent-data/dm-btree.c
++++ b/drivers/md/persistent-data/dm-btree.c
+@@ -788,8 +788,12 @@ static int find_key(struct ro_spine *s,
+               else
+                       *result_key = le64_to_cpu(ro_node(s)->keys[0]);
+-              if (next_block || flags & INTERNAL_NODE)
+-                      block = value64(ro_node(s), i);
++              if (next_block || flags & INTERNAL_NODE) {
++                      if (find_highest)
++                              block = value64(ro_node(s), i);
++                      else
++                              block = value64(ro_node(s), 0);
++              }
+       } while (flags & INTERNAL_NODE);
diff --git a/queue-3.18/dm-bufio-avoid-a-possible-abba-deadlock.patch b/queue-3.18/dm-bufio-avoid-a-possible-abba-deadlock.patch
new file mode 100644 (file)
index 0000000..db52f96
--- /dev/null
@@ -0,0 +1,50 @@
+From 1b0fb5a5b2dc0dddcfa575060441a7176ba7ac37 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Sun, 30 Apr 2017 17:33:26 -0400
+Subject: dm bufio: avoid a possible ABBA deadlock
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 1b0fb5a5b2dc0dddcfa575060441a7176ba7ac37 upstream.
+
+__get_memory_limit() tests if dm_bufio_cache_size changed and calls
+__cache_size_refresh() if it did.  It takes dm_bufio_clients_lock while
+it already holds the client lock.  However, lock ordering is violated
+because in cleanup_old_buffers() dm_bufio_clients_lock is taken before
+the client lock.
+
+This results in a possible deadlock and lockdep engine warning.
+
+Fix this deadlock by changing mutex_lock() to mutex_trylock().  If the
+lock can't be taken, it will be re-checked next time when a new buffer
+is allocated.
+
+Also add "unlikely" to the if condition, so that the optimizer assumes
+that the condition is false.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-bufio.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -862,10 +862,11 @@ static void __get_memory_limit(struct dm
+ {
+       unsigned long buffers;
+-      if (ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch) {
+-              mutex_lock(&dm_bufio_clients_lock);
+-              __cache_size_refresh();
+-              mutex_unlock(&dm_bufio_clients_lock);
++      if (unlikely(ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch)) {
++              if (mutex_trylock(&dm_bufio_clients_lock)) {
++                      __cache_size_refresh();
++                      mutex_unlock(&dm_bufio_clients_lock);
++              }
+       }
+       buffers = dm_bufio_cache_size_per_client >>
diff --git a/queue-3.18/dm-space-map-disk-fix-some-book-keeping-in-the-disk-space-map.patch b/queue-3.18/dm-space-map-disk-fix-some-book-keeping-in-the-disk-space-map.patch
new file mode 100644 (file)
index 0000000..a01da19
--- /dev/null
@@ -0,0 +1,47 @@
+From 0377a07c7a035e0d033cd8b29f0cb15244c0916a Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Mon, 15 May 2017 09:45:40 -0400
+Subject: dm space map disk: fix some book keeping in the disk space map
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit 0377a07c7a035e0d033cd8b29f0cb15244c0916a upstream.
+
+When decrementing the reference count for a block, the free count wasn't
+being updated if the reference count went to zero.
+
+Signed-off-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/persistent-data/dm-space-map-disk.c |   15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/persistent-data/dm-space-map-disk.c
++++ b/drivers/md/persistent-data/dm-space-map-disk.c
+@@ -140,10 +140,23 @@ static int sm_disk_inc_block(struct dm_s
+ static int sm_disk_dec_block(struct dm_space_map *sm, dm_block_t b)
+ {
++      int r;
++      uint32_t old_count;
+       enum allocation_event ev;
+       struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
+-      return sm_ll_dec(&smd->ll, b, &ev);
++      r = sm_ll_dec(&smd->ll, b, &ev);
++      if (!r && (ev == SM_FREE)) {
++              /*
++               * It's only free if it's also free in the last
++               * transaction.
++               */
++              r = sm_ll_lookup(&smd->old_ll, b, &old_count);
++              if (!r && !old_count)
++                      smd->nr_allocated_this_transaction--;
++      }
++
++      return r;
+ }
+ static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
diff --git a/queue-3.18/dm-thin-metadata-call-precommit-before-saving-the-roots.patch b/queue-3.18/dm-thin-metadata-call-precommit-before-saving-the-roots.patch
new file mode 100644 (file)
index 0000000..32f1c0b
--- /dev/null
@@ -0,0 +1,35 @@
+From 91bcdb92d39711d1adb40c26b653b7978d93eb98 Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Mon, 15 May 2017 09:43:05 -0400
+Subject: dm thin metadata: call precommit before saving the roots
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit 91bcdb92d39711d1adb40c26b653b7978d93eb98 upstream.
+
+These calls were the wrong way round in __write_initial_superblock.
+
+Signed-off-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-thin-metadata.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/dm-thin-metadata.c
++++ b/drivers/md/dm-thin-metadata.c
+@@ -484,11 +484,11 @@ static int __write_initial_superblock(st
+       if (r < 0)
+               return r;
+-      r = save_sm_roots(pmd);
++      r = dm_tm_pre_commit(pmd->tm);
+       if (r < 0)
+               return r;
+-      r = dm_tm_pre_commit(pmd->tm);
++      r = save_sm_roots(pmd);
+       if (r < 0)
+               return r;
diff --git a/queue-3.18/mwifiex-pcie-fix-cmd_buf-use-after-free-in-remove-reset.patch b/queue-3.18/mwifiex-pcie-fix-cmd_buf-use-after-free-in-remove-reset.patch
new file mode 100644 (file)
index 0000000..8f4312d
--- /dev/null
@@ -0,0 +1,144 @@
+From 3c8cb9ad032d737b874e402c59eb51e3c991a144 Mon Sep 17 00:00:00 2001
+From: Brian Norris <briannorris@chromium.org>
+Date: Fri, 14 Apr 2017 14:51:17 -0700
+Subject: mwifiex: pcie: fix cmd_buf use-after-free in remove/reset
+
+From: Brian Norris <briannorris@chromium.org>
+
+commit 3c8cb9ad032d737b874e402c59eb51e3c991a144 upstream.
+
+Command buffers (skb's) are allocated by the main driver, and freed upon
+the last use. That last use is often in mwifiex_free_cmd_buffer(). In
+the meantime, if the command buffer gets used by the PCI driver, we map
+it as DMA-able, and store the mapping information in the 'cb' memory.
+
+However, if a command was in-flight when resetting the device (and
+therefore was still mapped), we don't get a chance to unmap this memory
+until after the core has cleaned up its command handling.
+
+Let's keep a refcount within the PCI driver, so we ensure the memory
+only gets freed after we've finished unmapping it.
+
+Noticed by KASAN when forcing a reset via:
+
+  echo 1 > /sys/bus/pci/.../reset
+
+The same code path can presumably be exercised in remove() and
+shutdown().
+
+[  205.390377] mwifiex_pcie 0000:01:00.0: info: shutdown mwifiex...
+[  205.400393] ==================================================================
+[  205.407719] BUG: KASAN: use-after-free in mwifiex_unmap_pci_memory.isra.14+0x4c/0x100 [mwifiex_pcie] at addr ffffffc0ad471b28
+[  205.419040] Read of size 16 by task bash/1913
+[  205.423421] =============================================================================
+[  205.431625] BUG skbuff_head_cache (Tainted: G    B          ): kasan: bad access detected
+[  205.439815] -----------------------------------------------------------------------------
+[  205.439815]
+[  205.449534] INFO: Allocated in __build_skb+0x48/0x114 age=1311 cpu=4 pid=1913
+[  205.456709]         alloc_debug_processing+0x124/0x178
+[  205.461282]         ___slab_alloc.constprop.58+0x528/0x608
+[  205.466196]         __slab_alloc.isra.54.constprop.57+0x44/0x54
+[  205.471542]         kmem_cache_alloc+0xcc/0x278
+[  205.475497]         __build_skb+0x48/0x114
+[  205.479019]         __netdev_alloc_skb+0xe0/0x170
+[  205.483244]         mwifiex_alloc_cmd_buffer+0x68/0xdc [mwifiex]
+[  205.488759]         mwifiex_init_fw+0x40/0x6cc [mwifiex]
+[  205.493584]         _mwifiex_fw_dpc+0x158/0x520 [mwifiex]
+[  205.498491]         mwifiex_reinit_sw+0x2c4/0x398 [mwifiex]
+[  205.503510]         mwifiex_pcie_reset_notify+0x114/0x15c [mwifiex_pcie]
+[  205.509643]         pci_reset_notify+0x5c/0x6c
+[  205.513519]         pci_reset_function+0x6c/0x7c
+[  205.517567]         reset_store+0x68/0x98
+[  205.521003]         dev_attr_store+0x54/0x60
+[  205.524705]         sysfs_kf_write+0x9c/0xb0
+[  205.528413] INFO: Freed in __kfree_skb+0xb0/0xbc age=131 cpu=4 pid=1913
+[  205.535064]         free_debug_processing+0x264/0x370
+[  205.539550]         __slab_free+0x84/0x40c
+[  205.543075]         kmem_cache_free+0x1c8/0x2a0
+[  205.547030]         __kfree_skb+0xb0/0xbc
+[  205.550465]         consume_skb+0x164/0x178
+[  205.554079]         __dev_kfree_skb_any+0x58/0x64
+[  205.558304]         mwifiex_free_cmd_buffer+0xa0/0x158 [mwifiex]
+[  205.563817]         mwifiex_shutdown_drv+0x578/0x5c4 [mwifiex]
+[  205.569164]         mwifiex_shutdown_sw+0x178/0x310 [mwifiex]
+[  205.574353]         mwifiex_pcie_reset_notify+0xd4/0x15c [mwifiex_pcie]
+[  205.580398]         pci_reset_notify+0x5c/0x6c
+[  205.584274]         pci_dev_save_and_disable+0x24/0x6c
+[  205.588837]         pci_reset_function+0x30/0x7c
+[  205.592885]         reset_store+0x68/0x98
+[  205.596324]         dev_attr_store+0x54/0x60
+[  205.600017]         sysfs_kf_write+0x9c/0xb0
+...
+[  205.800488] Call trace:
+[  205.802980] [<ffffffc00020a69c>] dump_backtrace+0x0/0x190
+[  205.808415] [<ffffffc00020a96c>] show_stack+0x20/0x28
+[  205.813506] [<ffffffc0005d020c>] dump_stack+0xa4/0xcc
+[  205.818598] [<ffffffc0003be44c>] print_trailer+0x158/0x168
+[  205.824120] [<ffffffc0003be5f0>] object_err+0x4c/0x5c
+[  205.829210] [<ffffffc0003c45bc>] kasan_report+0x334/0x500
+[  205.834641] [<ffffffc0003c3994>] check_memory_region+0x20/0x14c
+[  205.840593] [<ffffffc0003c3b14>] __asan_loadN+0x14/0x1c
+[  205.845879] [<ffffffbffc46171c>] mwifiex_unmap_pci_memory.isra.14+0x4c/0x100 [mwifiex_pcie]
+[  205.854282] [<ffffffbffc461864>] mwifiex_pcie_delete_cmdrsp_buf+0x94/0xa8 [mwifiex_pcie]
+[  205.862421] [<ffffffbffc462028>] mwifiex_pcie_free_buffers+0x11c/0x158 [mwifiex_pcie]
+[  205.870302] [<ffffffbffc4620d4>] mwifiex_pcie_down_dev+0x70/0x80 [mwifiex_pcie]
+[  205.877736] [<ffffffbffc1397a8>] mwifiex_shutdown_sw+0x190/0x310 [mwifiex]
+[  205.884658] [<ffffffbffc4606b4>] mwifiex_pcie_reset_notify+0xd4/0x15c [mwifiex_pcie]
+[  205.892446] [<ffffffc000635f54>] pci_reset_notify+0x5c/0x6c
+[  205.898048] [<ffffffc00063a044>] pci_dev_save_and_disable+0x24/0x6c
+[  205.904350] [<ffffffc00063cf0c>] pci_reset_function+0x30/0x7c
+[  205.910134] [<ffffffc000641118>] reset_store+0x68/0x98
+[  205.915312] [<ffffffc000771588>] dev_attr_store+0x54/0x60
+[  205.920750] [<ffffffc00046f53c>] sysfs_kf_write+0x9c/0xb0
+[  205.926182] [<ffffffc00046dfb0>] kernfs_fop_write+0x184/0x1f8
+[  205.931963] [<ffffffc0003d64f4>] __vfs_write+0x6c/0x17c
+[  205.937221] [<ffffffc0003d7164>] vfs_write+0xf0/0x1c4
+[  205.942310] [<ffffffc0003d7da0>] SyS_write+0x78/0xd8
+[  205.947312] [<ffffffc000204634>] el0_svc_naked+0x24/0x28
+...
+[  205.998268] ==================================================================
+
+This bug has been around in different forms for a while. It was sort of
+noticed in commit 955ab095c51a ("mwifiex: Do not kfree cmd buf while
+unregistering PCIe"), but it just fixed the double-free, without
+acknowledging the potential for use-after-free.
+
+Fixes: fc3314609047 ("mwifiex: use pci_alloc/free_consistent APIs for PCIe")
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/mwifiex/pcie.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/net/wireless/mwifiex/pcie.c
++++ b/drivers/net/wireless/mwifiex/pcie.c
+@@ -930,6 +930,7 @@ static int mwifiex_pcie_delete_cmdrsp_bu
+       if (card && card->cmd_buf) {
+               mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
+                                        PCI_DMA_TODEVICE);
++              dev_kfree_skb_any(card->cmd_buf);
+       }
+       return 0;
+ }
+@@ -1485,6 +1486,11 @@ mwifiex_pcie_send_cmd(struct mwifiex_ada
+               return -1;
+       card->cmd_buf = skb;
++      /*
++       * Need to keep a reference, since core driver might free up this
++       * buffer before we've unmapped it.
++       */
++      skb_get(skb);
+       /* To send a command, the driver will:
+               1. Write the 64bit physical address of the data buffer to
+@@ -1581,6 +1587,7 @@ static int mwifiex_pcie_process_cmd_comp
+       if (card->cmd_buf) {
+               mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
+                                        PCI_DMA_TODEVICE);
++              dev_kfree_skb_any(card->cmd_buf);
+               card->cmd_buf = NULL;
+       }
index 2e1ebe42158656fcee9112355ef28c5b403090d6..53018ae117369f7ea8716d80bad5d5cadb009232 100644 (file)
@@ -2,3 +2,8 @@ usb-ene_usb6250-fix-dma-to-the-stack.patch
 watchdog-pcwd_usb-fix-null-deref-at-probe.patch
 char-lp-fix-possible-integer-overflow-in-lp_setup.patch
 usb-core-replace-p-with-pk.patch
+dm-btree-fix-for-dm_btree_find_lowest_key.patch
+dm-bufio-avoid-a-possible-abba-deadlock.patch
+dm-thin-metadata-call-precommit-before-saving-the-roots.patch
+dm-space-map-disk-fix-some-book-keeping-in-the-disk-space-map.patch
+mwifiex-pcie-fix-cmd_buf-use-after-free-in-remove-reset.patch