Patch "blk-mq: fix tags UAF when shrinking q->nr_hw_queues" has been added to the 6.5-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    blk-mq: fix tags UAF when shrinking q->nr_hw_queues

to the 6.5-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     blk-mq-fix-tags-uaf-when-shrinking-q-nr_hw_queues.patch
and it can be found in the queue-6.5 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 21e83fd7bf60c763036a94ec5f1f8aca8f29d3d5
Author: Chengming Zhou <zhouchengming@xxxxxxxxxxxxx>
Date:   Fri Sep 8 08:57:02 2023 +0800

    blk-mq: fix tags UAF when shrinking q->nr_hw_queues
    
    [ Upstream commit 6be6d112419713334ddd9c01f219ca16adaa4c76 ]
    
    When nr_hw_queues shrink, we free the excess tags before realloc'ing
    hw_ctxs for each queue. During that resize, we may need to access those
    tags, like blk_mq_tag_idle(hctx) will access queue shared tags.
    
    This can cause a slab use-after-free, as reported by KASAN. Fix it by
    moving the releasing of excess tags to the end.
    
    Fixes: e1dd7bc93029 ("blk-mq: fix tags leak when shrink nr_hw_queues")
    Reported-by: Yi Zhang <yi.zhang@xxxxxxxxxx>
    Closes: https://lore.kernel.org/all/CAHj4cs_CK63uoDpGBGZ6DN4OCTpzkR3UaVgK=LX8Owr8ej2ieQ@xxxxxxxxxxxxxx/
    Cc: Ming Lei <ming.lei@xxxxxxxxxx>
    Signed-off-by: Chengming Zhou <zhouchengming@xxxxxxxxxxxxx>
    Reviewed-by: Hannes Reinecke <hare@xxxxxxx>
    Link: https://lore.kernel.org/r/20230908005702.2183908-1-chengming.zhou@xxxxxxxxx
    Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/block/blk-mq.c b/block/blk-mq.c
index d9b365c2eaa0d..a90f1efb1c978 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -4404,11 +4404,8 @@ static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set,
 	struct blk_mq_tags **new_tags;
 	int i;
 
-	if (set->nr_hw_queues >= new_nr_hw_queues) {
-		for (i = new_nr_hw_queues; i < set->nr_hw_queues; i++)
-			__blk_mq_free_map_and_rqs(set, i);
+	if (set->nr_hw_queues >= new_nr_hw_queues)
 		goto done;
-	}
 
 	new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *),
 				GFP_KERNEL, set->numa_node);
@@ -4708,7 +4705,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
 {
 	struct request_queue *q;
 	LIST_HEAD(head);
-	int prev_nr_hw_queues;
+	int prev_nr_hw_queues = set->nr_hw_queues;
+	int i;
 
 	lockdep_assert_held(&set->tag_list_lock);
 
@@ -4735,7 +4733,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
 		blk_mq_sysfs_unregister_hctxs(q);
 	}
 
-	prev_nr_hw_queues = set->nr_hw_queues;
 	if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0)
 		goto reregister;
 
@@ -4771,6 +4768,10 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
 
 	list_for_each_entry(q, &set->tag_list, tag_set_list)
 		blk_mq_unfreeze_queue(q);
+
+	/* Free the excess tags when nr_hw_queues shrink. */
+	for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++)
+		__blk_mq_free_map_and_rqs(set, i);
 }
 
 void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux