You're correct, I was explicitly just trying to fix CVE-2024-58251 and not make any other changes but I see what you're saying. I think this solution would address most of the issues but like you said it's not fool-proof. This is an update from my original.
From: Kyle Steere <[email protected]> Date: Thu, 22 Aug 2024 12:00:00 -0500 Subject: [PATCH] Fix CVE-2024-58251: Filter escape sequences from process names Use the existing printable_string() function to sanitize process names in ps, top, pmap, and netstat. Add init_unicode() calls to enable filtering of C1 control characters (0x80-0x9F). Signed-off-by: Kyle Steere <[email protected]> --- diff --git a/libbb/procps.c b/libbb/procps.c index f56b71b21..abc7c6b14 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -584,7 +584,8 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) strchrnul(buf, ' ')[0] = '\0'; base = bb_basename(buf); /* before we replace argv0's NUL with space */ while (sz >= 0) { - if ((unsigned char)(buf[sz]) < ' ') + /* Only replace NUL with space, other controls handled by printable_string */ + if (buf[sz] == '\0') buf[sz] = ' '; sz--; } @@ -617,6 +618,14 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) } else { snprintf(buf, col, "[%s]", comm ? comm : "?"); } + + /* Sanitize the entire command line for terminal safety */ + const char *safe = printable_string(buf); + if (safe != buf) { + /* printable_string returned a new string, copy it back */ + int len = strlen(safe); + snprintf(buf, col, "%s", safe); + } } /* from kernel: diff --git a/networking/netstat.c b/networking/netstat.c index 807800a62..b098e9f23 100644 --- a/networking/netstat.c +++ b/networking/netstat.c @@ -41,6 +41,7 @@ #include "libbb.h" #include "inet_common.h" +#include "unicode.h" //usage:#define netstat_trivial_usage //usage: "[-"IF_ROUTE("r")"al] [-tuwx] [-en"IF_FEATURE_NETSTAT_WIDE("W")IF_FEATURE_NETSTAT_PRG("p")"]" @@ -316,7 +317,8 @@ static int FAST_FUNC dir_act(struct recursive_state *state, /* go through all files in /proc/PID/fd and check whether they are sockets */ strcpy(proc_pid_fname + len - (sizeof("cmdline")-1), "fd"); - pid_slash_progname = concat_path_file(pid, bb_basename(cmdline_buf)); /* "PID/argv0" */ + /* Sanitize argv[0] to prevent terminal escape sequences (CVE-2024-58251) */ + pid_slash_progname = concat_path_file(pid, printable_string(bb_basename(cmdline_buf))); /* "PID/argv0" */ n = recursive_action(proc_pid_fname, ACTION_RECURSE | ACTION_QUIET, add_to_prg_cache_if_socket, @@ -686,6 +688,7 @@ int netstat_main(int argc UNUSED_PARAM, char **argv) unsigned opt; INIT_G(); + init_unicode(); /* Option string must match NETSTAT_xxx constants */ opt = getopt32(argv, NETSTAT_OPTS); diff --git a/procps/pmap.c b/procps/pmap.c index 49f7688d9..3b367d34c 100644 --- a/procps/pmap.c +++ b/procps/pmap.c @@ -26,6 +26,7 @@ //usage: "\n -q Quiet" #include "libbb.h" +#include "unicode.h" #if ULLONG_MAX == 0xffffffff # define TABS "\t" @@ -96,6 +97,8 @@ int pmap_main(int argc UNUSED_PARAM, char **argv) unsigned opts; int ret; + init_unicode(); + opts = getopt32(argv, "^" "xq" "\0" "-1"); /* min one arg */ argv += optind; diff --git a/procps/ps.c b/procps/ps.c index 5b521aebd..f184f25ac 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -109,6 +109,7 @@ //usage: " 2990 andersen andersen R ps\n" #include "libbb.h" +#include "unicode.h" #include "common_bufsiz.h" #ifdef __linux__ # include <sys/sysinfo.h> @@ -576,6 +577,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv) G.kernel_HZ = bb_clk_tck(); /* this is sysconf(_SC_CLK_TCK) */ # endif #endif + init_unicode(); // POSIX: // -a Write information for all processes associated with terminals diff --git a/procps/top.c b/procps/top.c index 09d31c673..64acbafcb 100644 --- a/procps/top.c +++ b/procps/top.c @@ -116,6 +116,7 @@ //kbuild:lib-$(CONFIG_TOP) += top.o #include "libbb.h" +#include "unicode.h" #define ESC "\033" @@ -1160,6 +1161,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) unsigned scan_mask = TOP_MASK; INIT_G(); + init_unicode(); interval = 5; /* default update interval is 5 seconds */ iterations = 0; /* infinite */ Kyle Steere Senior Software Engineer Chainguard [email protected] | chainguard.dev <http://www.chainguard.dev> <https://github.com/chainguard-dev> <https://www.linkedin.com/company/chainguard-dev/> <https://x.com/chainguard_dev> On Fri, Aug 22, 2025 at 3:30 PM Valery Ushakov <[email protected]> wrote: > On Thu, Aug 21, 2025 at 22:56:20 +0000, Kyle Steere wrote: > > > In BusyBox netstat, local users can launch a network application with an > > argv[0] containing ANSI terminal escape sequences, leading to a denial of > > service (terminal locked up) when netstat is used by a victim. > > > > This patch sanitizes the process name before storing it in the cache, > > replacing any non-printable characters (including escape sequences) with > > '?'. > > > > CVE-2024-58251: https://nvd.nist.gov/vuln/detail/CVE-2024-58251 > > This might, pedantically speaking, tick off the CVE as reported, but > the very same process will trigger the exact same problem with ps(1) > &c that sanitizes C0 controls, but doesn't sanitize C1 controls (and > doesn't sanitize the {comm} part at all, btw, even for C0). I > recently posted about that, but got no feedback: > > https://lists.busybox.net/pipermail/busybox/2025-August/091682.html > https://lists.busybox.net/pipermail/busybox/2025-August/091683.html > > With ps &c you don't even need the argv[0] trickery that you need with > netstat (as neststat only shows argv[0]), just passing the offending > string as an argument is enough. > > The attached patch tries to address that issue too. It's probably > better done with some refactoring, but for now I did it defadvice > style. It's not very thoroughly tested. > > As explained in the second patch description, you cannot make this > completely fool-proof, b/c C1 bytes may be part of UTF-8 encoding for > normal characters. > > -uwe > _______________________________________________ > busybox mailing list > [email protected] > https://lists.busybox.net/mailman/listinfo/busybox >
_______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox
