diff --git a/SOURCES/glibc-rh2065588-1.patch b/SOURCES/glibc-rh2065588-1.patch
new file mode 100644
index 0000000..3b4db3f
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-1.patch
@@ -0,0 +1,253 @@
+commit 2a973ab7f1a6f6cd9be1c7257fd7b5d331515eab
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Sep 12 10:30:46 2018 -0300
+
+    posix: Add internal symbols for posix_spawn interface
+    
+    This patch adds internal hidden definition for mostly of the posix_spawn
+    function so it can be used internally on both popen and system
+    implementations.
+    
+    Checked on x86_64-linux-gnu.
+    
+            * include/spawn.h (__posix_spawn, posix_spawn_file_actions_addclose,
+            __posix_spawn_file_actions_adddup2, __posix_spawn_file_actions_destroy,
+            __posix_spawn_file_actions_init, __posix_spawnattr_init,
+            __posix_spawnattr_destroy, __posix_spawnattr_setflags,
+            __posix_spawnattr_setsigdefault, __posix_spawnattr_setsigmask): New
+            prototype.
+            * posix/spawn.c (__posix_spawn): Add libc_hidden_def.
+            * posix/spawn_faction_addclose.c
+            (__posix_spawn_file_actions_addclose): Add hidden definition.
+            * posix/spawn_faction_adddup2.c
+            (__posix_spawn_file_actions_adddup2): Likewise.
+            * posix/spawn_faction_destroy.c
+            (__posix_spawn_file_actions_destroy): Likewise.
+            * posix/spawn_faction_init.c (__posix_spawn_file_actions_init):
+            Likewise.
+            * posix/spawnattr_destroy.c (__posix_spawnattr_destroy): Likewise.
+            * posix/spawnattr_init.c (__posix_spawnattr_init): Likewise.
+            * posix/spawnattr_setdefault.c (__posix_spawnattr_setsigdefault):
+            Likewise.
+            * posix/spawnattr_setflags.c (__posix_spawnattr_setflags): Likewise.
+            * posix/spawnattr_setsigmask.c (__posix_spawnattr_setsigmask):
+            Likewise.
+
+diff --git a/include/spawn.h b/include/spawn.h
+index a6c7a8adc361927e..7fdd965bd780f8de 100644
+--- a/include/spawn.h
++++ b/include/spawn.h
+@@ -1 +1,36 @@
++#ifndef _SPAWN_H
+ #include <posix/spawn.h>
++
++# ifndef _ISOMAC
++__typeof (posix_spawn) __posix_spawn;
++libc_hidden_proto (__posix_spawn)
++
++__typeof (posix_spawn_file_actions_addclose)
++  __posix_spawn_file_actions_addclose attribute_hidden;
++
++__typeof (posix_spawn_file_actions_adddup2)
++  __posix_spawn_file_actions_adddup2 attribute_hidden;
++
++__typeof (posix_spawn_file_actions_destroy)
++  __posix_spawn_file_actions_destroy attribute_hidden;
++
++__typeof (posix_spawn_file_actions_init) __posix_spawn_file_actions_init
++  attribute_hidden;
++
++__typeof (posix_spawnattr_init) __posix_spawnattr_init
++  attribute_hidden;
++
++__typeof (posix_spawnattr_destroy) __posix_spawnattr_destroy
++  attribute_hidden;
++
++__typeof (posix_spawnattr_setflags) __posix_spawnattr_setflags
++  attribute_hidden;
++
++__typeof (posix_spawnattr_setsigdefault) __posix_spawnattr_setsigdefault
++  attribute_hidden;
++
++__typeof (posix_spawnattr_setsigmask) __posix_spawnattr_setsigmask
++  attribute_hidden;
++
++# endif /* !_ISOMAC  */
++#endif /* spawn.h  */
+diff --git a/posix/spawn.c b/posix/spawn.c
+index 51f67b2755bd4949..a82f1c84e299f018 100644
+--- a/posix/spawn.c
++++ b/posix/spawn.c
+@@ -30,6 +30,7 @@ __posix_spawn (pid_t *pid, const char *path,
+   return __spawni (pid, path, file_actions, attrp, argv, envp, 0);
+ }
+ versioned_symbol (libc, __posix_spawn, posix_spawn, GLIBC_2_15);
++libc_hidden_def (__posix_spawn)
+ 
+ 
+ #if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_15)
+diff --git a/posix/spawn_faction_addclose.c b/posix/spawn_faction_addclose.c
+index 21081e19b55db44c..e1fafe438cf15c91 100644
+--- a/posix/spawn_faction_addclose.c
++++ b/posix/spawn_faction_addclose.c
+@@ -24,8 +24,8 @@
+ /* Add an action to FILE-ACTIONS which tells the implementation to call
+    `close' for the given file descriptor during the `spawn' call.  */
+ int
+-posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions,
+-				   int fd)
++__posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions,
++				     int fd)
+ {
+   struct __spawn_action *rec;
+ 
+@@ -48,3 +48,5 @@ posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions,
+ 
+   return 0;
+ }
++weak_alias (__posix_spawn_file_actions_addclose,
++	    posix_spawn_file_actions_addclose)
+diff --git a/posix/spawn_faction_adddup2.c b/posix/spawn_faction_adddup2.c
+index 363bc29ae502bd60..371b1de3e6f1979a 100644
+--- a/posix/spawn_faction_adddup2.c
++++ b/posix/spawn_faction_adddup2.c
+@@ -24,8 +24,8 @@
+ /* Add an action to FILE-ACTIONS which tells the implementation to call
+    `dup2' for the given file descriptors during the `spawn' call.  */
+ int
+-posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions,
+-				  int fd, int newfd)
++__posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions,
++				    int fd, int newfd)
+ {
+   struct __spawn_action *rec;
+ 
+@@ -49,3 +49,5 @@ posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions,
+ 
+   return 0;
+ }
++weak_alias (__posix_spawn_file_actions_adddup2,
++	    posix_spawn_file_actions_adddup2)
+diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c
+index 46061ee3473d4475..2a2de4e41d6bd6d0 100644
+--- a/posix/spawn_faction_destroy.c
++++ b/posix/spawn_faction_destroy.c
+@@ -22,7 +22,7 @@
+ 
+ /* Deallocate the file actions.  */
+ int
+-posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
++__posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
+ {
+   /* Free the paths in the open actions.  */
+   for (int i = 0; i < file_actions->__used; ++i)
+@@ -44,3 +44,5 @@ posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
+   free (file_actions->__actions);
+   return 0;
+ }
++weak_alias (__posix_spawn_file_actions_destroy,
++	    posix_spawn_file_actions_destroy)
+diff --git a/posix/spawn_faction_init.c b/posix/spawn_faction_init.c
+index ddb42e6a77ba41ec..98432067c645021e 100644
+--- a/posix/spawn_faction_init.c
++++ b/posix/spawn_faction_init.c
+@@ -45,9 +45,10 @@ __posix_spawn_file_actions_realloc (posix_spawn_file_actions_t *file_actions)
+ 
+ /* Initialize data structure for file attribute for `spawn' call.  */
+ int
+-posix_spawn_file_actions_init (posix_spawn_file_actions_t *file_actions)
++__posix_spawn_file_actions_init (posix_spawn_file_actions_t *file_actions)
+ {
+   /* Simply clear all the elements.  */
+   memset (file_actions, '\0', sizeof (*file_actions));
+   return 0;
+ }
++weak_alias (__posix_spawn_file_actions_init, posix_spawn_file_actions_init)
+diff --git a/posix/spawnattr_destroy.c b/posix/spawnattr_destroy.c
+index 603e00fffefae2bf..043386778588913a 100644
+--- a/posix/spawnattr_destroy.c
++++ b/posix/spawnattr_destroy.c
+@@ -19,8 +19,9 @@
+ 
+ /* Initialize data structure for file attribute for `spawn' call.  */
+ int
+-posix_spawnattr_destroy (posix_spawnattr_t *attr)
++__posix_spawnattr_destroy (posix_spawnattr_t *attr)
+ {
+   /* Nothing to do in the moment.  */
+   return 0;
+ }
++weak_alias (__posix_spawnattr_destroy, posix_spawnattr_destroy)
+diff --git a/posix/spawnattr_init.c b/posix/spawnattr_init.c
+index bab464e62bdf7889..4e1218ab44e3f779 100644
+--- a/posix/spawnattr_init.c
++++ b/posix/spawnattr_init.c
+@@ -20,7 +20,7 @@
+ 
+ /* Initialize data structure for file attribute for `spawn' call.  */
+ int
+-posix_spawnattr_init (posix_spawnattr_t *attr)
++__posix_spawnattr_init (posix_spawnattr_t *attr)
+ {
+   /* All elements have to be initialized to the default values which
+      is generally zero.  */
+@@ -28,3 +28,4 @@ posix_spawnattr_init (posix_spawnattr_t *attr)
+ 
+   return 0;
+ }
++weak_alias (__posix_spawnattr_init, posix_spawnattr_init)
+diff --git a/posix/spawnattr_setdefault.c b/posix/spawnattr_setdefault.c
+index c77cda59be3dda20..174bcfa423dc5666 100644
+--- a/posix/spawnattr_setdefault.c
++++ b/posix/spawnattr_setdefault.c
+@@ -20,11 +20,12 @@
+ 
+ /* Set signal mask for signals with default handling in ATTR to SIGDEFAULT.  */
+ int
+-posix_spawnattr_setsigdefault (posix_spawnattr_t *attr,
+-			       const sigset_t *sigdefault)
++__posix_spawnattr_setsigdefault (posix_spawnattr_t *attr,
++				 const sigset_t *sigdefault)
+ {
+   /* Copy the sigset_t data to the user buffer.  */
+   memcpy (&attr->__sd, sigdefault, sizeof (sigset_t));
+ 
+   return 0;
+ }
++weak_alias (__posix_spawnattr_setsigdefault, posix_spawnattr_setsigdefault)
+diff --git a/posix/spawnattr_setflags.c b/posix/spawnattr_setflags.c
+index cf9a60181dc91ccd..0a42e94770224a94 100644
+--- a/posix/spawnattr_setflags.c
++++ b/posix/spawnattr_setflags.c
+@@ -30,7 +30,7 @@
+ 
+ /* Store flags in the attribute structure.  */
+ int
+-posix_spawnattr_setflags (posix_spawnattr_t *attr, short int flags)
++__posix_spawnattr_setflags (posix_spawnattr_t *attr, short int flags)
+ {
+   /* Check no invalid bits are set.  */
+   if (flags & ~ALL_FLAGS)
+@@ -41,3 +41,4 @@ posix_spawnattr_setflags (posix_spawnattr_t *attr, short int flags)
+ 
+   return 0;
+ }
++weak_alias (__posix_spawnattr_setflags, posix_spawnattr_setflags)
+diff --git a/posix/spawnattr_setsigmask.c b/posix/spawnattr_setsigmask.c
+index 7ae81ad47025db6f..12c0111af441dd13 100644
+--- a/posix/spawnattr_setsigmask.c
++++ b/posix/spawnattr_setsigmask.c
+@@ -20,7 +20,7 @@
+ 
+ /* Set signal mask for the new process in ATTR to SIGMASK.  */
+ int
+-posix_spawnattr_setsigmask (posix_spawnattr_t *attr,
++__posix_spawnattr_setsigmask (posix_spawnattr_t *attr,
+ 			    const sigset_t *sigmask)
+ {
+   /* Copy the sigset_t data to the user buffer.  */
+@@ -28,3 +28,4 @@ posix_spawnattr_setsigmask (posix_spawnattr_t *attr,
+ 
+   return 0;
+ }
++weak_alias (__posix_spawnattr_setsigmask, posix_spawnattr_setsigmask)
diff --git a/SOURCES/glibc-rh2065588-10.patch b/SOURCES/glibc-rh2065588-10.patch
new file mode 100644
index 0000000..3016994
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-10.patch
@@ -0,0 +1,21 @@
+commit 5fce0e095bc413f908f472074c2235198cd76bf4
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Tue Mar 24 15:36:23 2020 -0300
+
+    support/shell-container.c: Return 127 if execve fails
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/support/shell-container.c b/support/shell-container.c
+index e87ac5cf1baa84e5..e9eea64bca7e949d 100644
+--- a/support/shell-container.c
++++ b/support/shell-container.c
+@@ -238,7 +238,7 @@ run_command_array (char **argv)
+ 
+       fprintf (stderr, "sh: execing %s failed: %s",
+ 	       argv[0], strerror (errno));
+-      exit (1);
++      exit (127);
+     }
+ 
+   waitpid (pid, &status, 0);
diff --git a/SOURCES/glibc-rh2065588-11.patch b/SOURCES/glibc-rh2065588-11.patch
new file mode 100644
index 0000000..a1ef4a7
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-11.patch
@@ -0,0 +1,39 @@
+commit 5a5a3a3234bc220a5192d620e0cbc5360da46f14
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Tue Mar 24 15:40:36 2020 -0300
+
+    support/shell-container.c: Add builtin exit
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/support/shell-container.c b/support/shell-container.c
+index e9eea64bca7e949d..aeaf6d2733abce61 100644
+--- a/support/shell-container.c
++++ b/support/shell-container.c
+@@ -135,6 +135,18 @@ copy_func (char **argv)
+ 
+ }
+ 
++/* Emulate the 'exit' builtin.  The exit value is optional.  */
++static int
++exit_func (char **argv)
++{
++  int exit_val = 0;
++
++  if (argv[0] != 0)
++    exit_val = atoi (argv[0]) & 0xff;
++  exit (exit_val);
++  return 0;
++}
++
+ /* This is a list of all the built-in commands we understand.  */
+ static struct {
+   const char *name;
+@@ -143,6 +155,7 @@ static struct {
+   { "true", true_func },
+   { "echo", echo_func },
+   { "cp", copy_func },
++  { "exit", exit_func },
+   { NULL, NULL }
+ };
+ 
diff --git a/SOURCES/glibc-rh2065588-12.patch b/SOURCES/glibc-rh2065588-12.patch
new file mode 100644
index 0000000..7f4223f
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-12.patch
@@ -0,0 +1,60 @@
+commit 1c17100c43c0913ec94f3bcc966bf3792236c690
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Tue Mar 24 15:47:13 2020 -0300
+
+    support/shell-container.c: Add builtin kill
+    
+    No options supported.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+
+diff --git a/support/shell-container.c b/support/shell-container.c
+index aeaf6d2733abce61..3869e14683fb74dd 100644
+--- a/support/shell-container.c
++++ b/support/shell-container.c
+@@ -147,6 +147,25 @@ exit_func (char **argv)
+   return 0;
+ }
+ 
++/* Emulate the "/bin/kill" command.  Options are ignored.  */
++static int
++kill_func (char **argv)
++{
++  int signum = SIGTERM;
++  int i;
++
++  for (i = 0; argv[i]; i++)
++    {
++      pid_t pid;
++      if (strcmp (argv[i], "$$") == 0)
++	pid = getpid ();
++      else
++	pid = atoi (argv[i]);
++      kill (pid, signum);
++    }
++  return 0;
++}
++
+ /* This is a list of all the built-in commands we understand.  */
+ static struct {
+   const char *name;
+@@ -156,6 +175,7 @@ static struct {
+   { "echo", echo_func },
+   { "cp", copy_func },
+   { "exit", exit_func },
++  { "kill", kill_func },
+   { NULL, NULL }
+ };
+ 
+@@ -264,6 +284,11 @@ run_command_array (char **argv)
+       if (rv)
+ 	exit (rv);
+     }
++  else if (WIFSIGNALED (status))
++    {
++      int sig = WTERMSIG (status);
++      raise (sig);
++    }
+   else
+     exit (1);
+ }
diff --git a/SOURCES/glibc-rh2065588-13.patch b/SOURCES/glibc-rh2065588-13.patch
new file mode 100644
index 0000000..e4e9d70
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-13.patch
@@ -0,0 +1,66 @@
+commit 75fe6d1a1620d84e0e487868feba9b2c0f109610
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Wed May 12 10:13:41 2021 +0530
+
+    support: Close fds in copy_func
+    
+    copy_func may leave file descriptors open on error, so close them on
+    function exit.
+
+diff --git a/support/shell-container.c b/support/shell-container.c
+index 3869e14683fb74dd..f0a9814ae230d167 100644
+--- a/support/shell-container.c
++++ b/support/shell-container.c
+@@ -93,8 +93,9 @@ copy_func (char **argv)
+ {
+   char *sname = argv[0];
+   char *dname = argv[1];
+-  int sfd, dfd;
++  int sfd = -1, dfd = -1;
+   struct stat st;
++  int ret = 1;
+ 
+   sfd = open (sname, O_RDONLY);
+   if (sfd < 0)
+@@ -108,7 +109,7 @@ copy_func (char **argv)
+     {
+       fprintf (stderr, "cp: unable to fstat %s: %s\n",
+ 	       sname, strerror (errno));
+-      return 1;
++      goto out;
+     }
+ 
+   dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
+@@ -116,22 +117,26 @@ copy_func (char **argv)
+     {
+       fprintf (stderr, "cp: unable to open %s for writing: %s\n",
+ 	       dname, strerror (errno));
+-      return 1;
++      goto out;
+     }
+ 
+   if (support_copy_file_range (sfd, 0, dfd, 0, st.st_size, 0) != st.st_size)
+     {
+       fprintf (stderr, "cp: cannot copy file %s to %s: %s\n",
+ 	       sname, dname, strerror (errno));
+-      return 1;
++      goto out;
+     }
+ 
+-  close (sfd);
+-  close (dfd);
+-
++  ret = 0;
+   chmod (dname, st.st_mode & 0777);
+ 
+-  return 0;
++out:
++  if (sfd >= 0)
++    close (sfd);
++  if (dfd >= 0)
++    close (dfd);
++
++  return ret;
+ 
+ }
+ 
diff --git a/SOURCES/glibc-rh2065588-2.patch b/SOURCES/glibc-rh2065588-2.patch
new file mode 100644
index 0000000..c671cf9
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-2.patch
@@ -0,0 +1,231 @@
+commit 14d0e87d9b8caaa2eca7ca81f1189596671fe4fb
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Sep 12 10:32:05 2018 -0300
+
+    posix: Use posix_spawn on popen
+    
+    This patch uses posix_spawn on popen instead of fork and execl.  On Linux
+    this has the advantage of much lower memory consumption (usually 32 Kb
+    minimum for the mmap stack area).
+    
+    Two issues are also fixed with this change:
+    
+      * BZ#17490: although POSIX pthread_atfork description only list 'fork'
+        as the function that should execute the atfork handlers, popen
+        description states that:
+    
+          '[...] shall be *as if* a child process were created within the popen()
+           call using the fork() function [...]'
+    
+        Other libc/system seems to follow the idea atfork handlers should not be
+        executed for popen:
+    
+        libc/system | run atfork handles   | notes
+        ------------|----------------------|---------------------------------------
+        Freebsd     |        no            | uses vfork
+        Solaris 11  |        no            |
+        MacOSX 11   |        no            | implemented through posix_spawn syscall
+        ------------|----------------------|----------------------------------------
+    
+        Similar to posix_spawn and system, popen idea is to spawn a different
+        binary so all the POSIX rationale to run the atfork handlers to avoid
+        internal process inconsistency is not really required and in some cases
+        might be unsafe.
+    
+      * BZ#22834: the described scenario, where the forked process might access
+        invalid memory due an inconsistent state in multithreaded environment,
+        should not happen because posix_spawn does not access the affected
+        data structure (proc_file_chain).
+    
+    Checked on x86_64-linux-gnu and i686-linux-gnu.
+    
+            [BZ #22834]
+            [BZ #17490]
+            * NEWS: Add new semantic for atfork with popen and system.
+            * libio/iopopen.c (_IO_new_proc_open): use posix_spawn instead of
+            fork and execl.
+
+diff --git a/libio/iopopen.c b/libio/iopopen.c
+index 2eff45b4c80b5cd6..c768295180fdf809 100644
+--- a/libio/iopopen.c
++++ b/libio/iopopen.c
+@@ -34,7 +34,8 @@
+ #include <not-cancel.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+-#include <kernel-features.h>
++#include <spawn.h>
++#include <paths.h>
+ 
+ struct _IO_proc_file
+ {
+@@ -59,13 +60,60 @@ unlock (void *not_used)
+ }
+ #endif
+ 
++/* POSIX states popen shall ensure that any streams from previous popen()
++   calls that remain open in the parent process should be closed in the new
++   child process.
++   To avoid a race-condition between checking which file descriptors need to
++   be close (by transversing the proc_file_chain list) and the insertion of a
++   new one after a successful posix_spawn this function should be called
++   with proc_file_chain_lock acquired.  */
++static bool
++spawn_process (posix_spawn_file_actions_t *fa, FILE *fp, const char *command,
++	       int do_cloexec, int pipe_fds[2], int parent_end, int child_end,
++	       int child_pipe_fd)
++{
++
++  for (struct _IO_proc_file *p = proc_file_chain; p; p = p->next)
++    {
++      int fd = _IO_fileno ((FILE *) p);
++
++      /* If any stream from previous popen() calls has fileno
++	 child_pipe_fd, it has been already closed by the adddup2 action
++	 above.  */
++      if (fd != child_pipe_fd
++	  && __posix_spawn_file_actions_addclose (fa, fd) != 0)
++	return false;
++    }
++
++  if (__posix_spawn (&((_IO_proc_file *) fp)->pid, _PATH_BSHELL, fa, 0,
++		     (char *const[]){ (char*) "sh", (char*) "-c",
++		     (char *) command, NULL }, __environ) != 0)
++    return false;
++
++  __close_nocancel (pipe_fds[child_end]);
++
++  if (!do_cloexec)
++    /* Undo the effects of the pipe2 call which set the
++       close-on-exec flag.  */
++    __fcntl (pipe_fds[parent_end], F_SETFD, 0);
++
++  _IO_fileno (fp) = pipe_fds[parent_end];
++
++  ((_IO_proc_file *) fp)->next = proc_file_chain;
++  proc_file_chain = (_IO_proc_file *) fp;
++
++  return true;
++}
++
+ FILE *
+ _IO_new_proc_open (FILE *fp, const char *command, const char *mode)
+ {
+   int read_or_write;
++  /* These are indexes for pipe_fds.  */
+   int parent_end, child_end;
+   int pipe_fds[2];
+-  pid_t child_pid;
++  int child_pipe_fd;
++  bool spawn_ok;
+ 
+   int do_read = 0;
+   int do_write = 0;
+@@ -108,72 +156,62 @@ _IO_new_proc_open (FILE *fp, const char *command, const char *mode)
+ 
+   if (do_read)
+     {
+-      parent_end = pipe_fds[0];
+-      child_end = pipe_fds[1];
++      parent_end = 0;
++      child_end = 1;
+       read_or_write = _IO_NO_WRITES;
++      child_pipe_fd = 1;
+     }
+   else
+     {
+-      parent_end = pipe_fds[1];
+-      child_end = pipe_fds[0];
++      parent_end = 1;
++      child_end = 0;
+       read_or_write = _IO_NO_READS;
++      child_pipe_fd = 0;
+     }
+ 
+-  ((_IO_proc_file *) fp)->pid = child_pid = __fork ();
+-  if (child_pid == 0)
+-    {
+-      int child_std_end = do_read ? 1 : 0;
+-      struct _IO_proc_file *p;
+-
+-      if (child_end != child_std_end)
+-	__dup2 (child_end, child_std_end);
+-      else
+-	/* The descriptor is already the one we will use.  But it must
+-	   not be marked close-on-exec.  Undo the effects.  */
+-	__fcntl (child_end, F_SETFD, 0);
+-      /* POSIX.2:  "popen() shall ensure that any streams from previous
+-         popen() calls that remain open in the parent process are closed
+-	 in the new child process." */
+-      for (p = proc_file_chain; p; p = p->next)
+-	{
+-	  int fd = _IO_fileno ((FILE *) p);
++  posix_spawn_file_actions_t fa;
++  /* posix_spawn_file_actions_init does not fail.  */
++  __posix_spawn_file_actions_init (&fa);
+ 
+-	  /* If any stream from previous popen() calls has fileno
+-	     child_std_end, it has been already closed by the dup2 syscall
+-	     above.  */
+-	  if (fd != child_std_end)
+-	    __close_nocancel (fd);
+-	}
+-
+-      execl ("/bin/sh", "sh", "-c", command, (char *) 0);
+-      _exit (127);
+-    }
+-  __close_nocancel (child_end);
+-  if (child_pid < 0)
++  /* The descriptor is already the one the child will use.  In this case
++     it must be moved to another one otherwise, there is no safe way to
++     remove the close-on-exec flag in the child without creating a FD leak
++     race in the parent.  */
++  if (pipe_fds[child_end] == child_pipe_fd)
+     {
+-      __close_nocancel (parent_end);
+-      return NULL;
++      int tmp = __fcntl (child_pipe_fd, F_DUPFD_CLOEXEC, 0);
++      if (tmp < 0)
++	goto spawn_failure;
++      __close_nocancel (pipe_fds[child_end]);
++      pipe_fds[child_end] = tmp;
+     }
+ 
+-  if (!do_cloexec)
+-    /* Undo the effects of the pipe2 call which set the
+-       close-on-exec flag.  */
+-    __fcntl (parent_end, F_SETFD, 0);
++  if (__posix_spawn_file_actions_adddup2 (&fa, pipe_fds[child_end],
++      child_pipe_fd) != 0)
++    goto spawn_failure;
+ 
+-  _IO_fileno (fp) = parent_end;
+-
+-  /* Link into proc_file_chain. */
+ #ifdef _IO_MTSAFE_IO
+   _IO_cleanup_region_start_noarg (unlock);
+   _IO_lock_lock (proc_file_chain_lock);
+ #endif
+-  ((_IO_proc_file *) fp)->next = proc_file_chain;
+-  proc_file_chain = (_IO_proc_file *) fp;
++  spawn_ok = spawn_process (&fa, fp, command, do_cloexec, pipe_fds,
++			    parent_end, child_end, child_pipe_fd);
+ #ifdef _IO_MTSAFE_IO
+   _IO_lock_unlock (proc_file_chain_lock);
+   _IO_cleanup_region_end (0);
+ #endif
+ 
++  __posix_spawn_file_actions_destroy (&fa);
++
++  if (!spawn_ok)
++    {
++    spawn_failure:
++      __close_nocancel (pipe_fds[child_end]);
++      __close_nocancel (pipe_fds[parent_end]);
++      __set_errno (ENOMEM);
++      return NULL;
++    }
++
+   _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
+   return fp;
+ }
diff --git a/SOURCES/glibc-rh2065588-3.patch b/SOURCES/glibc-rh2065588-3.patch
new file mode 100644
index 0000000..d168d88
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-3.patch
@@ -0,0 +1,527 @@
+commit 5fb7fc96350575c9adb1316833e48ca11553be49
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Oct 24 16:29:38 2018 -0300
+
+    posix: Use posix_spawn on system
+    
+    This patch uses posix_spawn on system implementation.  On Linux this has
+    the advantage of much lower memory consumption (usually 32 Kb minimum for
+    the mmap stack area).
+    
+    Although POSIX does not require, glibc system implementation aims to be
+    thread and cancellation safe.  The cancellation code is moved to generic
+    implementation and enabled iff SIGCANCEL is defined (similar on how the
+    cancellation handler is enabled on nptl-init.c).
+    
+    Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
+    arm-linux-gnueabihf, and powerpc64le-linux-gnu.
+    
+            * sysdeps/unix/sysv/linux/spawni.c (__spawni_child): Use
+            __sigismember instead of sigismember.
+            * sysdeps/posix/system.c [SIGCANCEL] (cancel_handler_args,
+            cancel_handler): New definitions.
+            (CLEANUP_HANDLER, CLEANUP_RESET): Likewise.
+            (DO_LOCK, DO_UNLOCK, INIT_LOCK, ADD_REF, SUB_REF): Remove.
+            (do_system): Use posix_spawn instead of fork and execl and remove
+            reentracy code.
+            * sysdeps/generic/not-errno.h (__kill_noerrno): New prototype.
+            * sysdeps/unix/sysv/linux/not-errno.h (__kill_noerrno): Likewise.
+            * sysdeps/unix/sysv/linux/ia64/system.c: Remove file.
+            * sysdeps/unix/sysv/linux/s390/system.c: Likewise.
+            * sysdeps/unix/sysv/linux/sparc/system.c: Likewise.
+            * sysdeps/unix/sysv/linux/system.c: Likewise.
+
+diff --git a/sysdeps/generic/not-errno.h b/sysdeps/generic/not-errno.h
+index 93617a3266fd4aad..0fd66b5c5ed82315 100644
+--- a/sysdeps/generic/not-errno.h
++++ b/sysdeps/generic/not-errno.h
+@@ -17,3 +17,5 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ extern __typeof (__access) __access_noerrno attribute_hidden;
++
++extern __typeof (__kill) __kill_noerrno attribute_hidden;
+diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
+index d7594436ed59906f..8a51a6b9919ec39b 100644
+--- a/sysdeps/posix/system.c
++++ b/sysdeps/posix/system.c
+@@ -17,20 +17,36 @@
+ 
+ #include <errno.h>
+ #include <signal.h>
+-#include <stddef.h>
+ #include <stdlib.h>
+ #include <unistd.h>
++#include <sigsetops.h>
++#include <spawn.h>
++#include <pthread.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+-#include <libc-lock.h>
+-#include <sysdep-cancel.h>
+-#include <sigsetops.h>
++#include <stdio.h>
+ 
++#include <libc-lock.h>
++#include <not-errno.h>
++#include <not-cancel.h>
++#include <internal-signals.h>
+ 
+ #define	SHELL_PATH	"/bin/sh"	/* Path of the shell.  */
+ #define	SHELL_NAME	"sh"		/* Name to give it.  */
+ 
+ 
++/* This system implementation aims to be thread-safe, which requires to
++   restore the signal dispositions for SIGINT and SIGQUIT correctly and to
++   deal with cancellation by terminating the child process.
++
++   The signal disposition restoration on the single-thread case is
++   straighfoward.  For multithreaded case, a reference-counter with a lock
++   is used, so the first thread will set the SIGINT/SIGQUIT dispositions and
++   last thread will restore them.
++
++   Cancellation handling is done with thread cancellation clean-up handlers
++   on waitpid call.  */
++
+ #ifdef _LIBC_REENTRANT
+ static struct sigaction intr, quit;
+ static int sa_refcntr;
+@@ -50,17 +66,45 @@ __libc_lock_define_initialized (static, lock);
+ #endif
+ 
+ 
++#if defined(_LIBC_REENTRANT) && defined(SIGCANCEL)
++struct cancel_handler_args
++{
++  struct sigaction *quit;
++  struct sigaction *intr;
++  pid_t pid;
++};
++
++static void
++cancel_handler (void *arg)
++{
++  struct cancel_handler_args *args = (struct cancel_handler_args *) (arg);
++
++  __kill_noerrno (args->pid, SIGKILL);
++
++  TEMP_FAILURE_RETRY (__waitpid_nocancel (args->pid, NULL, 0));
++
++  DO_LOCK ();
++  if (SUB_REF () == 0)
++    {
++      __sigaction (SIGQUIT, args->quit, NULL);
++      __sigaction (SIGINT, args->intr, NULL);
++    }
++  DO_UNLOCK ();
++}
++#endif
++
+ /* Execute LINE as a shell command, returning its status.  */
+ static int
+ do_system (const char *line)
+ {
+-  int status, save;
++  int status;
+   pid_t pid;
+   struct sigaction sa;
+ #ifndef _LIBC_REENTRANT
+   struct sigaction intr, quit;
+ #endif
+   sigset_t omask;
++  sigset_t reset;
+ 
+   sa.sa_handler = SIG_IGN;
+   sa.sa_flags = 0;
+@@ -69,105 +113,72 @@ do_system (const char *line)
+   DO_LOCK ();
+   if (ADD_REF () == 0)
+     {
+-      if (__sigaction (SIGINT, &sa, &intr) < 0)
+-	{
+-	  (void) SUB_REF ();
+-	  goto out;
+-	}
+-      if (__sigaction (SIGQUIT, &sa, &quit) < 0)
+-	{
+-	  save = errno;
+-	  (void) SUB_REF ();
+-	  goto out_restore_sigint;
+-	}
++      /* sigaction can not fail with SIGINT/SIGQUIT used with SIG_IGN.  */
++      __sigaction (SIGINT, &sa, &intr);
++      __sigaction (SIGQUIT, &sa, &quit);
+     }
+   DO_UNLOCK ();
+ 
+-  /* We reuse the bitmap in the 'sa' structure.  */
+   __sigaddset (&sa.sa_mask, SIGCHLD);
+-  save = errno;
+-  if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
++  /* sigprocmask can not fail with SIG_BLOCK used with valid input
++     arguments.  */
++  __sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask);
++
++  __sigemptyset (&reset);
++  if (intr.sa_handler != SIG_IGN)
++    __sigaddset(&reset, SIGINT);
++  if (quit.sa_handler != SIG_IGN)
++    __sigaddset(&reset, SIGQUIT);
++
++  posix_spawnattr_t spawn_attr;
++  /* None of the posix_spawnattr_* function returns an error, including
++     posix_spawnattr_setflags for the follow specific usage (using valid
++     flags).  */
++  __posix_spawnattr_init (&spawn_attr);
++  __posix_spawnattr_setsigmask (&spawn_attr, &omask);
++  __posix_spawnattr_setsigdefault (&spawn_attr, &reset);
++  __posix_spawnattr_setflags (&spawn_attr,
++			      POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK);
++
++  status = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
++			  (char *const[]){ (char*) SHELL_NAME,
++					   (char*) "-c",
++					   (char *) line, NULL },
++			  __environ);
++  __posix_spawnattr_destroy (&spawn_attr);
++
++  if (status == 0)
+     {
+-#ifndef _LIBC
+-      if (errno == ENOSYS)
+-	__set_errno (save);
+-      else
+-#endif
+-	{
+-	  DO_LOCK ();
+-	  if (SUB_REF () == 0)
+-	    {
+-	      save = errno;
+-	      (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+-	    out_restore_sigint:
+-	      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+-	      __set_errno (save);
+-	    }
+-	out:
+-	  DO_UNLOCK ();
+-	  return -1;
+-	}
+-    }
+-
+-#ifdef CLEANUP_HANDLER
+-  CLEANUP_HANDLER;
+-#endif
+-
+-#ifdef FORK
+-  pid = FORK ();
+-#else
+-  pid = __fork ();
++      /* Cancellation results in cleanup handlers running as exceptions in
++	 the block where they were installed, so it is safe to reference
++	 stack variable allocate in the broader scope.  */
++#if defined(_LIBC_REENTRANT) && defined(SIGCANCEL)
++      struct cancel_handler_args cancel_args =
++      {
++	.quit = &quit,
++	.intr = &intr,
++	.pid = pid
++      };
++      __libc_cleanup_region_start (1, cancel_handler, &cancel_args);
+ #endif
+-  if (pid == (pid_t) 0)
+-    {
+-      /* Child side.  */
+-      const char *new_argv[4];
+-      new_argv[0] = SHELL_NAME;
+-      new_argv[1] = "-c";
+-      new_argv[2] = line;
+-      new_argv[3] = NULL;
+-
+-      /* Restore the signals.  */
+-      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+-      (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+-      (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
+-      INIT_LOCK ();
+-
+-      /* Exec the shell.  */
+-      (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
+-      _exit (127);
+-    }
+-  else if (pid < (pid_t) 0)
+-    /* The fork failed.  */
+-    status = -1;
+-  else
+-    /* Parent side.  */
+-    {
+       /* Note the system() is a cancellation point.  But since we call
+ 	 waitpid() which itself is a cancellation point we do not
+ 	 have to do anything here.  */
+       if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
+ 	status = -1;
+-    }
+-
+-#ifdef CLEANUP_HANDLER
+-  CLEANUP_RESET;
++#if defined(_LIBC_REENTRANT) && defined(SIGCANCEL)
++      __libc_cleanup_region_end (0);
+ #endif
++    }
+ 
+-  save = errno;
+   DO_LOCK ();
+-  if ((SUB_REF () == 0
+-       && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
+-	   | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
+-      || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
++  if (SUB_REF () == 0)
+     {
+-#ifndef _LIBC
+-      /* glibc cannot be used on systems without waitpid.  */
+-      if (errno == ENOSYS)
+-	__set_errno (save);
+-      else
+-#endif
+-	status = -1;
++      /* sigaction can not fail with SIGINT/SIGQUIT used with old
++	 disposition.  Same applies for sigprocmask.  */
++      __sigaction (SIGINT, &intr, NULL);
++      __sigaction (SIGQUIT, &quit, NULL);
++      __sigprocmask (SIG_SETMASK, &omask, NULL);
+     }
+   DO_UNLOCK ();
+ 
+diff --git a/sysdeps/unix/sysv/linux/ia64/system.c b/sysdeps/unix/sysv/linux/ia64/system.c
+deleted file mode 100644
+index d09fefefe64753ab..0000000000000000
+--- a/sysdeps/unix/sysv/linux/ia64/system.c
++++ /dev/null
+@@ -1,30 +0,0 @@
+-/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* We have to and actually can handle cancelable system().  The big
+-   problem: we have to kill the child process if necessary.  To do
+-   this a cleanup handler has to be registered and is has to be able
+-   to find the PID of the child.  The main problem is to reliable have
+-   the PID when needed.  It is not necessary for the parent thread to
+-   return.  It might still be in the kernel when the cancellation
+-   request comes.  Therefore we have to use the clone() calls ability
+-   to have the kernel write the PID into the user-level variable.  */
+-#define FORK() \
+-  INLINE_SYSCALL (clone2, 6, CLONE_PARENT_SETTID | SIGCHLD, NULL, 0, \
+-		  &pid, NULL, NULL)
+-
+-#include <sysdeps/unix/sysv/linux/system.c>
+diff --git a/sysdeps/unix/sysv/linux/not-errno.h b/sysdeps/unix/sysv/linux/not-errno.h
+index 106ba5c72e3d7dda..b2f72cfb3d412c56 100644
+--- a/sysdeps/unix/sysv/linux/not-errno.h
++++ b/sysdeps/unix/sysv/linux/not-errno.h
+@@ -16,6 +16,9 @@
+    License along with the GNU C Library; if not, see
+    <http://www.gnu.org/licenses/>.  */
+ 
++#include <sysdep.h>
++#include <fcntl.h>
++
+ /* This function is used on maybe_enable_malloc_check (elf/dl-tunables.c)
+    and to avoid having to build/use multiple versions if stack protection
+    in enabled it is defined as inline.  */
+@@ -33,3 +36,14 @@ __access_noerrno (const char *pathname, int mode)
+     return INTERNAL_SYSCALL_ERRNO (res, err);
+   return 0;
+ }
++
++static inline int
++__kill_noerrno (pid_t pid, int sig)
++{
++  int res;
++  INTERNAL_SYSCALL_DECL (err);
++  res = INTERNAL_SYSCALL_CALL (kill, err, pid, sig);
++  if (INTERNAL_SYSCALL_ERROR_P (res, err))
++    return INTERNAL_SYSCALL_ERRNO (res, err);
++  return 0;
++}
+diff --git a/sysdeps/unix/sysv/linux/s390/system.c b/sysdeps/unix/sysv/linux/s390/system.c
+deleted file mode 100644
+index d8ef46133419dd89..0000000000000000
+--- a/sysdeps/unix/sysv/linux/s390/system.c
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* We have to and actually can handle cancelable system().  The big
+-   problem: we have to kill the child process if necessary.  To do
+-   this a cleanup handler has to be registered and is has to be able
+-   to find the PID of the child.  The main problem is to reliable have
+-   the PID when needed.  It is not necessary for the parent thread to
+-   return.  It might still be in the kernel when the cancellation
+-   request comes.  Therefore we have to use the clone() calls ability
+-   to have the kernel write the PID into the user-level variable.  */
+-#define FORK() \
+-  INLINE_SYSCALL (clone, 3, 0, CLONE_PARENT_SETTID | SIGCHLD, &pid)
+-
+-#include "../system.c"
+diff --git a/sysdeps/unix/sysv/linux/sparc/system.c b/sysdeps/unix/sysv/linux/sparc/system.c
+deleted file mode 100644
+index 1f65c83399f920d6..0000000000000000
+--- a/sysdeps/unix/sysv/linux/sparc/system.c
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-/* We have to and actually can handle cancelable system().  The big
+-   problem: we have to kill the child process if necessary.  To do
+-   this a cleanup handler has to be registered and is has to be able
+-   to find the PID of the child.  The main problem is to reliable have
+-   the PID when needed.  It is not necessary for the parent thread to
+-   return.  It might still be in the kernel when the cancellation
+-   request comes.  Therefore we have to use the clone() calls ability
+-   to have the kernel write the PID into the user-level variable.  */
+-#define FORK() \
+-  INLINE_CLONE_SYSCALL (CLONE_PARENT_SETTID | SIGCHLD, 0, &pid, NULL, NULL)
+-
+-#include "../system.c"
+diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
+index 85239cedbf2a5ab5..6a8bd2ed2e1c29b7 100644
+--- a/sysdeps/unix/sysv/linux/spawni.c
++++ b/sysdeps/unix/sysv/linux/spawni.c
+@@ -138,11 +138,11 @@ __spawni_child (void *arguments)
+   for (int sig = 1; sig < _NSIG; ++sig)
+     {
+       if ((attr->__flags & POSIX_SPAWN_SETSIGDEF)
+-	  && sigismember (&attr->__sd, sig))
++	  && __sigismember (&attr->__sd, sig))
+ 	{
+ 	  sa.sa_handler = SIG_DFL;
+ 	}
+-      else if (sigismember (&hset, sig))
++      else if (__sigismember (&hset, sig))
+ 	{
+ 	  if (__is_internal_signal (sig))
+ 	    sa.sa_handler = SIG_IGN;
+diff --git a/sysdeps/unix/sysv/linux/system.c b/sysdeps/unix/sysv/linux/system.c
+deleted file mode 100644
+index 7cc68a1528ee8f99..0000000000000000
+--- a/sysdeps/unix/sysv/linux/system.c
++++ /dev/null
+@@ -1,76 +0,0 @@
+-/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, see
+-   <http://www.gnu.org/licenses/>.  */
+-
+-#include <sched.h>
+-#include <signal.h>
+-#include <string.h>	/* For the real memset prototype.  */
+-#include <sysdep.h>
+-#include <unistd.h>
+-#include <sys/wait.h>
+-#include <libc-lock.h>
+-
+-/* We have to and actually can handle cancelable system().  The big
+-   problem: we have to kill the child process if necessary.  To do
+-   this a cleanup handler has to be registered and is has to be able
+-   to find the PID of the child.  The main problem is to reliable have
+-   the PID when needed.  It is not necessary for the parent thread to
+-   return.  It might still be in the kernel when the cancellation
+-   request comes.  Therefore we have to use the clone() calls ability
+-   to have the kernel write the PID into the user-level variable.  */
+-#ifndef FORK
+-# define FORK() \
+-  INLINE_SYSCALL (clone, 3, CLONE_PARENT_SETTID | SIGCHLD, 0, &pid)
+-#endif
+-
+-#ifdef _LIBC_REENTRANT
+-static void cancel_handler (void *arg);
+-
+-# define CLEANUP_HANDLER \
+-  __libc_cleanup_region_start (1, cancel_handler, &pid)
+-
+-# define CLEANUP_RESET \
+-  __libc_cleanup_region_end (0)
+-#endif
+-
+-
+-/* Linux has waitpid(), so override the generic unix version.  */
+-#include <sysdeps/posix/system.c>
+-
+-
+-#ifdef _LIBC_REENTRANT
+-/* The cancellation handler.  */
+-static void
+-cancel_handler (void *arg)
+-{
+-  pid_t child = *(pid_t *) arg;
+-
+-  INTERNAL_SYSCALL_DECL (err);
+-  INTERNAL_SYSCALL (kill, err, 2, child, SIGKILL);
+-
+-  TEMP_FAILURE_RETRY (__waitpid (child, NULL, 0));
+-
+-  DO_LOCK ();
+-
+-  if (SUB_REF () == 0)
+-    {
+-      (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
+-      (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
+-    }
+-
+-  DO_UNLOCK ();
+-}
+-#endif
diff --git a/SOURCES/glibc-rh2065588-4.patch b/SOURCES/glibc-rh2065588-4.patch
new file mode 100644
index 0000000..33a0cce
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-4.patch
@@ -0,0 +1,194 @@
+commit f09542c584b121da0322fde4b55306d512b85d93
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Mon Mar 23 15:23:20 2020 -0300
+
+    posix: Fix system error return value [BZ #25715]
+    
+    It fixes 5fb7fc9635 when posix_spawn fails.
+    
+    Checked on x86_64-linux-gnu and i686-linux-gnu.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+
+diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
+index d14839f3ec3a7bad..b61bd347df7ec46a 100644
+--- a/stdlib/tst-system.c
++++ b/stdlib/tst-system.c
+@@ -17,14 +17,128 @@
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <signal.h>
++#include <paths.h>
+ 
++#include <support/capture_subprocess.h>
++#include <support/check.h>
++#include <support/temp_file.h>
++#include <support/support.h>
++
++static char *tmpdir;
++static long int namemax;
++
++static void
++do_prepare (int argc, char *argv[])
++{
++  tmpdir = support_create_temp_directory ("tst-system-");
++  /* Include the last '/0'.  */
++  namemax = pathconf (tmpdir, _PC_NAME_MAX) + 1;
++  TEST_VERIFY_EXIT (namemax != -1);
++}
++#define PREPARE do_prepare
++
++struct args
++{
++  const char *command;
++  int exit_status;
++  int term_sig;
++  const char *path;
++};
++
++static void
++call_system (void *closure)
++{
++  struct args *args = (struct args *) closure;
++  int ret;
++
++  if (args->path != NULL)
++    TEST_COMPARE (setenv ("PATH", args->path, 1), 0);
++  ret = system (args->command);
++  if (args->term_sig == 0)
++    {
++      /* Expect regular termination.  */
++      TEST_VERIFY (WIFEXITED (ret) != 0);
++      TEST_COMPARE (WEXITSTATUS (ret), args->exit_status);
++    }
++  else
++    {
++      /* status_or_signal < 0.  Expect termination by signal.  */
++      TEST_VERIFY (WIFSIGNALED (ret) != 0);
++      TEST_COMPARE (WTERMSIG (ret), args->term_sig);
++    }
++}
+ 
+ static int
+ do_test (void)
+ {
+-  return system (":");
+-}
++  TEST_VERIFY (system (NULL) != 0);
+ 
++  {
++    char cmd[namemax];
++    memset (cmd, 'a', sizeof(cmd));
++    cmd[sizeof(cmd) - 1] = '\0';
++
++    struct support_capture_subprocess result;
++    result = support_capture_subprocess (call_system,
++					 &(struct args) {
++					   cmd, 127, 0, tmpdir
++					 });
++    support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
++
++    char *returnerr = xasprintf ("%s: 1: %s: not found\n",
++				 basename(_PATH_BSHELL), cmd);
++    TEST_COMPARE_STRING (result.err.buffer, returnerr);
++    free (returnerr);
++  }
++
++  {
++    char cmd[namemax + 1];
++    memset (cmd, 'a', sizeof(cmd));
++    cmd[sizeof(cmd) - 1] = '\0';
++
++    struct support_capture_subprocess result;
++    result = support_capture_subprocess (call_system,
++					 &(struct args) {
++					   cmd, 127, 0, tmpdir
++					 });
++    support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
++
++    char *returnerr = xasprintf ("%s: 1: %s: File name too long\n",
++				 basename(_PATH_BSHELL), cmd);
++    TEST_COMPARE_STRING (result.err.buffer, returnerr);
++    free (returnerr);
++  }
++
++  {
++    struct support_capture_subprocess result;
++    result = support_capture_subprocess (call_system,
++					 &(struct args) {
++					   "kill -USR1 $$", 0, SIGUSR1
++					 });
++    support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
++  }
++
++  {
++    struct support_capture_subprocess result;
++    result = support_capture_subprocess (call_system,
++					 &(struct args) { "echo ...", 0 });
++    support_capture_subprocess_check (&result, "system", 0, sc_allow_stdout);
++    TEST_COMPARE_STRING (result.out.buffer, "...\n");
++  }
++
++  {
++    struct support_capture_subprocess result;
++    result = support_capture_subprocess (call_system,
++					 &(struct args) { "exit 1", 1 });
++    support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
++  }
++
++  TEST_COMPARE (system (":"), 0);
++
++  return 0;
++}
+ 
+-#define TEST_FUNCTION do_test ()
+-#include "../test-skeleton.c"
++#include <support/test-driver.c>
+diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
+index 8a51a6b9919ec39b..7db09a05c3fbca43 100644
+--- a/sysdeps/posix/system.c
++++ b/sysdeps/posix/system.c
+@@ -97,7 +97,8 @@ cancel_handler (void *arg)
+ static int
+ do_system (const char *line)
+ {
+-  int status;
++  int status = -1;
++  int ret;
+   pid_t pid;
+   struct sigaction sa;
+ #ifndef _LIBC_REENTRANT
+@@ -140,14 +141,14 @@ do_system (const char *line)
+   __posix_spawnattr_setflags (&spawn_attr,
+ 			      POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK);
+ 
+-  status = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
+-			  (char *const[]){ (char*) SHELL_NAME,
+-					   (char*) "-c",
+-					   (char *) line, NULL },
+-			  __environ);
++  ret = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
++		       (char *const[]){ (char *) SHELL_NAME,
++					(char *) "-c",
++					(char *) line, NULL },
++		       __environ);
+   __posix_spawnattr_destroy (&spawn_attr);
+ 
+-  if (status == 0)
++  if (ret == 0)
+     {
+       /* Cancellation results in cleanup handlers running as exceptions in
+ 	 the block where they were installed, so it is safe to reference
+@@ -182,6 +183,9 @@ do_system (const char *line)
+     }
+   DO_UNLOCK ();
+ 
++  if (ret != 0)
++    __set_errno (ret);
++
+   return status;
+ }
+ 
diff --git a/SOURCES/glibc-rh2065588-5.patch b/SOURCES/glibc-rh2065588-5.patch
new file mode 100644
index 0000000..368e759
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-5.patch
@@ -0,0 +1,64 @@
+commit 7a7226543611897103c7483bec160547294dcf0d
+Author: Alexandra Hájková <ahajkova@redhat.com>
+Date:   Sat Dec 26 20:44:34 2020 +0100
+
+     Add xfchmod to libsupport
+
+diff --git a/support/Makefile b/support/Makefile
+index d2b95539403e416c..4875f52495ef292d 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -91,6 +91,7 @@ libsupport-routines = \
+   xdlfcn \
+   xdlmopen \
+   xdup2 \
++  xfchmod \
+   xfclose \
+   xfopen \
+   xfork \
+diff --git a/support/xfchmod.c b/support/xfchmod.c
+new file mode 100644
+index 0000000000000000..4323b9ca8e078c98
+--- /dev/null
++++ b/support/xfchmod.c
+@@ -0,0 +1,28 @@
++/* fchmod with error checking.
++   Copyright (C) 2021 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <support/check.h>
++#include <support/xunistd.h>
++#include <sys/stat.h>
++
++void
++xfchmod (int fd, mode_t mode)
++{
++  if (fchmod (fd, mode) != 0)
++    FAIL_EXIT1 ("fchmod (%d, 0%o): %m", fd, mode);
++}
+diff --git a/support/xunistd.h b/support/xunistd.h
+index 74fd2771d12c36fe..ced8cb1dd9ee356c 100644
+--- a/support/xunistd.h
++++ b/support/xunistd.h
+@@ -45,6 +45,7 @@ long long xlseek (int fd, long long offset, int whence);
+ void xftruncate (int fd, long long length);
+ void xsymlink (const char *target, const char *linkpath);
+ void xchdir (const char *path);
++void xfchmod (int fd, mode_t mode);
+ 
+ /* Equivalent of "mkdir -p".  */
+ void xmkdirp (const char *, mode_t);
diff --git a/SOURCES/glibc-rh2065588-6.patch b/SOURCES/glibc-rh2065588-6.patch
new file mode 100644
index 0000000..16fdb47
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-6.patch
@@ -0,0 +1,56 @@
+commit 7b9c3260bcca73781dda6bc2ddee84869bedfb8c
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Mon Dec 14 11:42:33 2020 -0300
+
+    support: Add xchmod wrapper
+    
+    Checked on x86_64-linux-gnu.
+
+diff --git a/support/xchmod.c b/support/xchmod.c
+new file mode 100644
+index 0000000000000000..5e403c7cc2705aef
+--- /dev/null
++++ b/support/xchmod.c
+@@ -0,0 +1,30 @@
++/* chmod with error checking.
++   Copyright (C) 2020 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <https://www.gnu.org/licenses/>.  */
++
++#include <support/xunistd.h>
++#include <support/check.h>
++
++#include <sys/stat.h>
++
++void
++xchmod (const char *pathname, mode_t mode)
++{
++  int r = chmod (pathname, mode);
++  if (r < 0)
++    FAIL_EXIT1 ("chmod (%s, %d): %m", pathname, mode);
++}
+diff --git a/support/xunistd.h b/support/xunistd.h
+index ced8cb1dd9ee356c..e92056c65efe8d6a 100644
+--- a/support/xunistd.h
++++ b/support/xunistd.h
+@@ -46,6 +46,7 @@ void xftruncate (int fd, long long length);
+ void xsymlink (const char *target, const char *linkpath);
+ void xchdir (const char *path);
+ void xfchmod (int fd, mode_t mode);
++void xchmod (const char *pathname, mode_t mode);
+ 
+ /* Equivalent of "mkdir -p".  */
+ void xmkdirp (const char *, mode_t);
diff --git a/SOURCES/glibc-rh2065588-7.patch b/SOURCES/glibc-rh2065588-7.patch
new file mode 100644
index 0000000..b16b79e
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-7.patch
@@ -0,0 +1,73 @@
+commit 4eda036f5b897fa8bc20ddd2099b5a6ed4239dc9
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Tue Mar 24 15:48:34 2020 -0300
+
+    stdlib: Move tst-system to tests-container
+    
+    Fix some issues with different shell and error messages.
+    
+    Checked on x86_64-linux-gnu and i686-linux-gnu.
+
+diff --git a/stdlib/Makefile b/stdlib/Makefile
+index 01194bbf7cc96851..9d0edcf6a7749b28 100644
+--- a/stdlib/Makefile
++++ b/stdlib/Makefile
+@@ -70,7 +70,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
+ 		   test-canon test-canon2 tst-strtoll tst-environ	    \
+ 		   tst-xpg-basename tst-random tst-random2 tst-bsearch	    \
+ 		   tst-limits tst-rand48 bug-strtod tst-setcontext	    \
+-		   tst-setcontext2 test-a64l tst-qsort tst-system testmb2   \
++		   tst-setcontext2 test-a64l tst-qsort testmb2              \
+ 		   bug-strtod2 tst-atof1 tst-atof2 tst-strtod2		    \
+ 		   tst-rand48-2 tst-makecontext tst-strtod5		    \
+ 		   tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1    \
+@@ -92,6 +92,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
+ tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
+ 		   tst-tls-atexit tst-tls-atexit-nodelete
+ tests-static	:= tst-secure-getenv
++tests-container := tst-system
+ 
+ ifeq ($(build-hardcoded-path-in-tests),yes)
+ tests += tst-empty-env
+diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
+index b61bd347df7ec46a..194e09828dd5c206 100644
+--- a/stdlib/tst-system.c
++++ b/stdlib/tst-system.c
+@@ -88,7 +88,8 @@ do_test (void)
+ 					 });
+     support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
+ 
+-    char *returnerr = xasprintf ("%s: 1: %s: not found\n",
++    char *returnerr = xasprintf ("%s: execing %s failed: "
++				 "No such file or directory",
+ 				 basename(_PATH_BSHELL), cmd);
+     TEST_COMPARE_STRING (result.err.buffer, returnerr);
+     free (returnerr);
+@@ -106,7 +107,8 @@ do_test (void)
+ 					 });
+     support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
+ 
+-    char *returnerr = xasprintf ("%s: 1: %s: File name too long\n",
++    char *returnerr = xasprintf ("%s: execing %s failed: "
++				 "File name too long",
+ 				 basename(_PATH_BSHELL), cmd);
+     TEST_COMPARE_STRING (result.err.buffer, returnerr);
+     free (returnerr);
+@@ -116,7 +118,7 @@ do_test (void)
+     struct support_capture_subprocess result;
+     result = support_capture_subprocess (call_system,
+ 					 &(struct args) {
+-					   "kill -USR1 $$", 0, SIGUSR1
++					   "kill $$", 0, SIGTERM
+ 					 });
+     support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
+   }
+@@ -136,7 +138,7 @@ do_test (void)
+     support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
+   }
+ 
+-  TEST_COMPARE (system (":"), 0);
++  TEST_COMPARE (system (""), 0);
+ 
+   return 0;
+ }
diff --git a/SOURCES/glibc-rh2065588-8.patch b/SOURCES/glibc-rh2065588-8.patch
new file mode 100644
index 0000000..102b72a
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-8.patch
@@ -0,0 +1,74 @@
+commit 42dda89dcb0407f6799dbfd0b9dab1529666ad51
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Dec 11 15:23:05 2020 -0300
+
+    posix: Fix return value of system if shell can not be executed [BZ #27053]
+    
+    POSIX states that system returned code for failure to execute the shell
+    shall be as if the shell had terminated using _exit(127).  This
+    behaviour was removed with 5fb7fc96350575.
+    
+    Checked on x86_64-linux-gnu.
+
+diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
+index 194e09828dd5c206..8681584f15ef3b47 100644
+--- a/stdlib/tst-system.c
++++ b/stdlib/tst-system.c
+@@ -26,6 +26,7 @@
+ #include <support/check.h>
+ #include <support/temp_file.h>
+ #include <support/support.h>
++#include <support/xunistd.h>
+ 
+ static char *tmpdir;
+ static long int namemax;
+@@ -138,6 +139,22 @@ do_test (void)
+     support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
+   }
+ 
++  {
++    struct stat64 st;
++    xstat (_PATH_BSHELL, &st);
++    mode_t mode = st.st_mode;
++    xchmod (_PATH_BSHELL, mode & ~(S_IXUSR | S_IXGRP | S_IXOTH));
++
++    struct support_capture_subprocess result;
++    result = support_capture_subprocess (call_system,
++					 &(struct args) {
++					   "exit 1", 127, 0
++					 });
++    support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
++
++    xchmod (_PATH_BSHELL, st.st_mode);
++  }
++
+   TEST_COMPARE (system (""), 0);
+ 
+   return 0;
+diff --git a/support/Makefile b/support/Makefile
+index 4875f52495ef292d..09b41b0d57e9239a 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -86,6 +86,7 @@ libsupport-routines = \
+   xchroot \
+   xclone \
+   xclose \
++  xchmod \
+   xconnect \
+   xcopy_file_range \
+   xdlfcn \
+diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
+index 7db09a05c3fbca43..047ded4badfddcab 100644
+--- a/sysdeps/posix/system.c
++++ b/sysdeps/posix/system.c
+@@ -171,6 +171,10 @@ do_system (const char *line)
+       __libc_cleanup_region_end (0);
+ #endif
+     }
++  else
++   /* POSIX states that failure to execute the shell should return
++      as if the shell had terminated using _exit(127).  */
++   status = W_EXITCODE (127, 0);
+ 
+   DO_LOCK ();
+   if (SUB_REF () == 0)
diff --git a/SOURCES/glibc-rh2065588-9.patch b/SOURCES/glibc-rh2065588-9.patch
new file mode 100644
index 0000000..6d259d8
--- /dev/null
+++ b/SOURCES/glibc-rh2065588-9.patch
@@ -0,0 +1,21 @@
+commit 542160f0b6a7c26758c9575a8876f6624a5dd65f
+Author: Girish Joshi <girish946@gmail.com>
+Date:   Mon Mar 2 15:19:29 2020 -0500
+
+    Fixed typo in run_command_array() in support/shell-container.c
+    
+    https://sourceware.org/bugzilla/show_bug.cgi?id=23991
+
+diff --git a/support/shell-container.c b/support/shell-container.c
+index 9bd90d3f60529079..e87ac5cf1baa84e5 100644
+--- a/support/shell-container.c
++++ b/support/shell-container.c
+@@ -228,7 +228,7 @@ run_command_array (char **argv)
+       if (new_stderr != 2)
+ 	{
+ 	  dup2 (new_stderr, 2);
+-	  close (new_stdout);
++	  close (new_stderr);
+ 	}
+ 
+       if (builtin_func != NULL)
diff --git a/SOURCES/glibc-rh2072329.patch b/SOURCES/glibc-rh2072329.patch
new file mode 100644
index 0000000..e26331e
--- /dev/null
+++ b/SOURCES/glibc-rh2072329.patch
@@ -0,0 +1,86 @@
+commit 33e03f9cd2be4f2cd62f93fda539cc07d9c8130e
+Author: Joan Bruguera <joanbrugueram@gmail.com>
+Date:   Mon Apr 11 19:49:56 2022 +0200
+
+    misc: Fix rare fortify crash on wchar funcs. [BZ 29030]
+    
+    If `__glibc_objsize (__o) == (size_t) -1` (i.e. `__o` is unknown size), fortify
+    checks should pass, and `__whatever_alias` should be called.
+    
+    Previously, `__glibc_objsize (__o) == (size_t) -1` was explicitly checked, but
+    on commit a643f60c53876b, this was moved into `__glibc_safe_or_unknown_len`.
+    
+    A comment says the -1 case should work as: "The -1 check is redundant because
+    since it implies that __glibc_safe_len_cond is true.". But this fails when:
+    * `__s > 1`
+    * `__osz == -1` (i.e. unknown size at compile time)
+    * `__l` is big enough
+    * `__l * __s <= __osz` can be folded to a constant
+    (I only found this to be true for `mbsrtowcs` and other functions in wchar2.h)
+    
+    In this case `__l * __s <= __osz` is false, and `__whatever_chk_warn` will be
+    called by `__glibc_fortify` or `__glibc_fortify_n` and crash the program.
+    
+    This commit adds the explicit `__osz == -1` check again.
+    moc crashes on startup due to this, see: https://bugs.archlinux.org/task/74041
+    
+    Minimal test case (test.c):
+        #include <wchar.h>
+    
+        int main (void)
+        {
+            const char *hw = "HelloWorld";
+            mbsrtowcs (NULL, &hw, (size_t)-1, NULL);
+            return 0;
+        }
+    
+    Build with:
+        gcc -O2 -Wp,-D_FORTIFY_SOURCE=2 test.c -o test && ./test
+    
+    Output:
+        *** buffer overflow detected ***: terminated
+    
+    Fixes: BZ #29030
+    Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
+    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
+index 1668294e48b5c63c..701bffd1d664f289 100644
+--- a/debug/tst-fortify.c
++++ b/debug/tst-fortify.c
+@@ -1505,6 +1505,11 @@ do_test (void)
+       CHK_FAIL_END
+ #endif
+ 
++      /* Bug 29030 regresion check */
++      cp = "HelloWorld";
++      if (mbsrtowcs (NULL, &cp, (size_t)-1, &s) != 10)
++        FAIL ();
++
+       cp = "A";
+       if (mbstowcs (wenough, cp, 10) != 1
+ 	  || wcscmp (wenough, L"A") != 0)
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index a17ae0ed87e6163f..404496c7d6da4fb3 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -143,13 +143,13 @@
+    || (__builtin_constant_p (__l) && (__l) > 0))
+ 
+ /* Length is known to be safe at compile time if the __L * __S <= __OBJSZ
+-   condition can be folded to a constant and if it is true.  The -1 check is
+-   redundant because since it implies that __glibc_safe_len_cond is true.  */
++   condition can be folded to a constant and if it is true, or unknown (-1) */
+ #define __glibc_safe_or_unknown_len(__l, __s, __osz) \
+-  (__glibc_unsigned_or_positive (__l)					      \
+-   && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l),     \
+-						   __s, __osz))		      \
+-   && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
++  ((__osz) == (__SIZE_TYPE__) -1					      \
++   || (__glibc_unsigned_or_positive (__l)				      \
++       && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
++						       (__s), (__osz)))	      \
++       && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))))
+ 
+ /* Conversely, we know at compile time that the length is unsafe if the
+    __L * __S <= __OBJSZ condition can be folded to a constant and if it is
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index 450bf54..bef8a91 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -1,6 +1,6 @@
 %define glibcsrcdir glibc-2.28
 %define glibcversion 2.28
-%define glibcrelease 198%{?dist}
+%define glibcrelease 200%{?dist}
 # Pre-release tarballs are pulled in from git using a command that is
 # effectively:
 #
@@ -879,6 +879,20 @@ Patch684: glibc-rh2033684-12.patch
 Patch685: glibc-rh2063712.patch
 Patch686: glibc-rh2063042.patch
 Patch687: glibc-rh2071745.patch
+Patch688: glibc-rh2065588-1.patch
+Patch689: glibc-rh2065588-2.patch
+Patch690: glibc-rh2065588-3.patch
+Patch691: glibc-rh2065588-4.patch
+Patch692: glibc-rh2065588-5.patch
+Patch693: glibc-rh2065588-6.patch
+Patch694: glibc-rh2065588-7.patch
+Patch695: glibc-rh2065588-8.patch
+Patch696: glibc-rh2065588-9.patch
+Patch697: glibc-rh2065588-10.patch
+Patch698: glibc-rh2065588-11.patch
+Patch699: glibc-rh2065588-12.patch
+Patch700: glibc-rh2065588-13.patch
+Patch701: glibc-rh2072329.patch 
 
 # Intel Optimizations
 Patch1001: 0001-Backport-of-Add-NT_VMCOREDD-AT_MINSIGSTKSZ-from-Linu.patch
@@ -2719,9 +2733,15 @@ fi
 %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
 
 %changelog
-* Tue Apr 26 2022 Ali Erdinc Koroglu <aekoroglu@centosproject.org> - 2.28-198
+* Tue May 03 2022 Ali Erdinc Koroglu <aekoroglu@centosproject.org> - 2.28-200
 - Intel optimizations added
 
+* Tue Apr 26 2022 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-199
+- Fix fortify false positive with mbsrtowcs and mbsnrtowcs (#2072329).
+
+* Fri Apr 22 2022 Carlos O'Donell <carlos@redhat.com> - 2.28-198
+- Fix multi-threaded popen defect leading to segfault (#2065588) 
+
 * Tue Apr 05 2022 Arjun Shankar <arjun@redhat.com> - 2.28-197
 - timezone: Fix a test that causes occasional build failure (#2071745)