]> granicus.if.org Git - sudo/commitdiff
Normally, sudo disables core dumps while it is running. This
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 3 Feb 2012 19:57:03 +0000 (14:57 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 3 Feb 2012 19:57:03 +0000 (14:57 -0500)
behavior can now be modified at run time with a line in sudo.conf
like "Set disable_coredumps false"

NEWS
common/sudo_conf.c
doc/sample.sudo.conf
doc/sudo.pod
include/sudo_conf.h
src/sudo.c

diff --git a/NEWS b/NEWS
index 657345a8849dc0072b8736368f9091d0e98d8ced..6f139299c5ef19ca0a34971a2c3c7ec4a7f15e7b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
index 108f431781fd86524347a220f2900d20399e6b83..3ddd8619ef9d3fc9706cf40ca0cbf3c791702687 100644 (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.
index 18baa59bb02d09dc907ea57676c2e0256d674a3d..529602fb10fe2827a7606f3923891dae86309fb3 100644 (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
index b6e5915f3c353da9f8eff0255259ea693c42237b..f35930fd904c2f6bb1d0bb825b6c16bc592c5501 100644 (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
index 7bd4489e1fb4f30671294fe0f21aec9868ab6e58..6efc302f8064795a2594b3ea8202cafa1effbb69 100644 (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 */
index 0efaee09114befffaf1c2d4887434eb50f328191..d80a204b08e9375f663b03f5ce9ba3c0dcf91835 100644 (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)
-           (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 {
@@ -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?
      */
-    (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;
 }