From c86b7a50d8ae083fda01a987ff4e769bbe8739f8 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 20 2020 12:12:42 +0000 Subject: import sudo-1.8.23-10.el7 --- diff --git a/SOURCES/sudo-1.8.28-CVE-strtouid-test.patch b/SOURCES/sudo-1.8.28-CVE-strtouid-test.patch new file mode 100644 index 0000000..b4bd095 --- /dev/null +++ b/SOURCES/sudo-1.8.28-CVE-strtouid-test.patch @@ -0,0 +1,96 @@ +diff -up ./lib/util/regress/atofoo/atofoo_test.c.CVE-strtouid-test ./lib/util/regress/atofoo/atofoo_test.c +--- ./lib/util/regress/atofoo/atofoo_test.c.CVE-strtouid-test 2018-04-29 21:59:23.000000000 +0200 ++++ ./lib/util/regress/atofoo/atofoo_test.c 2019-10-16 09:38:31.851404545 +0200 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2014 Todd C. Miller ++ * Copyright (c) 2014-2019 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -24,6 +24,7 @@ + #else + # include "compat/stdbool.h" + #endif ++#include + + #include "sudo_compat.h" + #include "sudo_util.h" +@@ -78,15 +79,20 @@ static struct strtoid_data { + id_t id; + const char *sep; + const char *ep; ++ int errnum; + } strtoid_data[] = { +- { "0,1", 0, ",", "," }, +- { "10", 10, NULL, NULL }, +- { "-2", -2, NULL, NULL }, ++ { "0,1", 0, ",", ",", 0 }, ++ { "10", 10, NULL, NULL, 0 }, ++ { "-1", 0, NULL, NULL, EINVAL }, ++ { "4294967295", 0, NULL, NULL, EINVAL }, ++ { "4294967296", 0, NULL, NULL, ERANGE }, ++ { "-2147483649", 0, NULL, NULL, ERANGE }, ++ { "-2", -2, NULL, NULL, 0 }, + #if SIZEOF_ID_T != SIZEOF_LONG_LONG +- { "-2", 4294967294U, NULL, NULL }, ++ { "-2", 4294967294U, NULL, NULL, 0 }, + #endif +- { "4294967294", 4294967294U, NULL, NULL }, +- { NULL, 0, NULL, NULL } ++ { "4294967294", 4294967294U, NULL, NULL, 0 }, ++ { NULL, 0, NULL, NULL, 0 } + }; + + static int +@@ -102,11 +108,23 @@ test_strtoid(int *ntests) + (*ntests)++; + errstr = "some error"; + value = sudo_strtoid(d->idstr, d->sep, &ep, &errstr); +- if (errstr != NULL) { +- if (d->id != (id_t)-1) { +- sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr); ++ if (d->errnum != 0) { ++ if (errstr == NULL) { ++ sudo_warnx_nodebug("FAIL: %s: missing errstr for errno %d", ++ d->idstr, d->errnum); ++ errors++; ++ } else if (value != 0) { ++ sudo_warnx_nodebug("FAIL: %s should return 0 on error", ++ d->idstr); ++ errors++; ++ } else if (errno != d->errnum) { ++ sudo_warnx_nodebug("FAIL: %s: errno mismatch, %d != %d", ++ d->idstr, errno, d->errnum); + errors++; + } ++ } else if (errstr != NULL) { ++ sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr); ++ errors++; + } else if (value != d->id) { + sudo_warnx_nodebug("FAIL: %s != %u", d->idstr, (unsigned int)d->id); + errors++; +diff -up ./plugins/sudoers/regress/testsudoers/test5.out.ok.CVE-strtouid-test ./plugins/sudoers/regress/testsudoers/test5.out.ok +--- ./plugins/sudoers/regress/testsudoers/test5.out.ok.CVE-strtouid-test 2018-04-29 21:59:23.000000000 +0200 ++++ ./plugins/sudoers/regress/testsudoers/test5.out.ok 2019-10-16 09:29:50.246761680 +0200 +@@ -4,7 +4,7 @@ Parse error in sudoers near line 1. + Entries for user root: + + Command unmatched +-testsudoers: test5.inc should be owned by gid 4294967295 ++testsudoers: test5.inc should be owned by gid 4294967294 + Parse error in sudoers near line 1. + + Entries for user root: +diff -up ./plugins/sudoers/regress/testsudoers/test5.sh.CVE-strtouid-test ./plugins/sudoers/regress/testsudoers/test5.sh +--- ./plugins/sudoers/regress/testsudoers/test5.sh.CVE-strtouid-test 2018-04-29 21:59:23.000000000 +0200 ++++ ./plugins/sudoers/regress/testsudoers/test5.sh 2019-10-16 09:29:50.246761680 +0200 +@@ -24,7 +24,7 @@ EOF + + # Test group writable + chmod 664 $TESTFILE +-./testsudoers -U $MYUID -G -1 root id < ++ * Copyright (c) 2013-2019 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -47,6 +47,27 @@ + #include "sudo_util.h" + + /* ++ * Make sure that the ID ends with a valid separator char. ++ */ ++static bool ++valid_separator(const char *p, const char *ep, const char *sep) ++{ ++ bool valid = false; ++ debug_decl(valid_separator, SUDO_DEBUG_UTIL) ++ ++ if (ep != p) { ++ /* check for valid separator (including '\0') */ ++ if (sep == NULL) ++ sep = ""; ++ do { ++ if (*ep == *sep) ++ valid = true; ++ } while (*sep++ != '\0'); ++ } ++ debug_return_bool(valid); ++} ++ ++/* + * Parse a uid/gid in string form. + * If sep is non-NULL, it contains valid separator characters (e.g. comma, space) + * If endp is non-NULL it is set to the next char after the ID. +@@ -60,38 +81,35 @@ sudo_strtoid_v1(const char *p, const cha + char *ep; + id_t ret = 0; + long long llval; +- bool valid = false; + debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL) + + /* skip leading space so we can pick up the sign, if any */ + while (isspace((unsigned char)*p)) + p++; +- if (sep == NULL) +- sep = ""; ++ ++ /* While id_t may be 64-bit signed, uid_t and gid_t are 32-bit unsigned. */ + errno = 0; + llval = strtoll(p, &ep, 10); +- if (ep != p) { +- /* check for valid separator (including '\0') */ +- do { +- if (*ep == *sep) +- valid = true; +- } while (*sep++ != '\0'); ++ if ((errno == ERANGE && llval == LLONG_MAX) || llval > (id_t)UINT_MAX) { ++ errno = ERANGE; ++ if (errstr != NULL) ++ *errstr = N_("value too large"); ++ goto done; + } +- if (!valid) { ++ if ((errno == ERANGE && llval == LLONG_MIN) || llval < INT_MIN) { ++ errno = ERANGE; ++ if (errstr != NULL) ++ *errstr = N_("value too small"); ++ goto done; ++ } ++ ++ /* Disallow id -1, which means "no change". */ ++ if (!valid_separator(p, ep, sep) || llval == -1 || llval == (id_t)UINT_MAX) { + if (errstr != NULL) + *errstr = N_("invalid value"); + errno = EINVAL; + goto done; + } +- if (errno == ERANGE) { +- if (errstr != NULL) { +- if (llval == LLONG_MAX) +- *errstr = N_("value too large"); +- else +- *errstr = N_("value too small"); +- } +- goto done; +- } + ret = (id_t)llval; + if (errstr != NULL) + *errstr = NULL; +@@ -106,30 +124,15 @@ sudo_strtoid_v1(const char *p, const cha + { + char *ep; + id_t ret = 0; +- bool valid = false; + debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL) + + /* skip leading space so we can pick up the sign, if any */ + while (isspace((unsigned char)*p)) + p++; +- if (sep == NULL) +- sep = ""; ++ + errno = 0; + if (*p == '-') { + long lval = strtol(p, &ep, 10); +- if (ep != p) { +- /* check for valid separator (including '\0') */ +- do { +- if (*ep == *sep) +- valid = true; +- } while (*sep++ != '\0'); +- } +- if (!valid) { +- if (errstr != NULL) +- *errstr = N_("invalid value"); +- errno = EINVAL; +- goto done; +- } + if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) { + errno = ERANGE; + if (errstr != NULL) +@@ -142,28 +145,31 @@ sudo_strtoid_v1(const char *p, const cha + *errstr = N_("value too small"); + goto done; + } +- ret = (id_t)lval; +- } else { +- unsigned long ulval = strtoul(p, &ep, 10); +- if (ep != p) { +- /* check for valid separator (including '\0') */ +- do { +- if (*ep == *sep) +- valid = true; +- } while (*sep++ != '\0'); +- } +- if (!valid) { ++ ++ /* Disallow id -1, which means "no change". */ ++ if (!valid_separator(p, ep, sep) || lval == -1) { + if (errstr != NULL) + *errstr = N_("invalid value"); + errno = EINVAL; + goto done; + } ++ ret = (id_t)lval; ++ } else { ++ unsigned long ulval = strtoul(p, &ep, 10); + if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) { + errno = ERANGE; + if (errstr != NULL) + *errstr = N_("value too large"); + goto done; + } ++ ++ /* Disallow id -1, which means "no change". */ ++ if (!valid_separator(p, ep, sep) || ulval == UINT_MAX) { ++ if (errstr != NULL) ++ *errstr = N_("invalid value"); ++ errno = EINVAL; ++ goto done; ++ } + ret = (id_t)ulval; + } + if (errstr != NULL) diff --git a/SOURCES/sudo-1.8.29-CVE-2019-18634-part1.patch b/SOURCES/sudo-1.8.29-CVE-2019-18634-part1.patch new file mode 100644 index 0000000..5b71919 --- /dev/null +++ b/SOURCES/sudo-1.8.29-CVE-2019-18634-part1.patch @@ -0,0 +1,158 @@ +diff -up ./src/tgetpass.c.bla ./src/tgetpass.c +--- ./src/tgetpass.c.bla 2018-08-18 16:10:15.000000000 +0200 ++++ ./src/tgetpass.c 2020-02-05 17:15:16.216904891 +0100 +@@ -44,11 +44,18 @@ + #include "sudo.h" + #include "sudo_plugin.h" + ++enum tgetpass_errval { ++ TGP_ERRVAL_NOERROR, ++ TGP_ERRVAL_TIMEOUT, ++ TGP_ERRVAL_NOPASSWORD, ++ TGP_ERRVAL_READERROR ++}; ++ + static volatile sig_atomic_t signo[NSIG]; + + static bool tty_present(void); + static void tgetpass_handler(int); +-static char *getln(int, char *, size_t, int); ++static char *getln(int, char *, size_t, int, enum tgetpass_errval *); + static char *sudo_askpass(const char *, const char *); + + static int +@@ -77,6 +84,27 @@ suspend(int signo, struct sudo_conv_call + debug_return_int(ret); + } + ++static void ++tgetpass_display_error(enum tgetpass_errval errval) ++{ ++ debug_decl(tgetpass_display_error, SUDO_DEBUG_CONV) ++ ++ switch (errval) { ++ case TGP_ERRVAL_NOERROR: ++ break; ++ case TGP_ERRVAL_TIMEOUT: ++ sudo_warnx(U_("timed out reading password")); ++ break; ++ case TGP_ERRVAL_NOPASSWORD: ++ sudo_warnx(U_("no password was provided")); ++ break; ++ case TGP_ERRVAL_READERROR: ++ sudo_warn(U_("unable to read password")); ++ break; ++ } ++ debug_return; ++} ++ + /* + * Like getpass(3) but with timeout and echo flags. + */ +@@ -90,6 +118,7 @@ tgetpass(const char *prompt, int timeout + static const char *askpass; + static char buf[SUDO_CONV_REPL_MAX + 1]; + int i, input, output, save_errno, neednl = 0, need_restart; ++ enum tgetpass_errval errval; + debug_decl(tgetpass, SUDO_DEBUG_CONV) + + (void) fflush(stdout); +@@ -175,7 +204,7 @@ restart: + + if (timeout > 0) + alarm(timeout); +- pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK)); ++ pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK), &errval); + alarm(0); + save_errno = errno; + +@@ -183,6 +212,7 @@ restart: + if (write(output, "\n", 1) == -1) + goto restore; + } ++ tgetpass_display_error(errval); + + restore: + /* Restore old signal handlers. */ +@@ -210,6 +240,8 @@ restore: + for (i = 0; i < NSIG; i++) { + if (signo[i]) { + switch (i) { ++ case SIGALRM: ++ break; + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: +@@ -239,6 +271,7 @@ sudo_askpass(const char *askpass, const + { + static char buf[SUDO_CONV_REPL_MAX + 1], *pass; + struct sigaction sa, savechld; ++ enum tgetpass_errval errval; + int pfd[2], status; + pid_t child; + debug_decl(sudo_askpass, SUDO_DEBUG_CONV) +@@ -281,9 +314,11 @@ sudo_askpass(const char *askpass, const + + /* Get response from child (askpass). */ + (void) close(pfd[1]); +- pass = getln(pfd[0], buf, sizeof(buf), 0); ++ pass = getln(pfd[0], buf, sizeof(buf), 0, &errval); + (void) close(pfd[0]); + ++ tgetpass_display_error(errval); ++ + /* Wait for child to exit. */ + for (;;) { + pid_t rv = waitpid(child, &status, 0); +@@ -305,7 +340,8 @@ sudo_askpass(const char *askpass, const + extern int sudo_term_erase, sudo_term_kill; + + static char * +-getln(int fd, char *buf, size_t bufsiz, int feedback) ++getln(int fd, char *buf, size_t bufsiz, int feedback, ++ enum tgetpass_errval *errval) + { + size_t left = bufsiz; + ssize_t nr = -1; +@@ -313,7 +349,10 @@ getln(int fd, char *buf, size_t bufsiz, + char c = '\0'; + debug_decl(getln, SUDO_DEBUG_CONV) + ++ *errval = TGP_ERRVAL_NOERROR; ++ + if (left == 0) { ++ *errval = TGP_ERRVAL_READERROR; + errno = EINVAL; + debug_return_str(NULL); /* sanity */ + } +@@ -354,14 +393,27 @@ getln(int fd, char *buf, size_t bufsiz, + } + } + +- debug_return_str_masked(nr == 1 ? buf : NULL); ++ if (nr != 1) { ++ if (nr == 0) { ++ *errval = TGP_ERRVAL_NOPASSWORD; ++ } else if (nr == -1) { ++ if (errno == EINTR) { ++ if (signo[SIGALRM] == 1) ++ *errval = TGP_ERRVAL_TIMEOUT; ++ } else { ++ *errval = TGP_ERRVAL_READERROR; ++ } ++ } ++ debug_return_str(NULL); ++ } ++ ++ debug_return_str_masked(buf); + } + + static void + tgetpass_handler(int s) + { +- if (s != SIGALRM) +- signo[s] = 1; ++ signo[s] = 1; + } + + static bool diff --git a/SOURCES/sudo-1.8.29-CVE-2019-18634-part2.patch b/SOURCES/sudo-1.8.29-CVE-2019-18634-part2.patch new file mode 100644 index 0000000..86743ba --- /dev/null +++ b/SOURCES/sudo-1.8.29-CVE-2019-18634-part2.patch @@ -0,0 +1,77 @@ +diff -up ./src/tgetpass.c.CVE-2019-18634 ./src/tgetpass.c +--- ./src/tgetpass.c.CVE-2019-18634 2020-02-05 17:16:07.601420697 +0100 ++++ ./src/tgetpass.c 2020-02-05 17:22:34.206301510 +0100 +@@ -55,7 +55,7 @@ static volatile sig_atomic_t signo[NSIG] + + static bool tty_present(void); + static void tgetpass_handler(int); +-static char *getln(int, char *, size_t, int, enum tgetpass_errval *); ++static char *getln(int, char *, size_t, bool, enum tgetpass_errval *); + static char *sudo_askpass(const char *, const char *); + + static int +@@ -118,6 +118,7 @@ tgetpass(const char *prompt, int timeout + static const char *askpass; + static char buf[SUDO_CONV_REPL_MAX + 1]; + int i, input, output, save_errno, neednl = 0, need_restart; ++ bool feedback = ISSET(flags, TGP_MASK); + enum tgetpass_errval errval; + debug_decl(tgetpass, SUDO_DEBUG_CONV) + +@@ -165,7 +166,7 @@ restart: + */ + if (!ISSET(flags, TGP_ECHO)) { + for (;;) { +- if (ISSET(flags, TGP_MASK)) ++ if (feedback) + neednl = sudo_term_cbreak(input); + else + neednl = sudo_term_noecho(input); +@@ -179,6 +180,9 @@ restart: + } + } + } ++ /* Only use feedback mode when we can disable echo. */ ++ if (!neednl) ++ feedback = false; + + /* + * Catch signals that would otherwise cause the user to end +@@ -204,7 +208,7 @@ restart: + + if (timeout > 0) + alarm(timeout); +- pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK), &errval); ++ pass = getln(input, buf, sizeof(buf), feedback, &errval); + alarm(0); + save_errno = errno; + +@@ -340,7 +344,7 @@ sudo_askpass(const char *askpass, const + extern int sudo_term_erase, sudo_term_kill; + + static char * +-getln(int fd, char *buf, size_t bufsiz, int feedback, ++getln(int fd, char *buf, size_t bufsiz, bool feedback, + enum tgetpass_errval *errval) + { + size_t left = bufsiz; +@@ -366,15 +370,15 @@ getln(int fd, char *buf, size_t bufsiz, + while (cp > buf) { + if (write(fd, "\b \b", 3) == -1) + break; +- --cp; ++ cp--; + } ++ cp = buf; + left = bufsiz; + continue; + } else if (c == sudo_term_erase) { + if (cp > buf) { +- if (write(fd, "\b \b", 3) == -1) +- break; +- --cp; ++ ignore_result(write(fd, "\b \b", 3)); ++ cp--; + left++; + } + continue; 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 19d4c0a..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: 7%{?dist} +Release: 10%{?dist} License: ISC Group: Applications/System URL: http://www.courtesan.com/sudo/ @@ -62,6 +62,18 @@ Patch11: sudo-1.8.23-who-am-i.patch # 1738841 - Crash in do_syslog() while doing sudoedit Patch12: sudo-1.8.23-fix_empty_username_in_do_syslog.patch +# 1760694 - CVE-2019-14287 sudo: Privilege escalation via 'Runas' specification with 'ALL' keyword [rhel-7.8] +Patch13: sudo-1.8.28-CVE-strtouid.patch +Patch14: sudo-1.8.28-CVE-strtouid-test.patch + +# 1798095 - CVE-2019-18634 sudo: Stack based buffer overflow in when pwfeedback is enabled [rhel-7.8] +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 @@ -100,6 +112,15 @@ plugins that use %{name}. %patch11 -p1 -b .who-am-i %patch12 -p1 -b .do_syslog-username +%patch13 -p1 -b .CVE-strtouid +%patch14 -p1 -b .CVE-strtouid-test + +%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 @@ -235,6 +256,20 @@ 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 + Resolves: rhbz#1798095 + +* Thu Oct 17 2019 Marek Tamaskovic 1.8.23-8 +- RHEL-7.8 +- fixed CVE-2019-14287 + Resolves: rhbz#1760695 * Thu Aug 22 2019 Marek Tamaskovic 1.8.23-7 - RHEL-7.8 erratum