From: Sasha Levin Date: Mon, 23 Dec 2019 22:28:58 +0000 (-0500) Subject: fixes for 4.4 X-Git-Tag: v4.14.161~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ef04612d5abc0ecc30fea2a47aca0a3e759617a;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 4.4 Signed-off-by: Sasha Levin --- diff --git a/queue-4.4/btrfs-abort-transaction-after-failed-inode-updates-i.patch b/queue-4.4/btrfs-abort-transaction-after-failed-inode-updates-i.patch new file mode 100644 index 00000000000..c491962531c --- /dev/null +++ b/queue-4.4/btrfs-abort-transaction-after-failed-inode-updates-i.patch @@ -0,0 +1,51 @@ +From 31ee884506517c9d05790894a0b8c54ac3c35d49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Dec 2019 09:37:15 -0500 +Subject: btrfs: abort transaction after failed inode updates in create_subvol + +From: Josef Bacik + +[ Upstream commit c7e54b5102bf3614cadb9ca32d7be73bad6cecf0 ] + +We can just abort the transaction here, and in fact do that for every +other failure in this function except these two cases. + +CC: stable@vger.kernel.org # 4.4+ +Reviewed-by: Filipe Manana +Reviewed-by: Johannes Thumshirn +Signed-off-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ioctl.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 3379490ce54d..119b1c5c279b 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -594,12 +594,18 @@ static noinline int create_subvol(struct inode *dir, + + btrfs_i_size_write(dir, dir->i_size + namelen * 2); + ret = btrfs_update_inode(trans, root, dir); +- BUG_ON(ret); ++ if (ret) { ++ btrfs_abort_transaction(trans, root, ret); ++ goto fail; ++ } + + ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, + objectid, root->root_key.objectid, + btrfs_ino(dir), index, name, namelen); +- BUG_ON(ret); ++ if (ret) { ++ btrfs_abort_transaction(trans, root, ret); ++ goto fail; ++ } + + ret = btrfs_uuid_tree_add(trans, root->fs_info->uuid_root, + root_item.uuid, BTRFS_UUID_KEY_SUBVOL, +-- +2.20.1 + diff --git a/queue-4.4/btrfs-do-not-call-synchronize_srcu-in-inode_tree_del.patch b/queue-4.4/btrfs-do-not-call-synchronize_srcu-in-inode_tree_del.patch new file mode 100644 index 00000000000..eb5d07e278b --- /dev/null +++ b/queue-4.4/btrfs-do-not-call-synchronize_srcu-in-inode_tree_del.patch @@ -0,0 +1,61 @@ +From dd00229e57aeaef2174ca23b5946ae33b480e34c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Nov 2019 13:59:35 -0500 +Subject: btrfs: do not call synchronize_srcu() in inode_tree_del + +From: Josef Bacik + +[ Upstream commit f72ff01df9cf5db25c76674cac16605992d15467 ] + +Testing with the new fsstress uncovered a pretty nasty deadlock with +lookup and snapshot deletion. + +Process A +unlink + -> final iput + -> inode_tree_del + -> synchronize_srcu(subvol_srcu) + +Process B +btrfs_lookup <- srcu_read_lock() acquired here + -> btrfs_iget + -> find inode that has I_FREEING set + -> __wait_on_freeing_inode() + +We're holding the srcu_read_lock() while doing the iget in order to make +sure our fs root doesn't go away, and then we are waiting for the inode +to finish freeing. However because the free'ing process is doing a +synchronize_srcu() we deadlock. + +Fix this by dropping the synchronize_srcu() in inode_tree_del(). We +don't need people to stop accessing the fs root at this point, we're +only adding our empty root to the dead roots list. + +A larger much more invasive fix is forthcoming to address how we deal +with fs roots, but this fixes the immediate problem. + +Fixes: 76dda93c6ae2 ("Btrfs: add snapshot/subvolume destroy ioctl") +CC: stable@vger.kernel.org # 4.4+ +Signed-off-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 383717ccecc7..548e9cd1a337 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -5506,7 +5506,6 @@ static void inode_tree_del(struct inode *inode) + spin_unlock(&root->inode_lock); + + if (empty && btrfs_root_refs(&root->root_item) == 0) { +- synchronize_srcu(&root->fs_info->subvol_srcu); + spin_lock(&root->inode_lock); + empty = RB_EMPTY_ROOT(&root->inode_tree); + spin_unlock(&root->inode_lock); +-- +2.20.1 + diff --git a/queue-4.4/btrfs-fix-removal-logic-of-the-tree-mod-log-that-lea.patch b/queue-4.4/btrfs-fix-removal-logic-of-the-tree-mod-log-that-lea.patch new file mode 100644 index 00000000000..d1a595c4062 --- /dev/null +++ b/queue-4.4/btrfs-fix-removal-logic-of-the-tree-mod-log-that-lea.patch @@ -0,0 +1,117 @@ +From 4c834a5cb59744dbc261d27024645f519e04535f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Dec 2019 12:27:39 +0000 +Subject: Btrfs: fix removal logic of the tree mod log that leads to + use-after-free issues + +From: Filipe Manana + +[ Upstream commit 6609fee8897ac475378388238456c84298bff802 ] + +When a tree mod log user no longer needs to use the tree it calls +btrfs_put_tree_mod_seq() to remove itself from the list of users and +delete all no longer used elements of the tree's red black tree, which +should be all elements with a sequence number less then our equals to +the caller's sequence number. However the logic is broken because it +can delete and free elements from the red black tree that have a +sequence number greater then the caller's sequence number: + +1) At a point in time we have sequence numbers 1, 2, 3 and 4 in the + tree mod log; + +2) The task which got assigned the sequence number 1 calls + btrfs_put_tree_mod_seq(); + +3) Sequence number 1 is deleted from the list of sequence numbers; + +4) The current minimum sequence number is computed to be the sequence + number 2; + +5) A task using sequence number 2 is at tree_mod_log_rewind() and gets + a pointer to one of its elements from the red black tree through + a call to tree_mod_log_search(); + +6) The task with sequence number 1 iterates the red black tree of tree + modification elements and deletes (and frees) all elements with a + sequence number less then or equals to 2 (the computed minimum sequence + number) - it ends up only leaving elements with sequence numbers of 3 + and 4; + +7) The task with sequence number 2 now uses the pointer to its element, + already freed by the other task, at __tree_mod_log_rewind(), resulting + in a use-after-free issue. When CONFIG_DEBUG_PAGEALLOC=y it produces + a trace like the following: + + [16804.546854] general protection fault: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI + [16804.547451] CPU: 0 PID: 28257 Comm: pool Tainted: G W 5.4.0-rc8-btrfs-next-51 #1 + [16804.548059] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014 + [16804.548666] RIP: 0010:rb_next+0x16/0x50 + (...) + [16804.550581] RSP: 0018:ffffb948418ef9b0 EFLAGS: 00010202 + [16804.551227] RAX: 6b6b6b6b6b6b6b6b RBX: ffff90e0247f6600 RCX: 6b6b6b6b6b6b6b6b + [16804.551873] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff90e0247f6600 + [16804.552504] RBP: ffff90dffe0d4688 R08: 0000000000000001 R09: 0000000000000000 + [16804.553136] R10: ffff90dffa4a0040 R11: 0000000000000000 R12: 000000000000002e + [16804.553768] R13: ffff90e0247f6600 R14: 0000000000001663 R15: ffff90dff77862b8 + [16804.554399] FS: 00007f4b197ae700(0000) GS:ffff90e036a00000(0000) knlGS:0000000000000000 + [16804.555039] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [16804.555683] CR2: 00007f4b10022000 CR3: 00000002060e2004 CR4: 00000000003606f0 + [16804.556336] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + [16804.556968] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + [16804.557583] Call Trace: + [16804.558207] __tree_mod_log_rewind+0xbf/0x280 [btrfs] + [16804.558835] btrfs_search_old_slot+0x105/0xd00 [btrfs] + [16804.559468] resolve_indirect_refs+0x1eb/0xc70 [btrfs] + [16804.560087] ? free_extent_buffer.part.19+0x5a/0xc0 [btrfs] + [16804.560700] find_parent_nodes+0x388/0x1120 [btrfs] + [16804.561310] btrfs_check_shared+0x115/0x1c0 [btrfs] + [16804.561916] ? extent_fiemap+0x59d/0x6d0 [btrfs] + [16804.562518] extent_fiemap+0x59d/0x6d0 [btrfs] + [16804.563112] ? __might_fault+0x11/0x90 + [16804.563706] do_vfs_ioctl+0x45a/0x700 + [16804.564299] ksys_ioctl+0x70/0x80 + [16804.564885] ? trace_hardirqs_off_thunk+0x1a/0x20 + [16804.565461] __x64_sys_ioctl+0x16/0x20 + [16804.566020] do_syscall_64+0x5c/0x250 + [16804.566580] entry_SYSCALL_64_after_hwframe+0x49/0xbe + [16804.567153] RIP: 0033:0x7f4b1ba2add7 + (...) + [16804.568907] RSP: 002b:00007f4b197adc88 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 + [16804.569513] RAX: ffffffffffffffda RBX: 00007f4b100210d8 RCX: 00007f4b1ba2add7 + [16804.570133] RDX: 00007f4b100210d8 RSI: 00000000c020660b RDI: 0000000000000003 + [16804.570726] RBP: 000055de05a6cfe0 R08: 0000000000000000 R09: 00007f4b197add44 + [16804.571314] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f4b197add48 + [16804.571905] R13: 00007f4b197add40 R14: 00007f4b100210d0 R15: 00007f4b197add50 + (...) + [16804.575623] ---[ end trace 87317359aad4ba50 ]--- + +Fix this by making btrfs_put_tree_mod_seq() skip deletion of elements that +have a sequence number equals to the computed minimum sequence number, and +not just elements with a sequence number greater then that minimum. + +Fixes: bd989ba359f2ac ("Btrfs: add tree modification log functions") +CC: stable@vger.kernel.org # 4.4+ +Reviewed-by: Josef Bacik +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index a980b3309770..62caf3bcadf8 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -425,7 +425,7 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info, + for (node = rb_first(tm_root); node; node = next) { + next = rb_next(node); + tm = container_of(node, struct tree_mod_elem, node); +- if (tm->seq > min_seq) ++ if (tm->seq >= min_seq) + continue; + rb_erase(node, tm_root); + kfree(tm); +-- +2.20.1 + diff --git a/queue-4.4/btrfs-return-error-pointer-from-alloc_test_extent_bu.patch b/queue-4.4/btrfs-return-error-pointer-from-alloc_test_extent_bu.patch new file mode 100644 index 00000000000..89db9e94503 --- /dev/null +++ b/queue-4.4/btrfs-return-error-pointer-from-alloc_test_extent_bu.patch @@ -0,0 +1,66 @@ +From 84e0b28f3e998bec7480276879c4ac587c926b9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2019 14:24:58 +0300 +Subject: btrfs: return error pointer from alloc_test_extent_buffer + +From: Dan Carpenter + +[ Upstream commit b6293c821ea8fa2a631a2112cd86cd435effeb8b ] + +Callers of alloc_test_extent_buffer have not correctly interpreted the +return value as error pointer, as alloc_test_extent_buffer should behave +as alloc_extent_buffer. The self-tests were unaffected but +btrfs_find_create_tree_block could call both functions and that would +cause problems up in the call chain. + +Fixes: faa2dbf004e8 ("Btrfs: add sanity tests for new qgroup accounting code") +CC: stable@vger.kernel.org # 4.4+ +Signed-off-by: Dan Carpenter +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/extent_io.c | 6 ++++-- + fs/btrfs/tests/qgroup-tests.c | 4 ++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index a18f558b4477..6f5563ca70c1 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -4948,12 +4948,14 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, + return eb; + eb = alloc_dummy_extent_buffer(fs_info, start); + if (!eb) +- return NULL; ++ return ERR_PTR(-ENOMEM); + eb->fs_info = fs_info; + again: + ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); +- if (ret) ++ if (ret) { ++ exists = ERR_PTR(ret); + goto free_eb; ++ } + spin_lock(&fs_info->buffer_lock); + ret = radix_tree_insert(&fs_info->buffer_radix, + start >> PAGE_CACHE_SHIFT, eb); +diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c +index 2b2978c04e80..1efec40455f8 100644 +--- a/fs/btrfs/tests/qgroup-tests.c ++++ b/fs/btrfs/tests/qgroup-tests.c +@@ -477,9 +477,9 @@ int btrfs_test_qgroups(void) + * *cough*backref walking code*cough* + */ + root->node = alloc_test_extent_buffer(root->fs_info, 4096); +- if (!root->node) { ++ if (IS_ERR(root->node)) { + test_msg("Couldn't allocate dummy buffer\n"); +- ret = -ENOMEM; ++ ret = PTR_ERR(root->node); + goto out; + } + btrfs_set_header_level(root->node, 0); +-- +2.20.1 + diff --git a/queue-4.4/series b/queue-4.4/series index 181921ae17a..f830fd1e801 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -67,3 +67,8 @@ perf-parse-fix-potential-memory-leak-when-handling-t.patch perf-intel-bts-does-not-support-aux-area-sampling.patch net-phy-initialise-phydev-speed-and-duplex-sanely.patch revert-mmc-sdhci-fix-incorrect-switch-to-hs-mode.patch +usb-xhci-fix-build-warning-seen-with-config_pm-n.patch +btrfs-do-not-call-synchronize_srcu-in-inode_tree_del.patch +btrfs-return-error-pointer-from-alloc_test_extent_bu.patch +btrfs-abort-transaction-after-failed-inode-updates-i.patch +btrfs-fix-removal-logic-of-the-tree-mod-log-that-lea.patch diff --git a/queue-4.4/usb-xhci-fix-build-warning-seen-with-config_pm-n.patch b/queue-4.4/usb-xhci-fix-build-warning-seen-with-config_pm-n.patch new file mode 100644 index 00000000000..6a809b8f3c2 --- /dev/null +++ b/queue-4.4/usb-xhci-fix-build-warning-seen-with-config_pm-n.patch @@ -0,0 +1,49 @@ +From 4616d8da7566a05346bf7564b01a6da6fdb0c543 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2019 17:19:11 -0800 +Subject: usb: xhci: Fix build warning seen with CONFIG_PM=n + +From: Guenter Roeck + +[ Upstream commit 6056a0f8ede27b296d10ef46f7f677cc9d715371 ] + +The following build warning is seen if CONFIG_PM is disabled. + +drivers/usb/host/xhci-pci.c:498:13: warning: + unused function 'xhci_pci_shutdown' + +Fixes: f2c710f7dca8 ("usb: xhci: only set D3hot for pci device") +Cc: Henry Lin +Cc: stable@vger.kernel.org # all stable releases with f2c710f7dca8 +Signed-off-by: Guenter Roeck +Acked-by: Mathias Nyman +Link: https://lore.kernel.org/r/20191218011911.6907-1-linux@roeck-us.net +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index bda176fa6e48..df86ea308415 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -444,7 +444,6 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) + retval = xhci_resume(xhci, hibernated); + return retval; + } +-#endif /* CONFIG_PM */ + + static void xhci_pci_shutdown(struct usb_hcd *hcd) + { +@@ -457,6 +456,7 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd) + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(pdev, PCI_D3hot); + } ++#endif /* CONFIG_PM */ + + /*-------------------------------------------------------------------------*/ + +-- +2.20.1 +