Btrfs: fix use after free when close_ctree frees the orphan_rsv
PATCH 1/1 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.
--- fs/btrfs/ctree.h | 1 + fs/btrfs/disk-io.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
fs/btrfs/ctree.h +1 -0
@@ -3488,6 +3488,7 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root, unsigned short type);void btrfs_free_block_rsv (struct btrfs_root *root,struct btrfs_block_rsv *rsv); +void __btrfs_free_block_rsv (struct btrfs_block_rsv *rsv);int btrfs_block_rsv_add (struct btrfs_root *root,struct btrfs_block_rsv *block_rsv,u64 num_bytes,enum btrfs_reserve_flush_enum flush);
fs/btrfs/disk-io.c +1 -1
@@ -3746,7 +3746,7 @@ void close_ctree(struct btrfs_root *root)btrfs_free_stripe_hash_table (fs_info); -btrfs_free_block_rsv (root, root->orphan_block_rsv); +__btrfs_free_block_rsv (root->orphan_block_rsv); root->orphan_block_rsv =NULL ;lock_chunks (root);
Signature · 1 line
1.8.1
PATCH v2 1/1 Btrfs: fix use after free when close_ctree frees the orphan_rsv
Quoted 1 line
From
471717f48f9d853a6ced290d91e8b7f1d1c039daMon Sep 17 00:00:00 2001
From: Chris Mason <[email protected]>
Date: Mon, 6 Apr 2015 18:17:00 -0700
Subject: [PATCH] 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.
---
v1 -> v2: whoops, get __btrfs-free_block_rsv in the right commit
fs/btrfs/ctree.h | 1 + fs/btrfs/disk-io.c | 2 +- fs/btrfs/extent-tree.c | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-)
fs/btrfs/ctree.h +1 -0
@@ -3488,6 +3488,7 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root, unsigned short type);void btrfs_free_block_rsv (struct btrfs_root *root,struct btrfs_block_rsv *rsv); +void __btrfs_free_block_rsv (struct btrfs_block_rsv *rsv);int btrfs_block_rsv_add (struct btrfs_root *root,struct btrfs_block_rsv *block_rsv,u64 num_bytes,enum btrfs_reserve_flush_enum flush);
fs/btrfs/disk-io.c +1 -1
@@ -3746,7 +3746,7 @@ void close_ctree(struct btrfs_root *root)btrfs_free_stripe_hash_table (fs_info); -btrfs_free_block_rsv (root, root->orphan_block_rsv); +__btrfs_free_block_rsv (root->orphan_block_rsv); root->orphan_block_rsv =NULL ;lock_chunks (root);
fs/btrfs/extent-tree.c +7 -0
@@ -4925,6 +4925,13 @@ void btrfs_free_block_rsv(struct btrfs_root *root,kfree (rsv); } +void __btrfs_free_block_rsv (struct btrfs_block_rsv *rsv) +{ +if (!rsv) +return ; +kfree (rsv); +} +int btrfs_block_rsv_add (struct btrfs_root *root,struct btrfs_block_rsv *block_rsv,u64 num_bytes,enum btrfs_reserve_flush_enum flush)
Signature · 1 line
1.8.1