diff --git a/SOURCES/emacs-ctags-local-command-execute-vulnerability.patch b/SOURCES/emacs-ctags-local-command-execute-vulnerability.patch
new file mode 100644
index 0000000..e930f73
--- /dev/null
+++ b/SOURCES/emacs-ctags-local-command-execute-vulnerability.patch
@@ -0,0 +1,223 @@
+diff --git a/lib-src/etags.c b/lib-src/etags.c
+index 588921bc70..a156444281 100644
+--- a/lib-src/etags.c
++++ b/lib-src/etags.c
+@@ -371,7 +371,7 @@ static void just_read_file (FILE *);
+
+ static language *get_language_from_langname (const char *);
+ static void readline (linebuffer *, FILE *);
+-static long readline_internal (linebuffer *, FILE *, char const *);
++static long readline_internal (linebuffer *, FILE *, char const *, const bool);
+ static bool nocase_tail (const char *);
+ static void get_tag (char *, char **);
+ static void get_lispy_tag (char *);
+@@ -394,7 +394,9 @@ static void free_fdesc (fdesc *);
+ static void pfnote (char *, bool, char *, int, int, long);
+ static void invalidate_nodes (fdesc *, node **);
+ static void put_entries (node *);
++static void clean_matched_file_tag (char const * const, char const * const);
+
++static void do_move_file (const char *, const char *);
+ static char *concat (const char *, const char *, const char *);
+ static char *skip_spaces (char *);
+ static char *skip_non_spaces (char *);
+@@ -1307,7 +1309,7 @@ main (int argc, char **argv)
+ 		  if (parsing_stdin)
+ 		    fatal ("cannot parse standard input "
+ 			   "AND read file names from it");
+-		  while (readline_internal (&filename_lb, stdin, "-") > 0)
++		  while (readline_internal (&filename_lb, stdin, "-", false) > 0)
+ 		    process_file_name (filename_lb.buffer, lang);
+ 		}
+ 	      else
+@@ -1355,9 +1357,6 @@ main (int argc, char **argv)
+   /* From here on, we are in (CTAGS && !cxref_style) */
+   if (update)
+     {
+-      char *cmd =
+-	xmalloc (strlen (tagfile) + whatlen_max +
+-		 sizeof "mv..OTAGS;grep -Fv '\t\t' OTAGS >;rm OTAGS");
+       for (i = 0; i < current_arg; ++i)
+ 	{
+ 	  switch (argbuffer[i].arg_type)
+@@ -1368,17 +1367,8 @@ main (int argc, char **argv)
+ 	    default:
+ 	      continue;		/* the for loop */
+ 	    }
+-	  char *z = stpcpy (cmd, "mv ");
+-	  z = stpcpy (z, tagfile);
+-	  z = stpcpy (z, " OTAGS;grep -Fv '\t");
+-	  z = stpcpy (z, argbuffer[i].what);
+-	  z = stpcpy (z, "\t' OTAGS >");
+-	  z = stpcpy (z, tagfile);
+-	  strcpy (z, ";rm OTAGS");
+-	  if (system (cmd) != EXIT_SUCCESS)
+-	    fatal ("failed to execute shell command");
++	  clean_matched_file_tag (tagfile, argbuffer[i].what);
+ 	}
+-      free (cmd);
+       append_to_tagfile = true;
+     }
+
+@@ -1407,6 +1397,51 @@ main (int argc, char **argv)
+   return EXIT_SUCCESS;
+ }
+
++/*
++ * Equivalent to: mv tags OTAGS;grep -Fv ' filename ' OTAGS >tags;rm OTAGS
++ */
++static void
++clean_matched_file_tag (const char* tagfile, const char* match_file_name)
++{
++  FILE *otags_f = fopen ("OTAGS", "wb");
++  FILE *tag_f = fopen (tagfile, "rb");
++
++  if (otags_f == NULL)
++    pfatal ("OTAGS");
++
++  if (tag_f == NULL)
++    pfatal (tagfile);
++
++  int buf_len = strlen (match_file_name) + sizeof ("\t\t ") + 1;
++  char *buf = xmalloc (buf_len);
++  snprintf (buf, buf_len, "\t%s\t", match_file_name);
++
++  linebuffer line;
++  linebuffer_init (&line);
++  while (readline_internal (&line, tag_f, tagfile, true) > 0)
++    {
++      if (ferror (tag_f))
++        pfatal (tagfile);
++
++      if (strstr (line.buffer, buf) == NULL)
++        {
++          fprintf (otags_f, "%s\n", line.buffer);
++          if (ferror (tag_f))
++            pfatal (tagfile);
++        }
++    }
++  free (buf);
++  free (line.buffer);
++
++  if (fclose (otags_f) == EOF)
++    pfatal ("OTAGS");
++
++  if (fclose (tag_f) == EOF)
++    pfatal (tagfile);
++
++  do_move_file ("OTAGS", tagfile);
++  return;
++}
+
+ /*
+  * Return a compressor given the file name.  If EXTPTR is non-zero,
+@@ -1794,7 +1829,7 @@ find_entries (FILE *inf)
+
+   /* Else look for sharp-bang as the first two characters. */
+   if (parser == NULL
+-      && readline_internal (&lb, inf, infilename) > 0
++      && readline_internal (&lb, inf, infilename, false) > 0
+       && lb.len >= 2
+       && lb.buffer[0] == '#'
+       && lb.buffer[1] == '!')
+@@ -6293,7 +6328,7 @@ analyze_regex (char *regex_arg)
+ 	if (regexfp == NULL)
+ 	  pfatal (regexfile);
+ 	linebuffer_init (&regexbuf);
+-	while (readline_internal (&regexbuf, regexfp, regexfile) > 0)
++	while (readline_internal (&regexbuf, regexfp, regexfile, false) > 0)
+ 	  analyze_regex (regexbuf.buffer);
+ 	free (regexbuf.buffer);
+ 	if (fclose (regexfp) != 0)
+@@ -6648,11 +6683,13 @@ get_lispy_tag (register char *bp)
+
+ /*
+  * Read a line of text from `stream' into `lbp', excluding the
+- * newline or CR-NL, if any.  Return the number of characters read from
+- * `stream', which is the length of the line including the newline.
++ * newline or CR-NL (if `leave_cr` is false), if any.  Return the
++ * number of characters read from `stream', which is the length
++ * of the line including the newline.
+  *
+- * On DOS or Windows we do not count the CR character, if any before the
+- * NL, in the returned length; this mirrors the behavior of Emacs on those
++ * On DOS or Windows, if `leave_cr` is false, we do not count the
++ * CR character, if any before the NL, in the returned length;
++ * this mirrors the behavior of Emacs on those
+  * platforms (for text files, it translates CR-NL to NL as it reads in the
+  * file).
+  *
+@@ -6660,7 +6697,7 @@ get_lispy_tag (register char *bp)
+  * appended to `filebuf'.
+  */
+ static long
+-readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
++readline_internal (linebuffer *lbp, FILE *stream, char const *filename, const bool leave_cr)
+ {
+   char *buffer = lbp->buffer;
+   char *p = lbp->buffer;
+@@ -6691,7 +6728,7 @@ readline_internal (linebuffer *lbp, FILE *stream, char const *filename)
+ 	}
+       if (c == '\n')
+ 	{
+-	  if (p > buffer && p[-1] == '\r')
++	  if (!leave_cr && p > buffer && p[-1] == '\r')
+ 	    {
+ 	      p -= 1;
+ 	      chars_deleted = 2;
+@@ -6736,7 +6773,7 @@ readline (linebuffer *lbp, FILE *stream)
+   long result;
+
+   linecharno = charno;		/* update global char number of line start */
+-  result = readline_internal (lbp, stream, infilename); /* read line */
++  result = readline_internal (lbp, stream, infilename, false); /* read line */
+   lineno += 1;			/* increment global line number */
+   charno += result;		/* increment global char number */
+
+@@ -7104,6 +7141,46 @@ etags_mktmp (void)
+   return templt;
+ }
+
++static void
++do_move_file(const char *src_file, const char *dst_file)
++{
++  if (rename (src_file, dst_file) == 0)
++    return;
++
++  FILE *src_f = fopen (src_file, "rb");
++  FILE *dst_f = fopen (dst_file, "wb");
++
++  if (src_f == NULL)
++    pfatal (src_file);
++
++  if (dst_f == NULL)
++    pfatal (dst_file);
++
++  int c;
++  while ((c = fgetc (src_f)) != EOF)
++    {
++      if (ferror (src_f))
++        pfatal (src_file);
++
++      if (ferror (dst_f))
++        pfatal (dst_file);
++
++      if (fputc (c, dst_f) == EOF)
++        pfatal ("cannot write");
++    }
++
++  if (fclose (src_f) == EOF)
++    pfatal (src_file);
++
++  if (fclose (dst_f) == EOF)
++    pfatal (dst_file);
++
++  if (unlink (src_file) == -1)
++    pfatal ("unlink error");
++
++  return;
++}
++
+ /* Return a newly allocated string containing the file name of FILE
+    relative to the absolute directory DIR (which should end with a slash). */
+ static char *
diff --git a/SOURCES/emacs-mh-rmail-nonempty-dir.patch b/SOURCES/emacs-mh-rmail-nonempty-dir.patch
new file mode 100644
index 0000000..1015420
--- /dev/null
+++ b/SOURCES/emacs-mh-rmail-nonempty-dir.patch
@@ -0,0 +1,31 @@
+From b73cde5e2815c531df7f5fd13e214a7d92f78239 Mon Sep 17 00:00:00 2001
+From: Mike Kupfer <mkupfer@alum.berkeley.edu>
+Date: Wed, 4 Jul 2018 15:43:04 -0700
+Subject: [PATCH] Fix MH-E mail composition with GNU Mailutils (SF#485)
+
+* lisp/mh-e/mh-comp.el (mh-bare-components): Recursively delete
+the temporary folder.
+---
+ lisp/mh-e/mh-comp.el | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
+index a9f809cfa1..aa22df8b18 100644
+--- a/lisp/mh-e/mh-comp.el
++++ b/lisp/mh-e/mh-comp.el
+@@ -925,8 +925,10 @@ mh-bare-components
+                      (list "-form" mh-comp-formfile)))
+     (setq new (make-temp-file "comp."))
+     (rename-file (concat temp-folder "/" "1") new t)
+-    (delete-file (concat temp-folder "/" ".mh_sequences"))
+-    (delete-directory temp-folder)
++    ;; The temp folder could contain various metadata files.  Rather
++    ;; than trying to enumerate all the known files, just do a
++    ;; recursive delete on the directory.
++    (delete-directory temp-folder t)
+     new))
+ 
+ (defun mh-read-draft (use initial-contents delete-contents-file)
+-- 
+2.36.1
+
diff --git a/SPECS/emacs.spec b/SPECS/emacs.spec
index 9d844b8..c83edd1 100644
--- a/SPECS/emacs.spec
+++ b/SPECS/emacs.spec
@@ -5,7 +5,7 @@ Summary:       GNU Emacs text editor
 Name:          emacs
 Epoch:         1
 Version:       26.1
-Release:       7%{?dist}
+Release:       9%{?dist}
 License:       GPLv3+ and CC0-1.0
 URL:           http://www.gnu.org/software/emacs/
 Group:         Applications/Editors
@@ -24,6 +24,8 @@ Source10:      package-keyring.gpg
 # rhbz#713600
 Patch1:        emacs-spellchecker.patch
 Patch2:        emacs-system-crypto-policies.patch
+Patch3:        emacs-ctags-local-command-execute-vulnerability.patch
+Patch4:        emacs-mh-rmail-nonempty-dir.patch
 
 BuildRequires: atk-devel
 BuildRequires: cairo-devel
@@ -178,6 +180,8 @@ packages that add functionality to Emacs.
 
 %patch1 -p1 -b .spellchecker
 %patch2 -p1 -b .system-crypto-policies
+%patch3 -p1 -b .ctags-local-command-execute-vulnerability
+%patch4 -p1 -b .mh-rmail-nonempty-dir.patch
 autoconf
 
 # We prefer our emacs.desktop file
@@ -464,6 +468,12 @@ fi
 %dir %{_datadir}/emacs/site-lisp/site-start.d
 
 %changelog
+* Tue Jan 10 2023 Jacek Migacz <jmigacz@redhat.com> - 1:26.1-9
+- Fix MH-E mail composition with GNU Mailutils (#1991156)
+
+* Thu Jan 05 2023 Jacek Migacz <jmigacz@redhat.com> - 1:26.1-8
+- Fix ctags local command execute vulnerability (#2149386)
+
 * Thu Aug 5 2021 Jacek Migacz <jmigacz@redhat.com> - 1:26.1-7
 - provide gating.yaml for CI