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.
This commit is contained in:
62
src/sudo.c
62
src/sudo.c
@@ -70,6 +70,9 @@
|
||||
# endif /* __hpux */
|
||||
# include <prot.h>
|
||||
#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
|
||||
#ifdef __linux__
|
||||
# include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#include <sudo_usage.h>
|
||||
#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)
|
||||
|
||||
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__ */
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
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);
|
||||
|
Reference in New Issue
Block a user