From: Todd C. Miller Date: Wed, 6 Sep 2017 21:59:37 +0000 (-0600) Subject: Set SIGCHLD handler to SIG_DFL before forking the askpass command X-Git-Tag: SUDO_1_8_21p2^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4b5aeefebc15593c1ec566168930b6da5cb22c7c;p=sudo Set SIGCHLD handler to SIG_DFL before forking the askpass command and restore after. Otherwise, SIGCHLD will end up in the list of pending signals and sudo_execute() will not execute the command. --- diff --git a/src/tgetpass.c b/src/tgetpass.c index 53c08b261..cc4738c45 100644 --- a/src/tgetpass.c +++ b/src/tgetpass.c @@ -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); }