Fix compressed io log corruption in background mode by using _exit()

instead of exit() to avoid flushing buffers twice.

Improved background mode support.  When not allocating a pty, the
command is run in its own process group.  This prevents write access
to the tty.  When running in a pty, stdin is not hooked up and we
never read from /dev/tty, which results in similar behavior.
This commit is contained in:
Todd C. Miller
2011-05-31 12:49:22 -04:00
parent 7199afec89
commit 3c9e5f28fc
2 changed files with 14 additions and 11 deletions

View File

@@ -216,20 +216,19 @@ sudo_execve(struct command_details *details, struct command_status *cstat)
cstat->val = errno; cstat->val = errno;
return -1; return -1;
case 0: case 0:
/* child continues in a new session in a different pty */ /* child continues without controlling terminal */
SET(details->flags, CD_USE_PTY); (void)setpgid(0, 0);
(void)setsid();
break; break;
default: default:
/* parent exits */ /* parent exits (but does not flush buffers) */
exit(0); _exit(0);
} }
} }
/* /*
* If we have an I/O plugin or the policy plugin has requested one, we * If we have an I/O plugin or the policy plugin has requested one, we
* need to allocate a pty. It is OK to set log_io in the pty-only case * need to allocate a pty. It is OK to set log_io in the pty-only case
* as the tailqueue plugin will be empty and no I/O logging will occur. * as the io plugin tailqueue will be empty and no I/O logging will occur.
*/ */
if (!tq_empty(&io_plugins) || ISSET(details->flags, CD_USE_PTY)) { if (!tq_empty(&io_plugins) || ISSET(details->flags, CD_USE_PTY)) {
log_io = TRUE; log_io = TRUE;

View File

@@ -493,17 +493,21 @@ fork_pty(struct command_details *details, int sv[], int *maxfd)
/* /*
* Setup stdin/stdout/stderr for child, to be duped after forking. * Setup stdin/stdout/stderr for child, 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_SLAVE]; io_fds[SFD_STDIN] = io_fds[SFD_SLAVE];
io_fds[SFD_STDOUT] = io_fds[SFD_SLAVE]; io_fds[SFD_STDOUT] = io_fds[SFD_SLAVE];
io_fds[SFD_STDERR] = io_fds[SFD_SLAVE]; io_fds[SFD_STDERR] = io_fds[SFD_SLAVE];
/* Copy /dev/tty -> pty master */
if (io_fds[SFD_USERTTY] != -1) { if (io_fds[SFD_USERTTY] != -1) {
/* Read from /dev/tty, write to pty master */
if (!ISSET(details->flags, CD_BACKGROUND)) {
iobufs = io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_MASTER], iobufs = io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_MASTER],
log_ttyin, iobufs); log_ttyin, iobufs);
}
/* Copy pty master -> /dev/tty */ /* Read from pty master, write to /dev/tty */
iobufs = io_buf_new(io_fds[SFD_MASTER], io_fds[SFD_USERTTY], iobufs = io_buf_new(io_fds[SFD_MASTER], io_fds[SFD_USERTTY],
log_ttyout, iobufs); log_ttyout, iobufs);