X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/73141a5abf8a3699249e401522fe9174b5aa8a1b..1d28cc061677bd07d9bed48dd84bd5c590247043:/src/src/child.c diff --git a/src/src/child.c b/src/src/child.c index 948e0d669..359b791e8 100644 --- a/src/src/child.c +++ b/src/src/child.c @@ -2,9 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ -/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" @@ -76,22 +77,19 @@ int n = 0; int extra = pcount ? *pcount : 0; uschar **argv; -argv = store_get((extra + acount + MAX_CLMACROS + 21) * sizeof(char *), FALSE); +argv = store_get((extra + acount + MAX_CLMACROS + 24) * sizeof(char *), GET_UNTAINTED); /* 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 *)); n += clmacro_count; } if (f.config_changed) - { - argv[n++] = US"-C"; - argv[n++] = config_main_filename; - } + { argv[n++] = US"-C"; argv[n++] = config_main_filename; } /* These values are added only for non-minimal cases. If debug_selector is precisely D_v, we have to assume this was started by a non-admin user, and @@ -108,24 +106,35 @@ if (!minimal) else { if (debug_selector != 0) + { argv[n++] = string_sprintf("-d=0x%x", debug_selector); + if (debug_fd > 2) + { + int flags = fcntl(debug_fd, F_GETFD); + if (flags != -1) (void)fcntl(debug_fd, F_SETFD, flags & ~FD_CLOEXEC); + close(2); + dup2(debug_fd, 2); + close(debug_fd); + } + } } + if (debug_pretrigger_buf) + { argv[n++] = US"-dp"; argv[n++] = string_sprintf("0x%x", debug_pretrigger_bsize); } + if (dtrigger_selector != 0) + argv[n++] = string_sprintf("-dt=0x%x", dtrigger_selector); DEBUG(D_any) { argv[n++] = US"-MCd"; argv[n++] = US process_purpose; } - if (!f.testsuite_delays) argv[n++] = US"-odd"; - if (f.dont_deliver) argv[n++] = US"-N"; - if (f.queue_smtp) argv[n++] = US"-odqs"; - if (f.synchronous_delivery) argv[n++] = US"-odi"; + if (!f.testsuite_delays) argv[n++] = US"-odd"; + if (f.dont_deliver) argv[n++] = US"-N"; + if (f.queue_smtp) argv[n++] = US"-odqs"; + if (f.synchronous_delivery) argv[n++] = US"-odi"; if (connection_max_messages >= 0) argv[n++] = string_sprintf("-oB%d", connection_max_messages); if (*queue_name) - { - argv[n++] = US"-MCG"; - argv[n++] = queue_name; - } + { argv[n++] = US"-MCG"; argv[n++] = queue_name; } } /* Now add in any others that are in the call. Remember which they were, @@ -159,7 +168,7 @@ exim_nullstd(); /* Make sure std{in,out,err} exist */ execv(CS argv[0], (char *const *)argv); log_write(0, - LOG_MAIN | ((exec_type == CEE_EXEC_EXIT)? LOG_PANIC : LOG_PANIC_DIE), + LOG_MAIN | (exec_type == CEE_EXEC_EXIT ? LOG_PANIC : LOG_PANIC_DIE), "re-exec of exim (%s) with %s failed: %s", exim_path, argv[first_special], strerror(errno)); @@ -335,6 +344,13 @@ 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]); + errno = EPERM; + return (pid_t)(-1); + } + /* Create the pipes. */ if (pipe(inpfd) != 0) return (pid_t)(-1);