From afa0a3fe86054ebe4876c2324806dd78ab1d55d4 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 23 May 2012 15:06:11 -0400 Subject: [PATCH] Linux select() may return ENOMEM if there is a kernel resource shortage. Older Solaris select() may return EIO instead of EBADF when the tty goes away. If we get an unhandled select() failure, kill the child and exit cleanly. --HG-- branch : 1.7 --- exec.c | 11 ++++++++--- exec_pty.c | 11 ++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/exec.c b/exec.c index f08493af9..fa0fd5186 100644 --- a/exec.c +++ b/exec.c @@ -367,15 +367,20 @@ sudo_execve(path, argv, envp, uid, cstat, dowait, bgmode) #endif nready = select(maxfd + 1, fdsr, fdsw, NULL, NULL); if (nready == -1) { - if (errno == EINTR) + if (errno == EINTR || errno == ENOMEM) continue; #ifdef _PATH_SUDO_IO_LOGDIR - if (errno == EBADF) { + if (errno == EBADF || errno == EIO) { /* One of the ttys must have gone away. */ goto do_tty_io; } #endif - error(1, "select failed"); + warning("select failed"); +#ifdef _PATH_SUDO_IO_LOGDIR + schedule_signal(SIGKILL); + forward_signals(sv[0]); +#endif + break; } #ifdef _PATH_SUDO_IO_LOGDIR if (FD_ISSET(sv[0], fdsw)) { diff --git a/exec_pty.c b/exec_pty.c index d1111fc1a..51d95cced 100644 --- a/exec_pty.c +++ b/exec_pty.c @@ -845,9 +845,10 @@ exec_monitor(path, argv, envp, backchannel, rbac) if (n <= 0) { if (n == 0) goto done; - if (errno == EINTR) + if (errno == EINTR || errno == ENOMEM) continue; - error(1, "select failed"); + warning("monitor: select failed"); + break; } if (FD_ISSET(signal_pipe[0], fdsr)) { @@ -979,11 +980,11 @@ flush_output() if (nready <= 0) { if (nready == 0) break; /* all I/O flushed */ - if (errno == EINTR) + if (errno == EINTR || errno == ENOMEM) continue; - error(1, "select failed"); + warning("select failed"); } - if (perform_io(fdsr, fdsw, NULL) != 0) + if (perform_io(fdsr, fdsw, NULL) != 0 || nready == -1) break; } efree(fdsr); -- 2.40.0