All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Putko <igorpetindev@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jirislaby@kernel.org>
Cc: Rob Herring <robh@kernel.org>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
	syzbot+843bf2f48f4d12e6682e@syzkaller.appspotmail.com,
	Igor Putko <igorpetindev@gmail.com>
Subject: [PATCH v2] serial: core: shut down initialized port on removal
Date: Sat,  3 Oct 2026 19:33:37 +0300	[thread overview]
Message-ID: <20261003163337.45577-1-igorpetindev@gmail.com> (raw)
In-Reply-To: <20260924192224.3175-1-igorpetindev@gmail.com>

When a serial port configured as a console is opened and subsequently
closed, tty_port_shutdown() skips invoking port->ops->shutdown() because
port->console is true. As a result, tty_port_initialized() remains true
and the port's interrupt handler stays registered in the irq subsystem.

If the underlying device is later unbound or removed (e.g. via sysfs
driver unbind or device hot-unplug), serial_core_remove_one_port()
unregisters the console, frees uport->name via kfree(), and tears down
the port without shutting it down or freeing its IRQ. Consequently, the
irqaction descriptor remains registered in genirq with action->name
pointing to freed memory.

This triggers a use-after-free read whenever genirq accesses action->name,
such as when reading /proc/interrupts:

  BUG: KASAN: slab-use-after-free in string+0x476/0x570
  Call Trace:
   string+0x476/0x570
   vsnprintf+0x422/0x1300
   seq_printf+0x...
   show_interrupts+...

Fix this by acquiring port->mutex in serial_core_remove_one_port() after
console unregistration, clearing port->console under the mutex to prevent
data races with concurrent tty_port_shutdown(), and invoking
uart_shutdown(NULL, state) if the port remains initialized. This ensures
that port->ops->shutdown() is called and the IRQ is freed before
kfree(uport->name).

Reported-by: syzbot+843bf2f48f4d12e6682e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=843bf2f48f4d12e6682e
Fixes: 761ed4a94582 ("tty: serial_core: convert uart_close to use tty_port_close")
Fixes: f7048b15900f ("tty: serial_core: Add name field to uart_port struct")
Signed-off-by: Igor Putko <igorpetindev@gmail.com>
---
v1 -> v2:
- Clear port->console under port->mutex using scoped_guard() to fix
  the data race pointed out by sashiko-bot.
- Verified without synthetic devices by reproducing via sysfs driver
  unbind (00:04 serial pnp device) and inspecting /proc/interrupts.
- Do not hold port->mutex across release_port() to preserve existing
  locking semantics.

Reproducer steps (tested on QEMU with console=ttyS0):
1. Open and close the console port:
   exec 3</dev/ttyS0 && exec 3<&-
2. Unbind the serial device:
   echo "00:04" > /sys/bus/pnp/drivers/serial/unbind
3. Read interrupts:
   cat /proc/interrupts
   -> triggers KASAN use-after-free in show_interrupts() without this fix.

 drivers/tty/serial/serial_core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 95774b0f1..f6253cd30 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -3213,6 +3213,13 @@ static void serial_core_remove_one_port(struct uart_driver *drv,
 	if (uart_console(uport))
 		unregister_console(uport->cons);

+	scoped_guard(mutex, &port->mutex) {
+		port->console = false;
+
+		if (tty_port_initialized(port))
+			uart_shutdown(NULL, state);
+	}
+
 	/*
 	 * Free the port IO and memory resources, if any.
 	 */
-- 
2.53.0


  parent reply	other threads:[~2026-10-03 16:33 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-24 19:22 [PATCH] serial: core: shut down initialized port on removal Igor Putko
2026-09-24 19:39 ` sashiko-bot
2026-09-25  5:34 ` Greg Kroah-Hartman
2026-09-26 13:05 ` IgorpetinDev
2026-10-01  8:58   ` Greg KH
2026-10-03 16:33 ` Igor Putko [this message]
2026-10-03 17:56   ` [PATCH v2] " sashiko-bot
2026-10-13 16:45   ` Phil Rosenthal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261003163337.45577-1-igorpetindev@gmail.com \
    --to=igorpetindev@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jirislaby@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=syzbot+843bf2f48f4d12e6682e@syzkaller.appspotmail.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.