Skip to content

Commit a0fbbd3

Browse files
robertosassurichardweinberger
authored andcommitted
um: Add winch to winch_handlers before registering winch IRQ
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: 42a359e ("uml: SIGIO support cleanup") Signed-off-by: Roberto Sassu <[email protected]> Reviewed-by: Johannes Berg <[email protected]> Signed-off-by: Richard Weinberger <[email protected]>
1 parent 49ff7d8 commit a0fbbd3

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

arch/um/drivers/line.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -676,24 +676,26 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
676676
goto cleanup;
677677
}
678678

679-
*winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
680-
.fd = fd,
679+
*winch = ((struct winch) { .fd = fd,
681680
.tty_fd = tty_fd,
682681
.pid = pid,
683682
.port = port,
684683
.stack = stack });
685684

685+
spin_lock(&winch_handler_lock);
686+
list_add(&winch->list, &winch_handlers);
687+
spin_unlock(&winch_handler_lock);
688+
686689
if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
687690
IRQF_SHARED, "winch", winch) < 0) {
688691
printk(KERN_ERR "register_winch_irq - failed to register "
689692
"IRQ\n");
693+
spin_lock(&winch_handler_lock);
694+
list_del(&winch->list);
695+
spin_unlock(&winch_handler_lock);
690696
goto out_free;
691697
}
692698

693-
spin_lock(&winch_handler_lock);
694-
list_add(&winch->list, &winch_handlers);
695-
spin_unlock(&winch_handler_lock);
696-
697699
return;
698700

699701
out_free:

0 commit comments

Comments
 (0)