Patch "fuse: fix use after free in fuse_read_interrupt()" has been added to the 5.4-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

    fuse: fix use after free in fuse_read_interrupt()

to the 5.4-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:
     fuse-fix-use-after-free-in-fuse_read_interrupt.patch
and it can be found in the queue-5.4 subdirectory.

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



commit 6e0c71a3561ccece64997547ae6563bd5f30b0ce
Author: Miklos Szeredi <mszeredi@xxxxxxxxxx>
Date:   Wed Aug 4 13:22:58 2021 +0200

    fuse: fix use after free in fuse_read_interrupt()
    
    [ Upstream commit e1e71c168813564be0f6ea3d6740a059ca42d177 ]
    
    There is a potential race between fuse_read_interrupt() and
    fuse_request_end().
    
    TASK1
      in fuse_read_interrupt(): delete req->intr_entry (while holding
      fiq->lock)
    
    TASK2
      in fuse_request_end(): req->intr_entry is empty -> skip fiq->lock
      wake up TASK3
    
    TASK3
      request is freed
    
    TASK1
      in fuse_read_interrupt(): dereference req->in.h.unique ***BAM***
    
    Fix by always grabbing fiq->lock if the request was ever interrupted
    (FR_INTERRUPTED set) thereby serializing with concurrent
    fuse_read_interrupt() calls.
    
    FR_INTERRUPTED is set before the request is queued on fiq->interrupts.
    Dequeing the request is done with list_del_init() but FR_INTERRUPTED is not
    cleared in this case.
    
    Reported-by: lijiazi <lijiazi@xxxxxxxxxx>
    Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 16aa55b73ccf..7205a89fbb5f 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -282,10 +282,10 @@ void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req)
 
 	/*
 	 * test_and_set_bit() implies smp_mb() between bit
-	 * changing and below intr_entry check. Pairs with
+	 * changing and below FR_INTERRUPTED check. Pairs with
 	 * smp_mb() from queue_interrupt().
 	 */
-	if (!list_empty(&req->intr_entry)) {
+	if (test_bit(FR_INTERRUPTED, &req->flags)) {
 		spin_lock(&fiq->lock);
 		list_del_init(&req->intr_entry);
 		spin_unlock(&fiq->lock);



[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