Skip to content

Commit 26a43ca

Browse files
djiatsaf-stdkalowsk
authored andcommitted
drivers: serial: stm32: prevent race condition
The async_user_callback could be triggered from both the DMA transfer complete interrupt and a k_work queue timeout. Since the timeout runs outside of an ISR context, it could be interrupted by the DMA ISR. This might leads to a race condition where both paths access and modify shared DMA buffer state (offset and length) simultaneously, causing data corruption or out-of-sequence processing. Introduces proper synchronization to prevent concurrent access to shared DMA buffer variables, ensuring consistent and reliable data handling. Signed-off-by: Fabrice DJIATSA <fabrice.djiatsa-ext@st.com>
1 parent 21daac5 commit 26a43ca

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

drivers/serial/uart_stm32.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,11 +1806,21 @@ static void uart_stm32_async_rx_timeout(struct k_work *work)
18061806

18071807
LOG_DBG("rx timeout");
18081808

1809+
/* The DMA is still active and could trigger an interrupt
1810+
* while we are processing this timeout, which could cause
1811+
* data corruption when the DMA ISR modifies shared data
1812+
* as we are operating on it. Prevent data race with ISR by
1813+
* masking all interrupts until we're done.
1814+
*/
1815+
unsigned int key = irq_lock();
1816+
18091817
if (data->dma_rx.counter == data->dma_rx.buffer_length) {
18101818
uart_stm32_async_rx_disable(dev);
18111819
} else {
18121820
uart_stm32_dma_rx_flush(dev, STM32_ASYNC_STATUS_TIMEOUT);
18131821
}
1822+
1823+
irq_unlock(key);
18141824
}
18151825

18161826
static void uart_stm32_async_tx_timeout(struct k_work *work)

0 commit comments

Comments
 (0)