From 17dc3da35d5ea692e015533bd4dd7a5dec6b35b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 12 Feb 2024 11:18:10 +0100 Subject: [PATCH] drivers: serial: uart_async_rx: Fix race condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a wrong order of conditions checking. First indexes were compared and then completed flag was checked. It was possible that after checking first condition context is preempted and new data is written to the buffer and completed flag is set. In that case both conditions are met but data added in preemption is dropped. In order to avoid that completed flag must be checked first. Signed-off-by: Krzysztof Chruściński --- drivers/serial/uart_async_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/serial/uart_async_rx.c b/drivers/serial/uart_async_rx.c index a411539bb7a..8aadddd6bef 100644 --- a/drivers/serial/uart_async_rx.c +++ b/drivers/serial/uart_async_rx.c @@ -91,7 +91,7 @@ size_t uart_async_rx_data_claim(struct uart_async_rx *rx_data, uint8_t **data, s /* Even though buffer is released in consume phase it is possible that * it is required here as well (e.g. was not completed previously). */ - if ((buf->rd_idx == buf->wr_idx) && (buf->completed == 1)) { + if ((buf->completed == 1) && (rx_data->rd_idx == buf->wr_idx)) { usr_rx_buf_release(rx_data, buf); } else { break; @@ -110,7 +110,7 @@ bool uart_async_rx_data_consume(struct uart_async_rx *rx_data, size_t length) buf->rd_idx += length; /* Attempt to release the buffer if it is completed and all data is consumed. */ - if ((buf->rd_idx == buf->wr_idx) && (buf->completed == 1)) { + if ((buf->completed == 1) && (rx_data->rd_idx == buf->wr_idx)) { usr_rx_buf_release(rx_data, buf); }