!142 Backport patches from upstream community

From: @fly_fzc 
Reviewed-by: @houmingyong, @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
This commit is contained in:
openeuler-ci-bot 2025-04-21 03:05:26 +00:00 committed by Gitee
commit b5579133e8
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 678 additions and 1 deletions

View File

@ -0,0 +1,225 @@
From a2d01a957d31e133c37d77ae149527f9483e4f19 Mon Sep 17 00:00:00 2001
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
Date: Sun, 28 Apr 2024 10:28:32 -0600
Subject: [PATCH] Avoid using ioctl(TIOCNOTTY) in the monitor.
We don't need to revoke the terminal in the monitor, just signal
the foreground process group. This is more portable and has the
same effect as ioctl(TIOCNOTTY) would on Linux. Since we now signal
the command from the monitor, there is no reason to forward SIGHUP
from the kernel. GitHub issue #367.
Reference:https://github.com/sudo-project/sudo/commit/a2d01a957d31e133c37d77ae149527f9483e4f19
Conflict:src/exec_monitor.c src/exec_pty.c
---
src/exec_monitor.c | 84 +++++++++++++++++++++++++---------------------
src/exec_pty.c | 31 ++++++++++-------
src/sudo.h | 2 +-
3 files changed, 64 insertions(+), 53 deletions(-)
diff --git a/src/exec_monitor.c b/src/exec_monitor.c
index c570b5d86..524f5c8c9 100644
--- a/src/exec_monitor.c
+++ b/src/exec_monitor.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: ISC
*
- * Copyright (c) 2009-2021 Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 2009-2024 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -310,6 +310,48 @@ mon_errsock_cb(int fd, int what, void *v)
debug_return;
}
+/*
+ * Called when the user's terminal has gone away but before our pty is
+ * actually revoked. We simulate the effect of ioctl(TIOCNOTTY) on Linux
+ * by sending SIGHUP and SIGCONT to the foreground process group.
+ */
+static void
+mon_handle_revoke(int fd, pid_t cmnd_pid, struct command_status *cstat)
+{
+ debug_decl(mon_handle_revoke, SUDO_DEBUG_EXEC);
+
+ /*
+ * Signal the foreground process group and the command's process group
+ * (if different). We must do this before the pty is revoked be the
+ * main sudo process so we can determine the foreground process group.
+ * Otherwise, if the foreground process group is different from the
+ * command's process group it will not be signaled.
+ */
+ if (io_fds[SFD_FOLLOWER] != -1) {
+ const pid_t pgrp = tcgetpgrp(io_fds[SFD_FOLLOWER]);
+ if (pgrp != -1 && pgrp != cmnd_pid) {
+ sudo_debug_printf(SUDO_DEBUG_NOTICE, "%s: killpg(%d, SIGHUP)",
+ __func__, pgrp);
+ killpg(pgrp, SIGHUP);
+ sudo_debug_printf(SUDO_DEBUG_NOTICE, "%s: killpg(%d, SIGCONT)",
+ __func__, pgrp);
+ killpg(pgrp, SIGCONT);
+ }
+ }
+ sudo_debug_printf(SUDO_DEBUG_NOTICE, "%s: killpg(%d, SIGHUP)",
+ __func__, cmnd_pid);
+ killpg(cmnd_pid, SIGHUP);
+ sudo_debug_printf(SUDO_DEBUG_NOTICE, "%s: killpg(%d, SIGCONT)",
+ __func__, cmnd_pid);
+ killpg(cmnd_pid, SIGCONT);
+
+ /*
+ * Now that the running command as been signaled, tell the
+ * parent it is OK to close the pty leader, revoking the pty.
+ */
+ send_status(fd, cstat);
+}
+
static void
mon_backchannel_cb(int fd, int what, void *v)
{
@@ -337,44 +379,8 @@ mon_backchannel_cb(int fd, int what, void *v)
sudo_ev_loopbreak(mc->evbase);
} else {
switch (cstmp.type) {
- case CMD_IOCTL:
- if (cstmp.val != TIOCNOTTY) {
- sudo_warnx(U_("unexpected ioctl on backchannel: %d"),
- cstmp.val);
- } else if (io_fds[SFD_FOLLOWER] != -1) {
- int result, ttyfd;
-
- /*
- * Parent asks us to revoke the terminal when the
- * user's terminal goes away. Doing this in the
- * monitor allows the foreground command to receive
- * SIGHUP before the terminal is revoked.
- */
- result = ioctl(io_fds[SFD_FOLLOWER], TIOCNOTTY, NULL);
- if (result == -1) {
- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
- "%s: unable to revoke follower pty", __func__);
- ttyfd = open(_PATH_TTY, O_RDWR);
- if (ttyfd != -1) {
- result = ioctl(ttyfd, TIOCNOTTY, NULL);
- if (result == -1) {
- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
- "%s: unable to revoke controlling tty",
- __func__);
- }
- close(ttyfd);
- } else {
- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
- "%s: unable to open %s", __func__, _PATH_TTY);
- }
- }
- if (result == 0) {
- sudo_debug_printf(SUDO_DEBUG_INFO,
- "%s: revoked controlling tty for session", __func__);
- }
- /* Now tell the parent to close the pty leader. */
- send_status(fd, &cstmp);
- }
+ case CMD_REVOKE:
+ mon_handle_revoke(fd, mc->cmnd_pid, &cstmp);
break;
case CMD_SIGNO:
deliver_signal(mc, cstmp.val, true);
diff --git a/src/exec_pty.c b/src/exec_pty.c
index fff9b8f1e..4dd5915ed 100644
--- a/src/exec_pty.c
+++ b/src/exec_pty.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: ISC
*
- * Copyright (c) 2009-2021 Todd C. Miller <Todd.Miller@sudo.ws>
+ * Copyright (c) 2009-2024 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -385,13 +385,13 @@ read_callback(int fd, int what, void *v)
/* If writer already consumed the buffer, close it too. */
if (iob->wevent != NULL && iob->off == iob->len) {
/*
- * Don't close the pty leader, it will invalidate the pty.
- * We ask the monitor to revoke the pty nicely using TIOCNOTTY.
+ * Don't close the pty leader yet, it will invalidate the pty.
+ * We ask the monitor to signal the running process first.
*/
const int wfd = sudo_ev_get_fd(iob->wevent);
if (wfd == io_fds[SFD_LEADER]) {
sudo_debug_printf(SUDO_DEBUG_NOTICE, "user's tty revoked");
- send_command_status(iob->ec, CMD_IOCTL, TIOCNOTTY);
+ send_command_status(iob->ec, CMD_REVOKE, 0);
} else {
safe_close(wfd);
}
@@ -474,12 +474,12 @@ write_callback(int fd, int what, void *v)
if (iob->revent != NULL) {
/*
* Don't close the pty leader, it will invalidate the pty.
- * We ask the monitor to revoke the pty nicely using TIOCNOTTY.
+ * We ask the monitor to signal the running process first.
*/
const int rfd = sudo_ev_get_fd(iob->revent);
if (rfd == io_fds[SFD_LEADER]) {
sudo_debug_printf(SUDO_DEBUG_NOTICE, "user's tty revoked");
- send_command_status(iob->ec, CMD_IOCTL, TIOCNOTTY);
+ send_command_status(iob->ec, CMD_REVOKE, 0);
} else {
safe_close(rfd);
}
@@ -684,15 +684,11 @@ backchannel_cb(int fd, int what, void *v)
sudo_ev_loopbreak(ec->evbase);
*ec->cstat = cstat;
break;
- case CMD_IOCTL:
- if (cstat.val != TIOCNOTTY) {
- sudo_warnx(U_("unexpected ioctl on backchannel: %d"),
- cstat.val);
- } else if (io_fds[SFD_LEADER] != -1) {
+ case CMD_REVOKE:
+ if (io_fds[SFD_LEADER] != -1) {
/*
* Monitor requests that we revoke the user's terminal.
- * This must happen after the monitor has used TIOCNOTTY
- * to invalidate the session and gracefully kill the
+ * This must happen after the monitor has signaled the
* controlling terminal's process group.
*/
close(io_fds[SFD_LEADER]);
@@ -855,6 +851,15 @@ signal_cb_pty(int signo, int what, void *v)
case SIGWINCH:
sync_ttysize(ec);
break;
+ case SIGHUP:
+ /*
+ * Avoid forwarding SIGHUP sent by the kernel, it probably means
+ * that the user's terminal was revoked. When we detect that the
+ * terminal has been revoked, the monitor will send SIGHUP itself.
+ */
+ if (!USER_SIGNALED(sc->siginfo))
+ break;
+ FALLTHROUGH;
default:
/*
* Do not forward signals sent by a process in the command's process
diff --git a/src/sudo.h b/src/sudo.h
index ca245ca68..d3122ef4e 100644
--- a/src/sudo.h
+++ b/src/sudo.h
@@ -225,7 +225,7 @@ struct command_status {
#define CMD_WSTATUS 2
#define CMD_SIGNO 3
#define CMD_PID 4
-#define CMD_IOCTL 5
+#define CMD_REVOKE 5
int type;
int val;
};
--
2.33.0

View File

@ -0,0 +1,212 @@
From 41978a56e042977923c1a55191b887218c536145 Mon Sep 17 00:00:00 2001
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
Date: Sat, 27 Apr 2024 18:53:50 -0600
Subject: [PATCH] If user's tty goes away, tell monitor to revoke the tty in
its session.
Previously, we would simply close the pty leader in the main sudo
process. This had the effect of revoking the pty, but the foreground
process would not necessarily receive SIGHUP. By using TIOCNOTTY
in the monitor, the running command has a better chance of getting
SIGHUP. Once the monitor has revoked the pty, the main sudo process
will close the pty leader, invalidating the pty. GitHub issue #367.
Reference:https://github.com/sudo-project/sudo/commit/41978a56e042977923c1a55191b887218c536145
Conflict:src/exec_monitor.c src/exec_pty.c
---
src/exec_monitor.c | 48 +++++++++++++++++++++++++++++++++++--
src/exec_pty.c | 60 ++++++++++++++++++++++++++++++++++++----------
src/sudo.h | 1 +
3 files changed, 95 insertions(+), 14 deletions(-)
diff --git a/src/exec_monitor.c b/src/exec_monitor.c
index 05f5f8cd1..c570b5d86 100644
--- a/src/exec_monitor.c
+++ b/src/exec_monitor.c
@@ -118,6 +118,8 @@ deliver_signal(struct monitor_closure *mc, int signo, bool from_parent)
/* NOTREACHED */
default:
/* Relay signal to command. */
+ sudo_debug_printf(SUDO_DEBUG_NOTICE, "%s: killpg(%d, %d)",
+ __func__, (int)mc->cmnd_pid, signo);
killpg(mc->cmnd_pid, signo);
break;
}
@@ -334,11 +336,53 @@ mon_backchannel_cb(int fd, int what, void *v)
mc->cstat->val = n ? EIO : ECONNRESET;
sudo_ev_loopbreak(mc->evbase);
} else {
- if (cstmp.type == CMD_SIGNO) {
+ switch (cstmp.type) {
+ case CMD_IOCTL:
+ if (cstmp.val != TIOCNOTTY) {
+ sudo_warnx(U_("unexpected ioctl on backchannel: %d"),
+ cstmp.val);
+ } else if (io_fds[SFD_FOLLOWER] != -1) {
+ int result, ttyfd;
+
+ /*
+ * Parent asks us to revoke the terminal when the
+ * user's terminal goes away. Doing this in the
+ * monitor allows the foreground command to receive
+ * SIGHUP before the terminal is revoked.
+ */
+ result = ioctl(io_fds[SFD_FOLLOWER], TIOCNOTTY, NULL);
+ if (result == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to revoke follower pty", __func__);
+ ttyfd = open(_PATH_TTY, O_RDWR);
+ if (ttyfd != -1) {
+ result = ioctl(ttyfd, TIOCNOTTY, NULL);
+ if (result == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to revoke controlling tty",
+ __func__);
+ }
+ close(ttyfd);
+ } else {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
+ "%s: unable to open %s", __func__, _PATH_TTY);
+ }
+ }
+ if (result == 0) {
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: revoked controlling tty for session", __func__);
+ }
+ /* Now tell the parent to close the pty leader. */
+ send_status(fd, &cstmp);
+ }
+ break;
+ case CMD_SIGNO:
deliver_signal(mc, cstmp.val, true);
- } else {
+ break;
+ default:
sudo_warnx(U_("unexpected reply type on backchannel: %d"),
cstmp.type);
+ break;
}
}
debug_return;
diff --git a/src/exec_pty.c b/src/exec_pty.c
index 6c0f7583e..fff9b8f1e 100644
--- a/src/exec_pty.c
+++ b/src/exec_pty.c
@@ -61,6 +61,7 @@ static struct exec_closure pty_ec;
static pid_t check_foreground(struct exec_closure_pty *ec);
static void add_io_events(struct sudo_event_base *evbase);
static void schedule_signal(struct exec_closure_pty *ec, int signo);
+static void send_command_status(struct exec_closure_pty *ec, int type, int val);
/*
* Cleanup hook for sudo_fatal()/sudo_fatalx()
@@ -383,8 +384,18 @@ read_callback(int fd, int what, void *v)
ev_free_by_fd(evbase, fd);
/* If writer already consumed the buffer, close it too. */
if (iob->wevent != NULL && iob->off == iob->len) {
- safe_close(sudo_ev_get_fd(iob->wevent));
- ev_free_by_fd(evbase, sudo_ev_get_fd(iob->wevent));
+ /*
+ * Don't close the pty leader, it will invalidate the pty.
+ * We ask the monitor to revoke the pty nicely using TIOCNOTTY.
+ */
+ const int wfd = sudo_ev_get_fd(iob->wevent);
+ if (wfd == io_fds[SFD_LEADER]) {
+ sudo_debug_printf(SUDO_DEBUG_NOTICE, "user's tty revoked");
+ send_command_status(iob->ec, CMD_IOCTL, TIOCNOTTY);
+ } else {
+ safe_close(wfd);
+ }
+ ev_free_by_fd(evbase, wfd);
iob->off = iob->len = 0;
}
break;
@@ -461,8 +472,18 @@ write_callback(int fd, int what, void *v)
iob->len - iob->off, fd);
/* Close reader if there is one. */
if (iob->revent != NULL) {
- safe_close(sudo_ev_get_fd(iob->revent));
- ev_free_by_fd(evbase, sudo_ev_get_fd(iob->revent));
+ /*
+ * Don't close the pty leader, it will invalidate the pty.
+ * We ask the monitor to revoke the pty nicely using TIOCNOTTY.
+ */
+ const int rfd = sudo_ev_get_fd(iob->revent);
+ if (rfd == io_fds[SFD_LEADER]) {
+ sudo_debug_printf(SUDO_DEBUG_NOTICE, "user's tty revoked");
+ send_command_status(iob->ec, CMD_IOCTL, TIOCNOTTY);
+ } else {
+ safe_close(rfd);
+ }
+ ev_free_by_fd(evbase, rfd);
}
safe_close(fd);
ev_free_by_fd(evbase, fd);
@@ -656,6 +677,28 @@ backchannel_cb(int fd, int what, void *v)
case sizeof(cstat):
/* Check command status. */
switch (cstat.type) {
+ case CMD_ERRNO:
+ /* Monitor was unable to execute command or broken pipe. */
+ sudo_debug_printf(SUDO_DEBUG_INFO, "errno from monitor: %s",
+ strerror(cstat.val));
+ sudo_ev_loopbreak(ec->evbase);
+ *ec->cstat = cstat;
+ break;
+ case CMD_IOCTL:
+ if (cstat.val != TIOCNOTTY) {
+ sudo_warnx(U_("unexpected ioctl on backchannel: %d"),
+ cstat.val);
+ } else if (io_fds[SFD_LEADER] != -1) {
+ /*
+ * Monitor requests that we revoke the user's terminal.
+ * This must happen after the monitor has used TIOCNOTTY
+ * to invalidate the session and gracefully kill the
+ * controlling terminal's process group.
+ */
+ close(io_fds[SFD_LEADER]);
+ io_fds[SFD_LEADER] = -1;
+ }
+ break;
case CMD_PID:
ec->cmnd_pid = cstat.val;
sudo_debug_printf(SUDO_DEBUG_INFO, "executed %s, pid %d",
@@ -693,13 +736,6 @@ backchannel_cb(int fd, int what, void *v)
*ec->cstat = cstat;
}
break;
- case CMD_ERRNO:
- /* Monitor was unable to execute command or broken pipe. */
- sudo_debug_printf(SUDO_DEBUG_INFO, "errno from monitor: %s",
- strerror(cstat.val));
- sudo_ev_loopbreak(ec->evbase);
- *ec->cstat = cstat;
- break;
}
/* Keep reading command status messages until EAGAIN or EOF. */
break;
@@ -1382,7 +1418,7 @@ exec_pty(struct command_details *details,
if (sudo_ev_dispatch(ec.evbase) == -1)
sudo_warn("%s", U_("error in event loop"));
if (sudo_ev_got_break(ec.evbase)) {
- /* error from callback or monitor died */
+ /* error from callback */
sudo_debug_printf(SUDO_DEBUG_ERROR, "event loop exited prematurely");
/* XXX: no good way to know if we should terminate the command. */
if (cstat->val == CMD_INVALID && ec.cmnd_pid != -1) {
diff --git a/src/sudo.h b/src/sudo.h
index a7450dca9..ca245ca68 100644
--- a/src/sudo.h
+++ b/src/sudo.h
@@ -225,6 +225,7 @@ struct command_status {
#define CMD_WSTATUS 2
#define CMD_SIGNO 3
#define CMD_PID 4
+#define CMD_IOCTL 5
int type;
int val;
};
--
2.33.0

View File

@ -0,0 +1,234 @@
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

View File

@ -1,6 +1,6 @@
Name: sudo
Version: 1.9.8p2
Release: 17
Release: 18
Summary: Allows restricted root access for specified users
License: ISC
URL: http://www.courtesan.com/sudo/
@ -43,6 +43,9 @@ Patch29: backport-Do-not-rely-on-the-definition-of-ALLOW-DENY-being-tr.patch
Patch30: backport-CVE-2023-42465.patch
Patch31: backport-Make-all-match-functions-return-ALLOW-DENY-.patch
Patch32: backport-role_to_sudoers-only-try-to-reuse-a-privilege-if-one.patch
Patch33: backport-Move-updating-of-the-window-size-back-to-the-main-su.patch
Patch34: backport-If-user-s-tty-goes-away-tell-monitor-to-revoke-the-t.patch
Patch35: backport-Avoid-using-ioctl-TIOCNOTTY-in-the-monitor.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires: pam
@ -193,6 +196,9 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i
%exclude %{_pkgdocdir}/ChangeLog
%changelog
* Fri Apr 18 2025 fuanan <fuanan3@h-partners.com> - 1.9.8p2-18
- Backport patch from upstream community
* Wed Jan 31 2024 fuanan <fuanan3@h-partners.com> - 1.9.8p2-17
- Backport patch from upstream community