From 982a06e3ecae45893e8db50d5b18b1a5ea514f1c Mon Sep 17 00:00:00 2001 From: Jakub Rzeszutko Date: Tue, 8 Oct 2024 15:06:23 +0200 Subject: [PATCH] shell: flush RX buffer on resume to prevent unexpected commands Introduced an RX buffer flush in the backend when calling shell_start. Previously, after shell_stop, the backend continued buffering data and commands. When shell_start was called, all buffered data was processed, leading to the potential execution of commands issued while the shell was inactive. This update ensures the RX buffer is flushed upon resuming the shell, preventing unexpected command execution. Signed-off-by: Jakub Rzeszutko --- subsys/shell/shell.c | 8 ++++++++ subsys/shell/shell_ops.c | 15 +++++++++++++++ subsys/shell/shell_ops.h | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 3ffe26914170ae..2f36a1b60b7ad8 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1452,6 +1452,14 @@ int shell_start(const struct shell *sh) z_cursor_next_line_move(sh); state_set(sh, SHELL_STATE_ACTIVE); + /* + * If the shell is stopped with the shell_stop function, its backend remains active + * and continues to buffer incoming data. As a result, when the shell is resumed, + * all buffered data is processed, which may lead to the execution of commands + * received while the shell was stopped. + */ + z_shell_backend_rx_buffer_flush(sh); + k_mutex_unlock(&sh->ctx->wr_mtx); return 0; diff --git a/subsys/shell/shell_ops.c b/subsys/shell/shell_ops.c index b7f68e22a5832b..f3dd057c00bc84 100644 --- a/subsys/shell/shell_ops.c +++ b/subsys/shell/shell_ops.c @@ -548,3 +548,18 @@ void z_shell_fprintf(const struct shell *sh, z_shell_vfprintf(sh, color, fmt, args); va_end(args); } + +void z_shell_backend_rx_buffer_flush(const struct shell *sh) +{ + __ASSERT_NO_MSG(sh); + + int32_t max_iterations = 1000; + uint8_t buf[64]; + size_t count = 0; + int err; + + do { + err = (void)sh->iface->api->read(sh->iface, buf, + sizeof(buf), &count); + } while (count != 0 && err == 0 && --max_iterations > 0); +} diff --git a/subsys/shell/shell_ops.h b/subsys/shell/shell_ops.h index b72d6456cb69fc..c673c974331dd8 100644 --- a/subsys/shell/shell_ops.h +++ b/subsys/shell/shell_ops.h @@ -372,6 +372,15 @@ void z_shell_fprintf(const struct shell *sh, enum shell_vt100_color color, void z_shell_vfprintf(const struct shell *sh, enum shell_vt100_color color, const char *fmt, va_list args); +/** + * @brief Flushes the shell backend receive buffer. + * + * This function repeatedly reads from the shell interface's receive buffer + * until it is empty or a maximum number of iterations is reached. + * It ensures that no additional data is left in the buffer. + */ +void z_shell_backend_rx_buffer_flush(const struct shell *sh); + #ifdef __cplusplus } #endif