Btrfs: eliminate a use-after-free in btrfs_balance()
authorIlya Dryomov <idryomov@gmail.com>
Tue, 12 Feb 2013 16:27:46 +0000 (16:27 +0000)
committerJosef Bacik <jbacik@fusionio.com>
Wed, 20 Feb 2013 17:59:53 +0000 (12:59 -0500)
Commit 5af3e8cc introduced a use-after-free at volumes.c:3139: bctl is freed
above in __cancel_balance() in all cases except for balance pause.  Fix this
by moving the offending check a couple statements above, the meaning of the
check is preserved.

Reported-by: Chris Mason <chris.mason@fusionio.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
fs/btrfs/volumes.c

index 305b6a63ab1f6b2e394be8cd41a91d9506345f6e..d778e96665971ffc5e0915ecd9f16df3b6dbcb1c 100644 (file)
@@ -3195,6 +3195,11 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
        mutex_lock(&fs_info->balance_mutex);
        atomic_dec(&fs_info->balance_running);
 
+       if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
+               fs_info->num_tolerated_disk_barrier_failures =
+                       btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
+       }
+
        if (bargs) {
                memset(bargs, 0, sizeof(*bargs));
                update_ioctl_balance_args(fs_info, 0, bargs);
@@ -3205,11 +3210,6 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
                __cancel_balance(fs_info);
        }
 
-       if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
-               fs_info->num_tolerated_disk_barrier_failures =
-                       btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
-       }
-
        wake_up(&fs_info->balance_wait_q);
 
        return ret;