From: Todd C. Miller Date: Wed, 9 Jun 2010 13:22:44 +0000 (-0400) Subject: Remove commented out copy of old sudo_execve() function. X-Git-Tag: SUDO_1_8_0~511 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ecfb70b056a9d9320891ebe785cdebcc481bd988;p=sudo Remove commented out copy of old sudo_execve() function. --- diff --git a/src/exec_pty.c b/src/exec_pty.c index 91db15623..8e3f35644 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -700,418 +700,6 @@ fd_set_iobs(fd_set *fdsr, fd_set *fdsw) } } -#if 0 -/* - * This is a little bit tricky due to how POSIX job control works and - * we fact that we have two different controlling terminals to deal with. - * There are three processes: - * 1) parent, which forks a child and does all the I/O passing. - * Handles job control signals send by its child to bridge the - * two sessions (and ttys). - * 2) child, creates a new session so it can receive notification of - * tty stop signals (SIGTSTP, SIGTTIN, SIGTTOU). Waits for the - * command to stop or die and passes back tty stop signals to parent - * so job control works in the user's shell. - * 3) grandchild, executes the actual command with the pty slave as its - * controlling tty, belongs to child's session but has its own pgrp. - */ -int -sudo_execve(struct command_details *details, char *argv[], char *envp[], - struct command_status *cstat) -{ - sigaction_t sa; - struct io_buffer *iob, *iobufs = NULL; - int n, nready; - int io_pipe[3][2], sv[2]; - fd_set *fdsr, *fdsw; - int rbac_enabled = 0; - int log_io, maxfd, status; - - cstat->type = CMD_INVALID; - - log_io = !tq_empty(&io_plugins); - if (log_io) { - sudo_debug(8, "allocate pty for I/O logging"); - pty_setup(details->euid); - } - -#ifdef HAVE_SELINUX - rbac_enabled = is_selinux_enabled() > 0 && details->selinux_role != NULL; -#endif - - ppgrp = getpgrp(); /* parent's pgrp, so child can signal us */ - - /* - * We communicate with the child over a bi-directional pipe. - * Parent sends signal info to child and child sends back wait status. - */ - if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) != 0) - error(1, "cannot create sockets"); - - zero_bytes(&sa, sizeof(sa)); - sigemptyset(&sa.sa_mask); - - /* Note: HP-UX select() will not be interrupted if SA_RESTART set */ - sa.sa_flags = 0; /* do not restart syscalls */ - sa.sa_handler = handler; - sigaction(SIGALRM, &sa, NULL); - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGHUP, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - sigaction(SIGQUIT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - - if (log_io) { - if (io_fds[SFD_USERTTY] != -1) { - sa.sa_flags = SA_RESTART; - sa.sa_handler = sigwinch; - sigaction(SIGWINCH, &sa, NULL); - } - - /* So we can block tty-generated signals */ - sigemptyset(&ttyblock); - sigaddset(&ttyblock, SIGINT); - sigaddset(&ttyblock, SIGQUIT); - sigaddset(&ttyblock, SIGTSTP); - sigaddset(&ttyblock, SIGTTIN); - sigaddset(&ttyblock, SIGTTOU); - - /* - * Setup stdin/stdout/stderr for child, to be duped after forking. - */ - io_fds[SFD_STDIN] = io_fds[SFD_SLAVE]; - io_fds[SFD_STDOUT] = io_fds[SFD_SLAVE]; - io_fds[SFD_STDERR] = io_fds[SFD_SLAVE]; - - /* Copy /dev/tty -> pty master */ - if (io_fds[SFD_USERTTY] != -1) { - iobufs = io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_MASTER], - log_ttyin, iobufs); - - /* Copy pty master -> /dev/tty */ - iobufs = io_buf_new(io_fds[SFD_MASTER], io_fds[SFD_USERTTY], - log_ttyout, iobufs); - - /* Are we the foreground process? */ - foreground = tcgetpgrp(io_fds[SFD_USERTTY]) == ppgrp; - } - - /* - * If either stdin, stdout or stderr is not a tty we use a pipe - * to interpose ourselves instead of duping the pty fd. - */ - memset(io_pipe, 0, sizeof(io_pipe)); - if (!isatty(STDIN_FILENO)) { - pipeline = TRUE; - if (pipe(io_pipe[STDIN_FILENO]) != 0) - error(1, "unable to create pipe"); - iobufs = io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1], - log_stdin, iobufs); - io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0]; - } - if (!isatty(STDOUT_FILENO)) { - pipeline = TRUE; - if (pipe(io_pipe[STDOUT_FILENO]) != 0) - error(1, "unable to create pipe"); - iobufs = io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO, - log_stdout, iobufs); - io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1]; - } - if (!isatty(STDERR_FILENO)) { - if (pipe(io_pipe[STDERR_FILENO]) != 0) - error(1, "unable to create pipe"); - iobufs = io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO, - log_stderr, iobufs); - io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1]; - } - - /* Job control signals to relay from parent to child. */ - sa.sa_flags = 0; /* do not restart syscalls */ - sa.sa_handler = handler; - sigaction(SIGTSTP, &sa, NULL); -#if 0 /* XXX - add these? */ - sigaction(SIGTTIN, &sa, NULL); - sigaction(SIGTTOU, &sa, NULL); -#endif - - if (foreground) { - /* Copy terminal attrs from user tty -> pty slave. */ - if (term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) { - tty_initialized = 1; - sync_ttysize(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]); - } - - /* Start out in raw mode if we are not part of a pipeline. */ - if (!pipeline) { - ttymode = TERM_RAW; - do { - n = term_raw(io_fds[SFD_USERTTY], 0); - } while (!n && errno == EINTR); - if (!n) - error(1, "Can't set terminal to raw mode"); - } - } - } - - /* - * Child will run the command in the pty, parent will pass data - * to and from pty. - */ - child = fork(); - switch (child) { - case -1: - error(1, "fork"); - break; - case 0: - /* child */ - close(sv[0]); - fcntl(sv[1], F_SETFD, FD_CLOEXEC); - if (exec_setup(details) == TRUE) { - /* headed for execve() */ - if (log_io) { - /* Close the other end of the stdin/stdout/stderr pipes. */ - if (io_pipe[STDIN_FILENO][1]) - close(io_pipe[STDIN_FILENO][1]); - if (io_pipe[STDOUT_FILENO][0]) - close(io_pipe[STDOUT_FILENO][0]); - if (io_pipe[STDERR_FILENO][0]) - close(io_pipe[STDERR_FILENO][0]); - exec_monitor(details, argv, envp, sv[1], rbac_enabled); - } else { - if (details->closefrom >= 0) - closefrom(details->closefrom); -#ifdef HAVE_SELINUX - if (rbac_enabled) - selinux_execve(details->command, argv, envp); - else -#endif - my_execve(details->command, argv, envp); - } - } - cstat->type = CMD_ERRNO; - cstat->val = errno; - send(sv[1], cstat, sizeof(*cstat), 0); - _exit(1); - } - close(sv[1]); - - /* Set command timeout if specified. */ - if (ISSET(details->flags, CD_SET_TIMEOUT)) - alarm(details->timeout); - - /* Max fd we will be selecting on. */ - maxfd = sv[0]; - - if (log_io) { - /* Close the other end of the stdin/stdout/stderr pipes. */ - if (io_pipe[STDIN_FILENO][0]) - close(io_pipe[STDIN_FILENO][0]); - if (io_pipe[STDOUT_FILENO][1]) - close(io_pipe[STDOUT_FILENO][1]); - if (io_pipe[STDERR_FILENO][1]) - close(io_pipe[STDERR_FILENO][1]); - - for (iob = iobufs; iob; iob = iob->next) { - /* Determine maxfd */ - if (iob->rfd > maxfd) - maxfd = iob->rfd; - if (iob->wfd > maxfd) - maxfd = iob->wfd; - - /* Set non-blocking mode. */ - n = fcntl(iob->rfd, F_GETFL, 0); - if (n != -1 && !ISSET(n, O_NONBLOCK)) - (void) fcntl(iob->rfd, F_SETFL, n | O_NONBLOCK); - n = fcntl(iob->wfd, F_GETFL, 0); - if (n != -1 && !ISSET(n, O_NONBLOCK)) - (void) fcntl(iob->wfd, F_SETFL, n | O_NONBLOCK); - } - } - - /* - * In the event loop we pass input from user tty to master - * and pass output from master to stdout and IO plugin. - */ - fdsr = (fd_set *)emalloc2(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask)); - fdsw = (fd_set *)emalloc2(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask)); - for (;;) { - if (recvsig[SIGCHLD]) { - pid_t pid; - - /* - * If logging I/O, child is the intermediate process, - * otherwise it is the command itself. - */ - recvsig[SIGCHLD] = FALSE; - do { - pid = waitpid(child, &status, WNOHANG); - } while (pid == -1 && errno == EINTR); - if (pid == child) { - /* If not logging I/O and child has exited we are done. */ - if (!log_io) { - cstat->type = CMD_WSTATUS; - cstat->val = status; - return 0; - } - } - } - - zero_bytes(fdsw, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask)); - zero_bytes(fdsr, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask)); - - FD_SET(sv[0], fdsr); - for (iob = iobufs; iob; iob = iob->next) { - if (iob->rfd == -1 && iob->wfd == -1) - continue; - if (iob->off == iob->len) { - iob->off = iob->len = 0; - /* Forward the EOF from reader to writer. */ - if (iob->rfd == -1) { - safe_close(iob->wfd); - iob->wfd = -1; - } - } - /* Don't read/write /dev/tty if we are not in the foreground. */ - if (iob->rfd != -1 && - (ttymode == TERM_RAW || iob->rfd != io_fds[SFD_USERTTY])) { - if (iob->len != sizeof(iob->buf)) - FD_SET(iob->rfd, fdsr); - } - if (iob->wfd != -1 && - (foreground || iob->wfd != io_fds[SFD_USERTTY])) { - if (iob->len > iob->off) - FD_SET(iob->wfd, fdsw); - } - } - for (n = 0; n < NSIG; n++) { - if (recvsig[n] && n != SIGCHLD) { - if (log_io) { - FD_SET(sv[0], fdsw); - break; - } else { - /* nothing listening on sv[0], send directly */ - if (n == SIGALRM) { - terminate_child(child, FALSE); - } else { - kill(child, n); - } - } - } - } - - if (recvsig[SIGCHLD]) - continue; - nready = select(maxfd + 1, fdsr, fdsw, NULL, NULL); - if (nready == -1) { - if (errno == EINTR) - continue; - error(1, "select failed"); - } - if (FD_ISSET(sv[0], fdsr)) { - /* read child status */ - n = recv(sv[0], cstat, sizeof(*cstat), 0); - if (n == -1) { - if (errno == EINTR) - continue; - /* - * If not logging I/O we will receive ECONNRESET when - * the command is executed. It is safe to ignore this. - */ - if (log_io && errno != EAGAIN) { - cstat->type = CMD_ERRNO; - cstat->val = errno; - break; - } - } - if (cstat->type == CMD_WSTATUS) { - if (WIFSTOPPED(cstat->val)) { - /* Suspend parent and tell child how to resume on return. */ - sudo_debug(8, "child stopped, suspending parent"); - n = suspend_parent(WSTOPSIG(cstat->val)); - recvsig[n] = TRUE; - continue; - } else { - /* Child exited or was killed, either way we are done. */ - break; - } - } else if (cstat->type == CMD_ERRNO) { - /* Child was unable to execute command or broken pipe. */ - break; - } - } - - if (FD_ISSET(sv[0], fdsw)) { - for (n = 0; n < NSIG; n++) { - if (!recvsig[n]) - continue; - recvsig[n] = FALSE; - sudo_debug(9, "sending signal %d to child over backchannel", n); - cstat->type = CMD_SIGNO; - cstat->val = n; - do { - n = send(sv[0], cstat, sizeof(*cstat), 0); - } while (n == -1 && errno == EINTR); - if (n != sizeof(*cstat)) { - recvsig[n] = TRUE; - break; - } - } - } - if (perform_io(fdsr, fdsw, cstat) != 0) - break; - } - - if (log_io) { - /* Flush any remaining output (the plugin already got it) */ - if (io_fds[SFD_USERTTY] != -1) { - n = fcntl(io_fds[SFD_USERTTY], F_GETFL, 0); - if (n != -1 && ISSET(n, O_NONBLOCK)) { - CLR(n, O_NONBLOCK); - (void) fcntl(io_fds[SFD_USERTTY], F_SETFL, n); - } - } - flush_output(); - - if (io_fds[SFD_USERTTY] != -1) { - do { - n = term_restore(io_fds[SFD_USERTTY], 0); - } while (!n && errno == EINTR); - } - - if (cstat->type == CMD_WSTATUS && WIFSIGNALED(cstat->val)) { - int signo = WTERMSIG(cstat->val); - if (signo && signo != SIGINT && signo != SIGPIPE) { - char *reason = strsignal(signo); - n = io_fds[SFD_USERTTY] != -1 ? - io_fds[SFD_USERTTY] : STDOUT_FILENO; - write(n, reason, strlen(reason)); - if (WCOREDUMP(cstat->val)) - write(n, " (core dumped)", 14); - write(n, "\n", 1); - } - } - } - -#ifdef HAVE_SELINUX - if (rbac_enabled) { - /* This is probably not needed in log_io mode. */ - if (selinux_restore_tty() != 0) - warningx("unable to restore tty label"); - } -#endif - - efree(fdsr); - efree(fdsw); - while ((iob = iobufs) != NULL) { - iobufs = iobufs->next; - efree(iob); - } - - return cstat->type == CMD_ERRNO ? -1 : 0; -} -#endif - static void deliver_signal(pid_t pid, int signo) {