Skip to content

Commit d36a9ea

Browse files
Ming Leiaxboe
authored andcommitted
block: fix use-after-free of q->q_usage_counter
For blk-mq, queue release handler is usually called after blk_mq_freeze_queue_wait() returns. However, the q_usage_counter->release() handler may not be run yet at that time, so this can cause a use-after-free. Fix the issue by moving percpu_ref_exit() into blk_free_queue_rcu(). Since ->release() is called with rcu read lock held, it is agreed that the race should be covered in caller per discussion from the two links. Reported-by: Zhang Wensheng <[email protected]> Reported-by: Zhong Jinghua <[email protected]> Link: https://lore.kernel.org/linux-block/Y5prfOjyyjQKUrtH@T590/T/#u Link: https://lore.kernel.org/lkml/Y4%2FmzMd4evRg9yDi@fedora/ Cc: Hillf Danton <[email protected]> Cc: Yu Kuai <[email protected]> Cc: Dennis Zhou <[email protected]> Fixes: 2b0d3d3 ("percpu_ref: reduce memory footprint of percpu_ref in fast path") Signed-off-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 1eb2062 commit d36a9ea

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

block/blk-core.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,15 @@ EXPORT_SYMBOL_GPL(blk_clear_pm_only);
254254

255255
static void blk_free_queue_rcu(struct rcu_head *rcu_head)
256256
{
257-
kmem_cache_free(blk_requestq_cachep,
258-
container_of(rcu_head, struct request_queue, rcu_head));
257+
struct request_queue *q = container_of(rcu_head,
258+
struct request_queue, rcu_head);
259+
260+
percpu_ref_exit(&q->q_usage_counter);
261+
kmem_cache_free(blk_requestq_cachep, q);
259262
}
260263

261264
static void blk_free_queue(struct request_queue *q)
262265
{
263-
percpu_ref_exit(&q->q_usage_counter);
264-
265266
if (q->poll_stat)
266267
blk_stat_remove_callback(q, q->poll_cb);
267268
blk_stat_free_callback(q->poll_cb);

0 commit comments

Comments
 (0)