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:
11
src/exec.c
11
src/exec.c
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user