Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cdbc3fa authored by Qu Wenruo's avatar Qu Wenruo Committed by Greg Kroah-Hartman
Browse files

btrfs: relocation: Only remove reloc rb_trees if reloc control has been initialized

[ Upstream commit 389305b2aa68723c754f88d9dbd268a400e10664 ]

Invalid reloc tree can cause kernel NULL pointer dereference when btrfs
does some cleanup of the reloc roots.

It turns out that fs_info::reloc_ctl can be NULL in
btrfs_recover_relocation() as we allocate relocation control after all
reloc roots have been verified.
So when we hit: note, we haven't called set_reloc_control() thus
fs_info::reloc_ctl is still NULL.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=199833


Reported-by: default avatarXu Wen <wen.xu@gatech.edu>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Tested-by: default avatarGu Jinxiang <gujx@cn.fujitsu.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2f92584b
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -1334,6 +1334,7 @@ static void __del_reloc_root(struct btrfs_root *root)
	struct mapping_node *node = NULL;
	struct reloc_control *rc = fs_info->reloc_ctl;

	if (rc) {
		spin_lock(&rc->reloc_root_tree.lock);
		rb_node = tree_search(&rc->reloc_root_tree.rb_root,
				      root->node->start);
@@ -1342,10 +1343,10 @@ static void __del_reloc_root(struct btrfs_root *root)
			rb_erase(&node->rb_node, &rc->reloc_root_tree.rb_root);
		}
		spin_unlock(&rc->reloc_root_tree.lock);

		if (!node)
			return;
		BUG_ON((struct btrfs_root *)node->data != root);
	}

	spin_lock(&fs_info->trans_lock);
	list_del_init(&root->root_list);