diff options
author | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-04-19 14:34:57 -0600 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-04-19 14:34:57 -0600 |
commit | d48a3fdeef949d44c817035a85cb4b540b3b5fc4 (patch) | |
tree | 7c5cc022991c3dd7b83cbf835f0d90a2445c632a | |
parent | 5579d3f2ba7c666149bd660bb1687f402996194a (diff) | |
download | sudo-d48a3fdeef949d44c817035a85cb4b540b3b5fc4.tar.gz |
Better support for "sudo -b" when running the command in a pty.
When a command is run via "sudo -b" it has no access to terminal
input. In non-pty mode, the command runs in an orphaned process
group and reads from the controlling terminal fail with EIO. We
cannot do the same while running in a pty but if we set stdin to a
half-closed pipe, reads from it will get EOF. That is close enough.
-rw-r--r-- | src/exec_pty.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/exec_pty.c b/src/exec_pty.c index 2b5228020..dc58138f6 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -1150,10 +1150,8 @@ exec_pty(struct command_details *details, /* * Setup stdin/stdout/stderr for command, to be duped after forking. - * In background mode there is no stdin. */ - if (!ISSET(details->flags, CD_BACKGROUND)) - io_fds[SFD_STDIN] = io_fds[SFD_FOLLOWER]; + io_fds[SFD_STDIN] = io_fds[SFD_FOLLOWER]; io_fds[SFD_STDOUT] = io_fds[SFD_FOLLOWER]; io_fds[SFD_STDERR] = io_fds[SFD_FOLLOWER]; @@ -1178,7 +1176,7 @@ exec_pty(struct command_details *details, * If stdin, stdout or stderr is not a tty and logging is enabled, * use a pipe to interpose ourselves instead of using the pty fd. */ - if (io_fds[SFD_STDIN] == -1 || !isatty(STDIN_FILENO)) { + if (!isatty(STDIN_FILENO)) { if (!interpose[STDIN_FILENO]) { /* Not logging stdin, do not interpose. */ sudo_debug_printf(SUDO_DEBUG_INFO, @@ -1208,8 +1206,24 @@ exec_pty(struct command_details *details, */ SET(details->flags, CD_EXEC_BG); } + } else if (ISSET(details->flags, CD_BACKGROUND)) { + /* + * Running in background (sudo -b), no access to terminal input. + * In non-pty mode, the command runs in an orphaned process + * group and reads from the controlling terminal fail with EIO. + * We cannot do the same while running in a pty but if we set + * stdin to a half-closed pipe, reads from it will get EOF. + */ + sudo_debug_printf(SUDO_DEBUG_INFO, + "terminal input not available, creating empty pipe"); + pipeline = true; + if (pipe2(io_pipe[STDIN_FILENO], O_CLOEXEC) != 0) + sudo_fatal("%s", U_("unable to create pipe")); + io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0]; + close(io_pipe[STDIN_FILENO][1]); + io_pipe[STDIN_FILENO][1] = -1; } - if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) { + if (!isatty(STDOUT_FILENO)) { if (!interpose[STDOUT_FILENO]) { /* Not logging stdout, do not interpose. */ sudo_debug_printf(SUDO_DEBUG_INFO, @@ -1230,7 +1244,7 @@ exec_pty(struct command_details *details, io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1]; } } - if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) { + if (!isatty(STDERR_FILENO)) { if (!interpose[STDERR_FILENO]) { /* Not logging stderr, do not interpose. */ sudo_debug_printf(SUDO_DEBUG_INFO, |