Skip to content

Commit

Permalink
block: fix locking in bdev_del_partition
Browse files Browse the repository at this point in the history
We need to hold the whole device bd_mutex to protect against
other thread concurrently deleting out partition before we get
to it, and thus causing a use after free.

Fixes: cddae80 ("block: pass a hd_struct to delete_partition")
Reported-by: syzbot+6448f3c229bc52b82f69@syzkaller.appspotmail.com
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Christoph Hellwig authored and Jens Axboe committed Sep 1, 2020
1 parent cafe01e commit 08fc1ab
Showing 1 changed file with 13 additions and 14 deletions.
27 changes: 13 additions & 14 deletions block/partitions/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,19 +532,20 @@ int bdev_add_partition(struct block_device *bdev, int partno,
int bdev_del_partition(struct block_device *bdev, int partno)
{
struct block_device *bdevp;
struct hd_struct *part;
int ret = 0;

part = disk_get_part(bdev->bd_disk, partno);
if (!part)
return -ENXIO;
struct hd_struct *part = NULL;
int ret;

ret = -ENOMEM;
bdevp = bdget(part_devt(part));
bdevp = bdget_disk(bdev->bd_disk, partno);
if (!bdevp)
goto out_put_part;
return -ENOMEM;

mutex_lock(&bdevp->bd_mutex);
mutex_lock_nested(&bdev->bd_mutex, 1);

ret = -ENXIO;
part = disk_get_part(bdev->bd_disk, partno);
if (!part)
goto out_unlock;

ret = -EBUSY;
if (bdevp->bd_openers)
Expand All @@ -553,16 +554,14 @@ int bdev_del_partition(struct block_device *bdev, int partno)
sync_blockdev(bdevp);
invalidate_bdev(bdevp);

mutex_lock_nested(&bdev->bd_mutex, 1);
delete_partition(bdev->bd_disk, part);
mutex_unlock(&bdev->bd_mutex);

ret = 0;
out_unlock:
mutex_unlock(&bdev->bd_mutex);
mutex_unlock(&bdevp->bd_mutex);
bdput(bdevp);
out_put_part:
disk_put_part(part);
if (part)
disk_put_part(part);
return ret;
}

Expand Down

0 comments on commit 08fc1ab

Please sign in to comment.