From: Todd C. Miller Date: Fri, 2 Oct 2015 17:24:01 +0000 (-0600) Subject: It is possible for WIFSTOPPED to be true even if waitpid() is not X-Git-Tag: SUDO_1_8_15^2~24 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5ad68edd6586da36a32b8a9005962edd0f7201e6;p=sudo It is possible for WIFSTOPPED to be true even if waitpid() is not given WUNTRACED if the child is ptraced. Don't exit the waitpid() loop if WIFSTOPPED is true, just in case. --- diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 19902ae10..cbb18ce00 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -591,9 +591,13 @@ send_mail(const char *fmt, ...) break; default: /* Parent. */ - do { + for (;;) { rv = waitpid(pid, &status, 0); - } while (rv == -1 && errno == EINTR); + if (rv == -1 && errno != EINTR) + break; + if (rv != -1 && !WIFSTOPPED(status)) + break; + } return true; /* not debug */ } @@ -732,9 +736,13 @@ send_mail(const char *fmt, ...) fputs("\n\n", mail); fclose(mail); - do { - rv = waitpid(pid, &status, 0); - } while (rv == -1 && errno == EINTR); + for (;;) { + rv = waitpid(pid, &status, 0); + if (rv == -1 && errno != EINTR) + break; + if (rv != -1 && !WIFSTOPPED(status)) + break; + } sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys); _exit(0); } diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c index 155de7c1c..62e8a5a98 100644 --- a/plugins/sudoers/visudo.c +++ b/plugins/sudoers/visudo.c @@ -849,9 +849,13 @@ run_command(char *path, char **argv) break; /* NOTREACHED */ } - do { + for (;;) { rv = waitpid(pid, &status, 0); - } while (rv == -1 && errno == EINTR); + if (rv == -1 && errno != EINTR) + break; + if (rv != -1 && !WIFSTOPPED(status)) + break; + } if (rv != -1) rv = WIFEXITED(status) ? WEXITSTATUS(status) : -1; diff --git a/src/tgetpass.c b/src/tgetpass.c index 3811fd587..47291bc1f 100644 --- a/src/tgetpass.c +++ b/src/tgetpass.c @@ -300,8 +300,13 @@ sudo_askpass(const char *askpass, const char *prompt) (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL); /* Wait for child to exit. */ - while (waitpid(child, &status, 0) == -1 && errno == EINTR) - continue; + for (;;) { + pid_t rv = waitpid(child, &status, 0); + if (rv == -1 && errno != EINTR) + break; + if (rv != -1 && !WIFSTOPPED(status)) + break; + } if (pass == NULL) errno = EINTR; /* make cancel button simulate ^C */