Blame SOURCES/sudo-1.8.19p2-iologtruncate.patch

ce887b
diff --git a/src/exec_pty.c b/src/exec_pty.c
ce887b
index 7403506..56b2899 100644
ce887b
--- a/src/exec_pty.c
ce887b
+++ b/src/exec_pty.c
ce887b
@@ -711,8 +711,10 @@ io_buf_new(int rfd, int wfd,
ce887b
 int
ce887b
 fork_pty(struct command_details *details, int sv[], sigset_t *omask)
ce887b
 {
ce887b
+    struct plugin_container *plugin;
ce887b
     struct command_status cstat;
ce887b
-    int io_pipe[3][2];
ce887b
+    int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
ce887b
+    bool interpose[3] = { false, false, false };
ce887b
     sigaction_t sa;
ce887b
     sigset_t mask;
ce887b
     pid_t child;
ce887b
@@ -738,6 +740,16 @@ fork_pty(struct command_details *details, int sv[], sigset_t *omask)
ce887b
     sigaddset(&ttyblock, SIGTTIN);
ce887b
     sigaddset(&ttyblock, SIGTTOU);
ce887b
 
ce887b
+    /* Determine whether any of std{in,out,err} should be logged. */
ce887b
+    TAILQ_FOREACH(plugin, &io_plugins, entries) {
ce887b
+	if (plugin->u.io->log_stdin)
ce887b
+	    interpose[STDIN_FILENO] = true;
ce887b
+	if (plugin->u.io->log_stdout)
ce887b
+	    interpose[STDOUT_FILENO] = true;
ce887b
+	if (plugin->u.io->log_stderr)
ce887b
+	    interpose[STDERR_FILENO] = true;
ce887b
+    } 
ce887b
+
ce887b
     /*
ce887b
      * Setup stdin/stdout/stderr for child, to be duped after forking.
ce887b
      * In background mode there is no stdin.
ce887b
@@ -763,35 +775,64 @@ fork_pty(struct command_details *details, int sv[], sigset_t *omask)
ce887b
     }
ce887b
 
ce887b
     /*
ce887b
-     * If either stdin, stdout or stderr is not a tty we use a pipe
ce887b
-     * to interpose ourselves instead of duping the pty fd.
ce887b
+     * If stdin, stdout or stderr is not a tty and logging is enabled,
ce887b
+     * use a pipe to interpose ourselves instead of using the pty fd.
ce887b
      */
ce887b
-    memset(io_pipe, 0, sizeof(io_pipe));
ce887b
     if (io_fds[SFD_STDIN] == -1 || !isatty(STDIN_FILENO)) {
ce887b
-	sudo_debug_printf(SUDO_DEBUG_INFO, "stdin not a tty, creating a pipe");
ce887b
-	pipeline = true;
ce887b
-	if (pipe(io_pipe[STDIN_FILENO]) != 0)
ce887b
-	    sudo_fatal(U_("unable to create pipe"));
ce887b
-	io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
ce887b
-	    log_stdin, &iobufs);
ce887b
-	io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
ce887b
-    }
ce887b
-    if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) {
ce887b
-	sudo_debug_printf(SUDO_DEBUG_INFO, "stdout not a tty, creating a pipe");
ce887b
-	pipeline = true;
ce887b
-	if (pipe(io_pipe[STDOUT_FILENO]) != 0)
ce887b
-	    sudo_fatal(U_("unable to create pipe"));
ce887b
-	io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
ce887b
-	    log_stdout, &iobufs);
ce887b
-	io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
ce887b
-    }
ce887b
-    if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) {
ce887b
-	sudo_debug_printf(SUDO_DEBUG_INFO, "stderr not a tty, creating a pipe");
ce887b
-	if (pipe(io_pipe[STDERR_FILENO]) != 0)
ce887b
-	    sudo_fatal(U_("unable to create pipe"));
ce887b
-	io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO,
ce887b
-	    log_stderr, &iobufs);
ce887b
-	io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
ce887b
+	if (!interpose[STDIN_FILENO]) {
ce887b
+	    /* Not logging stdin, do not interpose. */
ce887b
+	    sudo_debug_printf(SUDO_DEBUG_INFO,
ce887b
+		"stdin not a tty, not logging");
ce887b
+	    io_fds[SFD_STDIN] = dup(STDIN_FILENO);
ce887b
+	    if (io_fds[SFD_STDIN] == -1)
ce887b
+		sudo_fatal("dup");
ce887b
+	} else {
ce887b
+	    sudo_debug_printf(SUDO_DEBUG_INFO,
ce887b
+		"stdin not a tty, creating a pipe");
ce887b
+	    pipeline = true;
ce887b
+	    if (pipe(io_pipe[STDIN_FILENO]) != 0)
ce887b
+		sudo_fatal(U_("unable to create pipe"));
ce887b
+	    io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
ce887b
+		log_stdin, &iobufs);
ce887b
+	    io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
ce887b
+	}
ce887b
+     }
ce887b
+     if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) {
ce887b
+	if (!interpose[STDOUT_FILENO]) {
ce887b
+	    /* Not logging stdout, do not interpose. */
ce887b
+	    sudo_debug_printf(SUDO_DEBUG_INFO,
ce887b
+		"stdout not a tty, not logging");
ce887b
+	    io_fds[SFD_STDOUT] = dup(STDOUT_FILENO);
ce887b
+	    if (io_fds[SFD_STDOUT] == -1)
ce887b
+		sudo_fatal("dup");
ce887b
+	} else {
ce887b
+	    sudo_debug_printf(SUDO_DEBUG_INFO,
ce887b
+		"stdout not a tty, creating a pipe");
ce887b
+	    pipeline = true;
ce887b
+	    if (pipe(io_pipe[STDOUT_FILENO]) != 0)
ce887b
+		sudo_fatal(U_("unable to create pipe"));
ce887b
+	    io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
ce887b
+		log_stdout, &iobufs);
ce887b
+	    io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
ce887b
+	}
ce887b
+     }
ce887b
+     if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) {
ce887b
+	if (!interpose[STDERR_FILENO]) {
ce887b
+	    /* Not logging stderr, do not interpose. */
ce887b
+	    sudo_debug_printf(SUDO_DEBUG_INFO,
ce887b
+		"stderr not a tty, not logging");
ce887b
+	    io_fds[SFD_STDERR] = dup(STDERR_FILENO);
ce887b
+	    if (io_fds[SFD_STDERR] == -1)
ce887b
+		sudo_fatal("dup");
ce887b
+	} else {
ce887b
+	    sudo_debug_printf(SUDO_DEBUG_INFO,
ce887b
+		"stderr not a tty, creating a pipe");
ce887b
+	    if (pipe(io_pipe[STDERR_FILENO]) != 0)
ce887b
+		sudo_fatal(U_("unable to create pipe"));
ce887b
+	    io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO,
ce887b
+		log_stderr, &iobufs);
ce887b
+	    io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
ce887b
+	}
ce887b
     }
ce887b
 
ce887b
     /* We don't want to receive SIGTTIN/SIGTTOU, getting EIO is preferable. */
ce887b
@@ -1549,10 +1590,24 @@ exec_pty(struct command_details *details,
ce887b
     setpgid(0, self);
ce887b
 
ce887b
     /* Wire up standard fds, note that stdout/stderr may be pipes. */
ce887b
-    if (dup2(io_fds[SFD_STDIN], STDIN_FILENO) == -1 ||
ce887b
-	dup2(io_fds[SFD_STDOUT], STDOUT_FILENO) == -1 ||
ce887b
-	dup2(io_fds[SFD_STDERR], STDERR_FILENO) == -1)
ce887b
-	sudo_fatal("dup2");
ce887b
+    if (io_fds[SFD_STDIN] != STDIN_FILENO) {
ce887b
+	if (dup2(io_fds[SFD_STDIN], STDIN_FILENO) == -1)
ce887b
+	    sudo_fatal("dup2");
ce887b
+	if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
ce887b
+	    close(io_fds[SFD_STDIN]);
ce887b
+    }
ce887b
+    if (io_fds[SFD_STDOUT] != STDOUT_FILENO) {
ce887b
+	if (dup2(io_fds[SFD_STDOUT], STDOUT_FILENO) == -1)
ce887b
+	    sudo_fatal("dup2");
ce887b
+	if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
ce887b
+	    close(io_fds[SFD_STDOUT]);
ce887b
+    }
ce887b
+    if (io_fds[SFD_STDERR] != STDERR_FILENO) {
ce887b
+	if (dup2(io_fds[SFD_STDERR], STDERR_FILENO) == -1)
ce887b
+	    sudo_fatal("dup2");
ce887b
+	if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
ce887b
+	    close(io_fds[SFD_STDERR]);
ce887b
+    }
ce887b
 
ce887b
     /* Wait for parent to grant us the tty if we are foreground. */
ce887b
     if (foreground && !ISSET(details->flags, CD_EXEC_BG)) {
ce887b
@@ -1561,15 +1616,9 @@ exec_pty(struct command_details *details,
ce887b
 	    nanosleep(&ts, NULL);
ce887b
     }
ce887b
 
ce887b
-    /* We have guaranteed that the slave fd is > 2 */
ce887b
+    /* Done with the pty slave, don't leak it. */
ce887b
     if (io_fds[SFD_SLAVE] != -1)
ce887b
 	close(io_fds[SFD_SLAVE]);
ce887b
-    if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
ce887b
-	close(io_fds[SFD_STDIN]);
ce887b
-    if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
ce887b
-	close(io_fds[SFD_STDOUT]);
ce887b
-    if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
ce887b
-	close(io_fds[SFD_STDERR]);
ce887b
 
ce887b
     /* Execute command; only returns on error. */
ce887b
     exec_cmnd(details, cstat, errfd);