* Patch "Btrfs: fix use-after-free on root->orphan_block_rsv" has been added to the 4.15-stable tree
@ 2018-02-20 15:49 gregkh
0 siblings, 0 replies; only message in thread
From: gregkh @ 2018-02-20 15:49 UTC (permalink / raw)
To: bo.li.liu, dsterba, gregkh, jbacik, stable; +Cc: stable, stable-commits
This is a note to let you know that I've just added the patch titled
Btrfs: fix use-after-free on root->orphan_block_rsv
to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
btrfs-fix-use-after-free-on-root-orphan_block_rsv.patch
and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
>From 1a932ef4e47984dee227834667b5ff5a334e4805 Mon Sep 17 00:00:00 2001
From: Liu Bo <bo.li.liu@oracle.com>
Date: Thu, 25 Jan 2018 11:02:54 -0700
Subject: Btrfs: fix use-after-free on root->orphan_block_rsv
From: Liu Bo <bo.li.liu@oracle.com>
commit 1a932ef4e47984dee227834667b5ff5a334e4805 upstream.
I got these from running generic/475,
WARNING: CPU: 0 PID: 26384 at fs/btrfs/inode.c:3326 btrfs_orphan_commit_root+0x1ac/0x2b0 [btrfs]
BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
IP: btrfs_block_rsv_release+0x1c/0x70 [btrfs]
Call Trace:
btrfs_orphan_release_metadata+0x9f/0x200 [btrfs]
btrfs_orphan_del+0x10d/0x170 [btrfs]
btrfs_setattr+0x500/0x640 [btrfs]
notify_change+0x7ae/0x870
do_truncate+0xca/0x130
vfs_truncate+0x2ee/0x3d0
do_sys_truncate+0xaf/0xf0
SyS_truncate+0xe/0x10
entry_SYSCALL_64_fastpath+0x1f/0x96
The race is between btrfs_orphan_commit_root and btrfs_orphan_del,
t1 t2
btrfs_orphan_commit_root btrfs_orphan_del
spin_lock
check (&root->orphan_inodes)
root->orphan_block_rsv = NULL;
spin_unlock
atomic_dec(&root->orphan_inodes);
access root->orphan_block_rsv
Accessing root->orphan_block_rsv must be done before decreasing
root->orphan_inodes.
cc: <stable@vger.kernel.org> v3.12+
Fixes: 703c88e03524 ("Btrfs: fix tracking of orphan inode count")
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/btrfs/inode.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3369,6 +3369,11 @@ int btrfs_orphan_add(struct btrfs_trans_
ret = btrfs_orphan_reserve_metadata(trans, inode);
ASSERT(!ret);
if (ret) {
+ /*
+ * dec doesn't need spin_lock as ->orphan_block_rsv
+ * would be released only if ->orphan_inodes is
+ * zero.
+ */
atomic_dec(&root->orphan_inodes);
clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
&inode->runtime_flags);
@@ -3383,12 +3388,17 @@ int btrfs_orphan_add(struct btrfs_trans_
if (insert >= 1) {
ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode));
if (ret) {
- atomic_dec(&root->orphan_inodes);
if (reserve) {
clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
&inode->runtime_flags);
btrfs_orphan_release_metadata(inode);
}
+ /*
+ * btrfs_orphan_commit_root may race with us and set
+ * ->orphan_block_rsv to zero, in order to avoid that,
+ * decrease ->orphan_inodes after everything is done.
+ */
+ atomic_dec(&root->orphan_inodes);
if (ret != -EEXIST) {
clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
&inode->runtime_flags);
@@ -3420,28 +3430,26 @@ static int btrfs_orphan_del(struct btrfs
{
struct btrfs_root *root = inode->root;
int delete_item = 0;
- int release_rsv = 0;
int ret = 0;
- spin_lock(&root->orphan_lock);
if (test_and_clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
&inode->runtime_flags))
delete_item = 1;
+ if (delete_item && trans)
+ ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode));
+
if (test_and_clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
&inode->runtime_flags))
- release_rsv = 1;
- spin_unlock(&root->orphan_lock);
+ btrfs_orphan_release_metadata(inode);
- if (delete_item) {
+ /*
+ * btrfs_orphan_commit_root may race with us and set ->orphan_block_rsv
+ * to zero, in order to avoid that, decrease ->orphan_inodes after
+ * everything is done.
+ */
+ if (delete_item)
atomic_dec(&root->orphan_inodes);
- if (trans)
- ret = btrfs_del_orphan_item(trans, root,
- btrfs_ino(inode));
- }
-
- if (release_rsv)
- btrfs_orphan_release_metadata(inode);
return ret;
}
Patches currently in stable-queue which might be from bo.li.liu@oracle.com are
queue-4.15/btrfs-fix-btrfs_evict_inode-to-handle-abnormal-inodes-correctly.patch
queue-4.15/btrfs-fix-crash-due-to-not-cleaning-up-tree-log-block-s-dirty-bits.patch
queue-4.15/btrfs-fix-use-after-free-on-root-orphan_block_rsv.patch
queue-4.15/btrfs-fix-extent-state-leak-from-tree-log.patch
queue-4.15/btrfs-fix-unexpected-eexist-when-creating-new-inode.patch
queue-4.15/btrfs-fix-deadlock-in-run_delalloc_nocow.patch
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2018-02-20 15:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-20 15:49 Patch "Btrfs: fix use-after-free on root->orphan_block_rsv" has been added to the 4.15-stable tree gregkh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).