Patch "um: Add winch to winch_handlers before registering winch IRQ" has been added to the 5.10-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

    um: Add winch to winch_handlers before registering winch IRQ

to the 5.10-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:
     um-add-winch-to-winch_handlers-before-registering-wi.patch
and it can be found in the queue-5.10 subdirectory.

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



commit 907c883f23a76e1023c80ba1da0791e3a55446b6
Author: Roberto Sassu <roberto.sassu@xxxxxxxxxx>
Date:   Thu Mar 7 11:49:26 2024 +0100

    um: Add winch to winch_handlers before registering winch IRQ
    
    [ Upstream commit a0fbbd36c156b9f7b2276871d499c9943dfe5101 ]
    
    Registering a winch IRQ is racy, an interrupt may occur before the winch is
    added to the winch_handlers list.
    
    If that happens, register_winch_irq() adds to that list a winch that is
    scheduled to be (or has already been) freed, causing a panic later in
    winch_cleanup().
    
    Avoid the race by adding the winch to the winch_handlers list before
    registering the IRQ, and rolling back if um_request_irq() fails.
    
    Fixes: 42a359e31a0e ("uml: SIGIO support cleanup")
    Signed-off-by: Roberto Sassu <roberto.sassu@xxxxxxxxxx>
    Reviewed-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
    Signed-off-by: Richard Weinberger <richard@xxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 14ad9f495fe69..37e96ba0f5fb1 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -668,24 +668,26 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
 		goto cleanup;
 	}
 
-	*winch = ((struct winch) { .list  	= LIST_HEAD_INIT(winch->list),
-				   .fd  	= fd,
+	*winch = ((struct winch) { .fd  	= fd,
 				   .tty_fd 	= tty_fd,
 				   .pid  	= pid,
 				   .port 	= port,
 				   .stack	= stack });
 
+	spin_lock(&winch_handler_lock);
+	list_add(&winch->list, &winch_handlers);
+	spin_unlock(&winch_handler_lock);
+
 	if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
 			   IRQF_SHARED, "winch", winch) < 0) {
 		printk(KERN_ERR "register_winch_irq - failed to register "
 		       "IRQ\n");
+		spin_lock(&winch_handler_lock);
+		list_del(&winch->list);
+		spin_unlock(&winch_handler_lock);
 		goto out_free;
 	}
 
-	spin_lock(&winch_handler_lock);
-	list_add(&winch->list, &winch_handlers);
-	spin_unlock(&winch_handler_lock);
-
 	return;
 
  out_free:




[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