* [PATCH] serial: fix ioctl hangup race
@ 2026-09-03 16:34 Johan Hovold
0 siblings, 0 replies; only message in thread
From: Johan Hovold @ 2026-09-03 16:34 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: linux-serial, linux-kernel, Johan Hovold, stable
The tty ioctls can race with hangup and end up calling into a tty
driver for a device that is already gone or powered down.
Add the missing checks to make sure the port has not been hung up before
accessing the hardware to avoid issues like kernel panic due to
unclocked accesses.
Note that TIOCGSERIAL, TIOCGICOUNT and TIOCMIWAIT do not access hardware
and are therefore not affected by the race.
Fixes: 04f378b198da ("tty: BKL pushdown")
Cc: stable@vger.kernel.org # 2.6.26
Signed-off-by: Johan Hovold <johan@kernel.org>
---
I've just sent a fix for USB serial here:
https://lore.kernel.org/r/20260903163146.1498497-1-johan@kernel.org
and will take closer look at the other TTY drivers tomorrow.
Johan
drivers/tty/serial/serial_core.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 95774b0f1484..aac12be4ceac 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -896,7 +896,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
upf_t old_flags, new_flags;
int retval;
- if (!uport)
+ if (!uport || tty_io_error(tty))
return -EIO;
new_port = new_info->port;
@@ -1119,7 +1119,7 @@ static int uart_break_ctl(struct tty_struct *tty, int break_state)
guard(mutex)(&port->mutex);
uport = uart_port_check(state);
- if (!uport)
+ if (!uport || tty_io_error(tty))
return -EIO;
if (uport->type != PORT_UNKNOWN && uport->ops->break_ctl)
@@ -1144,7 +1144,7 @@ static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state)
*/
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &port->mutex) {
uport = uart_port_check(state);
- if (!uport)
+ if (!uport || tty_io_error(tty))
return -EIO;
if (tty_port_users(port) != 1)
@@ -1646,7 +1646,7 @@ static void uart_set_termios(struct tty_struct *tty,
guard(mutex)(&state->port.mutex);
uport = uart_port_check(state);
- if (!uport)
+ if (!uport || tty_io_error(tty))
return;
/*
@@ -1798,7 +1798,11 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
* 'timeout' / 'expire' give us the maximum amount of time
* we wait.
*/
- while (!port->ops->tx_empty(port)) {
+ for (;;) {
+ scoped_guard(mutex, &state->port.mutex) {
+ if (tty_io_error(tty) || port->ops->tx_empty(port))
+ break;
+ }
msleep_interruptible(jiffies_to_msecs(char_time));
if (signal_pending(current))
break;
--
2.55.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-03 16:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-03 16:34 [PATCH] serial: fix ioctl hangup race Johan Hovold
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®