]> granicus.if.org Git - sudo/commitdiff
Set SIGCHLD handler to SIG_DFL before forking the askpass command
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 6 Sep 2017 21:59:37 +0000 (15:59 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 6 Sep 2017 21:59:37 +0000 (15:59 -0600)
and restore after.  Otherwise, SIGCHLD will end up in the list of
pending signals and sudo_execute() will not execute the command.

src/tgetpass.c

index 53c08b261604e313b19b3e136a2deae7f7282326..cc4738c456c8a5a0360a559a3e94487e7432f4b6 100644 (file)
@@ -238,10 +238,18 @@ static char *
 sudo_askpass(const char *askpass, const char *prompt)
 {
     static char buf[SUDO_CONV_REPL_MAX + 1], *pass;
+    struct sigaction sa, savechld;
     int pfd[2], status;
     pid_t child;
     debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
 
+    /* Set SIGCHLD handler to default since we call waitpid() below. */
+    memset(&sa, 0, sizeof(sa));
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+    sa.sa_handler = SIG_DFL;
+    (void) sigaction(SIGCHLD, &sa, &savechld);
+
     if (pipe(pfd) == -1)
        sudo_fatal(U_("unable to create pipe"));
 
@@ -288,6 +296,9 @@ sudo_askpass(const char *askpass, const char *prompt)
     if (pass == NULL)
        errno = EINTR;  /* make cancel button simulate ^C */
 
+    /* Restore saved SIGCHLD handler. */
+    (void) sigaction(SIGCHLD, &savechld, NULL);
+
     debug_return_str_masked(pass);
 }