From f57629c95308cb87da059c37722bb8b65217f318 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 27 Apr 2017 12:28:08 -0600 Subject: [PATCH] On Linux, if the command we ran dumped core, set PR_SET_DUMPABLE to 0. This will prevent sudo itself from dumping core in this case. --- src/sudo.c | 60 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/sudo.c b/src/sudo.c index 0af1433f8..b5a081d02 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -70,6 +70,9 @@ # endif /* __hpux */ # include #endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ +#ifdef __linux__ +# include +#endif #include #include "sudo.h" @@ -104,7 +107,7 @@ static struct sudo_gc_list sudo_gc_list = SLIST_HEAD_INITIALIZER(sudo_gc_list); * Local functions */ static void fix_fds(void); -static void disable_coredumps(void); +static void disable_coredump(bool restore); static void sudo_check_suid(const char *path); static char **get_user_info(struct user_details *); static void command_info_to_details(char * const info[], @@ -136,9 +139,6 @@ static void iolog_close(struct plugin_container *plugin, int exit_status, static int iolog_show_version(struct plugin_container *plugin, int verbose); static void iolog_unlink(struct plugin_container *plugin); -#ifdef RLIMIT_CORE -static struct rlimit corelimit; -#endif #ifdef __linux__ static struct rlimit nproclimit; #endif @@ -201,7 +201,8 @@ main(int argc, char *argv[], char *envp[]) exit(EXIT_FAILURE); /* get_user_info printed error message */ /* Disable core dumps if not enabled in sudo.conf. */ - disable_coredumps(); + if (sudo_conf_disable_coredump()) + disable_coredump(false); /* Parse command line arguments. */ sudo_mode = parse_args(argc, argv, &nargc, &nargv, &settings, &env_add); @@ -300,11 +301,6 @@ main(int argc, char *argv[], char *envp[]) /* Become full root (not just setuid) so user cannot kill us. */ if (setuid(ROOT_UID) == -1) sudo_warn("setuid(%d)", ROOT_UID); - /* Restore coredumpsize resource limit before running. */ -#ifdef RLIMIT_CORE - if (sudo_conf_disable_coredump()) - (void) setrlimit(RLIMIT_CORE, &corelimit); -#endif /* RLIMIT_CORE */ if (ISSET(command_details.flags, CD_SUDOEDIT)) { status = sudo_edit(&command_details); } else { @@ -325,7 +321,7 @@ main(int argc, char *argv[], char *envp[]) sigaction_t sa; if (WCOREDUMP(status)) - disable_coredumps(); + disable_coredump(false); memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); @@ -899,27 +895,39 @@ sudo_check_suid(const char *sudo) /* * Disable core dumps to avoid dropping a core with user password in it. - * We will reset this limit before executing the command. + * Called with restore set to true before executing the command. * Not all operating systems disable core dumps for setuid processes. */ static void -disable_coredumps(void) +disable_coredump(bool restore) { -#if defined(RLIMIT_CORE) struct rlimit rl; - debug_decl(disable_coredumps, SUDO_DEBUG_UTIL) + static struct rlimit corelimit; +#ifdef __linux__ + static int dumpflag; +#endif + debug_decl(disable_coredump, SUDO_DEBUG_UTIL) - /* - * Turn off core dumps? - */ - if (sudo_conf_disable_coredump()) { - (void) getrlimit(RLIMIT_CORE, &corelimit); - memcpy(&rl, &corelimit, sizeof(struct rlimit)); - rl.rlim_cur = 0; - (void) setrlimit(RLIMIT_CORE, &rl); + if (restore) { + (void) setrlimit(RLIMIT_CORE, &corelimit); +#ifdef __linux__ + (void) prctl(PR_SET_DUMPABLE, dumpflag, 0, 0, 0); +#endif /* __linux__ */ + debug_return; } + + (void) getrlimit(RLIMIT_CORE, &corelimit); + rl.rlim_cur = 0; + rl.rlim_max = 0; + (void) setrlimit(RLIMIT_CORE, &rl); +#ifdef __linux__ + /* On Linux, also set PR_SET_DUMPABLE to zero (reset by execve). */ + if ((dumpflag = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) == -1) + dumpflag = 0; + (void) prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); +#endif /* __linux__ */ + debug_return; -#endif /* RLIMIT_CORE */ } /* @@ -1014,6 +1022,10 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd) } #endif + /* Restore coredumpsize resource limit before running. */ + if (sudo_conf_disable_coredump()) + disable_coredump(true); + if (details->pw != NULL) { #ifdef HAVE_PROJECT_H set_project(details->pw); -- 2.40.0