diff mbox series

btrfs: fix UAF in btrfs_drop_snapshot

Message ID ae224a6030d984c20e09093e6f93a0f33e757cd3.1645717258.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series btrfs: fix UAF in btrfs_drop_snapshot | expand

Commit Message

Josef Bacik Feb. 24, 2022, 3:41 p.m. UTC
This is for the KASAN report for my in progress snapshot drop fix, this
should apply cleanly to the existing patch.  At this point root could
have been free'd, so we need to check if we're an unfinished drop before
we start the drop and use that variable to see if we need to wake
anybody up.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/extent-tree.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

David Sterba Feb. 24, 2022, 4:08 p.m. UTC | #1
On Thu, Feb 24, 2022 at 10:41:06AM -0500, Josef Bacik wrote:
> This is for the KASAN report for my in progress snapshot drop fix, this
> should apply cleanly to the existing patch.  At this point root could
> have been free'd, so we need to check if we're an unfinished drop before
> we start the drop and use that variable to see if we need to wake
> anybody up.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>

Folded to the patch, thanks.
diff mbox series

Patch

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e94b8f168a85..b7b49b4eb68d 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5621,6 +5621,7 @@  int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
 	int ret;
 	int level;
 	bool root_dropped = false;
+	bool unfinished_drop = false;
 
 	btrfs_debug(fs_info, "Drop subvolume %llu", root->root_key.objectid);
 
@@ -5663,6 +5664,8 @@  int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
 	 * already dropped.
 	 */
 	set_bit(BTRFS_ROOT_DELETING, &root->state);
+	unfinished_drop = test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);
+
 	if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
 		level = btrfs_header_level(root->node);
 		path->nodes[level] = btrfs_lock_root_node(root);
@@ -5841,7 +5844,7 @@  int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
 	 * We were an unfinished drop root, check to see if there are any
 	 * pending, and if not clear and wake up any waiters.
 	 */
-	if (!err && test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state))
+	if (!err && unfinished_drop)
 		btrfs_maybe_wake_unfinished_drop(fs_info);
 
 	/*