Compare commits
10 Commits
2f4d35adb1
...
b5579133e8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5579133e8 | ||
|
|
67a74408d0 | ||
|
|
0d0f8edec9 | ||
|
|
38e7f1e2fa | ||
|
|
6aff24a439 | ||
|
|
32e9f5e7c8 | ||
|
|
8b88b8a47f | ||
|
|
e0f7944170 | ||
|
|
2e0d9d82fd | ||
|
|
efb33c4dd8 |
225
backport-Avoid-using-ioctl-TIOCNOTTY-in-the-monitor.patch
Normal file
225
backport-Avoid-using-ioctl-TIOCNOTTY-in-the-monitor.patch
Normal 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
|
||||
|
||||
442
backport-CVE-2023-42465.patch
Normal file
442
backport-CVE-2023-42465.patch
Normal file
@ -0,0 +1,442 @@
|
||||
From 7873f8334c8d31031f8cfa83bd97ac6029309e4f Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Sat, 9 Sep 2023 14:07:04 -0600
|
||||
Subject: [PATCH] Try to make sudo less vulnerable to ROWHAMMER attacks.
|
||||
|
||||
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
|
||||
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
|
||||
explicitly test for expected values instead of using a negated test
|
||||
against an error value. In the parser match functions this means
|
||||
explicitly checking for ALLOW or DENY instead of accepting anything
|
||||
that is not set to UNSPEC.
|
||||
|
||||
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
|
||||
Sunar, all affiliated with the Vernam Applied Cryptography and
|
||||
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
|
||||
Paper preprint: https://arxiv.org/abs/2309.02545
|
||||
|
||||
Reference: https://github.com/sudo-project/sudo/commit/7873f8334c8d31031f8cfa83bd97ac6029309e4f
|
||||
Conflict: passwd.c sudo_auth.h match.c parse.c
|
||||
---
|
||||
plugins/sudoers/auth/passwd.c | 27 ++++++++++-------
|
||||
plugins/sudoers/auth/sudo_auth.c | 51 ++++++++++++++++++++++----------
|
||||
plugins/sudoers/auth/sudo_auth.h | 10 +++----
|
||||
plugins/sudoers/match.c | 25 ++++++++--------
|
||||
plugins/sudoers/parse.c | 6 ++--
|
||||
plugins/sudoers/parse.h | 23 ++++++++++----
|
||||
6 files changed, 92 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/auth/passwd.c b/plugins/sudoers/auth/passwd.c
|
||||
index bb9f2d6..8f163cb 100644
|
||||
--- a/plugins/sudoers/auth/passwd.c
|
||||
+++ b/plugins/sudoers/auth/passwd.c
|
||||
@@ -62,7 +62,7 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
|
||||
char des_pass[9], *epass;
|
||||
char *pw_epasswd = auth->data;
|
||||
size_t pw_len;
|
||||
- int matched = 0;
|
||||
+ int ret;
|
||||
debug_decl(sudo_passwd_verify, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
/* An empty plain-text password must match an empty encrypted password. */
|
||||
@@ -74,7 +74,7 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
|
||||
*/
|
||||
pw_len = strlen(pw_epasswd);
|
||||
if (pw_len == DESLEN || HAS_AGEINFO(pw_epasswd, pw_len)) {
|
||||
- strlcpy(des_pass, pass, sizeof(des_pass));
|
||||
+ (void)strlcpy(des_pass, pass, sizeof(des_pass));
|
||||
pass = des_pass;
|
||||
}
|
||||
|
||||
@@ -84,29 +84,36 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
|
||||
* only compare the first DESLEN characters in that case.
|
||||
*/
|
||||
epass = (char *) crypt(pass, pw_epasswd);
|
||||
+ ret = AUTH_FAILURE;
|
||||
if (epass != NULL) {
|
||||
- if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN)
|
||||
- matched = !strncmp(pw_epasswd, epass, DESLEN);
|
||||
- else
|
||||
- matched = !strcmp(pw_epasswd, epass);
|
||||
+ if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN) {
|
||||
+ if (strncmp(pw_epasswd, epass, DESLEN) == 0)
|
||||
+ ret = AUTH_SUCCESS;
|
||||
+ } else {
|
||||
+ if (strcmp(pw_epasswd, epass) == 0)
|
||||
+ ret = AUTH_SUCCESS;
|
||||
+ }
|
||||
}
|
||||
|
||||
explicit_bzero(des_pass, sizeof(des_pass));
|
||||
|
||||
- debug_return_int(matched ? AUTH_SUCCESS : AUTH_FAILURE);
|
||||
+ debug_return_int(ret);
|
||||
}
|
||||
#else
|
||||
int
|
||||
sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
|
||||
{
|
||||
char *pw_passwd = auth->data;
|
||||
- int matched;
|
||||
+ int ret;
|
||||
debug_decl(sudo_passwd_verify, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
/* Simple string compare for systems without crypt(). */
|
||||
- matched = !strcmp(pass, pw_passwd);
|
||||
+ if (strcmp(pass, pw_passwd) == 0)
|
||||
+ ret = AUTH_SUCCESS;
|
||||
+ else
|
||||
+ ret = AUTH_FAILURE;
|
||||
|
||||
- debug_return_int(matched ? AUTH_SUCCESS : AUTH_FAILURE);
|
||||
+ debug_return_int(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c
|
||||
index 188b65f..467233a 100644
|
||||
--- a/plugins/sudoers/auth/sudo_auth.c
|
||||
+++ b/plugins/sudoers/auth/sudo_auth.c
|
||||
@@ -112,10 +112,16 @@ sudo_auth_init(struct passwd *pw)
|
||||
if (auth->init && !IS_DISABLED(auth)) {
|
||||
/* Disable if it failed to init unless there was a fatal error. */
|
||||
status = (auth->init)(pw, auth);
|
||||
- if (status == AUTH_FAILURE)
|
||||
+ switch (status) {
|
||||
+ case AUTH_SUCCESS:
|
||||
+ break;
|
||||
+ case AUTH_FAILURE:
|
||||
SET(auth->flags, FLAG_DISABLED);
|
||||
- else if (status == AUTH_FATAL)
|
||||
- break; /* assume error msg already printed */
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* Assume error msg already printed. */
|
||||
+ debug_return_int(-1);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +167,7 @@ sudo_auth_init(struct passwd *pw)
|
||||
}
|
||||
}
|
||||
|
||||
- debug_return_int(status == AUTH_FATAL ? -1 : 0);
|
||||
+ debug_return_int(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -202,7 +208,7 @@ sudo_auth_cleanup(struct passwd *pw, bool force)
|
||||
for (auth = auth_switch; auth->name; auth++) {
|
||||
if (auth->cleanup && !IS_DISABLED(auth)) {
|
||||
int status = (auth->cleanup)(pw, auth, force);
|
||||
- if (status == AUTH_FATAL) {
|
||||
+ if (status != AUTH_SUCCESS) {
|
||||
/* Assume error msg already printed. */
|
||||
debug_return_int(-1);
|
||||
}
|
||||
@@ -297,7 +303,7 @@ verify_user(struct passwd *pw, char *prompt, int validated,
|
||||
status = (auth->setup)(pw, &prompt, auth);
|
||||
if (status == AUTH_FAILURE)
|
||||
SET(auth->flags, FLAG_DISABLED);
|
||||
- else if (status == AUTH_FATAL || user_interrupted())
|
||||
+ else if (status != AUTH_SUCCESS || user_interrupted())
|
||||
goto done; /* assume error msg already printed */
|
||||
}
|
||||
}
|
||||
@@ -348,7 +354,6 @@ done:
|
||||
log_auth_failure(validated, ntries);
|
||||
ret = false;
|
||||
break;
|
||||
- case AUTH_FATAL:
|
||||
default:
|
||||
log_auth_failure(validated, 0);
|
||||
ret = -1;
|
||||
@@ -360,24 +365,32 @@ done:
|
||||
|
||||
/*
|
||||
* Call authentication method begin session hooks.
|
||||
- * Returns 1 on success and -1 on error.
|
||||
+ * Returns true on success, false on failure and -1 on error.
|
||||
*/
|
||||
int
|
||||
sudo_auth_begin_session(struct passwd *pw, char **user_env[])
|
||||
{
|
||||
sudo_auth *auth;
|
||||
+ int ret = true;
|
||||
debug_decl(sudo_auth_begin_session, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
for (auth = auth_switch; auth->name; auth++) {
|
||||
if (auth->begin_session && !IS_DISABLED(auth)) {
|
||||
int status = (auth->begin_session)(pw, user_env, auth);
|
||||
- if (status != AUTH_SUCCESS) {
|
||||
+ switch (status) {
|
||||
+ case AUTH_SUCCESS:
|
||||
+ break;
|
||||
+ case AUTH_FAILURE:
|
||||
+ ret = false;
|
||||
+ break;
|
||||
+ default:
|
||||
/* Assume error msg already printed. */
|
||||
- debug_return_int(-1);
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- debug_return_int(1);
|
||||
+ debug_return_int(ret);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -398,25 +411,33 @@ sudo_auth_needs_end_session(void)
|
||||
|
||||
/*
|
||||
* Call authentication method end session hooks.
|
||||
- * Returns 1 on success and -1 on error.
|
||||
+ * Returns true on success, false on failure and -1 on error.
|
||||
*/
|
||||
int
|
||||
sudo_auth_end_session(struct passwd *pw)
|
||||
{
|
||||
sudo_auth *auth;
|
||||
+ int ret = true;
|
||||
int status;
|
||||
debug_decl(sudo_auth_end_session, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
for (auth = auth_switch; auth->name; auth++) {
|
||||
if (auth->end_session && !IS_DISABLED(auth)) {
|
||||
status = (auth->end_session)(pw, auth);
|
||||
- if (status == AUTH_FATAL) {
|
||||
+ switch (status) {
|
||||
+ case AUTH_SUCCESS:
|
||||
+ break;
|
||||
+ case AUTH_FAILURE:
|
||||
+ ret = false;
|
||||
+ break;
|
||||
+ default:
|
||||
/* Assume error msg already printed. */
|
||||
- debug_return_int(-1);
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- debug_return_int(1);
|
||||
+ debug_return_int(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/plugins/sudoers/auth/sudo_auth.h b/plugins/sudoers/auth/sudo_auth.h
|
||||
index 9ee408d..0b30d0c 100644
|
||||
--- a/plugins/sudoers/auth/sudo_auth.h
|
||||
+++ b/plugins/sudoers/auth/sudo_auth.h
|
||||
@@ -19,11 +19,11 @@
|
||||
#ifndef SUDO_AUTH_H
|
||||
#define SUDO_AUTH_H
|
||||
|
||||
-/* Auth function return values. */
|
||||
-#define AUTH_SUCCESS 0
|
||||
-#define AUTH_FAILURE 1
|
||||
-#define AUTH_INTR 2
|
||||
-#define AUTH_FATAL 3
|
||||
+/* Auth function return values (rowhammer resistent). */
|
||||
+#define AUTH_SUCCESS 0x52a2925 /* 0101001010100010100100100101 */
|
||||
+#define AUTH_FAILURE 0xad5d6da /* 1010110101011101011011011010 */
|
||||
+#define AUTH_INTR 0x69d61fc8 /* 1101001110101100001111111001000 */
|
||||
+#define AUTH_FATAL 0x1629e037 /* 0010110001010011110000000110111 */
|
||||
|
||||
typedef struct sudo_auth {
|
||||
int flags; /* various flags, see below */
|
||||
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
|
||||
index 9324159..0891d63 100644
|
||||
--- a/plugins/sudoers/match.c
|
||||
+++ b/plugins/sudoers/match.c
|
||||
@@ -92,7 +92,7 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
if ((a = alias_get(parse_tree, m->name, USERALIAS)) != NULL) {
|
||||
/* XXX */
|
||||
const int rc = userlist_matches(parse_tree, pw, &a->members);
|
||||
- if (rc != UNSPEC) {
|
||||
+ if (SPECIFIED(rc)) {
|
||||
if (m->negated) {
|
||||
matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -124,7 +124,8 @@ userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
debug_decl(userlist_matches, SUDOERS_DEBUG_MATCH);
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
- if ((matched = user_matches(parse_tree, pw, m)) != UNSPEC)
|
||||
+ matched = user_matches(parse_tree, pw, m);
|
||||
+ if (SPECIFIED(matched))
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -194,7 +195,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &a->members,
|
||||
&empty, matching_user, NULL);
|
||||
- if (rc != UNSPEC) {
|
||||
+ if (SPECIFIED(rc)) {
|
||||
if (m->negated) {
|
||||
user_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -215,7 +216,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
- if (user_matched != UNSPEC) {
|
||||
+ if (SPECIFIED(user_matched)) {
|
||||
if (matching_user != NULL && m->type != ALIAS)
|
||||
*matching_user = m;
|
||||
break;
|
||||
@@ -228,7 +229,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
* Skip checking runas group if none was specified.
|
||||
*/
|
||||
if (ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) {
|
||||
- if (user_matched == UNSPEC) {
|
||||
+ if (!SPECIFIED(user_matched)) {
|
||||
if (strcmp(user_name, runas_pw->pw_name) == 0)
|
||||
user_matched = ALLOW; /* only changing group */
|
||||
}
|
||||
@@ -243,7 +244,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &empty,
|
||||
&a->members, NULL, matching_group);
|
||||
- if (rc != UNSPEC) {
|
||||
+ if (SPECIFIED(rc)) {
|
||||
if (m->negated) {
|
||||
group_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -259,14 +260,14 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
group_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
- if (group_matched != UNSPEC) {
|
||||
+ if (SPECIFIED(group_matched)) {
|
||||
if (matching_group != NULL && m->type != ALIAS)
|
||||
*matching_group = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (group_matched == UNSPEC) {
|
||||
+ if (!SPECIFIED(group_matched)) {
|
||||
struct gid_list *runas_groups;
|
||||
/*
|
||||
* The runas group was not explicitly allowed by sudoers.
|
||||
@@ -310,7 +311,7 @@ hostlist_matches_int(struct sudoers_parse_tree *parse_tree,
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
matched = host_matches(parse_tree, pw, lhost, shost, m);
|
||||
- if (matched != UNSPEC)
|
||||
+ if (SPECIFIED(matched))
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -361,7 +362,7 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
/* XXX */
|
||||
const int rc = hostlist_matches_int(parse_tree, pw, lhost,
|
||||
shost, &a->members);
|
||||
- if (rc != UNSPEC) {
|
||||
+ if (SPECIFIED(rc)) {
|
||||
if (m->negated) {
|
||||
matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -395,7 +396,7 @@ cmndlist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
matched = cmnd_matches(parse_tree, m, runchroot, info);
|
||||
- if (matched != UNSPEC)
|
||||
+ if (SPECIFIED(matched))
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -425,7 +426,7 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m,
|
||||
a = alias_get(parse_tree, m->name, CMNDALIAS);
|
||||
if (a != NULL) {
|
||||
rc = cmndlist_matches(parse_tree, &a->members, runchroot, info);
|
||||
- if (rc != UNSPEC) {
|
||||
+ if (SPECIFIED(rc)) {
|
||||
if (m->negated) {
|
||||
matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c
|
||||
index d3bf8a5..e38e7e9 100644
|
||||
--- a/plugins/sudoers/parse.c
|
||||
+++ b/plugins/sudoers/parse.c
|
||||
@@ -153,7 +153,7 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw,
|
||||
if (runas_match == ALLOW) {
|
||||
cmnd_match = cmnd_matches(nss->parse_tree, cs->cmnd,
|
||||
cs->runchroot, info);
|
||||
- if (cmnd_match != UNSPEC) {
|
||||
+ if (SPECIFIED(cmnd_match)) {
|
||||
/*
|
||||
* If user is running command as himself,
|
||||
* set runas_pw = sudo_user.pw.
|
||||
@@ -396,7 +396,7 @@ sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int *cmnd_status,
|
||||
}
|
||||
|
||||
m = sudoers_lookup_check(nss, pw, &validated, &info, &cs, &defs, now);
|
||||
- if (m != UNSPEC) {
|
||||
+ if (SPECIFIED(m)) {
|
||||
match = m;
|
||||
parse_tree = nss->parse_tree;
|
||||
}
|
||||
@@ -404,7 +404,7 @@ sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int *cmnd_status,
|
||||
if (!sudo_nss_can_continue(nss, m))
|
||||
break;
|
||||
}
|
||||
- if (match != UNSPEC) {
|
||||
+ if (SPECIFIED(match)) {
|
||||
if (info.cmnd_path != NULL) {
|
||||
/* Update user_cmnd, user_stat, cmnd_status from matching entry. */
|
||||
free(user_cmnd);
|
||||
diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
|
||||
index ea2a179..8559849 100644
|
||||
--- a/plugins/sudoers/parse.h
|
||||
+++ b/plugins/sudoers/parse.h
|
||||
@@ -34,15 +34,28 @@
|
||||
# define SUDOERS_NAME_MATCH
|
||||
#endif
|
||||
|
||||
+/* Allowed by policy (rowhammer resistent). */
|
||||
+#undef ALLOW
|
||||
+#define ALLOW 0x52a2925 /* 0101001010100010100100100101 */
|
||||
+
|
||||
+/* Denied by policy (rowhammer resistent). */
|
||||
+#undef DENY
|
||||
+#define DENY 0xad5d6da /* 1010110101011101011011011010 */
|
||||
+
|
||||
+/* Neither allowed, nor denied. */
|
||||
#undef UNSPEC
|
||||
#define UNSPEC -1
|
||||
-#undef DENY
|
||||
-#define DENY 0
|
||||
-#undef ALLOW
|
||||
-#define ALLOW 1
|
||||
+
|
||||
+/* Tag implied by root access (SETENV only). */
|
||||
#undef IMPLIED
|
||||
#define IMPLIED 2
|
||||
|
||||
+/*
|
||||
+ * We must explicitly check against ALLOW and DENY instead testing
|
||||
+ * that the value is not UNSPEC to avoid potential ROWHAMMER issues.
|
||||
+ */
|
||||
+#define SPECIFIED(_v) ((_v) == ALLOW || (_v) == DENY)
|
||||
+
|
||||
/*
|
||||
* Initialize all tags to UNSPEC.
|
||||
*/
|
||||
@@ -92,7 +105,7 @@
|
||||
* Returns true if the specified tag is not UNSPEC or IMPLIED, else false.
|
||||
*/
|
||||
#define TAG_SET(tt) \
|
||||
- ((tt) != UNSPEC && (tt) != IMPLIED)
|
||||
+ ((tt) == true || (tt) == false)
|
||||
|
||||
/*
|
||||
* Returns true if any tags set in nt differ between ot and nt, else false.
|
||||
--
|
||||
2.42.0.windows.2
|
||||
|
||||
@ -0,0 +1,249 @@
|
||||
From cf00568d888c90a8c5d06a06283bc87a45992933 Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Sat, 26 Aug 2023 10:32:37 -0600
|
||||
Subject: [PATCH] Do not rely on the definition of ALLOW/DENY being true/false.
|
||||
|
||||
We now explicitly check for ALLOW and DENY when checking return
|
||||
values and negating values.
|
||||
|
||||
Reference: https://github.com/sudo-project/sudo/commit/cf00568d888c90a8c5d06a06283bc87a45992933
|
||||
Conflict: cvtsudoers.c match.c
|
||||
---
|
||||
plugins/sudoers/cvtsudoers.c | 6 +--
|
||||
plugins/sudoers/match.c | 83 +++++++++++++++++++++++-------------
|
||||
2 files changed, 57 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c
|
||||
index 79558c3..8cedcc6 100644
|
||||
--- a/plugins/sudoers/cvtsudoers.c
|
||||
+++ b/plugins/sudoers/cvtsudoers.c
|
||||
@@ -690,7 +690,7 @@ userlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||
pw.pw_uid = (uid_t)-1;
|
||||
pw.pw_gid = (gid_t)-1;
|
||||
|
||||
- if (user_matches(parse_tree, &pw, m) == true)
|
||||
+ if (user_matches(parse_tree, &pw, m) == ALLOW)
|
||||
matched = true;
|
||||
} else {
|
||||
STAILQ_FOREACH(s, &filters->users, entries) {
|
||||
@@ -716,7 +716,7 @@ userlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||
if (pw == NULL)
|
||||
continue;
|
||||
|
||||
- if (user_matches(parse_tree, pw, m) == true)
|
||||
+ if (user_matches(parse_tree, pw, m) == ALLOW)
|
||||
matched = true;
|
||||
sudo_pw_delref(pw);
|
||||
|
||||
@@ -792,7 +792,7 @@ hostlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||
|
||||
/* Only need one host in the filter to match. */
|
||||
/* XXX - can't use netgroup_tuple with NULL pw */
|
||||
- if (host_matches(parse_tree, NULL, lhost, shost, m) == true) {
|
||||
+ if (host_matches(parse_tree, NULL, lhost, shost, m) == ALLOW) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
|
||||
index 9801f38..9324159 100644
|
||||
--- a/plugins/sudoers/match.c
|
||||
+++ b/plugins/sudoers/match.c
|
||||
@@ -76,31 +76,36 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name,
|
||||
def_netgroup_tuple ? lhost : NULL,
|
||||
def_netgroup_tuple ? shost : NULL, pw->pw_name))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case USERGROUP:
|
||||
if (usergr_matches(m->name, pw->pw_name, pw))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(parse_tree, m->name, USERALIAS)) != NULL) {
|
||||
/* XXX */
|
||||
- int rc = userlist_matches(parse_tree, pw, &a->members);
|
||||
- if (rc != UNSPEC)
|
||||
- matched = m->negated ? !rc : rc;
|
||||
+ const int rc = userlist_matches(parse_tree, pw, &a->members);
|
||||
+ if (rc != UNSPEC) {
|
||||
+ if (m->negated) {
|
||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case WORD:
|
||||
if (userpw_matches(m->name, pw->pw_name, pw))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -171,38 +176,43 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name,
|
||||
def_netgroup_tuple ? lhost : NULL,
|
||||
def_netgroup_tuple ? shost : NULL,
|
||||
runas_pw->pw_name))
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case USERGROUP:
|
||||
if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &a->members,
|
||||
&empty, matching_user, NULL);
|
||||
- if (rc != UNSPEC)
|
||||
- user_matched = m->negated ? !rc : rc;
|
||||
+ if (rc != UNSPEC) {
|
||||
+ if (m->negated) {
|
||||
+ user_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ user_matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case WORD:
|
||||
if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case MYSELF:
|
||||
if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) ||
|
||||
strcmp(user_name, runas_pw->pw_name) == 0)
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
if (user_matched != UNSPEC) {
|
||||
@@ -226,22 +236,27 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- group_matched = !m->negated;
|
||||
+ group_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &empty,
|
||||
&a->members, NULL, matching_group);
|
||||
- if (rc != UNSPEC)
|
||||
- group_matched = m->negated ? !rc : rc;
|
||||
+ if (rc != UNSPEC) {
|
||||
+ if (m->negated) {
|
||||
+ group_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ group_matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case WORD:
|
||||
if (group_matches(m->name, runas_gr))
|
||||
- group_matched = !m->negated;
|
||||
+ group_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
if (group_matched != UNSPEC) {
|
||||
@@ -329,32 +344,37 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name, lhost, shost,
|
||||
def_netgroup_tuple ? pw->pw_name : NULL))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NTWKADDR:
|
||||
if (addr_matches(m->name))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, HOSTALIAS);
|
||||
if (a != NULL) {
|
||||
/* XXX */
|
||||
- int rc = hostlist_matches_int(parse_tree, pw, lhost, shost,
|
||||
- &a->members);
|
||||
- if (rc != UNSPEC)
|
||||
- matched = m->negated ? !rc : rc;
|
||||
+ const int rc = hostlist_matches_int(parse_tree, pw, lhost,
|
||||
+ shost, &a->members);
|
||||
+ if (rc != UNSPEC) {
|
||||
+ if (m->negated) {
|
||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case WORD:
|
||||
if (hostname_matches(shost, lhost, m->name))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -399,14 +419,19 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m,
|
||||
case COMMAND:
|
||||
c = (struct sudo_command *)m->name;
|
||||
if (command_matches(c->cmnd, c->args, runchroot, info, &c->digests))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, CMNDALIAS);
|
||||
if (a != NULL) {
|
||||
rc = cmndlist_matches(parse_tree, &a->members, runchroot, info);
|
||||
- if (rc != UNSPEC)
|
||||
- matched = m->negated ? !rc : rc;
|
||||
+ if (rc != UNSPEC) {
|
||||
+ if (m->negated) {
|
||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
}
|
||||
break;
|
||||
--
|
||||
2.42.0.windows.2
|
||||
|
||||
@ -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
|
||||
|
||||
1117
backport-Make-all-match-functions-return-ALLOW-DENY-.patch
Normal file
1117
backport-Make-all-match-functions-return-ALLOW-DENY-.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
25
backport-Set-command_info-to-NULL-once-it-is-freed.patch
Normal file
25
backport-Set-command_info-to-NULL-once-it-is-freed.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 0bb41ed82a5849b0c64d7046662825d84e983e4d Mon Sep 17 00:00:00 2001
|
||||
From: Rose <83477269+AtariDreams@users.noreply.github.com>
|
||||
Date: Mon, 26 Jun 2023 15:08:51 -0400
|
||||
Subject: [PATCH] Set command_info to NULL once it is freed
|
||||
|
||||
The lack of setting to NULL is a holdover from when command_info was a local variable and not a global one. However, we given how other global variables are set to NULL, it is best that we do the same here to avoid potential issues should sudoers_policy_store_result be called again after the first time failed, otherwise we could get a double-free.
|
||||
|
||||
---
|
||||
plugins/sudoers/policy.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c
|
||||
index 7157fab2b..f018caca2 100644
|
||||
--- a/plugins/sudoers/policy.c
|
||||
+++ b/plugins/sudoers/policy.c
|
||||
@@ -1054,6 +1054,7 @@ bad:
|
||||
while (info_len--)
|
||||
free(command_info[info_len]);
|
||||
free(command_info);
|
||||
+ command_info = NULL;
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
@ -0,0 +1,29 @@
|
||||
From 2ffcda8e15afe312550be4017d8c40dbb438b786 Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Thu, 2 Nov 2023 14:42:42 -0600
|
||||
Subject: [PATCH] role_to_sudoers: only try to reuse a privilege if one is
|
||||
present
|
||||
|
||||
Reference:https://github.com/sudo-project/sudo/commit/2ffcda8e15afe312550be4017d8c40dbb438b786
|
||||
Conflict:NA
|
||||
|
||||
---
|
||||
plugins/sudoers/parse_ldif.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/sudoers/parse_ldif.c b/plugins/sudoers/parse_ldif.c
|
||||
index 87c94125c..180e7da6c 100644
|
||||
--- a/plugins/sudoers/parse_ldif.c
|
||||
+++ b/plugins/sudoers/parse_ldif.c
|
||||
@@ -427,7 +427,7 @@ role_to_sudoers(struct sudoers_parse_tree *parse_tree, struct sudo_role *role,
|
||||
U_("unable to allocate memory"));
|
||||
}
|
||||
|
||||
- if (reuse_privilege) {
|
||||
+ if (reuse_privilege && !TAILQ_EMPTY(&us->privileges)) {
|
||||
/* Hostspec unchanged, append cmndlist to previous privilege. */
|
||||
struct privilege *prev_priv = TAILQ_LAST(&us->privileges, privilege_list);
|
||||
if (reuse_runas) {
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From a712af5a26d886d1db88d77575b7998a1944d3a9 Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Fri, 18 Aug 2023 12:22:43 -0600
|
||||
Subject: [PATCH] sudoers_parse_ldif: do not free parse_tree before using
|
||||
|
||||
The user is expected to pass in an initialized and empty parse_tree
|
||||
so there is no need to free it first.
|
||||
---
|
||||
plugins/sudoers/parse_ldif.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/parse_ldif.c b/plugins/sudoers/parse_ldif.c
|
||||
index a9944171b..98d84488a 100644
|
||||
--- a/plugins/sudoers/parse_ldif.c
|
||||
+++ b/plugins/sudoers/parse_ldif.c
|
||||
@@ -582,9 +582,6 @@ sudoers_parse_ldif(struct sudoers_parse_tree *parse_tree,
|
||||
int errors = 0;
|
||||
debug_decl(sudoers_parse_ldif, SUDOERS_DEBUG_UTIL);
|
||||
|
||||
- /* Free old contents of the parse tree (if any). */
|
||||
- free_parse_tree(parse_tree);
|
||||
-
|
||||
/*
|
||||
* We cache user, group and host lists to make it eay to detect when there
|
||||
* are identical lists (simple pointer compare). This makes it possible
|
||||
--
|
||||
2.33.0
|
||||
|
||||
26
sudo.spec
26
sudo.spec
@ -1,6 +1,6 @@
|
||||
Name: sudo
|
||||
Version: 1.9.8p2
|
||||
Release: 13
|
||||
Release: 18
|
||||
Summary: Allows restricted root access for specified users
|
||||
License: ISC
|
||||
URL: http://www.courtesan.com/sudo/
|
||||
@ -37,6 +37,15 @@ Patch23: backport-sudoers_main-defer-setting-return-value-until-the-en.patch
|
||||
Patch24: backport-sudo_putenv_nodebug-require-that-the-environment-str.patch
|
||||
Patch25: backport-Linux-execve-2-allows-argv-or-envp-to-be-NULL.patch
|
||||
Patch26: backport-Fix-potential-NULL-pointer-deference-found-by-clang-.patch
|
||||
Patch27: backport-Set-command_info-to-NULL-once-it-is-freed.patch
|
||||
Patch28: backport-sudoers_parse_ldif-do-not-free-parse_tree-before-usi.patch
|
||||
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
|
||||
@ -187,6 +196,21 @@ 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
|
||||
|
||||
* Wed Jan 10 2024 wangqingsan <wangqingsan@huawei.com> - 1.9.8p2-16
|
||||
- fix CVE-2023-42465
|
||||
|
||||
* Tue Nov 28 2023 zhangruifang <zhangruifang1@h-partners.com> - 1.9.8p2-15
|
||||
- Backport patches from upstream community
|
||||
|
||||
* Mon Aug 07 2023 zhoushuiqing <zhoushuiqing2@huawei.com> - 1.9.8p2-14
|
||||
- Backport patche from upstream community
|
||||
|
||||
* Tue Jun 13 2023 zhoushuiqing <zhoushuiqing2@huawei.com> - 1.9.8p2-13
|
||||
- Backport patches from upstream community
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user