Skip to content

Commit 8663be5

Browse files
committed
exec_pty: Fix "sudo -b" when taking input from a pipe or file
In background mode (sudo -b), the sudo process runs in an orphaned process group so the calls to fd_matches_pgrp() will always return false. Move the logic to handle CD_BACKGROUND into the non-interpose section of the stdin handling. Also reverse the logic and check for interpose[fd] instead of !interpose[fd] to improve readability.
1 parent 2faf4c8 commit 8663be5

File tree

1 file changed

+34
-33
lines changed

1 file changed

+34
-33
lines changed

src/exec_pty.c

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,11 +1208,22 @@ exec_pty(struct command_details *details,
12081208
/*
12091209
* If stdin, stdout or stderr is not the user's tty and logging is
12101210
* enabled, use a pipe to interpose ourselves instead of using the
1211-
* pty fd. We always use a pipe for stdin when in background mode.
1211+
* pty fd. In background mode, sudo runs in an orphaned process
1212+
* group so fd_matches_pgrp() will always return false.
12121213
*/
1213-
if (ISSET(details->flags, CD_BACKGROUND)) {
1214+
if (!fd_matches_pgrp(STDIN_FILENO, ppgrp, &sb)) {
1215+
if (interpose[STDIN_FILENO]) {
1216+
sudo_debug_printf(SUDO_DEBUG_INFO,
1217+
"stdin not user's tty, creating a pipe");
1218+
SET(details->flags, CD_EXEC_BG);
1219+
if (pipe2(io_pipe[STDIN_FILENO], O_CLOEXEC) != 0)
1220+
sudo_fatal("%s", U_("unable to create pipe"));
1221+
io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
1222+
log_stdin, read_callback, write_callback, ec);
1223+
io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
1224+
} else if (ISSET(details->flags, CD_BACKGROUND) && S_ISCHR(sb.st_mode)) {
12141225
/*
1215-
* Running in background (sudo -b), no access to terminal input.
1226+
* Background mode (sudo -b) has no access to terminal input.
12161227
* In non-pty mode, the command runs in an orphaned process
12171228
* group and reads from the controlling terminal fail with EIO.
12181229
* We cannot do the same while running in a pty but if we set
@@ -1226,8 +1237,7 @@ exec_pty(struct command_details *details,
12261237
io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
12271238
close(io_pipe[STDIN_FILENO][1]);
12281239
io_pipe[STDIN_FILENO][1] = -1;
1229-
} else if (!fd_matches_pgrp(STDIN_FILENO, ppgrp, &sb)) {
1230-
if (!interpose[STDIN_FILENO]) {
1240+
} else {
12311241
/* Not logging stdin, do not interpose. */
12321242
sudo_debug_printf(SUDO_DEBUG_INFO,
12331243
"stdin not user's tty, not logging");
@@ -1236,15 +1246,6 @@ exec_pty(struct command_details *details,
12361246
io_fds[SFD_STDIN] = dup(STDIN_FILENO);
12371247
if (io_fds[SFD_STDIN] == -1)
12381248
sudo_fatal("dup");
1239-
} else {
1240-
sudo_debug_printf(SUDO_DEBUG_INFO,
1241-
"stdin not user's tty, creating a pipe");
1242-
SET(details->flags, CD_EXEC_BG);
1243-
if (pipe2(io_pipe[STDIN_FILENO], O_CLOEXEC) != 0)
1244-
sudo_fatal("%s", U_("unable to create pipe"));
1245-
io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
1246-
log_stdin, read_callback, write_callback, ec);
1247-
io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
12481249
}
12491250

12501251
if (ec->foreground && ppgrp != sudo_pid) {
@@ -1258,7 +1259,17 @@ exec_pty(struct command_details *details,
12581259
}
12591260
}
12601261
if (!fd_matches_pgrp(STDOUT_FILENO, ppgrp, &sb)) {
1261-
if (!interpose[STDOUT_FILENO]) {
1262+
if (interpose[STDOUT_FILENO]) {
1263+
sudo_debug_printf(SUDO_DEBUG_INFO,
1264+
"stdout not user's tty, creating a pipe");
1265+
SET(details->flags, CD_EXEC_BG);
1266+
term_raw_flags = SUDO_TERM_OFLAG;
1267+
if (pipe2(io_pipe[STDOUT_FILENO], O_CLOEXEC) != 0)
1268+
sudo_fatal("%s", U_("unable to create pipe"));
1269+
io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
1270+
log_stdout, read_callback, write_callback, ec);
1271+
io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
1272+
} else {
12621273
/* Not logging stdout, do not interpose. */
12631274
sudo_debug_printf(SUDO_DEBUG_INFO,
12641275
"stdout not user's tty, not logging");
@@ -1269,34 +1280,24 @@ exec_pty(struct command_details *details,
12691280
io_fds[SFD_STDOUT] = dup(STDOUT_FILENO);
12701281
if (io_fds[SFD_STDOUT] == -1)
12711282
sudo_fatal("dup");
1272-
} else {
1273-
sudo_debug_printf(SUDO_DEBUG_INFO,
1274-
"stdout not user's tty, creating a pipe");
1275-
SET(details->flags, CD_EXEC_BG);
1276-
term_raw_flags = SUDO_TERM_OFLAG;
1277-
if (pipe2(io_pipe[STDOUT_FILENO], O_CLOEXEC) != 0)
1278-
sudo_fatal("%s", U_("unable to create pipe"));
1279-
io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
1280-
log_stdout, read_callback, write_callback, ec);
1281-
io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
12821283
}
12831284
}
12841285
if (!fd_matches_pgrp(STDERR_FILENO, ppgrp, &sb)) {
1285-
if (!interpose[STDERR_FILENO]) {
1286-
/* Not logging stderr, do not interpose. */
1287-
sudo_debug_printf(SUDO_DEBUG_INFO,
1288-
"stderr not user's tty, not logging");
1289-
io_fds[SFD_STDERR] = dup(STDERR_FILENO);
1290-
if (io_fds[SFD_STDERR] == -1)
1291-
sudo_fatal("dup");
1292-
} else {
1286+
if (interpose[STDERR_FILENO]) {
12931287
sudo_debug_printf(SUDO_DEBUG_INFO,
12941288
"stderr not user's tty, creating a pipe");
12951289
if (pipe2(io_pipe[STDERR_FILENO], O_CLOEXEC) != 0)
12961290
sudo_fatal("%s", U_("unable to create pipe"));
12971291
io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO,
12981292
log_stderr, read_callback, write_callback, ec);
12991293
io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
1294+
} else {
1295+
/* Not logging stderr, do not interpose. */
1296+
sudo_debug_printf(SUDO_DEBUG_INFO,
1297+
"stderr not user's tty, not logging");
1298+
io_fds[SFD_STDERR] = dup(STDERR_FILENO);
1299+
if (io_fds[SFD_STDERR] == -1)
1300+
sudo_fatal("dup");
13001301
}
13011302
}
13021303

0 commit comments

Comments
 (0)