import sudo-1.8.29-8.el8_7.1

This commit is contained in:
CentOS Sources 2023-01-23 03:23:39 -05:00 committed by Stepan Oksanichenko
parent 6c0248553e
commit e879763e7b
4 changed files with 365 additions and 1 deletions

View File

@ -0,0 +1,171 @@
diff -up ./plugins/sudoers/editor.c.other ./plugins/sudoers/editor.c
--- ./plugins/sudoers/editor.c.other 2023-01-16 17:37:04.659967300 +0100
+++ ./plugins/sudoers/editor.c 2023-01-16 17:40:35.944400376 +0100
@@ -39,6 +39,82 @@
#include "sudoers.h"
/*
+ * Non-destructive word-split that handles single and double quotes and
+ * escaped white space. Quotes are only recognized at the start of a word.
+ * They are treated as normal characters inside a word.
+ */
+static const char *
+wordsplit(const char *str, const char *endstr, const char **last)
+{
+ const char *cp;
+ debug_decl(wordsplit, SUDO_DEBUG_UTIL);
+
+ /* If no str specified, use last ptr (if any). */
+ if (str == NULL) {
+ str = *last;
+ /* Consume end quote if present. */
+ if (*str == '"' || *str == '\'')
+ str++;
+ }
+
+ /* Skip leading white space characters. */
+ while (str < endstr && (*str == ' ' || *str == '\t'))
+ str++;
+
+ /* Empty string? */
+ if (str >= endstr) {
+ *last = endstr;
+ debug_return_ptr(NULL);
+ }
+
+ /* If word is quoted, skip to end quote and return. */
+ if (*str == '"' || *str == '\'') {
+ const char *endquote = memchr(str + 1, *str, endstr - str);
+ if (endquote != NULL) {
+ *last = endquote;
+ debug_return_const_ptr(str + 1);
+ }
+ }
+
+ /* Scan str until we encounter white space. */
+ for (cp = str; cp < endstr; cp++) {
+ if (*cp == '\\') {
+ /* quoted char, do not interpret */
+ cp++;
+ continue;
+ }
+ if (*cp == ' ' || *cp == '\t') {
+ /* end of word */
+ break;
+ }
+ }
+ *last = cp;
+ debug_return_const_ptr(str);
+}
+
+/* Copy len chars from string, collapsing chars escaped with a backslash. */
+static char *
+copy_arg(const char *src, size_t len)
+{
+ const char *src_end = src + len;
+ char *copy, *dst;
+ debug_decl(copy_arg, SUDOERS_DEBUG_UTIL);
+
+ if ((copy = malloc(len + 1)) != NULL) {
+ for (dst = copy; src < src_end; ) {
+ if (*src == '\\') {
+ src++;
+ continue;
+ }
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+ }
+
+ debug_return_ptr(copy);
+}
+
+/*
* Search for the specified editor in the user's PATH, checking
* the result against allowlist if non-NULL. An argument vector
* suitable for execve() is allocated and stored in argv_out.
@@ -52,7 +128,7 @@ static char *
resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
int *argc_out, char ***argv_out, char * const *allowlist)
{
- char **nargv, *editor, *editor_path = NULL;
+ char **nargv = NULL, *editor = NULL, *editor_path = NULL;
const char *cp, *ep, *tmp;
const char *edend = ed + edlen;
struct stat user_editor_sb;
@@ -64,14 +140,12 @@ resolve_editor(const char *ed, size_t ed
* The EDITOR and VISUAL environment variables may contain command
* line args so look for those and alloc space for them too.
*/
- cp = sudo_strsplit(ed, edend, " \t", &ep);
+ cp = wordsplit(ed, edend, &ep);
if (cp == NULL)
debug_return_str(NULL);
- editor = strndup(cp, (size_t)(ep - cp));
- if (editor == NULL) {
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
- debug_return_str(NULL);
- }
+ editor = copy_arg(cp, ep - cp);
+ if (editor == NULL)
+ goto oom;
/* If we can't find the editor in the user's PATH, give up. */
if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, allowlist) != FOUND) {
@@ -81,30 +155,22 @@ resolve_editor(const char *ed, size_t ed
}
/* Count rest of arguments and allocate editor argv. */
- for (nargc = 1, tmp = ep; sudo_strsplit(NULL, edend, " \t", &tmp) != NULL; )
+ for (nargc = 1, tmp = ep; wordsplit(NULL, edend, &tmp) != NULL; )
nargc++;
if (nfiles != 0)
nargc += nfiles + 1;
nargv = reallocarray(NULL, nargc + 1, sizeof(char *));
- if (nargv == NULL) {
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
- free(editor);
- free(editor_path);
- debug_return_str(NULL);
- }
+ if (nargv == NULL)
+ goto oom;
/* Fill in editor argv (assumes files[] is NULL-terminated). */
nargv[0] = editor;
- for (nargc = 1; (cp = sudo_strsplit(NULL, edend, " \t", &ep)) != NULL; nargc++) {
- nargv[nargc] = strndup(cp, (size_t)(ep - cp));
- if (nargv[nargc] == NULL) {
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
- free(editor_path);
- while (nargc--)
- free(nargv[nargc]);
- free(nargv);
- debug_return_str(NULL);
- }
+ editor = NULL;
+ for (nargc = 1; (cp = wordsplit(NULL, edend, &ep)) != NULL; nargc++) {
+ /* Copy string, collapsing chars escaped with a backslash. */
+ nargv[nargc] = copy_arg(cp, ep - cp);
+ if (nargv[nargc] == NULL)
+ goto oom;
}
if (nfiles != 0) {
nargv[nargc++] = "--";
@@ -116,6 +182,16 @@ resolve_editor(const char *ed, size_t ed
*argc_out = nargc;
*argv_out = nargv;
debug_return_str(editor_path);
+oom:
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ free(editor);
+ free(editor_path);
+ if (nargv != NULL) {
+ while (nargc--)
+ free(nargv[nargc]);
+ free(nargv);
+ }
+ debug_return_str(NULL);
}
/*

View File

@ -0,0 +1,57 @@
diff -up ./plugins/sudoers/editor.c.whitelist ./plugins/sudoers/editor.c
--- ./plugins/sudoers/editor.c.whitelist 2023-01-16 17:31:58.108335076 +0100
+++ ./plugins/sudoers/editor.c 2023-01-16 17:33:37.375547672 +0100
@@ -40,7 +40,7 @@
/*
* Search for the specified editor in the user's PATH, checking
- * the result against whitelist if non-NULL. An argument vector
+ * the result against allowlist if non-NULL. An argument vector
* suitable for execve() is allocated and stored in argv_out.
* If nfiles is non-zero, files[] is added to the end of argv_out.
*
@@ -50,7 +50,7 @@
*/
static char *
resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
- int *argc_out, char ***argv_out, char * const *whitelist)
+ int *argc_out, char ***argv_out, char * const *allowlist)
{
char **nargv, *editor, *editor_path = NULL;
const char *cp, *ep, *tmp;
@@ -74,7 +74,7 @@ resolve_editor(const char *ed, size_t ed
}
/* If we can't find the editor in the user's PATH, give up. */
- if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, whitelist) != FOUND) {
+ if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, allowlist) != FOUND) {
free(editor);
errno = ENOENT;
debug_return_str(NULL);
@@ -130,7 +130,7 @@ resolve_editor(const char *ed, size_t ed
*/
char *
find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
- char * const *whitelist, const char **env_editor, bool env_error)
+ char * const *allowlist, const char **env_editor, bool env_error)
{
char *ev[3], *editor_path = NULL;
unsigned int i;
@@ -149,7 +149,7 @@ find_editor(int nfiles, char **files, in
if (editor != NULL && *editor != '\0') {
*env_editor = editor;
editor_path = resolve_editor(editor, strlen(editor),
- nfiles, files, argc_out, argv_out, whitelist);
+ nfiles, files, argc_out, argv_out, allowlist);
if (editor_path != NULL)
break;
if (errno != ENOENT)
@@ -169,7 +169,7 @@ find_editor(int nfiles, char **files, in
for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
editor_path = resolve_editor(cp, (size_t)(ep - cp), nfiles,
- files, argc_out, argv_out, whitelist);
+ files, argc_out, argv_out, allowlist);
if (editor_path != NULL)
break;
if (errno != ENOENT)

View File

@ -0,0 +1,122 @@
diff -up ./plugins/sudoers/editor.c.cve ./plugins/sudoers/editor.c
--- ./plugins/sudoers/editor.c.cve 2023-01-16 17:52:37.074066664 +0100
+++ ./plugins/sudoers/editor.c 2023-01-16 17:58:06.603774304 +0100
@@ -132,7 +132,7 @@ resolve_editor(const char *ed, size_t ed
const char *cp, *ep, *tmp;
const char *edend = ed + edlen;
struct stat user_editor_sb;
- int nargc;
+ int nargc = 0;
debug_decl(resolve_editor, SUDOERS_DEBUG_UTIL)
/*
@@ -149,9 +149,7 @@ resolve_editor(const char *ed, size_t ed
/* If we can't find the editor in the user's PATH, give up. */
if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, allowlist) != FOUND) {
- free(editor);
- errno = ENOENT;
- debug_return_str(NULL);
+ goto bad;
}
/* Count rest of arguments and allocate editor argv. */
@@ -171,7 +169,19 @@ resolve_editor(const char *ed, size_t ed
nargv[nargc] = copy_arg(cp, ep - cp);
if (nargv[nargc] == NULL)
goto oom;
+
+ /*
+ * We use "--" to separate the editor and arguments from the files
+ * to edit. The editor arguments themselves may not contain "--".
+ */
+ if (strcmp(nargv[nargc], "--") == 0) {
+ sudo_warnx(U_("ignoring editor: %.*s"), (int)edlen, ed);
+ sudo_warnx("%s", U_("editor arguments may not contain \"--\""));
+ errno = EINVAL;
+ goto bad;
+ }
}
+
if (nfiles != 0) {
nargv[nargc++] = "--";
while (nfiles--)
@@ -184,6 +194,7 @@ resolve_editor(const char *ed, size_t ed
debug_return_str(editor_path);
oom:
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+bad:
free(editor);
free(editor_path);
if (nargv != NULL) {
diff -up ./plugins/sudoers/sudoers.c.cve ./plugins/sudoers/sudoers.c
--- ./plugins/sudoers/sudoers.c.cve 2023-01-16 17:52:37.074066664 +0100
+++ ./plugins/sudoers/sudoers.c 2023-01-16 18:02:43.928307505 +0100
@@ -634,21 +634,32 @@ sudoers_policy_main(int argc, char * con
/* Note: must call audit before uid change. */
if (ISSET(sudo_mode, MODE_EDIT)) {
- int edit_argc;
- const char *env_editor;
+ const char *env_editor = NULL;
+ int edit_argc;
free(safe_cmnd);
safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc,
&edit_argv, NULL, &env_editor, false);
if (safe_cmnd == NULL) {
- if (errno != ENOENT)
- goto done;
- audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
- env_editor ? env_editor : def_editor);
- sudo_warnx(U_("%s: command not found"),
- env_editor ? env_editor : def_editor);
- goto bad;
- }
+ switch (errno) {
+ case ENOENT:
+ audit_failure(NewArgc, NewArgv, N_("%s: command not found"),
+ env_editor ? env_editor : def_editor);
+ sudo_warnx(U_("%s: command not found"),
+ env_editor ? env_editor : def_editor);
+ goto bad;
+ case EINVAL:
+ if (def_env_editor && env_editor != NULL) {
+ /* User tried to do something funny with the editor. */
+ log_warningx(SLOG_NO_STDERR|SLOG_SEND_MAIL,
+ "invalid user-specified editor: %s", env_editor);
+ goto bad;
+ }
+ default:
+ goto done;
+ }
+ }
+
if (audit_success(edit_argc, edit_argv) != 0 && !def_ignore_audit_errors)
goto done;
diff -up ./plugins/sudoers/visudo.c.cve ./plugins/sudoers/visudo.c
--- ./plugins/sudoers/visudo.c.cve 2019-10-28 13:28:54.000000000 +0100
+++ ./plugins/sudoers/visudo.c 2023-01-16 18:03:48.713975354 +0100
@@ -308,7 +308,7 @@ static char *
get_editor(int *editor_argc, char ***editor_argv)
{
char *editor_path = NULL, **whitelist = NULL;
- const char *env_editor;
+ const char *env_editor = NULL;
static char *files[] = { "+1", "sudoers" };
unsigned int whitelist_len = 0;
debug_decl(get_editor, SUDOERS_DEBUG_UTIL)
@@ -342,7 +342,11 @@ get_editor(int *editor_argc, char ***edi
if (editor_path == NULL) {
if (def_env_editor && env_editor != NULL) {
/* We are honoring $EDITOR so this is a fatal error. */
- sudo_fatalx(U_("specified editor (%s) doesn't exist"), env_editor);
+ if (errno == ENOENT) {
+ sudo_warnx(U_("specified editor (%s) doesn't exist"),
+ env_editor);
+ }
+ exit(EXIT_FAILURE);
}
sudo_fatalx(U_("no editor found (editor path = %s)"), def_editor);
}

View File

@ -1,7 +1,7 @@
Summary: Allows restricted root access for specified users Summary: Allows restricted root access for specified users
Name: sudo Name: sudo
Version: 1.8.29 Version: 1.8.29
Release: 8%{?dist} Release: 8%{?dist}.1
License: ISC License: ISC
Group: Applications/System Group: Applications/System
URL: https://www.sudo.ws/ URL: https://www.sudo.ws/
@ -76,6 +76,11 @@ Patch21: sudo-1.9.7-krb5ccname.patch
# 1986572 - utmp resource leak in sudo # 1986572 - utmp resource leak in sudo
Patch22: sudo-1.9.7-utmp-leak.patch Patch22: sudo-1.9.7-utmp-leak.patch
# 2161220 - EMBARGOED CVE-2023-22809 sudo: arbitrary file write with privileges of the RunAs user [rhel-8.7.0]
Patch24: sudo-1.9.12-CVE-2023-22809-whitelist.patch
Patch25: sudo-1.9.12-CVE-2023-22809-backports.patch
Patch26: sudo-1.9.12-CVE-2023-22809.patch
%description %description
Sudo (superuser do) allows a system administrator to give certain Sudo (superuser do) allows a system administrator to give certain
users (or groups of users) the ability to run some (or all) commands users (or groups of users) the ability to run some (or all) commands
@ -128,6 +133,10 @@ plugins that use %{name}.
%patch21 -p1 -b .krb5ccname %patch21 -p1 -b .krb5ccname
%patch22 -p1 -b .utmp-leak %patch22 -p1 -b .utmp-leak
%patch24 -p1 -b .whitelist
%patch25 -p1 -b .backports
%patch26 -p1 -b .cve
%build %build
# Remove bundled copy of zlib # Remove bundled copy of zlib
rm -rf zlib/ rm -rf zlib/
@ -286,6 +295,11 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man8/sudo_plugin.8* %{_mandir}/man8/sudo_plugin.8*
%changelog %changelog
* Wed Jan 11 2023 Radovan Sroka <rsroka@redhat.com> - 1.8.29.8.1
RHEL 8.7.0.Z ERRATUM
- CVE-2023-22809 sudo: arbitrary file write with privileges of the RunAs user
Resolves: rhbz#2161220
* Mon Dec 06 2021 Radovan Sroka <rsroka@redhat.com> - 1.8.29-8 * Mon Dec 06 2021 Radovan Sroka <rsroka@redhat.com> - 1.8.29-8
RHEL 8.6.0 ERRATUM RHEL 8.6.0 ERRATUM
- sudoedit does not work with selinux args - sudoedit does not work with selinux args