Skip to content

Commit 670bfe6

Browse files
YuKuai-huaweiaxboe
authored andcommitted
blk-mq: fix null-ptr-deref in blk_mq_free_tags() from error path
blk_mq_free_tags() can be called after blk_mq_init_tags(), while tags->page_list is still not initialized, causing null-ptr-deref. Fix this problem by initializing tags->page_list at blk_mq_init_tags(), meanwhile, also free tags directly from error path because there is no srcu barrier. Fixes: ad0d05d ("blk-mq: Defer freeing of tags page_list to SRCU callback") Reported-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Yu Kuai <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent fea5569 commit 670bfe6

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

block/blk-mq-tag.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
566566
tags->nr_tags = total_tags;
567567
tags->nr_reserved_tags = reserved_tags;
568568
spin_lock_init(&tags->lock);
569+
INIT_LIST_HEAD(&tags->page_list);
570+
569571
if (bt_alloc(&tags->bitmap_tags, depth, round_robin, node))
570572
goto out_free_tags;
571573
if (bt_alloc(&tags->breserved_tags, reserved_tags, round_robin, node))
@@ -603,6 +605,13 @@ void blk_mq_free_tags(struct blk_mq_tag_set *set, struct blk_mq_tags *tags)
603605
{
604606
sbitmap_queue_free(&tags->bitmap_tags);
605607
sbitmap_queue_free(&tags->breserved_tags);
608+
609+
/* if tags pages is not allocated yet, free tags directly */
610+
if (list_empty(&tags->page_list)) {
611+
kfree(tags);
612+
return;
613+
}
614+
606615
call_srcu(&set->tags_srcu, &tags->rcu_head, blk_mq_free_tags_callback);
607616
}
608617

block/blk-mq.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3582,8 +3582,6 @@ static int blk_mq_alloc_rqs(struct blk_mq_tag_set *set,
35823582
if (node == NUMA_NO_NODE)
35833583
node = set->numa_node;
35843584

3585-
INIT_LIST_HEAD(&tags->page_list);
3586-
35873585
/*
35883586
* rq_size is the size of the request plus driver payload, rounded
35893587
* to the cacheline size

0 commit comments

Comments
 (0)