Normally, sudo disables core dumps while it is running. This

behavior can now be modified at run time with a line in sudo.conf
like "Set disable_coredumps false"
This commit is contained in:
Todd C. Miller
2012-02-03 14:57:03 -05:00
parent e6fbba6986
commit c970d464cb
6 changed files with 90 additions and 15 deletions

10
NEWS
View File

@@ -72,6 +72,16 @@ What's new in Sudo 1.8.4?
now run "visudo -c". Previously, write permissions were required
even though no writing is down in check-only mode.
* It is now possible to prevent the disabling of core dumps from
within sudo itself by adding a line to the sudo.conf file like
"Set disable_coredump false".
What's new in Sudo 1.8.3p2?
* Fixed a format string vulnerability when the sudo binary (or a
symbolic link to the sudo binary) contains printf format escapes
and the -D (debugging) flag is used.
What's new in Sudo 1.8.3p1?
* Fixed a crash in the monitor process on Solaris when NOPASSWD

View File

@@ -59,6 +59,8 @@
# define _PATH_SUDO_ASKPASS NULL
#endif
extern bool atobool(const char *str); /* atobool.c */
struct sudo_conf_table {
const char *name;
unsigned int namelen;
@@ -74,19 +76,23 @@ struct sudo_conf_paths {
static bool set_debug(const char *entry);
static bool set_path(const char *entry);
static bool set_plugin(const char *entry);
static bool set_variable(const char *entry);
static struct sudo_conf_table sudo_conf_table[] = {
{ "Debug", sizeof("Debug") - 1, set_debug },
{ "Path", sizeof("Path") - 1, set_path },
{ "Plugin", sizeof("Plugin") - 1, set_plugin },
{ "Set", sizeof("Set") - 1, set_variable },
{ NULL }
};
static struct sudo_conf_data {
bool disable_coredump;
const char *debug_flags;
struct sudo_conf_paths paths[3];
struct plugin_info_list plugins;
} sudo_conf_data = {
true,
NULL,
{
#define SUDO_CONF_ASKPASS_IDX 0
@@ -99,6 +105,26 @@ static struct sudo_conf_data {
}
};
/*
* "Set variable_name value"
*/
static bool
set_variable(const char *entry)
{
#undef DC_LEN
#define DC_LEN (sizeof("disable_coredump") - 1)
/* Currently the only variable supported is "disable_coredump". */
if (strncmp(entry, "disable_coredump", DC_LEN) == 0 &&
isblank((unsigned char)entry[DC_LEN])) {
entry += DC_LEN + 1;
while (isblank((unsigned char)*entry))
entry++;
sudo_conf_data.disable_coredump = atobool(entry);
}
#undef DC_LEN
return true;
}
/*
* "Debug progname debug_file debug_flags"
*/
@@ -217,6 +243,12 @@ sudo_conf_plugins(void)
return &sudo_conf_data.plugins;
}
bool
sudo_conf_disable_coredump(void)
{
return sudo_conf_data.disable_coredump;
}
/*
* Reads in /etc/sudo.conf
* Returns a list of plugins.

View File

@@ -5,6 +5,8 @@
# Plugin plugin_name plugin_path
# Path askpass /path/to/askpass
# Path noexec /path/to/noexec.so
# Debug sudo /var/log/sudo_debug all@warn
# Set disable_coredump true
#
# Sudo plugins:
#
@@ -40,3 +42,13 @@ Plugin sudoers_io sudoers.so
# if you rename or move the sudo_noexec.so file.
#
#Path noexec /usr/libexec/sudo_noexec.so
#
# Core dumps:
#
# By default, sudo disables core dumps while it is executing (they
# are re-enabled for the command that is run).
# To aid in debugging sudo problems, you may wish to enable core
# dumps by setting "disable_coredump" to false.
#
#Set disable_coredump false

View File

@@ -425,6 +425,7 @@ which corresponds to the following F<@sysconfdir@/sudo.conf> file.
# Path askpass /path/to/askpass
# Path noexec /path/to/noexec.so
# Debug sudo /var/log/sudo_debug all@warn
# Set disable_coredump true
#
# The plugin_path is relative to @prefix@/libexec unless
# fully qualified.
@@ -553,6 +554,20 @@ commands via B<sudo> to verify that the command does not inadvertently
give the user an effective root shell. For more information, please
see the C<PREVENTING SHELL ESCAPES> section in L<sudoers(5)>.
To prevent the disclosure of potentially sensitive information,
B<sudo> disables core dumps by default while it is executing (they
are re-enabled for the command that is run). To aid in debugging
B<sudo> crashes, you may wish to re-enable core dumps by setting
"disable_coredump" to false in the F<@sysconfdir@/sudo.conf> file.
Set disable_coredump false
Note that by default, most operating systems disable core dumps
from setuid programs, which includes B<sudo>. To actually get a
B<sudo> core file you may need to enable core dumps for setuid
processes. On BSD and Linux systems this is accomplished via the
sysctl command, on Solaris the coreadm command can be used.
=head1 ENVIRONMENT
B<sudo> utilizes the following environment variables. The security

View File

@@ -35,5 +35,6 @@ const char *sudo_conf_askpass_path(void);
const char *sudo_conf_noexec_path(void);
const char *sudo_conf_debug_flags(void);
struct plugin_info_list *sudo_conf_plugins(void);
bool sudo_conf_disable_coredump(void);
#endif /* _SUDO_CONF_H */

View File

@@ -137,9 +137,9 @@ static void iolog_close(struct plugin_container *plugin, int exit_status,
int error);
static int iolog_show_version(struct plugin_container *plugin, int verbose);
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
#ifdef RLIMIT_CORE
static struct rlimit corelimit;
#endif /* RLIMIT_CORE && !SUDO_DEVEL */
#endif /* RLIMIT_CORE */
#if defined(__linux__)
static struct rlimit nproclimit;
#endif
@@ -188,10 +188,9 @@ main(int argc, char *argv[], char *envp[])
if (geteuid() != 0)
errorx(1, _("must be setuid root"));
/* Reset signal mask, disable core dumps and make sure fds 0-2 are open. */
/* Reset signal mask and make sure fds 0-2 are open. */
(void) sigemptyset(&mask);
(void) sigprocmask(SIG_SETMASK, &mask, NULL);
disable_coredumps();
fix_fds();
/* Fill in user_info with user name, uid, cwd, etc. */
@@ -201,6 +200,9 @@ main(int argc, char *argv[], char *envp[])
/* Read sudo.conf. */
sudo_conf_read();
/* Disable core dumps if not enabled in sudo.conf. */
disable_coredumps();
/* Parse command line arguments. */
sudo_mode = parse_args(argc, argv, &nargc, &nargv, &settings, &env_add);
sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_mode %d", sudo_mode);
@@ -287,9 +289,10 @@ main(int argc, char *argv[], char *envp[])
if (ISSET(sudo_mode, MODE_BACKGROUND))
SET(command_details.flags, CD_BACKGROUND);
/* Restore coredumpsize resource limit before running. */
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
#ifdef RLIMIT_CORE
if (sudo_conf_disable_coredump())
(void) setrlimit(RLIMIT_CORE, &corelimit);
#endif /* RLIMIT_CORE && !SUDO_DEVEL */
#endif /* RLIMIT_CORE */
if (ISSET(command_details.flags, CD_SUDOEDIT)) {
exitcode = sudo_edit(&command_details);
} else {
@@ -722,7 +725,7 @@ command_info_to_details(char * const info[], struct command_details *details)
static void
disable_coredumps(void)
{
#if defined(__linux__) || (defined(RLIMIT_CORE) && !defined(SUDO_DEVEL))
#if defined(__linux__) || defined(RLIMIT_CORE)
struct rlimit rl;
#endif
debug_decl(disable_coredumps, SUDO_DEBUG_UTIL)
@@ -741,15 +744,17 @@ disable_coredumps(void)
(void)setrlimit(RLIMIT_NPROC, &rl);
}
#endif /* __linux__ */
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
#ifdef RLIMIT_CORE
/*
* Turn off core dumps.
* 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);
#endif /* RLIMIT_CORE && !SUDO_DEVEL */
}
#endif /* RLIMIT_CORE */
debug_return;
}