Linux Serial subsystem development
 help / color / mirror / Atom feed
* [PATCH] serial: 8250: validate iomem_base in serial8250_verify_port()
@ 2026-07-20  5:37 Mingyu Wang
  2026-07-20  6:08 ` Jiri Slaby
  0 siblings, 1 reply; 5+ messages in thread
From: Mingyu Wang @ 2026-07-20  5:37 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: ilpo.jarvinen, john.ogness, andriy.shevchenko, linux-serial,
	linux-kernel, syzkaller, stable, Mingyu Wang

syzkaller reports a slab-use-after-free in mutex_spin_on_owner().
This occurs because a previous thread crashed during tty_open() while
holding the tty_lock, leaving the owner pointer dangling.

The initial crash is an unhandled Page Fault in mem_serial_in():

  BUG: unable to handle page fault for address: ffffc90001206014
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  Oops: Oops: 0000 [#1] SMP KASAN PTI
  RIP: 0010:mem_serial_in+0x67/0x90
  Call Trace:
   serial8250_clear_interrupts+0x40/0xf0
   serial8250_do_startup+0x3f5/0x3220
   serial8250_startup+0x6c/0x90
   uart_startup+0x4ff/0x12c0
   uart_port_activate+0xf3/0x1a0
   tty_port_open+0x15c/0x200
   uart_open+0x47/0x60
   tty_open+0x39b/0x1310

This sequence is triggered because the TIOCSSERIAL ioctl allows a user
with CAP_SYS_ADMIN to change the io_type of a serial port to UPIO_MEM
(or other memory-mapped types) and inject an arbitrary physical address
via iomem_base.

When uart_change_port() applies these changes, it attempts to remap the
port's I/O memory based on the injected iomem_base. This can result in an
invalid or inaccessible virtual mapping for port->membase. The subsequent
call to mem_serial_in() then dereferences this bogus pointer, triggering
a fatal Page Fault.

Fix this by tightening the validation in serial8250_verify_port().
Reject any TIOCSSERIAL requests that attempt to modify the io_type
to/from memory-mapped types, or change the iomem_base of an existing
memory-mapped port. Userspace can still legitimately modify IRQs or
baud rates of MMIO ports as long as the io_type and mapbase remain
unchanged.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
---
 drivers/tty/serial/8250/8250_port.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index e94a0802cbdd..79563afe9db9 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -3146,6 +3146,16 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
 	    ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
 	    ser->type == PORT_STARTECH)
 		return -EINVAL;
+
+	if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32 ||
+	    port->iotype == UPIO_MEM32BE || port->iotype == UPIO_MEM16 ||
+	    ser->io_type == UPIO_MEM || ser->io_type == UPIO_MEM32 ||
+	    ser->io_type == UPIO_MEM32BE || ser->io_type == UPIO_MEM16) {
+		if (ser->io_type != port->iotype ||
+		    (unsigned long)ser->iomem_base != port->mapbase)
+			return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-07-20  7:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20  5:37 [PATCH] serial: 8250: validate iomem_base in serial8250_verify_port() Mingyu Wang
2026-07-20  6:08 ` Jiri Slaby
2026-07-20  6:44   ` Mingyu Wang
2026-07-20  6:47     ` Greg KH
2026-07-20  7:36       ` Mingyu Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox