From 7596f24296bffbb02eeb7e13b6580d67ccaf798e Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 9 Mar 2022 14:11:50 +0000 Subject: [PATCH] Add backstop check for taint of executable name when calling exec() --- src/src/child.c | 8 +++++++- src/src/exim.c | 2 +- src/src/smtp_in.c | 1 + src/src/transport.c | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/src/child.c b/src/src/child.c index 267306ee3..4c0dbabd1 100644 --- a/src/src/child.c +++ b/src/src/child.c @@ -81,7 +81,7 @@ argv = store_get((extra + acount + MAX_CLMACROS + 24) * sizeof(char *), GET_UNTA /* In all case, the list starts out with the path, any macros, and a changed config file. */ -argv[n++] = exim_path; +argv[n++] = exim_path; /* assume untainted */ if (clmacro_count > 0) { memcpy(argv + n, clmacros, clmacro_count * sizeof(uschar *)); @@ -343,6 +343,12 @@ int save_errno; int inpfd[2], outpfd[2]; pid_t pid; +if (is_tainted(argv[0])) + { + log_write(0, LOG_MAIN | LOG_PANIC, "Attempt to exec tainted path: '%s'", argv[0]); + return (pid_t)(-1); + } + /* Create the pipes. */ if (pipe(inpfd) != 0) return (pid_t)(-1); diff --git a/src/src/exim.c b/src/src/exim.c index eada6bbf8..ade96fe20 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -4397,7 +4397,7 @@ if (bi_option) { int i = 0; uschar *argv[3]; - argv[i++] = bi_command; + argv[i++] = bi_command; /* nonexpanded option so assume untainted */ if (alias_arg) argv[i++] = alias_arg; argv[i++] = NULL; diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 852148fcf..3fe3dab82 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -5911,6 +5911,7 @@ while (done <= 0) { DEBUG(D_exec) debug_print_argv(argv); exim_nullstd(); /* Ensure std{in,out,err} exist */ + /* argv[0] should be untainted, from child_exec_exim() */ execv(CS argv[0], (char *const *)argv); log_write(0, LOG_MAIN|LOG_PANIC_DIE, "exec of \"%s\" (ETRN) failed: %s", etrn_command, strerror(errno)); diff --git a/src/src/transport.c b/src/src/transport.c index 8b320ecc2..37623ea1a 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -1972,6 +1972,7 @@ if (socket_fd != 0) DEBUG(D_exec) debug_print_argv(argv); exim_nullstd(); /* Ensure std{out,err} exist */ +/* argv[0] should be untainted, from child_exec_exim() */ execv(CS argv[0], (char *const *)argv); DEBUG(D_any) debug_printf("execv failed: %s\n", strerror(errno)); -- 2.30.2