shell: Add synchronization for prompt-string access in shell
Resolved a data race in shell.c by copying the user-provided prompt-string into a private buffer within the shell, ensuring proper synchronization with the shell-thread. Fixes: #64972 Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@verkada.com>
This commit is contained in:
parent
7a8d454e22
commit
f8263e8293
|
@ -26,6 +26,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SHELL_PROMPT_BUFF_SIZE
|
||||
#define CONFIG_SHELL_PROMPT_BUFF_SIZE 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SHELL_CMD_BUFF_SIZE
|
||||
#define CONFIG_SHELL_CMD_BUFF_SIZE 0
|
||||
#endif
|
||||
|
@ -779,7 +783,11 @@ enum shell_signal {
|
|||
* @brief Shell instance context.
|
||||
*/
|
||||
struct shell_ctx {
|
||||
const char *prompt; /*!< shell current prompt. */
|
||||
#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE
|
||||
char prompt[CONFIG_SHELL_PROMPT_BUFF_SIZE]; /*!< shell current prompt. */
|
||||
#else
|
||||
const char *prompt;
|
||||
#endif
|
||||
|
||||
enum shell_state state; /*!< Internal module state.*/
|
||||
enum shell_receive_state receive_state;/*!< Escape sequence indicator.*/
|
||||
|
|
|
@ -55,6 +55,24 @@ config SHELL_BACKSPACE_MODE_DELETE
|
|||
Some terminals send code: 0x08 (backspace) other 0x7F (delete). When
|
||||
this option is set shell will expect 0x7F for backspace key.
|
||||
|
||||
config SHELL_PROMPT_CHANGE
|
||||
bool "Allow prompt change in runtime"
|
||||
default y if !SHELL_MINIMAL
|
||||
help
|
||||
Allow for the modification of the shell prompt at runtime.
|
||||
Enabling this will allocate additional RAM memory where
|
||||
the string of the prompt will be stored.
|
||||
|
||||
config SHELL_PROMPT_BUFF_SIZE
|
||||
int "Shell prompt buffer size"
|
||||
depends on SHELL_PROMPT_CHANGE
|
||||
range 2 40
|
||||
default 10 if SHELL_MINIMAL
|
||||
default 20
|
||||
help
|
||||
Maximum prompt size in bytes. One byte is reserved for the string
|
||||
terminator character.
|
||||
|
||||
config SHELL_CMD_BUFF_SIZE
|
||||
int "Shell command buffer size"
|
||||
default 128 if SHELL_MINIMAL
|
||||
|
|
|
@ -1208,7 +1208,6 @@ static int instance_init(const struct shell *sh,
|
|||
(sh->shell_flag == SHELL_FLAG_OLF_CRLF));
|
||||
|
||||
memset(sh->ctx, 0, sizeof(*sh->ctx));
|
||||
sh->ctx->prompt = sh->default_prompt;
|
||||
if (CONFIG_SHELL_CMD_ROOT[0]) {
|
||||
sh->ctx->selected_cmd = root_cmd_find(CONFIG_SHELL_CMD_ROOT);
|
||||
}
|
||||
|
@ -1235,7 +1234,13 @@ static int instance_init(const struct shell *sh,
|
|||
CONFIG_SHELL_DEFAULT_TERMINAL_WIDTH;
|
||||
sh->ctx->vt100_ctx.cons.terminal_hei =
|
||||
CONFIG_SHELL_DEFAULT_TERMINAL_HEIGHT;
|
||||
|
||||
#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE
|
||||
shell_prompt_change(sh, sh->default_prompt);
|
||||
#else
|
||||
sh->ctx->prompt = sh->default_prompt;
|
||||
sh->ctx->vt100_ctx.cons.name_len = z_shell_strlen(sh->ctx->prompt);
|
||||
#endif
|
||||
|
||||
/* Configure backend according to enabled shell features and backend
|
||||
* specific settings.
|
||||
|
@ -1614,15 +1619,35 @@ void shell_hexdump(const struct shell *sh, const uint8_t *data, size_t len)
|
|||
|
||||
int shell_prompt_change(const struct shell *sh, const char *prompt)
|
||||
{
|
||||
#if defined(CONFIG_SHELL_PROMPT_CHANGE) && CONFIG_SHELL_PROMPT_CHANGE
|
||||
__ASSERT_NO_MSG(sh);
|
||||
|
||||
if (prompt == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
sh->ctx->prompt = prompt;
|
||||
sh->ctx->vt100_ctx.cons.name_len = z_shell_strlen(prompt);
|
||||
|
||||
static const size_t mtx_timeout_ms = 20;
|
||||
size_t prompt_length = z_shell_strlen(prompt);
|
||||
|
||||
if (k_mutex_lock(&sh->ctx->wr_mtx, K_MSEC(mtx_timeout_ms))) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if ((prompt_length + 1 > CONFIG_SHELL_PROMPT_BUFF_SIZE) || (prompt_length == 0)) {
|
||||
k_mutex_unlock(&sh->ctx->wr_mtx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
strcpy(sh->ctx->prompt, prompt);
|
||||
|
||||
sh->ctx->vt100_ctx.cons.name_len = prompt_length;
|
||||
|
||||
k_mutex_unlock(&sh->ctx->wr_mtx);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -EPERM;
|
||||
#endif
|
||||
}
|
||||
|
||||
void shell_help(const struct shell *sh)
|
||||
|
|
Loading…
Reference in New Issue