235 lines
7.6 KiB
Diff
235 lines
7.6 KiB
Diff
From adb84293abfc1c3349ab34c03b036f1756e89aca Mon Sep 17 00:00:00 2001
|
|
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
|
Date: Tue, 21 Mar 2023 15:30:54 -0600
|
|
Subject: [PATCH] Move updating of the window size back to the main sudo
|
|
process. We can use the leader file descriptor with TIOCGWINSZ to set the
|
|
window size of the pty. Thanks to Duncan Overbruck for the hint.
|
|
|
|
|
|
Reference:https://github.com/sudo-project/sudo/commit/adb84293abfc1c3349ab34c03b036f1756e89aca
|
|
Conflict:src/exec_monitor.c src/exec_pty.c
|
|
|
|
---
|
|
src/exec_monitor.c | 60 ++++++----------------------------------------
|
|
src/exec_pty.c | 23 +++++++++---------
|
|
src/sudo.h | 1 -
|
|
3 files changed, 18 insertions(+), 66 deletions(-)
|
|
|
|
diff --git a/src/exec_monitor.c b/src/exec_monitor.c
|
|
index a92ed4099..2f2e0bd83 100644
|
|
--- a/src/exec_monitor.c
|
|
+++ b/src/exec_monitor.c
|
|
@@ -24,7 +24,6 @@
|
|
#include <config.h>
|
|
|
|
#include <sys/types.h>
|
|
-#include <sys/ioctl.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/wait.h>
|
|
#include <stdio.h>
|
|
@@ -35,7 +34,6 @@
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
-#include <termios.h>
|
|
|
|
#include "sudo.h"
|
|
#include "sudo_exec.h"
|
|
@@ -62,8 +60,6 @@ struct monitor_closure {
|
|
struct sudo_event *sigchld_event;
|
|
};
|
|
|
|
-static bool tty_initialized;
|
|
-
|
|
/*
|
|
* Deliver a signal to the running command.
|
|
* The signal was either forwarded to us by the parent sudo process
|
|
@@ -103,11 +99,6 @@ deliver_signal(struct monitor_closure *mc, int signo, bool from_parent)
|
|
"%s: unable to set foreground pgrp to %d (command)",
|
|
__func__, (int)mc->cmnd_pgrp);
|
|
}
|
|
- /* Lazily initialize the pty if needed. */
|
|
- if (!tty_initialized) {
|
|
- if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_FOLLOWER]))
|
|
- tty_initialized = true;
|
|
- }
|
|
killpg(mc->cmnd_pid, SIGCONT);
|
|
break;
|
|
case SIGCONT_BG:
|
|
@@ -130,34 +121,6 @@ deliver_signal(struct monitor_closure *mc, int signo, bool from_parent)
|
|
debug_return;
|
|
}
|
|
|
|
-/*
|
|
- * Unpack rows and cols from a CMD_TTYWINCH value, set the new window
|
|
- * size on the pty follower and inform the command of the change.
|
|
- */
|
|
-static void
|
|
-handle_winch(struct monitor_closure *mc, unsigned int wsize_packed)
|
|
-{
|
|
- struct winsize wsize, owsize;
|
|
- debug_decl(handle_winch, SUDO_DEBUG_EXEC);
|
|
-
|
|
- /* Rows and columns are stored as two shorts packed into a single int. */
|
|
- wsize.ws_row = wsize_packed & 0xffff;
|
|
- wsize.ws_col = (wsize_packed >> 16) & 0xffff;
|
|
-
|
|
- if (ioctl(io_fds[SFD_FOLLOWER], TIOCGWINSZ, &owsize) == 0 &&
|
|
- (wsize.ws_row != owsize.ws_row || wsize.ws_col != owsize.ws_col)) {
|
|
-
|
|
- sudo_debug_printf(SUDO_DEBUG_INFO,
|
|
- "window size change %dx%d -> %dx%d",
|
|
- owsize.ws_col, owsize.ws_row, wsize.ws_col, wsize.ws_row);
|
|
-
|
|
- (void)ioctl(io_fds[SFD_FOLLOWER], TIOCSWINSZ, &wsize);
|
|
- deliver_signal(mc, SIGWINCH, true);
|
|
- }
|
|
-
|
|
- debug_return;
|
|
-}
|
|
-
|
|
/*
|
|
* Send status to parent over socketpair.
|
|
* Return value is the same as send(2).
|
|
@@ -368,16 +331,11 @@ mon_backchannel_cb(int fd, int what, void *v)
|
|
mc->cstat->val = n ? EIO : ECONNRESET;
|
|
sudo_ev_loopbreak(mc->evbase);
|
|
} else {
|
|
- switch (cstmp.type) {
|
|
- case CMD_TTYWINCH:
|
|
- handle_winch(mc, cstmp.val);
|
|
- break;
|
|
- case CMD_SIGNO:
|
|
+ if (cstmp.type == CMD_SIGNO) {
|
|
deliver_signal(mc, cstmp.val, true);
|
|
- break;
|
|
- default:
|
|
- sudo_warnx(U_("unexpected reply type on backchannel: %d"), cstmp.type);
|
|
- break;
|
|
+ } else {
|
|
+ sudo_warnx(U_("unexpected reply type on backchannel: %d"),
|
|
+ cstmp.type);
|
|
}
|
|
}
|
|
debug_return;
|
|
@@ -556,9 +514,11 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|
int errpipe[2];
|
|
debug_decl(exec_monitor, SUDO_DEBUG_EXEC);
|
|
|
|
- /* The pty leader is not used by the monitor. */
|
|
+ /* Close fds the monitor doesn't use. */
|
|
if (io_fds[SFD_LEADER] != -1)
|
|
close(io_fds[SFD_LEADER]);
|
|
+ if (io_fds[SFD_USERTTY] != -1)
|
|
+ close(io_fds[SFD_USERTTY]);
|
|
|
|
/* Ignore any SIGTTIN or SIGTTOU we receive (shouldn't be possible). */
|
|
memset(&sa, 0, sizeof(sa));
|
|
@@ -570,10 +530,6 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|
if (sudo_sigaction(SIGTTOU, &sa, NULL) != 0)
|
|
sudo_warn(U_("unable to set handler for signal %d"), SIGTTOU);
|
|
|
|
- /* If we are starting in the foreground, the pty was already initialized. */
|
|
- if (foreground)
|
|
- tty_initialized = true;
|
|
-
|
|
/*
|
|
* Start a new session with the parent as the session leader
|
|
* and the follower device as the controlling terminal.
|
|
@@ -630,8 +586,6 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|
sigprocmask(SIG_SETMASK, oset, NULL);
|
|
close(backchannel);
|
|
close(errpipe[0]);
|
|
- if (io_fds[SFD_USERTTY] != -1)
|
|
- close(io_fds[SFD_USERTTY]);
|
|
restore_signals();
|
|
|
|
/* setup tty and exec command */
|
|
diff --git a/src/exec_pty.c b/src/exec_pty.c
|
|
index 9a8ddfab1..e764564aa 100644
|
|
--- a/src/exec_pty.c
|
|
+++ b/src/exec_pty.c
|
|
@@ -59,6 +59,7 @@ static struct monitor_message_list monitor_messages =
|
|
static char ptyname[PATH_MAX];
|
|
int io_fds[6] = { -1, -1, -1, -1, -1, -1};
|
|
static bool foreground, pipeline;
|
|
+static bool tty_initialized;
|
|
static int ttymode = TERM_COOKED;
|
|
static sigset_t ttyblock;
|
|
static struct io_buffer_list iobufs;
|
|
@@ -159,6 +160,10 @@ check_foreground(struct exec_closure *ec)
|
|
if (io_fds[SFD_USERTTY] != -1) {
|
|
if ((ret = tcgetpgrp(io_fds[SFD_USERTTY])) != -1) {
|
|
foreground = ret == ec->ppgrp;
|
|
+ if (foreground && !tty_initialized) {
|
|
+ if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_FOLLOWER]))
|
|
+ tty_initialized = true;
|
|
+ }
|
|
|
|
/* Also check for window size changes. */
|
|
sync_ttysize(ec);
|
|
@@ -840,11 +845,6 @@ fwdchannel_cb(int sock, int what, void *v)
|
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
|
"sending SIG%s to monitor over backchannel", signame);
|
|
break;
|
|
- case CMD_TTYWINCH:
|
|
- sudo_debug_printf(SUDO_DEBUG_INFO, "sending window size change "
|
|
- "to monitor over backchannelL %d x %d",
|
|
- msg->cstat.val & 0xffff, (msg->cstat.val >> 16) & 0xffff);
|
|
- break;
|
|
default:
|
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
|
"sending cstat type %d, value %d to monitor over backchannel",
|
|
@@ -1192,6 +1192,7 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|
if (sudo_term_raw(io_fds[SFD_USERTTY], 0))
|
|
ttymode = TERM_RAW;
|
|
}
|
|
+ tty_initialized = true;
|
|
}
|
|
}
|
|
|
|
@@ -1347,8 +1348,8 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|
}
|
|
|
|
/*
|
|
- * Check for tty size changes.
|
|
- * Passes the new window size to the I/O plugin and to the monitor.
|
|
+ * Propagate tty size change to pty being used by the command, pass
|
|
+ * new window size to I/O plugins and deliver SIGWINCH to the command.
|
|
*/
|
|
static void
|
|
sync_ttysize(struct exec_closure_pty *ec)
|
|
@@ -1358,14 +1359,12 @@ sync_ttysize(struct exec_closure_pty *ec)
|
|
|
|
if (ioctl(io_fds[SFD_USERTTY], TIOCGWINSZ, &wsize) == 0) {
|
|
if (wsize.ws_row != ec->rows || wsize.ws_col != ec->cols) {
|
|
- const unsigned int wsize_packed = (wsize.ws_row & 0xffff) |
|
|
- ((wsize.ws_col & 0xffff) << 16);
|
|
-
|
|
/* Log window change event. */
|
|
log_winchange(ec, wsize.ws_row, wsize.ws_col);
|
|
|
|
- /* Send window change event to monitor process. */
|
|
- send_command_status(ec, CMD_TTYWINCH, wsize_packed);
|
|
+ /* Update pty window size and send command SIGWINCH. */
|
|
+ (void)ioctl(io_fds[SFD_LEADER], TIOCSWINSZ, &wsize);
|
|
+ killpg(ec->cmnd_pid, SIGWINCH);
|
|
|
|
/* Update rows/cols. */
|
|
ec->rows = wsize.ws_row;
|
|
diff --git a/src/sudo.h b/src/sudo.h
|
|
index acb89b751..204c3e76e 100644
|
|
--- a/src/sudo.h
|
|
+++ b/src/sudo.h
|
|
@@ -225,7 +225,6 @@ struct command_status {
|
|
#define CMD_WSTATUS 2
|
|
#define CMD_SIGNO 3
|
|
#define CMD_PID 4
|
|
-#define CMD_TTYWINCH 5
|
|
int type;
|
|
int val;
|
|
};
|
|
--
|
|
2.33.0
|
|
|