mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
block: fix use-after-free of the disk in sync_bdevs()
sync_bdevs() holds a reference to the bdev inode while it takes
bd_disk->open_mutex. For a partition the inode doesn't keep the gendisk
alive, the device reference does: part_release() drops the disk as soon
as the last reference to the partition device is gone. A sync(2) racing
with the last close of a partition of an already deleted disk locks a
freed open_mutex.
Take a device reference before touching the disk, like
blkdev_get_no_open() does, and skip the bdev if it's on its way out.
Fixes: a8698707a1 ("block: move bd_mutex to struct gendisk")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20261028164415.1262013-5-axboe@kernel.dk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
045cbfc369
commit
cebb1c2331
10
block/bdev.c
10
block/bdev.c
|
|
@ -1366,6 +1366,15 @@ void sync_bdevs(bool wait)
|
|||
old_inode = inode;
|
||||
bdev = I_BDEV(inode);
|
||||
|
||||
/*
|
||||
* The inode does not keep the gendisk of a partition alive, the
|
||||
* device does.
|
||||
*/
|
||||
if (!kobject_get_unless_zero(&bdev->bd_device.kobj)) {
|
||||
spin_lock(&blockdev_superblock->s_inode_list_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex_lock(&bdev->bd_disk->open_mutex);
|
||||
if (!atomic_read(&bdev->bd_openers)) {
|
||||
; /* skip */
|
||||
|
|
@ -1381,6 +1390,7 @@ void sync_bdevs(bool wait)
|
|||
filemap_fdatawrite(inode->i_mapping);
|
||||
}
|
||||
mutex_unlock(&bdev->bd_disk->open_mutex);
|
||||
put_device(&bdev->bd_device);
|
||||
|
||||
spin_lock(&blockdev_superblock->s_inode_list_lock);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user