[PATCH 2/2] tty: serial: samsung: do not re-arm RX DMA once RX has been stopped

From: Samarth Narang

Date: Fri Oct 30 2026 - 20:42:41 EST


s3c24xx_serial_rx_dma_complete() unconditionally submits a new RX
descriptor after each completion, even when reception has been stopped
or the port is shutting down. A completion racing with
s3c24xx_serial_stop_rx() or shutdown may therefore restart DMA after the
channel has been terminated, potentially allowing it to access the RX
buffer after s3c24xx_serial_release_dma() has unmapped and freed it.

Only re-arm RX DMA while rx_enabled is set, and clear the flag under the
port lock during shutdown, since the hangup path can reach
s3c64xx_serial_shutdown() without calling stop_rx(). Because the
completion callback also holds the port lock, any descriptor submitted
before rx_enabled is cleared will be covered by the subsequent channel
termination.

Fixes: b543c301c2c5 ("serial: samsung: add DMA support for RX")
Link: https://lore.kernel.org/r/20261030162334.3000737-1-samarth.colleges@xxxxxxxxx
Assisted-by: LLM
Signed-off-by: Samarth Narang <samarth.colleges@xxxxxxxxx>
---
drivers/tty/serial/samsung_tty.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 2f6c69bec..3f2346f4f 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -622,7 +622,8 @@ static void s3c24xx_serial_rx_dma_complete(void *args)
tty_kref_put(tty);
}

- s3c64xx_start_rx_dma(ourport);
+ if (ourport->rx_enabled)
+ s3c64xx_start_rx_dma(ourport);

uart_port_unlock_irqrestore(port, flags);
}
@@ -1165,10 +1166,13 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
static void s3c64xx_serial_shutdown(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
+ unsigned long flags;

+ uart_port_lock_irqsave(port, &flags);
ourport->tx_enabled = 0;
ourport->tx_mode = 0;
ourport->rx_enabled = 0;
+ uart_port_unlock_irqrestore(port, flags);

free_irq(port->irq, ourport);

--
2.34.1