Skip to content

Commit cdfb080

Browse files
committed
Btrfs: fix use after free when close_ctree frees the orphan_rsv
Near the end of close_ctree, we're calling btrfs_free_block_rsv to free up the orphan rsv. The problem is this call updates the space_info, which has already been freed. This adds a new __ function that directly calls kfree instead of trying to update the space infos. Signed-off-by: Chris Mason <clm@fb.com>
1 parent 1bbc621 commit cdfb080

File tree

3 files changed

+7
-1
lines changed

3 files changed

+7
-1
lines changed

fs/btrfs/ctree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3470,6 +3470,7 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root,
34703470
unsigned short type);
34713471
void btrfs_free_block_rsv(struct btrfs_root *root,
34723472
struct btrfs_block_rsv *rsv);
3473+
void __btrfs_free_block_rsv(struct btrfs_block_rsv *rsv);
34733474
int btrfs_block_rsv_add(struct btrfs_root *root,
34743475
struct btrfs_block_rsv *block_rsv, u64 num_bytes,
34753476
enum btrfs_reserve_flush_enum flush);

fs/btrfs/disk-io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3766,7 +3766,7 @@ void close_ctree(struct btrfs_root *root)
37663766

37673767
btrfs_free_stripe_hash_table(fs_info);
37683768

3769-
btrfs_free_block_rsv(root, root->orphan_block_rsv);
3769+
__btrfs_free_block_rsv(root->orphan_block_rsv);
37703770
root->orphan_block_rsv = NULL;
37713771

37723772
lock_chunks(root);

fs/btrfs/extent-tree.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4918,6 +4918,11 @@ void btrfs_free_block_rsv(struct btrfs_root *root,
49184918
kfree(rsv);
49194919
}
49204920

4921+
void __btrfs_free_block_rsv(struct btrfs_block_rsv *rsv)
4922+
{
4923+
kfree(rsv);
4924+
}
4925+
49214926
int btrfs_block_rsv_add(struct btrfs_root *root,
49224927
struct btrfs_block_rsv *block_rsv, u64 num_bytes,
49234928
enum btrfs_reserve_flush_enum flush)

0 commit comments

Comments
 (0)