From 63c98ac004cd75401146a5cac116d15bf4924a10 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 29 2020 06:55:59 +0000 Subject: import sudo-1.8.23-10.el7 --- diff --git a/SOURCES/sudo-1.8.29-expired-password-part1.patch b/SOURCES/sudo-1.8.29-expired-password-part1.patch new file mode 100644 index 0000000..8c8a0bb --- /dev/null +++ b/SOURCES/sudo-1.8.29-expired-password-part1.patch @@ -0,0 +1,154 @@ +From 4b6de608c25a6ffbdb507be958e12f814b43077c Mon Sep 17 00:00:00 2001 +From: "Todd C. Miller" +Date: Wed, 4 Dec 2019 12:38:22 -0700 +Subject: [PATCH] Only update the time stamp entry after the approval function + has succeeded. Bug #910 + +--- + plugins/sudoers/check.c | 59 +++++++++++++++++++---------------------- + 1 file changed, 27 insertions(+), 32 deletions(-) + +diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c +index db8e05161..ea1d89085 100644 +--- a/plugins/sudoers/check.c ++++ b/plugins/sudoers/check.c +@@ -51,6 +51,7 @@ static bool display_lecture(int); + static struct passwd *get_authpw(int); + + struct getpass_closure { ++ int tstat; + void *cookie; + struct passwd *auth_pw; + }; +@@ -89,27 +90,20 @@ getpass_resume(int signo, void *vclosure) + * or -1 on fatal error. + */ + static int +-check_user_interactive(int validated, int mode, struct passwd *auth_pw) ++check_user_interactive(int validated, int mode, struct getpass_closure *closure) + { + struct sudo_conv_callback cb, *callback = NULL; +- struct getpass_closure closure; +- int status = TS_ERROR; + int ret = -1; + char *prompt; + bool lectured; + debug_decl(check_user_interactive, SUDOERS_DEBUG_AUTH) + +- /* Setup closure for getpass_{suspend,resume} */ +- closure.auth_pw = auth_pw; +- closure.cookie = NULL; +- sudo_pw_addref(closure.auth_pw); +- + /* Open, lock and read time stamp file if we are using it. */ + if (!ISSET(mode, MODE_IGNORE_TICKET)) { + /* Open time stamp file and check its status. */ +- closure.cookie = timestamp_open(user_name, user_sid); +- if (timestamp_lock(closure.cookie, closure.auth_pw)) +- status = timestamp_status(closure.cookie, closure.auth_pw); ++ closure->cookie = timestamp_open(user_name, user_sid); ++ if (timestamp_lock(closure->cookie, closure->auth_pw)) ++ closure->tstat = timestamp_status(closure->cookie, closure->auth_pw); + + /* Construct callback for getpass function. */ + memset(&cb, 0, sizeof(cb)); +@@ -120,7 +114,7 @@ check_user_interactive(int validated, int mode, struct passwd *auth_pw) + callback = &cb; + } + +- switch (status) { ++ switch (closure->tstat) { + case TS_FATAL: + /* Fatal error (usually setuid failure), unsafe to proceed. */ + goto done; +@@ -144,32 +138,22 @@ check_user_interactive(int validated, int mode, struct passwd *auth_pw) + } + + /* XXX - should not lecture if askpass helper is being used. */ +- lectured = display_lecture(status); ++ lectured = display_lecture(closure->tstat); + + /* Expand any escapes in the prompt. */ + prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt, +- closure.auth_pw->pw_name); ++ closure->auth_pw->pw_name); + if (prompt == NULL) + goto done; + +- ret = verify_user(closure.auth_pw, prompt, validated, callback); ++ ret = verify_user(closure->auth_pw, prompt, validated, callback); + if (ret == true && lectured) + (void)set_lectured(); /* lecture error not fatal */ + free(prompt); + break; + } + +- /* +- * Only update time stamp if user was validated. +- * Failure to update the time stamp is not a fatal error. +- */ +- if (ret == true && ISSET(validated, VALIDATE_SUCCESS) && status != TS_ERROR) +- (void)timestamp_update(closure.cookie, closure.auth_pw); + done: +- if (closure.cookie != NULL) +- timestamp_close(closure.cookie); +- sudo_pw_delref(closure.auth_pw); +- + debug_return_int(ret); + } + +@@ -180,7 +164,7 @@ done: + int + check_user(int validated, int mode) + { +- struct passwd *auth_pw; ++ struct getpass_closure closure = { TS_ERROR }; + int ret = -1; + bool exempt = false; + debug_decl(check_user, SUDOERS_DEBUG_AUTH) +@@ -189,9 +173,9 @@ check_user(int validated, int mode) + * Init authentication system regardless of whether we need a password. + * Required for proper PAM session support. + */ +- if ((auth_pw = get_authpw(mode)) == NULL) ++ if ((closure.auth_pw = get_authpw(mode)) == NULL) + goto done; +- if (sudo_auth_init(auth_pw) == -1) ++ if (sudo_auth_init(closure.auth_pw) == -1) + goto done; + + /* +@@ -222,15 +206,26 @@ check_user(int validated, int mode) + } + } + +- ret = check_user_interactive(validated, mode, auth_pw); ++ ret = check_user_interactive(validated, mode, &closure); + + done: + if (ret == true) { + /* The approval function may disallow a user post-authentication. */ +- ret = sudo_auth_approval(auth_pw, validated, exempt); ++ ret = sudo_auth_approval(closure.auth_pw, validated, exempt); ++ ++ /* ++ * Only update time stamp if user validated and was approved. ++ * Failure to update the time stamp is not a fatal error. ++ */ ++ if (ret == true && closure.tstat != TS_ERROR) { ++ if (ISSET(validated, VALIDATE_SUCCESS)) ++ (void)timestamp_update(closure.cookie, closure.auth_pw); ++ } + } +- sudo_auth_cleanup(auth_pw); +- sudo_pw_delref(auth_pw); ++ timestamp_close(closure.cookie); ++ sudo_auth_cleanup(closure.auth_pw); ++ if (closure.auth_pw != NULL) ++ sudo_pw_delref(closure.auth_pw); + + debug_return_int(ret); + } +-- +2.25.1 + diff --git a/SOURCES/sudo-1.8.29-expired-password-part2.patch b/SOURCES/sudo-1.8.29-expired-password-part2.patch new file mode 100644 index 0000000..47f94d4 --- /dev/null +++ b/SOURCES/sudo-1.8.29-expired-password-part2.patch @@ -0,0 +1,29 @@ +From 5472b1751645f750e42a0ba6daac667983b1a56c Mon Sep 17 00:00:00 2001 +From: "Todd C. Miller" +Date: Fri, 24 Jan 2020 11:13:55 -0700 +Subject: [PATCH] Fix crash in sudo 1.8.30 when suspending sudo at the password + prompt. The closure pointer in sudo_conv_callback was being filled in with a + struct getpass_closure ** instead of a struct getpass_closure *. The bug was + introduced in the fix for Bug #910; previously the closure variable was a + struct getpass_closure, not a pointer. Fix from Michael Norton; Bug #914. + +--- + plugins/sudoers/check.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c +index 72e87eef6..9b03c7a05 100644 +--- a/plugins/sudoers/check.c ++++ b/plugins/sudoers/check.c +@@ -108,7 +108,7 @@ check_user_interactive(int validated, int mode, struct getpass_closure *closure) + /* Construct callback for getpass function. */ + memset(&cb, 0, sizeof(cb)); + cb.version = SUDO_CONV_CALLBACK_VERSION; +- cb.closure = &closure; ++ cb.closure = closure; + cb.on_suspend = getpass_suspend; + cb.on_resume = getpass_resume; + callback = &cb; +-- +2.25.1 + diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec index ce0645b..7dfc84d 100644 --- a/SPECS/sudo.spec +++ b/SPECS/sudo.spec @@ -1,7 +1,7 @@ Summary: Allows restricted root access for specified users Name: sudo Version: 1.8.23 -Release: 9%{?dist} +Release: 10%{?dist} License: ISC Group: Applications/System URL: http://www.courtesan.com/sudo/ @@ -70,6 +70,10 @@ Patch14: sudo-1.8.28-CVE-strtouid-test.patch Patch15: sudo-1.8.29-CVE-2019-18634-part1.patch Patch16: sudo-1.8.29-CVE-2019-18634-part2.patch +# 1788196 - sudo allows privilege escalation with expire password +Patch17: sudo-1.8.29-expired-password-part1.patch +Patch18: sudo-1.8.29-expired-password-part2.patch + %description Sudo (superuser do) allows a system administrator to give certain users (or groups of users) the ability to run some (or all) commands @@ -114,6 +118,9 @@ plugins that use %{name}. %patch15 -p1 -b .CVE-2019-18634-part1 %patch16 -p1 -b .CVE-2019-18634-part2 +%patch17 -p1 -b .expired-password-part1 +%patch18 -p1 -b .expired-password-part2 + %build autoreconf -I m4 -fv --install @@ -249,6 +256,11 @@ rm -rf %{buildroot} %{_mandir}/man8/sudo_plugin.8* %changelog +* Wed Mar 25 2020 Radovan Sroka - 1.8.23-10 +- RHEL-7.9 +- sudo allows privilege escalation with expire password + Resolves: rhbz#1788196 + * Wed Feb 05 2020 Radovan Sroka - 1.8.23-9 - RHEL-7.8 - CVE-2019-18634