From ab4bd9c707cd3e872039abd00b3274a01d7dd1c2 Mon Sep 17 00:00:00 2001 From: layderv <20249311+layderv@users.noreply.github.com> Date: Sun, 15 Jan 2023 05:50:31 -0500 Subject: Escape control characters Names and commands can contain control characters: ``` firejail --name="$(echo -e '\e[31mRed\n\b\b\bText\e[0m')" sleep 10s ``` results in "Text" printed in red. Prevent commands like `--tree` to control the terminal. --- src/lib/common.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/pid.c | 16 +++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/common.c b/src/lib/common.c index 111366782..338e9316c 100644 --- a/src/lib/common.c +++ b/src/lib/common.c @@ -404,6 +404,61 @@ char *replace_cntrl_chars(const char *str, char c) { return rv; } +char *escape_cntrl_chars(const char *str) { + if (str) { + unsigned int cntrl_chars = 0; + const char *c = str; + while (*c) { + switch (*c++) { + case '\b': + case '\a': + case '\e': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': + case '\"': + case '\'': + case '\?': + case '\\': + ++cntrl_chars; + default: break; + } + } + char *rv = malloc(strlen(str) + cntrl_chars + 1); + char *ptr = rv; + if (!rv) + errExit("malloc"); + c = str; + while (*c) { + if (iscntrl(*c)) { + *ptr++ = '\\'; + switch (*c) { + case '\b': *ptr++ = 'b'; break; + case '\a': *ptr++ = 'a'; break; + case '\e': *ptr++ = 'e'; break; + case '\f': *ptr++ = 'f'; break; + case '\n': *ptr++ = 'n'; break; + case '\r': *ptr++ = 'r'; break; + case '\t': *ptr++ = 't'; break; + case '\v': *ptr++ = 'v'; break; + case '\"': *ptr++ = '\"'; break; + case '\'': *ptr++ = '\''; break; + case '\?': *ptr++ = '?'; break; + case '\\': *ptr++ = '\\'; break; + } + } else { + *ptr++ = *c; + } + c++; + } + *ptr = '\0'; + return rv; + } + return NULL; +} + int has_cntrl_chars(const char *str) { assert(str); diff --git a/src/lib/pid.c b/src/lib/pid.c index 5e9b20c94..cb9686648 100644 --- a/src/lib/pid.c +++ b/src/lib/pid.c @@ -197,6 +197,12 @@ static void print_elem(unsigned index, int nowrap) { char *user = pid_get_user_name(uid); char *user_allocated = user; + char *cmd_escape = escape_cntrl_chars(cmd); + if (cmd_escape) { + free(cmd); + cmd = cmd_escape; + } + // extract sandbox name - pid == index char *sandbox_name = ""; char *sandbox_name_allocated = NULL; @@ -224,7 +230,15 @@ static void print_elem(unsigned index, int nowrap) { } free(fname); - if (user ==NULL) + char *sandbox_name_escape = escape_cntrl_chars(sandbox_name); + if (sandbox_name_escape) { + if (sandbox_name_allocated) + free(sandbox_name_allocated); + sandbox_name = sandbox_name_escape; + sandbox_name_allocated = sandbox_name; + } + + if (user == NULL) user = ""; if (cmd) { if (col < 4 || nowrap) -- cgit v1.2.3-54-g00ecf