Commit 1357272fc7deeebb7b3c5d1a071562edc273cdaf
Committed by
Josef Bacik
1 parent
964fb15acf
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
Btrfs: fix a use-after-free bug in btrfs_dev_replace_finishing
free_device rcu callback, scheduled from btrfs_rm_dev_replace_srcdev, can be processed before btrfs_scratch_superblock is called, which would result in a use-after-free on btrfs_device contents. Fix this by zeroing the superblock before the rcu callback is registered. Cc: Stefan Behrens <sbehrens@giantdisaster.de> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Showing 2 changed files with 7 additions and 5 deletions Side-by-side Diff
fs/btrfs/dev-replace.c
... | ... | @@ -535,10 +535,7 @@ |
535 | 535 | list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); |
536 | 536 | |
537 | 537 | btrfs_rm_dev_replace_srcdev(fs_info, src_device); |
538 | - if (src_device->bdev) { | |
539 | - /* zero out the old super */ | |
540 | - btrfs_scratch_superblock(src_device); | |
541 | - } | |
538 | + | |
542 | 539 | /* |
543 | 540 | * this is again a consistent state where no dev_replace procedure |
544 | 541 | * is running, the target device is part of the filesystem, the |
fs/btrfs/volumes.c
... | ... | @@ -1716,6 +1716,7 @@ |
1716 | 1716 | struct btrfs_device *srcdev) |
1717 | 1717 | { |
1718 | 1718 | WARN_ON(!mutex_is_locked(&fs_info->fs_devices->device_list_mutex)); |
1719 | + | |
1719 | 1720 | list_del_rcu(&srcdev->dev_list); |
1720 | 1721 | list_del_rcu(&srcdev->dev_alloc_list); |
1721 | 1722 | fs_info->fs_devices->num_devices--; |
1722 | 1723 | |
... | ... | @@ -1725,8 +1726,12 @@ |
1725 | 1726 | } |
1726 | 1727 | if (srcdev->can_discard) |
1727 | 1728 | fs_info->fs_devices->num_can_discard--; |
1728 | - if (srcdev->bdev) | |
1729 | + if (srcdev->bdev) { | |
1729 | 1730 | fs_info->fs_devices->open_devices--; |
1731 | + | |
1732 | + /* zero out the old super */ | |
1733 | + btrfs_scratch_superblock(srcdev); | |
1734 | + } | |
1730 | 1735 | |
1731 | 1736 | call_rcu(&srcdev->rcu, free_device); |
1732 | 1737 | } |