Re: [PATCH] serial: imx: cancel RS485 trigger hrtimers in shutdown and remove

[email protected]
Newsgroups dev.linux.lists.imx
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing cancellation of `sport->timer` and modem status GPIO IRQs in `imx_uart_remove()` leads to a use-after-free and system crash (bus fault) for console ports.
--

--- Patch [1]: [PATCH] serial: imx: cancel RS485 trigger hrtimers in shutdown and remove ---
commit 00c3fef931cf8afdbbbb1c6e8dc49797a632d082
Author: Fan Wu <[email protected]>

serial: imx: cancel RS485 trigger hrtimers in shutdown and remove

This commit cancels the RS485 trigger hrtimers synchronously in
imx_uart_shutdown() and imx_uart_remove() to prevent use-after-free
after the devm-allocated port is freed.

> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 251a50c8aa387..86c99f73c50a3 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c

[ ... ]

> @@ -2649,6 +2653,10 @@ static void imx_uart_remove(struct platform_device *pdev)
>  	struct imx_port *sport = platform_get_drvdata(pdev);
>  
>  	uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
> +
> +	/* Serial core can reach remove() without calling the driver shutdown. */
> +	hrtimer_cancel(&sport->trigger_start_tx);
> +	hrtimer_cancel(&sport->trigger_stop_tx);

[Severity: High]
This is a pre-existing issue, but since we are cancelling timers in
imx_uart_remove(), does this function also need to cancel sport->timer and
disable the modem status GPIO IRQs?

If the system boots with hardware flow control enabled on the console,
imx_uart_console_setup() sets termios, which calls imx_uart_enable_ms() and
arms sport->timer.

If the driver is unbound via sysfs or the module is unloaded,
imx_uart_remove() unregisters the console, disabling the UART clocks.
However, it does not cancel sport->timer or disable the MS GPIO interrupts.

When devres frees the imx_port structure, the timer can still fire:

drivers/tty/serial/imx.c:imx_uart_timeout() {
        struct imx_port *sport = timer_container_of(sport, t, timer);
        unsigned long flags;

        if (sport->port.state) {
                uart_port_lock_irqsave(&sport->port, &flags);
                imx_uart_mctrl_check(sport);
                uart_port_unlock_irqrestore(&sport->port, flags);

                mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT);
        }
}

Could this lead to accessing the freed sport struct and reading disabled
UART registers, resulting in a use-after-free and system crash?

>  }
>  
>  static void imx_uart_restore_context(struct imx_port *sport)

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.