Btrfs: fix unprotected device list access when cloning fs devices
authorMiao Xie <miaox@cn.fujitsu.com>
Wed, 3 Sep 2014 13:35:42 +0000 (21:35 +0800)
committerChris Mason <clm@fb.com>
Wed, 17 Sep 2014 20:38:43 +0000 (13:38 -0700)
We can build a new filesystem based a seed filesystem, and we need clone
the fs devices when we open the new filesystem. But someone might clear
the seed flag of the seed filesystem, then mount that filesystem and
remove some device. If we mount the new filesystem, we might access
a device list which was being changed when we clone the fs devices.
Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/volumes.c

index 105c5fe004db15e9d5f5de8412872a543d14eb50..d28e1761fdeb12ec5c6a1f8ca59ce61d96ce6b3d 100644 (file)
@@ -583,6 +583,7 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
        if (IS_ERR(fs_devices))
                return fs_devices;
 
+       mutex_lock(&orig->device_list_mutex);
        fs_devices->total_devices = orig->total_devices;
 
        /* We have held the volume lock, it is safe to get the devices. */
@@ -611,8 +612,10 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
                device->fs_devices = fs_devices;
                fs_devices->num_devices++;
        }
+       mutex_unlock(&orig->device_list_mutex);
        return fs_devices;
 error:
+       mutex_unlock(&orig->device_list_mutex);
        free_fs_devices(fs_devices);
        return ERR_PTR(-ENOMEM);
 }