Skip to content

Commit

Permalink
btrfs: fix use-after-free on rbtree that tracks inodes for auto defrag
Browse files Browse the repository at this point in the history
When cleaning up defrag inodes at btrfs_cleanup_defrag_inodes(), called
during remount and unmount, we are freeing every node from the rbtree
that tracks inodes for auto defrag using
rbtree_postorder_for_each_entry_safe(), which doesn't modify the tree
itself. So once we unlock the lock that protects the rbtree, we have a
tree pointing to a root that was freed (and a root pointing to freed
nodes, and their children pointing to other freed nodes, and so on).
This makes further access to the tree result in a use-after-free with
unpredictable results.

Fix this by initializing the rbtree to an empty root after the call to
rbtree_postorder_for_each_entry_safe() and before unlocking.

Fixes: 2769409 ("btrfs: clear defragmented inodes using postorder in btrfs_cleanup_defrag_inodes()")
Reported-by: [email protected]
Link: https://lore.kernel.org/linux-btrfs/[email protected]/
Reviewed-by: Qu Wenruo <[email protected]>
Signed-off-by: Filipe Manana <[email protected]>
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
  • Loading branch information
fdmanana authored and kdave committed Sep 17, 2024
1 parent b0b595e commit 7f1b63f
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions fs/btrfs/defrag.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ void btrfs_cleanup_defrag_inodes(struct btrfs_fs_info *fs_info)
&fs_info->defrag_inodes, rb_node)
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);

fs_info->defrag_inodes = RB_ROOT;

spin_unlock(&fs_info->defrag_inodes_lock);
}

Expand Down

0 comments on commit 7f1b63f

Please sign in to comment.