Skip to content

Commit 8514973

Browse files
committed
ublk: make sure ubq->canceling is set when queue is frozen
jira KERNEL-238 cve CVE-2025-22068 Rebuild_History Non-Buildable kernel-6.12.0-124.16.1.el10_1 commit-author Ming Lei <ming.lei@redhat.com> commit 8741d07 Now ublk driver depends on `ubq->canceling` for deciding if the request can be dispatched via uring_cmd & io_uring_cmd_complete_in_task(). Once ubq->canceling is set, the uring_cmd can be done via ublk_cancel_cmd() and io_uring_cmd_done(). So set ubq->canceling when queue is frozen, this way makes sure that the flag can be observed from ublk_queue_rq() reliably, and avoids use-after-free on uring_cmd. Fixes: 216c8f5 ("ublk: replace monitor with cancelable uring_cmd") Signed-off-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20250327095123.179113-2-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk> (cherry picked from commit 8741d07) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 2ed8f1b commit 8514973

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

drivers/block/ublk_drv.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,17 +1441,27 @@ static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq)
14411441
}
14421442
}
14431443

1444+
/* Must be called when queue is frozen */
1445+
static bool ublk_mark_queue_canceling(struct ublk_queue *ubq)
1446+
{
1447+
bool canceled;
1448+
1449+
spin_lock(&ubq->cancel_lock);
1450+
canceled = ubq->canceling;
1451+
if (!canceled)
1452+
ubq->canceling = true;
1453+
spin_unlock(&ubq->cancel_lock);
1454+
1455+
return canceled;
1456+
}
1457+
14441458
static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
14451459
{
1460+
bool was_canceled = ubq->canceling;
14461461
struct gendisk *disk;
14471462

1448-
spin_lock(&ubq->cancel_lock);
1449-
if (ubq->canceling) {
1450-
spin_unlock(&ubq->cancel_lock);
1463+
if (was_canceled)
14511464
return false;
1452-
}
1453-
ubq->canceling = true;
1454-
spin_unlock(&ubq->cancel_lock);
14551465

14561466
spin_lock(&ub->lock);
14571467
disk = ub->ub_disk;
@@ -1463,14 +1473,23 @@ static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
14631473
if (!disk)
14641474
return false;
14651475

1466-
/* Now we are serialized with ublk_queue_rq() */
1476+
/*
1477+
* Now we are serialized with ublk_queue_rq()
1478+
*
1479+
* Make sure that ubq->canceling is set when queue is frozen,
1480+
* because ublk_queue_rq() has to rely on this flag for avoiding to
1481+
* touch completed uring_cmd
1482+
*/
14671483
blk_mq_quiesce_queue(disk->queue);
1468-
/* abort queue is for making forward progress */
1469-
ublk_abort_queue(ub, ubq);
1484+
was_canceled = ublk_mark_queue_canceling(ubq);
1485+
if (!was_canceled) {
1486+
/* abort queue is for making forward progress */
1487+
ublk_abort_queue(ub, ubq);
1488+
}
14701489
blk_mq_unquiesce_queue(disk->queue);
14711490
put_device(disk_to_dev(disk));
14721491

1473-
return true;
1492+
return !was_canceled;
14741493
}
14751494

14761495
static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io,

0 commit comments

Comments
 (0)