]> git.hungrycats.org Git - linux/commitdiff
Btrfs: fix use after free when close_ctree frees the orphan_rsv
authorChris Mason <clm@fb.com>
Tue, 7 Apr 2015 01:17:00 +0000 (18:17 -0700)
committerZygo Blaxell <zblaxell@serenity.furryterror.org>
Mon, 4 May 2015 00:43:45 +0000 (20:43 -0400)
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>
(cherry picked from commit cdfb080e1853660952db5e5332727e59427856df)

fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c

index b06f2ca14f8a4cf6ae037d05ef3a6f8a1cfa28a6..9fa77a0b53372ba21bf373638c3d60dcb8a8ad07 100644 (file)
@@ -3462,6 +3462,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);
index 604eb56eb961dbff38bebd35770d4ae49d5b6812..ab7dd0a1af861b9747ef8f10cdd3f10e8c112fb4 100644 (file)
@@ -3726,7 +3726,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);
index 0cde529a4a9f2d1984d047615203a885d1d7adb2..cd4271c485ff5e6e5bcee986c24be278fb6274be 100644 (file)
@@ -4781,6 +4781,11 @@ void btrfs_free_block_rsv(struct btrfs_root *root,
        kfree(rsv);
 }
 
+void __btrfs_free_block_rsv(struct btrfs_block_rsv *rsv)
+{
+       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)