diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2022-03-09 14:11:50 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2022-03-09 14:11:50 +0000 |
commit | 7596f24296bffbb02eeb7e13b6580d67ccaf798e (patch) | |
tree | e37a0ad30a5441d3f7edbee1926d5efd5e1f7d4d /src | |
parent | 6e48a63849cd3f1dfb3555fe57094954b3f7f092 (diff) |
Add backstop check for taint of executable name when calling exec()
Diffstat (limited to 'src')
-rw-r--r-- | src/src/child.c | 8 | ||||
-rw-r--r-- | src/src/exim.c | 2 | ||||
-rw-r--r-- | src/src/smtp_in.c | 1 | ||||
-rw-r--r-- | 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)); |