btrfs: use after free when closing devices
authorSasha Levin <sasha.levin@oracle.com>
Tue, 12 May 2015 23:31:37 +0000 (19:31 -0400)
committerChris Mason <clm@fb.com>
Wed, 3 Jun 2015 02:34:36 +0000 (19:34 -0700)
__btrfs_close_devices() would call_rcu to free the device, which is racy with
list_for_each_entry() accessing the memory to retrieve the next device on the
list.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/volumes.c

index 403ed1fdd901ae38a991f4711b5108bb49775903..c99f29a52e0b32064fdb39727a66999b9b31ccf3 100644 (file)
@@ -693,13 +693,13 @@ static void free_device(struct rcu_head *head)
 
 static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
-       struct btrfs_device *device;
+       struct btrfs_device *device, *tmp;
 
        if (--fs_devices->opened > 0)
                return 0;
 
        mutex_lock(&fs_devices->device_list_mutex);
-       list_for_each_entry(device, &fs_devices->devices, dev_list) {
+       list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
                struct btrfs_device *new_device;
                struct rcu_string *name;