]> granicus.if.org Git - sudo/commitdiff
Ignore SIGTTIN and SIGTTOU in main sudo process when I/O logging.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 6 Apr 2012 16:45:30 +0000 (12:45 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 6 Apr 2012 16:45:30 +0000 (12:45 -0400)
It is better to receive EIO from read()/write() than to be suspended
when we don't expect it.  Fixes a problem when our terminal is
revoked which can happen when, e.g. our sshd is killed unceremoniously.
Also, only change the value of "alive" from true to false, never
from false to true.  It is possible for us to receive notification
of the child having stopped after it is already dead.  This does
not mean it has risen from the grave.

src/exec_pty.c

index d24f2793596c77b453422782cbf92d0f321fce07..5ce320824390195d129ee47ef79db60eea603884 100644 (file)
@@ -595,6 +595,11 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
     sa.sa_handler = handler;
     sigaction(SIGTSTP, &sa, NULL);
 
+    /* We don't want to receive SIGTTIN/SIGTTOU, getting EIO is preferable. */
+    sa.sa_handler = SIG_IGN;
+    sigaction(SIGTTIN, &sa, NULL);
+    sigaction(SIGTTOU, &sa, NULL);
+
     if (foreground) {
        /* Copy terminal attrs from user tty -> pty slave. */
        if (term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
@@ -1027,10 +1032,12 @@ exec_monitor(struct command_details *details, int backchannel)
             * Handle SIGCHLD specially and deliver other signals
             * directly to the child.
             */
-           if (signo == SIGCHLD)
-               alive = handle_sigchld(backchannel, &cstat);
-           else
+           if (signo == SIGCHLD) {
+               if (!handle_sigchld(backchannel, &cstat))
+                   alive = false;
+           } else {
                deliver_signal(child, signo, false);
+           }
            continue;
        }
        if (errpipe[0] != -1 && FD_ISSET(errpipe[0], fdsr)) {