diff --git a/SOURCES/sha-digest-calc.patch b/SOURCES/sha-digest-calc.patch
new file mode 100644
index 0000000..affab8b
--- /dev/null
+++ b/SOURCES/sha-digest-calc.patch
@@ -0,0 +1,26 @@
+From e4f08157b6693b956fe9c7c987bc3eeac1abb2cc Mon Sep 17 00:00:00 2001
+From: Tim Shearer <timtimminz@gmail.com>
+Date: Tue, 2 Aug 2022 08:48:32 -0400
+Subject: [PATCH] Fix incorrect SHA384/512 digest calculation.
+
+Resolves an issue where certain message sizes result in an incorrect
+checksum. Specifically, when:
+(n*8) mod 1024 == 896
+where n is the file size in bytes.
+---
+ lib/util/sha2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/util/sha2.c b/lib/util/sha2.c
+index b7a28cca8..f769f77f2 100644
+--- a/lib/util/sha2.c
++++ b/lib/util/sha2.c
+@@ -490,7 +490,7 @@ SHA512Pad(SHA2_CTX *ctx)
+ 	SHA512Update(ctx, (uint8_t *)"\200", 1);
+ 
+ 	/* Pad message such that the resulting length modulo 1024 is 896. */
+-	while ((ctx->count[0] & 1008) != 896)
++	while ((ctx->count[0] & 1016) != 896)
+ 		SHA512Update(ctx, (uint8_t *)"\0", 1);
+ 
+ 	/* Append length of message in bits and do final SHA512Transform(). */
diff --git a/SOURCES/sudo-1.9.12-CVE-2023-22809-backports.patch b/SOURCES/sudo-1.9.12-CVE-2023-22809-backports.patch
new file mode 100644
index 0000000..10745ac
--- /dev/null
+++ b/SOURCES/sudo-1.9.12-CVE-2023-22809-backports.patch
@@ -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);
+ }
+ 
+ /*
diff --git a/SOURCES/sudo-1.9.12-CVE-2023-22809-whitelist.patch b/SOURCES/sudo-1.9.12-CVE-2023-22809-whitelist.patch
new file mode 100644
index 0000000..fb78325
--- /dev/null
+++ b/SOURCES/sudo-1.9.12-CVE-2023-22809-whitelist.patch
@@ -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)
diff --git a/SOURCES/sudo-1.9.12-CVE-2023-22809.patch b/SOURCES/sudo-1.9.12-CVE-2023-22809.patch
new file mode 100644
index 0000000..15d5a06
--- /dev/null
+++ b/SOURCES/sudo-1.9.12-CVE-2023-22809.patch
@@ -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);
+     }
diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec
index ea0036c..678ac5f 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.29
-Release: 8%{?dist}
+Release: 10%{?dist}
 License: ISC
 Group: Applications/System
 URL: https://www.sudo.ws/
@@ -76,6 +76,13 @@ Patch21: sudo-1.9.7-krb5ccname.patch
 # 1986572 - utmp resource leak in sudo
 Patch22: sudo-1.9.7-utmp-leak.patch
 
+# 2114576 - sudo digest check fails incorrectly for certain file sizes (SHA512/SHA384)
+Patch23: sha-digest-calc.patch
+# 2161221 - EMBARGOED CVE-2023-22809 sudo: arbitrary file write with privileges of the RunAs user [rhel-8.8.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
 Sudo (superuser do) allows a system administrator to give certain
 users (or groups of users) the ability to run some (or all) commands
@@ -128,6 +135,11 @@ plugins that use %{name}.
 %patch21 -p1 -b .krb5ccname
 %patch22 -p1 -b .utmp-leak
 
+%patch23 -p1 -b .sha-digest
+%patch24 -p1 -b .whitelist
+%patch25 -p1 -b .backports
+%patch26 -p1 -b .cve
+
 %build
 # Remove bundled copy of zlib
 rm -rf zlib/
@@ -286,6 +298,13 @@ rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man8/sudo_plugin.8*
 
 %changelog
+* Wed Jan 11 2023 Radovan Sroka <rsroka@redhat.com> - 1.8.29.9
+RHEL 8.8.0 ERRATUM
+- CVE-2023-22809 sudo: arbitrary file write with privileges of the RunAs user
+Resolves: rhbz#2161221
+- sudo digest check fails incorrectly for certain file sizes (SHA512/SHA384)
+Resolves: rhbz#2114576
+
 * Mon Dec 06 2021 Radovan Sroka <rsroka@redhat.com> - 1.8.29-8
 RHEL 8.6.0 ERRATUM
 - sudoedit does not work with selinux args