Skip to content

Commit 75cd400

Browse files
Ming Leiaxboe
authored andcommitted
ublk: detach gendisk from ublk device if add_disk() fails
Inside ublk_abort_requests(), gendisk is grabbed for aborting all inflight requests. And ublk_abort_requests() is called when exiting the uring context or handling timeout. If add_disk() fails, the gendisk may have been freed when calling ublk_abort_requests(), so use-after-free can be caused when getting disk's reference in ublk_abort_requests(). Fixes the bug by detaching gendisk from ublk device if add_disk() fails. Fixes: bd23f6c ("ublk: quiesce request queue when aborting queue") Signed-off-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20241225110640.351531-1-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 85672ca commit 75cd400

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

drivers/block/ublk_drv.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,21 @@ static void ublk_unquiesce_dev(struct ublk_device *ub)
16181618
blk_mq_kick_requeue_list(ub->ub_disk->queue);
16191619
}
16201620

1621+
static struct gendisk *ublk_detach_disk(struct ublk_device *ub)
1622+
{
1623+
struct gendisk *disk;
1624+
1625+
/* Sync with ublk_abort_queue() by holding the lock */
1626+
spin_lock(&ub->lock);
1627+
disk = ub->ub_disk;
1628+
ub->dev_info.state = UBLK_S_DEV_DEAD;
1629+
ub->dev_info.ublksrv_pid = -1;
1630+
ub->ub_disk = NULL;
1631+
spin_unlock(&ub->lock);
1632+
1633+
return disk;
1634+
}
1635+
16211636
static void ublk_stop_dev(struct ublk_device *ub)
16221637
{
16231638
struct gendisk *disk;
@@ -1631,14 +1646,7 @@ static void ublk_stop_dev(struct ublk_device *ub)
16311646
ublk_unquiesce_dev(ub);
16321647
}
16331648
del_gendisk(ub->ub_disk);
1634-
1635-
/* Sync with ublk_abort_queue() by holding the lock */
1636-
spin_lock(&ub->lock);
1637-
disk = ub->ub_disk;
1638-
ub->dev_info.state = UBLK_S_DEV_DEAD;
1639-
ub->dev_info.ublksrv_pid = -1;
1640-
ub->ub_disk = NULL;
1641-
spin_unlock(&ub->lock);
1649+
disk = ublk_detach_disk(ub);
16421650
put_disk(disk);
16431651
unlock:
16441652
mutex_unlock(&ub->mutex);
@@ -2336,7 +2344,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
23362344

23372345
out_put_cdev:
23382346
if (ret) {
2339-
ub->dev_info.state = UBLK_S_DEV_DEAD;
2347+
ublk_detach_disk(ub);
23402348
ublk_put_device(ub);
23412349
}
23422350
if (ret)

0 commit comments

Comments
 (0)