]> granicus.if.org Git - sudo/commitdiff
Ignore SIGPIPE for the duration of sudo and not just in a few select
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 22 Apr 2016 22:36:36 +0000 (16:36 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 22 Apr 2016 22:36:36 +0000 (16:36 -0600)
places.  We have no control over what nss, PAM modules or sudo
plugins might do so ignoring SIGPIPE is safest.

doc/sudo_plugin.cat
doc/sudo_plugin.man.in
doc/sudo_plugin.mdoc.in
plugins/sudoers/ldap.c
plugins/sudoers/logging.c
src/signal.c
src/sudo.c
src/tgetpass.c

index c20fae1524852822548c3f6eac1f33b229b3ebec..4e2359c6447657f483e93234a23fc52212c6ce2f 100644 (file)
@@ -1111,6 +1111,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
      +\b+\bo\bo   SIGALRM
      +\b+\bo\bo   SIGHUP
      +\b+\bo\bo   SIGINT
+     +\b+\bo\bo   SIGPIPE
      +\b+\bo\bo   SIGQUIT
      +\b+\bo\bo   SIGTERM
      +\b+\bo\bo   SIGTSTP
@@ -1121,7 +1122,8 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
      call the plugin's c\bcl\blo\bos\bse\be() function with an exit status of 128 plus the
      value of the signal that was received.  This allows for consistent
      logging of commands killed by a signal for plugins that log such
-     information in their c\bcl\blo\bos\bse\be() function.
+     information in their c\bcl\blo\bos\bse\be() function.  An exception to this is SIGPIPE,
+     which is ignored until the command is executed.
 
      A plugin may temporarily install its own signal handlers but must restore
      the original handler before the plugin function returns.
index 67e5c16dae91c1c393ae69d6c8e4b9af6a1fe19a..1c47fec551de14996d2a3dfd3e2397ed9fff8a48 100644 (file)
@@ -1978,6 +1978,9 @@ executed:
 \fRSIGINT\fR
 .TP 4n
 \fB\(bu\fR
+\fRSIGPIPE\fR
+.TP 4n
+\fB\(bu\fR
 \fRSIGQUIT\fR
 .TP 4n
 \fB\(bu\fR
@@ -2003,6 +2006,9 @@ This allows for consistent logging of commands killed by a signal
 for plugins that log such information in their
 \fBclose\fR()
 function.
+An exception to this is
+\fRSIGPIPE\fR,
+which is ignored until the command is executed.
 .PP
 A plugin may temporarily install its own signal handlers but must
 restore the original handler before the plugin function returns.
index 87c933324b456878ee255efdc5639c39352fd2e8..d5507ba73ebcac4e14c78f25451d5e54bf694d94 100644 (file)
@@ -1735,6 +1735,8 @@ executed:
 .It
 .Dv SIGINT
 .It
+.Dv SIGPIPE
+.It
 .Dv SIGQUIT
 .It
 .Dv SIGTERM
@@ -1756,6 +1758,9 @@ This allows for consistent logging of commands killed by a signal
 for plugins that log such information in their
 .Fn close
 function.
+An exception to this is
+.Ev SIGPIPE ,
+which is ignored until the command is executed.
 .Pp
 A plugin may temporarily install its own signal handlers but must
 restore the original handler before the plugin function returns.
index 97c2c756f60f3de5c921c8770d30ce414169161c..00fcb2105548e48da6453c51fc7f32802b31fe6e 100644 (file)
@@ -2975,17 +2975,10 @@ sudo_ldap_open(struct sudo_nss *nss)
 {
     LDAP *ld;
     int rc = -1;
-    sigaction_t sa, saved_sa_pipe;
     bool ldapnoinit = false;
     struct sudo_ldap_handle *handle;
     debug_decl(sudo_ldap_open, SUDOERS_DEBUG_LDAP)
 
-    /* Ignore SIGPIPE if we cannot bind to the server. */
-    memset(&sa, 0, sizeof(sa));
-    sigemptyset(&sa.sa_mask);
-    sa.sa_handler = SIG_IGN;
-    (void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
-
     if (!sudo_ldap_read_config())
        goto done;
 
@@ -3071,7 +3064,6 @@ sudo_ldap_open(struct sudo_nss *nss)
     nss->handle = handle;
 
 done:
-    (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
     debug_return_int(rc == LDAP_SUCCESS ? 0 : -1);
 }
 
index cbb18ce00504f37f7e22d68ad53f00e6b356c87b..ed3c8be1ef2a8dd3eaa77cceea752c4645e96f86 100644 (file)
@@ -542,7 +542,6 @@ send_mail(const char *fmt, ...)
     const char *timestr;
     int fd, pfd[2], status;
     pid_t pid, rv;
-    sigaction_t sa;
     struct stat sb;
     va_list ap;
 #ifndef NO_ROOT_MAILER
@@ -619,13 +618,6 @@ send_mail(const char *fmt, ...)
     sudo_endgrent();
     closefrom(STDERR_FILENO + 1);
 
-    /* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */
-    memset(&sa, 0, sizeof(sa));
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_INTERRUPT;
-    sa.sa_handler = SIG_IGN;
-    (void) sigaction(SIGPIPE, &sa, NULL);
-
     if (pipe(pfd) == -1) {
        mysyslog(LOG_ERR, _("unable to open pipe: %m"));
        sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to open pipe: %s",
index 888492fade4dceda20a04457cb292d93169beae6..28a3b6e3f064d059390f78833564bb4189f5e0c5 100644 (file)
@@ -30,6 +30,7 @@
 #include <signal.h>
 
 #include "sudo.h"
+#include "sudo_exec.h"
 
 int signal_pipe[2];
 
@@ -151,6 +152,13 @@ init_signals(void)
                break;
        }
     }
+    /* Ignore SIGPIPE until exec. */
+    if (saved_signals[SAVED_SIGPIPE].sa.sa_handler != SIG_IGN) {
+       sa.sa_handler = SIG_IGN;
+       if (sigaction(SIGPIPE, &sa, NULL) != 0)
+           sudo_warn(U_("unable to set handler for signal %d"), SIGPIPE);
+    }
+
     debug_return;
 }
 
index d4be82acd31fc66b5bfb82fe2e09ebad17fae831..46e5ce44f8c3000747b3dcc28dd95e4d8ac941d8 100644 (file)
@@ -188,10 +188,13 @@ main(int argc, char *argv[], char *envp[])
     /* Make sure we are setuid root. */
     sudo_check_suid(argc > 0 ? argv[0] : "sudo");
 
-    /* Reset signal mask and save signal state. */
+    /* Save original signal state and setup default signal handlers. */
+    save_signals();
+    init_signals();
+
+    /* Reset signal mask to the default value (unblock). */
     (void) sigemptyset(&mask);
     (void) sigprocmask(SIG_SETMASK, &mask, NULL);
-    save_signals();
 
     /* Parse the rest of sudo.conf. */
     sudo_conf_read(NULL, SUDO_CONF_ALL & ~SUDO_CONF_DEBUG);
@@ -230,8 +233,6 @@ main(int argc, char *argv[], char *envp[])
            sudo_fatalx(U_("unable to initialize policy plugin"));
     }
 
-    init_signals();
-
     switch (sudo_mode & MODE_MASK) {
        case MODE_VERSION:
            policy_show_version(&policy_plugin, !user_details.uid);
index 47291bc1f1ff8c403c73f673be2bbbfc947deebe..671c021d877870be7b707a1f1e6938caab3bb08c 100644 (file)
@@ -85,7 +85,7 @@ tgetpass(const char *prompt, int timeout, int flags,
     struct sudo_conv_callback *callback)
 {
     sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm;
-    sigaction_t savetstp, savettin, savettou, savepipe;
+    sigaction_t savetstp, savettin, savettou;
     char *pass;
     static const char *askpass;
     static char buf[SUDO_CONV_REPL_MAX + 1];
@@ -168,10 +168,6 @@ restart:
     (void) sigaction(SIGTTIN, &sa, &savettin);
     (void) sigaction(SIGTTOU, &sa, &savettou);
 
-    /* Ignore SIGPIPE in case stdin is a pipe and TGP_STDIN is set */
-    sa.sa_handler = SIG_IGN;
-    (void) sigaction(SIGPIPE, &sa, &savepipe);
-
     if (prompt) {
        if (write(output, prompt, strlen(prompt)) == -1)
            goto restore;
@@ -198,7 +194,6 @@ restore:
     (void) sigaction(SIGTSTP, &savetstp, NULL);
     (void) sigaction(SIGTTIN, &savettin, NULL);
     (void) sigaction(SIGTTOU, &savettou, NULL);
-    (void) sigaction(SIGPIPE, &savepipe, NULL);
 
     /* Restore old tty settings. */
     if (!ISSET(flags, TGP_ECHO)) {
@@ -252,7 +247,6 @@ static char *
 sudo_askpass(const char *askpass, const char *prompt)
 {
     static char buf[SUDO_CONV_REPL_MAX + 1], *pass;
-    sigaction_t sa, saved_sa_pipe;
     int pfd[2], status;
     pid_t child;
     debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
@@ -286,18 +280,10 @@ sudo_askpass(const char *askpass, const char *prompt)
        _exit(255);
     }
 
-    /* Ignore SIGPIPE in case child exits prematurely */
-    memset(&sa, 0, sizeof(sa));
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_INTERRUPT;
-    sa.sa_handler = SIG_IGN;
-    (void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
-
-    /* Get response from child (askpass) and restore SIGPIPE handler */
+    /* Get response from child (askpass). */
     (void) close(pfd[1]);
     pass = getln(pfd[0], buf, sizeof(buf), 0);
     (void) close(pfd[0]);
-    (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
 
     /* Wait for child to exit. */
     for (;;) {