Thread (9 messages) flat view 9 messages, 2 authors, 17d ago

Re: [PATCH v4 2/4] serial: fix ioctl hangup race

From: sashiko-bot@kernel.org
Date: 2026-09-10 13:25:03

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The patch misses several tty driver callbacks that access hardware and can race with hangup, including those triggered by the TCXONC ioctl and racing writes.
--

commit b720c07153ba95668df0da514b07008b06834b2e
Author: Johan Hovold [off-list ref]

serial: fix ioctl hangup race

This commit adds tty_io_error checks to several tty ioctls and driver
operations. It aims to ensure the port has not been hung up before accessing
the hardware, avoiding kernel panics.
quoted hunk ↗ jump to hunk
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 1553bc6cbe7ba..139b938762298 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;
[Severity: High]
This isn't a bug introduced by this patch, but does this miss several other
tty driver callbacks that access hardware and can race with hangup, including
those triggered by the TCXONC ioctl and racing writes?

Invoking hardware callbacks (start_tx, stop_tx, send_xchar) on a powered-down
or unclocked UART port causes bus errors and kernel panics.

Can a user call ioctl(TCXONC) on a hung-up terminal and invoke uart_stop(),
uart_start(), or uart_send_xchar()? These do not check tty_io_error(tty) and
unconditionally access the hardware:

drivers/tty/serial/serial_core.c:uart_stop() {
	port = uart_port_ref_lock(state, &flags);
	if (port)
		port->ops->stop_tx(port);
	...
}

drivers/tty/serial/serial_core.c:uart_start() {
	port = uart_port_ref_lock(state, &flags);
	__uart_start(state);
	...
}

drivers/tty/serial/serial_core.c:uart_send_xchar() {
	if (port->ops->send_xchar)
		port->ops->send_xchar(port, ch);
	...
}

Additionally, can a concurrent write() race with uart_shutdown()? If
uart_write() acquires the port lock after uart_port_shutdown() disables the
hardware but before uart_free_xmit_buf() clears the buffer pointer, it will
pass the !state->port.xmit_buf check and invoke start_tx on the dead hardware:

drivers/tty/serial/serial_core.c:uart_write() {
	port = uart_port_ref_lock(state, &flags);
	if (!state->port.xmit_buf) {
		uart_port_unlock_deref(port, flags);
		return 0;
	}
	...
	__uart_start(state);
	...
}

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260910130816.642699-1-johan@kernel.org?part=2
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help