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
# define _PATH_SUDO_ASKPASS NULL
#endif
+extern bool atobool(const char *str); /* atobool.c */
+
struct sudo_conf_table {
const char *name;
unsigned int namelen;
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
}
};
+/*
+ * "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"
*/
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.
# 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:
#
# 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
# 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.
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
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 */
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
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. */
/* 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);
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)
- (void) setrlimit(RLIMIT_CORE, &corelimit);
-#endif /* RLIMIT_CORE && !SUDO_DEVEL */
+#ifdef RLIMIT_CORE
+ if (sudo_conf_disable_coredump())
+ (void) setrlimit(RLIMIT_CORE, &corelimit);
+#endif /* RLIMIT_CORE */
if (ISSET(command_details.flags, CD_SUDOEDIT)) {
exitcode = sudo_edit(&command_details);
} else {
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)
(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?
*/
- (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 */
+ 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 */
debug_return;
}