From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Karl Mehltretter <kmehltretter@gmail.com>
Cc: Jiri Slaby <jirislaby@kernel.org>, Frank Li <Frank.Li@nxp.com>,
Sascha Hauer <s.hauer@pengutronix.de>,
Pengutronix Kernel Team <kernel@pengutronix.de>,
Fabio Estevam <festevam@gmail.com>,
linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
Sashiko <sashiko-bot@kernel.org>,
stable@vger.kernel.org
Subject: Re: [PATCH v2 4/4] serial: imx: serialize imx_uart_ports[] lifetime
Date: Thu, 30 Jul 2026 16:31:51 +0200 [thread overview]
Message-ID: <2026073011-crock-utmost-6392@gregkh> (raw)
In-Reply-To: <20260719221014.44354-5-kmehltretter@gmail.com>
On Mon, Jul 20, 2026 at 12:10:14AM +0200, Karl Mehltretter wrote:
> imx_uart_probe() publishes the port in imx_uart_ports[] before
> uart_add_one_port(), because console setup during that call uses the
> table. The entry is not cleared if adding the port fails or after
> imx_uart_remove() removes it.
>
> The port is devm-allocated, so a failed probe or unbind leaves the table
> pointing at freed memory. A later registration of the shared console can
> then dereference the stale entry. Reproduced on QEMU's mcimx6ul-evk by
> unbinding a sibling UART, unbinding the console UART and rebinding the
> sibling:
>
> BUG: KASAN: slab-use-after-free in imx_uart_console_setup+0xd0/0x3d8
>
> The entry must remain valid until uart_remove_one_port() unregisters the
> console. Clearing it afterward without serialization still races a
> sibling probe: the sibling can register the shared console using the
> dying entry before it is cleared. The next console write then
> dereferences NULL.
>
> Use a driver-wide mutex to serialize table publication, port addition
> and rollback with port removal and table clearing. Console callbacks
> remain lockless because uart_add_one_port() may invoke setup while
> probe holds the mutex.
>
> The probe-failure path also relies on "serial: core: do fallible
> allocations before the console can be registered", which moves the
> uport->name and uport->tty_groups allocations before console
> registration. Both changes should be backported together.
>
> Fixes: dbff4e9ea2e8 ("IMX UART: remove statically initialized tables")
> Fixes: 9f322ad064f9 ("imx: serial: handle initialisation failure correctly")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Link: https://lore.kernel.org/all/20260719162850.043B41F000E9@smtp.kernel.org
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-fable-5
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> ---
> drivers/tty/serial/imx.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 251a50c8aa38..def874f9cd00 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -22,6 +22,7 @@
> #include <linux/clk.h>
> #include <linux/delay.h>
> #include <linux/ktime.h>
> +#include <linux/mutex.h>
> #include <linux/pinctrl/consumer.h>
> #include <linux/rational.h>
> #include <linux/slab.h>
> @@ -2080,6 +2081,15 @@ static const struct uart_ops imx_uart_pops = {
>
> static struct imx_port *imx_uart_ports[UART_NR];
>
> +/*
> + * Store the port in imx_uart_ports[] before uart_add_one_port() and clear
> + * it only after uart_remove_one_port() returns. Console callbacks in both
> + * calls use the table, so this mutex serializes these sequences between
> + * sibling ports. Callbacks must not take it because uart_add_one_port()
> + * may invoke setup while it is held.
> + */
> +static DEFINE_MUTEX(imx_uart_ports_lock);
Again, LLMs love to write comments/text, be sane please. This comment
has nothing to do with the storing and such.
> +
> #if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE)
> static void imx_uart_console_putchar(struct uart_port *port, unsigned char ch)
> {
> @@ -2632,11 +2642,14 @@ static int imx_uart_probe(struct platform_device *pdev)
> }
> }
>
> - imx_uart_ports[sport->port.line] = sport;
> -
> platform_set_drvdata(pdev, sport);
>
> + mutex_lock(&imx_uart_ports_lock);
guard()?
> + imx_uart_ports[sport->port.line] = sport;
> ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port);
> + if (ret)
> + imx_uart_ports[sport->port.line] = NULL;
> + mutex_unlock(&imx_uart_ports_lock);
>
> err_clk:
> clk_disable_unprepare(sport->clk_ipg);
> @@ -2647,8 +2660,12 @@ static int imx_uart_probe(struct platform_device *pdev)
> static void imx_uart_remove(struct platform_device *pdev)
> {
> struct imx_port *sport = platform_get_drvdata(pdev);
> + unsigned int line = sport->port.line;
Why are you reading this outside of the lock?
>
> + mutex_lock(&imx_uart_ports_lock);
guard()?
thanks,
greg k-h
next prev parent reply other threads:[~2026-07-30 16:19 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-19 22:10 [PATCH v2 0/4] serial: fix console lifetime bugs on failed bind and removal Karl Mehltretter
2026-07-19 22:10 ` [PATCH v2 1/4] serial: core: do fallible allocations before the console can be registered Karl Mehltretter
2026-07-30 14:28 ` Greg Kroah-Hartman
2026-07-19 22:10 ` [PATCH v2 2/4] serial: core: clear freed pointers on uart_register_driver() failure Karl Mehltretter
2026-07-30 14:28 ` Greg Kroah-Hartman
2026-07-19 22:10 ` [PATCH v2 3/4] tty: don't oops in tty_unregister_device() when no cdev is registered Karl Mehltretter
2026-07-30 14:29 ` Greg Kroah-Hartman
2026-07-19 22:10 ` [PATCH v2 4/4] serial: imx: serialize imx_uart_ports[] lifetime Karl Mehltretter
2026-07-19 22:25 ` sashiko-bot
2026-07-30 14:31 ` Greg Kroah-Hartman [this message]
2026-07-30 19:02 ` Frank Li
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=2026073011-crock-utmost-6392@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=Frank.Li@nxp.com \
--cc=festevam@gmail.com \
--cc=imx@lists.linux.dev \
--cc=jirislaby@kernel.org \
--cc=kernel@pengutronix.de \
--cc=kmehltretter@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=sashiko-bot@kernel.org \
--cc=stable@vger.kernel.org \
/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.