FAILED: patch "[PATCH] tty: n_gsm: fix reset fifo race condition" failed to apply to 5.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 73029a4d7161f8b6c0934553145ef574d2d0c645 Mon Sep 17 00:00:00 2001
From: Daniel Starke <[email protected]>
Date: Thu, 14 Apr 2022 02:42:22 -0700
Subject: [PATCH] tty: n_gsm: fix reset fifo race condition
gsmtty_write() and gsm_dlci_data_output() properly guard the fifo access. However, gsm_dlci_close() and gsmtty_flush_buffer() modifies the fifo but do not guard this.
Add a guard here to prevent race conditions on parallel writes to the fifo.
drivers/tty/n_gsm.c +8 -0
@@ -1442,13 +1442,17 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)static void gsm_dlci_close (struct gsm_dlci *dlci) { +unsigned long flags; +del_timer (&dlci->t1);if (debug &8 )pr_debug ("DLCI %d goes closed.\n" , dlci->addr); dlci->state =DLCI_CLOSED ;if (dlci->addr !=0 ) {tty_port_tty_hangup (&dlci->port, false); +spin_lock_irqsave (&dlci->lock, flags);kfifo_reset (&dlci->fifo); +spin_unlock_irqrestore (&dlci->lock, flags);/* Ensure that gsmtty_open() can return. */ tty_port_set_initialized (&dlci->port,0 );wake_up_interruptible (&dlci->port.open_wait);
@@ -3148,13 +3152,17 @@ static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty)static void gsmtty_flush_buffer (struct tty_struct *tty) {struct gsm_dlci *dlci = tty->driver_data; +unsigned long flags; +if (dlci->state ==DLCI_CLOSED )return ;/* Caution needed: If we implement reliable transport classes then the data being transmitted can't simply be junked once it has first hit the stack. Until then we can just blow it away */ +spin_lock_irqsave (&dlci->lock, flags);kfifo_reset (&dlci->fifo); +spin_unlock_irqrestore (&dlci->lock, flags);/* Need to unhook this DLCI from the transmit queue logic */ }