Index: sudo-1.7.4p4/exec.c =================================================================== --- sudo-1.7.4p4.orig/exec.c 2011-06-06 07:55:23.000000000 +0300 +++ sudo-1.7.4p4/exec.c 2011-06-06 09:17:17.000000000 +0300 @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef HAVE_SELINUX # include #endif @@ -69,6 +70,9 @@ sig_atomic_t recvsig[NSIG]; void handler __P((int s)); +static sigjmp_buf jmpbuf; +static void handler_jmp __P((int s)); + /* * Like execve(2) but falls back to running through /bin/sh * ala execvp(3) if we get ENOEXEC. @@ -212,10 +216,16 @@ zero_bytes(&sa, sizeof(sa)); sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGCHLD); + sigaddset(&sa.sa_mask, SIGHUP); + sigaddset(&sa.sa_mask, SIGINT); + sigaddset(&sa.sa_mask, SIGPIPE); + sigaddset(&sa.sa_mask, SIGQUIT); + sigaddset(&sa.sa_mask, SIGTERM); /* Note: HP-UX select() will not be interrupted if SA_RESTART set */ sa.sa_flags = SA_INTERRUPT; /* do not restart syscalls */ - sa.sa_handler = handler; + sa.sa_handler = handler_jmp; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGINT, &sa, NULL); @@ -253,6 +263,7 @@ fdsr = (fd_set *)emalloc2(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask)); fdsw = (fd_set *)emalloc2(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask)); for (;;) { + sigsetjmp(jmpbuf, 0); if (recvsig[SIGCHLD]) { pid_t pid; @@ -305,8 +316,7 @@ } } - if (recvsig[SIGCHLD]) - continue; + sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL); nready = select(maxfd + 1, fdsr, fdsw, NULL, NULL); if (nready == -1) { if (errno == EINTR) @@ -402,3 +412,11 @@ { recvsig[s] = TRUE; } + +void +handler_jmp(s) + int s; +{ + recvsig[s] = TRUE; + siglongjmp(jmpbuf, 1); +}