Patch "block, bfq: fix possible uaf for 'bfqq->bic'" has been added to the 6.0-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

    block, bfq: fix possible uaf for 'bfqq->bic'

to the 6.0-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:
     block-bfq-fix-possible-uaf-for-bfqq-bic.patch
and it can be found in the queue-6.0 subdirectory.

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



commit af01406cd0a3ee49b96c8ee520c2f814b6606675
Author: Yu Kuai <yukuai3@xxxxxxxxxx>
Date:   Wed Dec 14 11:04:30 2022 +0800

    block, bfq: fix possible uaf for 'bfqq->bic'
    
    [ Upstream commit 64dc8c732f5c2b406cc752e6aaa1bd5471159cab ]
    
    Our test report a uaf for 'bfqq->bic' in 5.10:
    
    ==================================================================
    BUG: KASAN: use-after-free in bfq_select_queue+0x378/0xa30
    
    CPU: 6 PID: 2318352 Comm: fsstress Kdump: loaded Not tainted 5.10.0-60.18.0.50.h602.kasan.eulerosv2r11.x86_64 #1
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58-20220320_160524-szxrtosci10000 04/01/2014
    Call Trace:
     bfq_select_queue+0x378/0xa30
     bfq_dispatch_request+0xe8/0x130
     blk_mq_do_dispatch_sched+0x62/0xb0
     __blk_mq_sched_dispatch_requests+0x215/0x2a0
     blk_mq_sched_dispatch_requests+0x8f/0xd0
     __blk_mq_run_hw_queue+0x98/0x180
     __blk_mq_delay_run_hw_queue+0x22b/0x240
     blk_mq_run_hw_queue+0xe3/0x190
     blk_mq_sched_insert_requests+0x107/0x200
     blk_mq_flush_plug_list+0x26e/0x3c0
     blk_finish_plug+0x63/0x90
     __iomap_dio_rw+0x7b5/0x910
     iomap_dio_rw+0x36/0x80
     ext4_dio_read_iter+0x146/0x190 [ext4]
     ext4_file_read_iter+0x1e2/0x230 [ext4]
     new_sync_read+0x29f/0x400
     vfs_read+0x24e/0x2d0
     ksys_read+0xd5/0x1b0
     do_syscall_64+0x33/0x40
     entry_SYSCALL_64_after_hwframe+0x61/0xc6
    
    Commit 3bc5e683c67d ("bfq: Split shared queues on move between cgroups")
    changes that move process to a new cgroup will allocate a new bfqq to
    use, however, the old bfqq and new bfqq can point to the same bic:
    
    1) Initial state, two process with io in the same cgroup.
    
    Process 1       Process 2
     (BIC1)          (BIC2)
      |  Λ            |  Λ
      |  |            |  |
      V  |            V  |
      bfqq1           bfqq2
    
    2) bfqq1 is merged to bfqq2.
    
    Process 1       Process 2
     (BIC1)          (BIC2)
      |               |
       \-------------\|
                      V
      bfqq1           bfqq2(coop)
    
    3) Process 1 exit, then issue new io(denoce IOA) from Process 2.
    
     (BIC2)
      |  Λ
      |  |
      V  |
      bfqq2(coop)
    
    4) Before IOA is completed, move Process 2 to another cgroup and issue io.
    
    Process 2
     (BIC2)
       Λ
       |\--------------\
       |                V
      bfqq2           bfqq3
    
    Now that BIC2 points to bfqq3, while bfqq2 and bfqq3 both point to BIC2.
    If all the requests are completed, and Process 2 exit, BIC2 will be
    freed while there is no guarantee that bfqq2 will be freed before BIC2.
    
    Fix the problem by clearing bfqq->bic while bfqq is detached from bic.
    
    Fixes: 3bc5e683c67d ("bfq: Split shared queues on move between cgroups")
    Suggested-by: Jan Kara <jack@xxxxxxx>
    Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx>
    Reviewed-by: Jan Kara <jack@xxxxxxx>
    Link: https://lore.kernel.org/r/20221214030430.3304151-1-yukuai1@xxxxxxxxxxxxxxx
    Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 68872a61706a..528ca21044a5 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -386,6 +386,12 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq);
 
 void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync)
 {
+	struct bfq_queue *old_bfqq = bic->bfqq[is_sync];
+
+	/* Clear bic pointer if bfqq is detached from this bic */
+	if (old_bfqq && old_bfqq->bic == bic)
+		old_bfqq->bic = NULL;
+
 	/*
 	 * If bfqq != NULL, then a non-stable queue merge between
 	 * bic->bfqq and bfqq is happening here. This causes troubles
@@ -5379,7 +5385,6 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
 		unsigned long flags;
 
 		spin_lock_irqsave(&bfqd->lock, flags);
-		bfqq->bic = NULL;
 		bfq_exit_bfqq(bfqd, bfqq);
 		bic_set_bfqq(bic, NULL, is_sync);
 		spin_unlock_irqrestore(&bfqd->lock, flags);



[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