!145 [sync] PR-141: Backport patches from upstream community

From: @openeuler-sync-bot 
Reviewed-by: @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
This commit is contained in:
openeuler-ci-bot 2025-04-21 06:05:35 +00:00 committed by Gitee
commit 7dee3ca186
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 443 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:NA
---
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-2023 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-2023 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 the command itself or a member of the
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:NA
---
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 void sync_ttysize(struct exec_closure *ec);
static void schedule_signal(struct exec_closure *ec, int signo);
+static void send_command_status(struct exec_closure *ec, int type, int val);
/*
* Allocate a pty if /dev/tty is a tty.
@@ -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

@ -1,6 +1,6 @@
Name: sudo Name: sudo
Version: 1.9.15p5 Version: 1.9.15p5
Release: 1 Release: 2
Summary: Allows restricted root access for specified users Summary: Allows restricted root access for specified users
License: ISC License: ISC
URL: https://www.sudo.ws URL: https://www.sudo.ws
@ -11,6 +11,8 @@ Source2: sudo
Source3: sudo-i Source3: sudo-i
Patch0: Fix-compilation-error-on-sw64-arch.patch Patch0: Fix-compilation-error-on-sw64-arch.patch
Patch1: backport-If-user-s-tty-goes-away-tell-monitor-to-revoke-the-t.patch
Patch2: backport-Avoid-using-ioctl-TIOCNOTTY-in-the-monitor.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires: pam Requires: pam
@ -155,6 +157,9 @@ chrpath -d $RPM_BUILD_ROOT/usr/libexec/sudo/*
%exclude %{_pkgdocdir}/ChangeLog %exclude %{_pkgdocdir}/ChangeLog
%changelog %changelog
* Fri Apr 18 2025 fuanan <fuanan3@h-partners.com> - 1.9.15p5-2
- Backport patches from upstream community
* Mon Jan 8 2024 wangqingsan <wangqingsan@huawei.com> - 1.9.15p5-1 * Mon Jan 8 2024 wangqingsan <wangqingsan@huawei.com> - 1.9.15p5-1
- Upgrade to 1.9.15p5 - Upgrade to 1.9.15p5