From afb275808bd091150fcdedcc4db08deca9dd6770 Mon Sep 17 00:00:00 2001
From: Peridot Bot <rockyautomation@rockylinux.org>
Date: Tue, 9 May 2023 06:33:46 +0000
Subject: [PATCH] import glibc-2.34-60.el9

---
 SOURCES/glibc-rh2117712-1.patch       | 154 +++++
 SOURCES/glibc-rh2117712-2.patch       |  45 ++
 SOURCES/glibc-rh2117712-3.patch       | 164 +++++
 SOURCES/glibc-rh2117712-4.patch       |  22 +
 SOURCES/glibc-rh2117712-5.patch       |  69 +++
 SOURCES/glibc-rh2117712-6.patch       |  35 ++
 SOURCES/glibc-rh2118666.patch         |  94 +++
 SOURCES/glibc-rh2128615-1.patch       |  37 ++
 SOURCES/glibc-rh2128615-2.patch       |  79 +++
 SOURCES/glibc-rh2128615-3.patch       |  90 +++
 SOURCES/glibc-rh2129005.patch         | 589 ++++++++++++++++++
 SOURCES/glibc-rh2149102.patch         |  19 +
 SOURCES/glibc-rh2162962.patch         | 306 +++++++++
 SOURCES/glibc-upstream-2.34-303.patch |  24 +
 SOURCES/glibc-upstream-2.34-304.patch |  54 ++
 SOURCES/glibc-upstream-2.34-305.patch |  85 +++
 SOURCES/glibc-upstream-2.34-306.patch |  54 ++
 SOURCES/glibc-upstream-2.34-307.patch |  30 +
 SOURCES/glibc-upstream-2.34-308.patch | 435 +++++++++++++
 SOURCES/glibc-upstream-2.34-309.patch | 212 +++++++
 SOURCES/glibc-upstream-2.34-310.patch | 334 ++++++++++
 SOURCES/glibc-upstream-2.34-311.patch | 414 +++++++++++++
 SOURCES/glibc-upstream-2.34-312.patch |  40 ++
 SOURCES/glibc-upstream-2.34-314.patch |  55 ++
 SOURCES/glibc-upstream-2.34-315.patch |  62 ++
 SOURCES/glibc-upstream-2.34-316.patch | 399 ++++++++++++
 SOURCES/glibc-upstream-2.34-317.patch | 289 +++++++++
 SOURCES/glibc-upstream-2.34-318.patch |  58 ++
 SOURCES/glibc-upstream-2.34-319.patch | 182 ++++++
 SOURCES/glibc-upstream-2.34-320.patch | 272 ++++++++
 SOURCES/glibc-upstream-2.34-321.patch | 532 ++++++++++++++++
 SOURCES/glibc-upstream-2.34-322.patch | 447 +++++++++++++
 SOURCES/glibc-upstream-2.34-323.patch | 507 +++++++++++++++
 SOURCES/glibc-upstream-2.34-324.patch | 311 ++++++++++
 SOURCES/glibc-upstream-2.34-325.patch | 565 +++++++++++++++++
 SOURCES/glibc-upstream-2.34-326.patch |  51 ++
 SOURCES/glibc-upstream-2.34-327.patch | 449 ++++++++++++++
 SOURCES/glibc-upstream-2.34-329.patch |  31 +
 SOURCES/glibc-upstream-2.34-330.patch |  33 +
 SOURCES/glibc-upstream-2.34-331.patch |  33 +
 SOURCES/glibc-upstream-2.34-332.patch |  46 ++
 SOURCES/glibc-upstream-2.34-333.patch |  66 ++
 SOURCES/glibc-upstream-2.34-334.patch |  38 ++
 SOURCES/glibc-upstream-2.34-335.patch |  68 ++
 SOURCES/glibc-upstream-2.34-336.patch | 209 +++++++
 SOURCES/glibc-upstream-2.34-337.patch |  26 +
 SOURCES/glibc-upstream-2.34-338.patch | 111 ++++
 SOURCES/glibc-upstream-2.34-339.patch |  55 ++
 SOURCES/glibc-upstream-2.34-340.patch |  62 ++
 SOURCES/glibc-upstream-2.34-341.patch |  51 ++
 SOURCES/glibc-upstream-2.34-342.patch |  61 ++
 SOURCES/glibc-upstream-2.34-343.patch |  56 ++
 SOURCES/glibc-upstream-2.34-344.patch |  78 +++
 SOURCES/glibc-upstream-2.34-345.patch |  46 ++
 SOURCES/glibc-upstream-2.34-346.patch |  55 ++
 SOURCES/glibc-upstream-2.34-347.patch |  38 ++
 SOURCES/glibc-upstream-2.34-348.patch |  47 ++
 SOURCES/glibc-upstream-2.34-349.patch |  92 +++
 SOURCES/glibc-upstream-2.34-350.patch | 861 ++++++++++++++++++++++++++
 SOURCES/glibc-upstream-2.34-351.patch | 107 ++++
 SOURCES/glibc-upstream-2.34-352.patch |  73 +++
 SOURCES/glibc-upstream-2.34-353.patch |  86 +++
 SOURCES/glibc-upstream-2.34-354.patch |  35 ++
 SOURCES/glibc-upstream-2.34-355.patch | 629 +++++++++++++++++++
 SOURCES/glibc-upstream-2.34-356.patch |  30 +
 SOURCES/glibc-upstream-2.34-357.patch | 203 ++++++
 SOURCES/glibc-upstream-2.34-358.patch |  25 +
 SOURCES/glibc-upstream-2.34-359.patch | 221 +++++++
 SOURCES/glibc-upstream-2.34-361.patch |  46 ++
 SOURCES/glibc-upstream-2.34-362.patch | 128 ++++
 SOURCES/glibc-upstream-2.34-363.patch |  26 +
 SOURCES/glibc-upstream-2.34-364.patch | 362 +++++++++++
 SOURCES/glibc-upstream-2.34-365.patch |  39 ++
 SOURCES/glibc-upstream-2.34-366.patch |  29 +
 SOURCES/glibc-upstream-2.34-367.patch |  72 +++
 SOURCES/glibc-upstream-2.34-368.patch | 241 +++++++
 SOURCES/glibc-upstream-2.34-369.patch |  73 +++
 SOURCES/glibc-upstream-2.34-370.patch |  38 ++
 SOURCES/glibc-upstream-2.34-371.patch |  24 +
 SOURCES/glibc-upstream-2.34-372.patch |  28 +
 SOURCES/glibc-upstream-2.34-373.patch | Bin 0 -> 6973 bytes
 SOURCES/glibc-upstream-2.34-374.patch | 526 ++++++++++++++++
 SOURCES/glibc-upstream-2.34-375.patch |  39 ++
 SOURCES/glibc-upstream-2.34-376.patch |  27 +
 SOURCES/glibc-upstream-2.34-377.patch |  34 +
 SOURCES/glibc-upstream-2.34-378.patch |  86 +++
 SOURCES/glibc-upstream-2.34-379.patch |  33 +
 SOURCES/glibc-upstream-2.34-380.patch | 176 ++++++
 SOURCES/glibc-upstream-2.34-381.patch |  28 +
 SOURCES/glibc-upstream-2.34-382.patch | 111 ++++
 SOURCES/glibc-upstream-2.34-383.patch |  43 ++
 SOURCES/glibc-upstream-2.34-384.patch |  83 +++
 SOURCES/glibc-upstream-2.34-385.patch |  48 ++
 SOURCES/glibc-upstream-2.34-386.patch | 127 ++++
 SOURCES/glibc-upstream-2.34-388.patch | 328 ++++++++++
 SOURCES/glibc-upstream-2.34-389.patch | 120 ++++
 SOURCES/wrap-find-debuginfo.sh        | 105 +++-
 SPECS/glibc.spec                      | 411 +++++++++++-
 98 files changed, 14513 insertions(+), 54 deletions(-)
 create mode 100644 SOURCES/glibc-rh2117712-1.patch
 create mode 100644 SOURCES/glibc-rh2117712-2.patch
 create mode 100644 SOURCES/glibc-rh2117712-3.patch
 create mode 100644 SOURCES/glibc-rh2117712-4.patch
 create mode 100644 SOURCES/glibc-rh2117712-5.patch
 create mode 100644 SOURCES/glibc-rh2117712-6.patch
 create mode 100644 SOURCES/glibc-rh2118666.patch
 create mode 100644 SOURCES/glibc-rh2128615-1.patch
 create mode 100644 SOURCES/glibc-rh2128615-2.patch
 create mode 100644 SOURCES/glibc-rh2128615-3.patch
 create mode 100644 SOURCES/glibc-rh2129005.patch
 create mode 100644 SOURCES/glibc-rh2149102.patch
 create mode 100644 SOURCES/glibc-rh2162962.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-303.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-304.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-305.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-306.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-307.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-308.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-309.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-310.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-311.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-312.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-314.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-315.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-316.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-317.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-318.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-319.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-320.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-321.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-322.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-323.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-324.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-325.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-326.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-327.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-329.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-330.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-331.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-332.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-333.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-334.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-335.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-336.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-337.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-338.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-339.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-340.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-341.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-342.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-343.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-344.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-345.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-346.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-347.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-348.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-349.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-350.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-351.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-352.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-353.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-354.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-355.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-356.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-357.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-358.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-359.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-361.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-362.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-363.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-364.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-365.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-366.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-367.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-368.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-369.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-370.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-371.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-372.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-373.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-374.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-375.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-376.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-377.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-378.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-379.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-380.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-381.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-382.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-383.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-384.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-385.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-386.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-388.patch
 create mode 100644 SOURCES/glibc-upstream-2.34-389.patch

diff --git a/SOURCES/glibc-rh2117712-1.patch b/SOURCES/glibc-rh2117712-1.patch
new file mode 100644
index 0000000..e154365
--- /dev/null
+++ b/SOURCES/glibc-rh2117712-1.patch
@@ -0,0 +1,154 @@
+commit cca9684f2d7a74fc0b28bfb1859955e0e28d7b4b
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Aug 3 11:41:53 2022 +0200
+
+    stdio: Clean up __libc_message after unconditional abort
+    
+    Since commit ec2c1fcefb200c6cb7e09553f3c6af8815013d83 ("malloc:
+    Abort on heap corruption, without a backtrace [BZ #21754]"),
+    __libc_message always terminates the process.  Since commit
+    a289ea09ea843ced6e5277c2f2e63c357bc7f9a3 ("Do not print backtraces
+    on fatal glibc errors"), the backtrace facility has been removed.
+    Therefore, remove enum __libc_message_action and the action
+    argument of __libc_message, and mark __libc_message as _No_return.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/debug/fortify_fail.c b/debug/fortify_fail.c
+index 9fa07af4867c2bd1..1b490d9da78b8d0d 100644
+--- a/debug/fortify_fail.c
++++ b/debug/fortify_fail.c
+@@ -21,8 +21,6 @@ void
+ __attribute__ ((noreturn))
+ __fortify_fail (const char *msg)
+ {
+-  /* The loop is added only to keep gcc happy.  */
+-  while (1)
+-    __libc_message (do_abort, "*** %s ***: terminated\n", msg);
++  __libc_message ("*** %s ***: terminated\n", msg);
+ }
+ libc_hidden_def (__fortify_fail)
+diff --git a/include/stdio.h b/include/stdio.h
+index 23b7fd288cdaba66..3d4544575318a934 100644
+--- a/include/stdio.h
++++ b/include/stdio.h
+@@ -143,18 +143,11 @@ extern int __gen_tempname (char *__tmpl, int __suffixlen, int __flags,
+ #  define __GT_DIR	1	/* create a directory */
+ #  define __GT_NOCREATE	2	/* just find a name not currently in use */
+ 
+-enum __libc_message_action
+-{
+-  do_message	= 0,		/* Print message.  */
+-  do_abort	= 1 << 0,	/* Abort.  */
+-};
+-
+ /* Print out MESSAGE (which should end with a newline) on the error output
+    and abort.  */
+ extern void __libc_fatal (const char *__message)
+      __attribute__ ((__noreturn__));
+-extern void __libc_message (enum __libc_message_action action,
+-			    const char *__fnt, ...) attribute_hidden;
++_Noreturn void __libc_message (const char *__fnt, ...) attribute_hidden;
+ extern void __fortify_fail (const char *msg) __attribute__ ((__noreturn__));
+ libc_hidden_proto (__fortify_fail)
+ 
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index d31e985ecce968fe..918e7936f1983437 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -298,8 +298,7 @@ _Noreturn static void
+ __malloc_assert (const char *assertion, const char *file, unsigned int line,
+ 		 const char *function)
+ {
+-  __libc_message (do_abort, "\
+-Fatal glibc error: malloc assertion failure in %s: %s\n",
++  __libc_message ("Fatal glibc error: malloc assertion failure in %s: %s\n",
+ 		  function, assertion);
+   __builtin_unreachable ();
+ }
+@@ -5528,7 +5527,7 @@ static void
+ malloc_printerr (const char *str)
+ {
+ #if IS_IN (libc)
+-  __libc_message (do_abort, "%s\n", str);
++  __libc_message ("%s\n", str);
+ #else
+   __libc_fatal (str);
+ #endif
+diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
+index 6d24bee6134856d1..1feacfbeba765035 100644
+--- a/sysdeps/posix/libc_fatal.c
++++ b/sysdeps/posix/libc_fatal.c
+@@ -54,7 +54,7 @@ struct str_list
+ 
+ /* Abort with an error message.  */
+ void
+-__libc_message (enum __libc_message_action action, const char *fmt, ...)
++__libc_message (const char *fmt, ...)
+ {
+   va_list ap;
+   int fd = -1;
+@@ -123,36 +123,31 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...)
+ 
+       WRITEV_FOR_FATAL (fd, iov, nlist, total);
+ 
+-      if ((action & do_abort))
++      total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
++      struct abort_msg_s *buf = __mmap (NULL, total,
++					PROT_READ | PROT_WRITE,
++					MAP_ANON | MAP_PRIVATE, -1, 0);
++      if (__glibc_likely (buf != MAP_FAILED))
+ 	{
+-	  total = ((total + 1 + GLRO(dl_pagesize) - 1)
+-		   & ~(GLRO(dl_pagesize) - 1));
+-	  struct abort_msg_s *buf = __mmap (NULL, total,
+-					    PROT_READ | PROT_WRITE,
+-					    MAP_ANON | MAP_PRIVATE, -1, 0);
+-	  if (__glibc_likely (buf != MAP_FAILED))
+-	    {
+-	      buf->size = total;
+-	      char *wp = buf->msg;
+-	      for (int cnt = 0; cnt < nlist; ++cnt)
+-		wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
+-	      *wp = '\0';
+-
+-	      /* We have to free the old buffer since the application might
+-		 catch the SIGABRT signal.  */
+-	      struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
+-							     buf);
+-	      if (old != NULL)
+-		__munmap (old, old->size);
+-	    }
++	  buf->size = total;
++	  char *wp = buf->msg;
++	  for (int cnt = 0; cnt < nlist; ++cnt)
++	    wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
++	  *wp = '\0';
++
++	  /* We have to free the old buffer since the application might
++	     catch the SIGABRT signal.  */
++	  struct abort_msg_s *old = atomic_exchange_acq (&__abort_msg,
++							 buf);
++	  if (old != NULL)
++	    __munmap (old, old->size);
+ 	}
+     }
+ 
+   va_end (ap);
+ 
+-  if ((action & do_abort))
+-    /* Kill the application.  */
+-    abort ();
++  /* Kill the application.  */
++  abort ();
+ }
+ 
+ 
+@@ -161,6 +156,6 @@ __libc_fatal (const char *message)
+ {
+   /* The loop is added only to keep gcc happy.  */
+   while (1)
+-    __libc_message (do_abort, "%s", message);
++    __libc_message ("%s", message);
+ }
+ libc_hidden_def (__libc_fatal)
diff --git a/SOURCES/glibc-rh2117712-2.patch b/SOURCES/glibc-rh2117712-2.patch
new file mode 100644
index 0000000..0a55182
--- /dev/null
+++ b/SOURCES/glibc-rh2117712-2.patch
@@ -0,0 +1,45 @@
+commit 68e036f27f31c3378201702e182246504fb00f87
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Aug 3 11:41:53 2022 +0200
+
+    nptl: Remove uses of assert_perror
+    
+    __pthread_sigmask cannot actually fail with valid pointer arguments
+    (it would need a really broken seccomp filter), and we do not check
+    for errors elsewhere.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/sysdeps/nptl/gai_misc.h b/sysdeps/nptl/gai_misc.h
+index 261e24dae62d7871..700fd5c46b4b7c82 100644
+--- a/sysdeps/nptl/gai_misc.h
++++ b/sysdeps/nptl/gai_misc.h
+@@ -81,9 +81,7 @@ __gai_start_notify_thread (void)
+ {
+   sigset_t ss;
+   sigemptyset (&ss);
+-  int sigerr __attribute__ ((unused));
+-  sigerr = __pthread_sigmask (SIG_SETMASK, &ss, NULL);
+-  assert_perror (sigerr);
++  (void) __pthread_sigmask (SIG_SETMASK, &ss, NULL);
+ }
+ 
+ extern inline int
+@@ -106,15 +104,12 @@ __gai_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
+   sigset_t ss;
+   sigset_t oss;
+   sigfillset (&ss);
+-  int sigerr __attribute__ ((unused));
+-  sigerr = __pthread_sigmask (SIG_SETMASK, &ss, &oss);
+-  assert_perror (sigerr);
++  (void) __pthread_sigmask (SIG_SETMASK, &ss, &oss);
+ 
+   int ret = __pthread_create (threadp, &attr, tf, arg);
+ 
+   /* Restore the signal mask.  */
+-  sigerr = __pthread_sigmask (SIG_SETMASK, &oss, NULL);
+-  assert_perror (sigerr);
++  (void) __pthread_sigmask (SIG_SETMASK, &oss, NULL);
+ 
+   (void) __pthread_attr_destroy (&attr);
+   return ret;
diff --git a/SOURCES/glibc-rh2117712-3.patch b/SOURCES/glibc-rh2117712-3.patch
new file mode 100644
index 0000000..e3cf26e
--- /dev/null
+++ b/SOURCES/glibc-rh2117712-3.patch
@@ -0,0 +1,164 @@
+commit 9001cb1102cddba54f0e84e147dfbb0356067356
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Aug 3 11:41:53 2022 +0200
+
+    assert: Do not use stderr in libc-internal assert
+    
+    Redirect internal assertion failures to __libc_assert_fail, based on
+    based on __libc_message, which writes directly to STDERR_FILENO
+    and calls abort.  Also disable message translation and reword the
+    error message slightly (adjusting stdlib/tst-bz20544 accordingly).
+    
+    As a result of these changes, malloc no longer needs its own
+    redefinition of __assert_fail.
+    
+    __libc_assert_fail needs to be stubbed out during rtld dependency
+    analysis because the rtld rebuilds turn __libc_assert_fail into
+    __assert_fail, which is unconditionally provided by elf/dl-minimal.c.
+    
+    This change is not possible for the public assert macro and its
+    __assert_fail function because POSIX requires that the diagnostic
+    is written to stderr.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/assert/Makefile b/assert/Makefile
+index 0008de34cb484a13..2bc9e2214e3e9a8b 100644
+--- a/assert/Makefile
++++ b/assert/Makefile
+@@ -24,7 +24,12 @@ include ../Makeconfig
+ 
+ headers	:= assert.h
+ 
+-routines := assert assert-perr __assert
++routines := \
++  __assert \
++  __libc_assert_fail \
++  assert \
++  assert-perr \
++  # routines
+ tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++
+ 
+ ifeq ($(have-cxx-thread_local),yes)
+diff --git a/assert/__libc_assert_fail.c b/assert/__libc_assert_fail.c
+new file mode 100644
+index 0000000000000000..149d5feae12f4af8
+--- /dev/null
++++ b/assert/__libc_assert_fail.c
+@@ -0,0 +1,33 @@
++/* libc-internal assert that calls __libc_message.
++   Copyright (C) 2022 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 <_itoa.h>
++#include <array_length.h>
++#include <intprops.h>
++#include <stdio.h>
++
++void
++__libc_assert_fail (const char *assertion, const char *file, unsigned int line,
++                    const char *function)
++{
++  char linebuf[INT_BUFSIZE_BOUND (unsigned int)];
++  array_end (linebuf)[-1] = '\0';
++  char *linestr = _itoa_word (line, array_end (linebuf) - 1, 10, 0);
++  __libc_message ("Fatal glibc error: %s:%s (%s): assertion failed: %s\n",
++                  file, linestr, function, assertion);
++}
+diff --git a/assert/assert.c b/assert/assert.c
+index 8a277dce008b3495..989126c7e5b6b265 100644
+--- a/assert/assert.c
++++ b/assert/assert.c
+@@ -101,4 +101,3 @@ __assert_fail (const char *assertion, const char *file, unsigned int line,
+   __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
+ 		      assertion, file, line, function);
+ }
+-hidden_def(__assert_fail)
+diff --git a/elf/Makefile b/elf/Makefile
+index 613d244e7781d479..2b547d5b58f1759b 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -1158,6 +1158,7 @@ $(objpfx)dl-allobjs.os: $(all-rtld-routines:%=$(objpfx)%.os)
+ rtld-stubbed-symbols = \
+   __GI___pthread_disable_asynccancel \
+   __GI___pthread_enable_asynccancel \
++  __libc_assert_fail \
+   __pthread_disable_asynccancel \
+   __pthread_enable_asynccancel \
+   calloc \
+diff --git a/include/assert.h b/include/assert.h
+index 61cc8aa22ff4b913..c812808f9b767964 100644
+--- a/include/assert.h
++++ b/include/assert.h
+@@ -20,8 +20,14 @@ extern void __assert_fail_base (const char *fmt, const char *assertion,
+ 				const char *function)
+      __THROW  __attribute__ ((__noreturn__)) attribute_hidden;
+ 
+-# if IS_IN (libc) || (IS_IN (rtld) && !defined NO_RTLD_HIDDEN)
+-hidden_proto (__assert_fail)
+-hidden_proto (__assert_perror_fail)
++rtld_hidden_proto (__assert_fail)
++rtld_hidden_proto (__assert_perror_fail)
++libc_hidden_proto (__assert_perror_fail)
++
++
++# if IS_IN (libc)
++/* Redirect to the internal version which does not use stderr.  */
++extern _Noreturn __typeof (__assert_fail) __libc_assert_fail attribute_hidden;
++#  define __assert_fail __libc_assert_fail
+ # endif
+ #endif
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 918e7936f1983437..2edb469d5dbf1203 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -289,22 +289,6 @@
+ #define MALLOC_DEBUG 0
+ #endif
+ 
+-#if IS_IN (libc)
+-#ifndef NDEBUG
+-# define __assert_fail(assertion, file, line, function)			\
+-	 __malloc_assert(assertion, file, line, function)
+-
+-_Noreturn static void
+-__malloc_assert (const char *assertion, const char *file, unsigned int line,
+-		 const char *function)
+-{
+-  __libc_message ("Fatal glibc error: malloc assertion failure in %s: %s\n",
+-		  function, assertion);
+-  __builtin_unreachable ();
+-}
+-#endif
+-#endif
+-
+ #if USE_TCACHE
+ /* We want 64 entries.  This is an arbitrary limit, which tunables can reduce.  */
+ # define TCACHE_MAX_BINS		64
+diff --git a/stdlib/tst-bz20544.c b/stdlib/tst-bz20544.c
+index 4aa5793b8994d1f6..1337a3952c30e517 100644
+--- a/stdlib/tst-bz20544.c
++++ b/stdlib/tst-bz20544.c
+@@ -78,7 +78,7 @@ test_bz20544_cxa_at_quick_exit (void *closure)
+ static void
+ test_one_fn (void (*test_fn) (void *))
+ {
+-  const char expected_error[] = "Assertion `func != NULL' failed.\n";
++  const char expected_error[] = "assertion failed: func != NULL\n";
+   struct support_capture_subprocess result;
+   result = support_capture_subprocess (test_fn, NULL);
+   support_capture_subprocess_check (&result, "bz20544", -SIGABRT,
diff --git a/SOURCES/glibc-rh2117712-4.patch b/SOURCES/glibc-rh2117712-4.patch
new file mode 100644
index 0000000..1d0a420
--- /dev/null
+++ b/SOURCES/glibc-rh2117712-4.patch
@@ -0,0 +1,22 @@
+commit 8fabe0e632bd441c760f878d1022c378f04f8497
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Aug 4 06:17:50 2022 +0200
+
+    Linux: Remove exit system call from _exit
+    
+    exit only terminates the current thread, not the whole process, so it
+    is the wrong fallback system call in this context.  All supported
+    Linux versions implement the exit_group system call anyway.
+
+diff --git a/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c
+index 2f0ec35459f25314..cd1270ac9b2b5b2b 100644
+--- a/sysdeps/unix/sysv/linux/_exit.c
++++ b/sysdeps/unix/sysv/linux/_exit.c
+@@ -28,7 +28,6 @@ _exit (int status)
+   while (1)
+     {
+       INLINE_SYSCALL (exit_group, 1, status);
+-      INLINE_SYSCALL (exit, 1, status);
+ 
+ #ifdef ABORT_INSTRUCTION
+       ABORT_INSTRUCTION;
diff --git a/SOURCES/glibc-rh2117712-5.patch b/SOURCES/glibc-rh2117712-5.patch
new file mode 100644
index 0000000..e147fa2
--- /dev/null
+++ b/SOURCES/glibc-rh2117712-5.patch
@@ -0,0 +1,69 @@
+Very limited backport of the following upstream commit, to obtain
+the definition of __getrandom_nocancel.
+
+commit 6f4e0fcfa2d2b0915816a3a3a1d48b4763a7dee2
+Author: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
+Date:   Thu Jul 21 10:04:59 2022 -0300
+
+    stdlib: Add arc4random, arc4random_buf, and arc4random_uniform (BZ #4417)
+
+With the INTERNAL_SYSCALL_CALL change from this patch already applied:
+
+commit 609c9d0951da387cd523b5db42a82d38dabc37c4
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Thu Sep 29 16:18:06 2022 -0300
+
+    malloc: Do not clobber errno on __getrandom_nocancel (BZ #29624)
+    
+    Use INTERNAL_SYSCALL_CALL instead of INLINE_SYSCALL_CALL.  This
+    requires emulate the semantic for hurd call (so __arc4random_buf
+    uses the fallback).
+    
+    Checked on x86_64-linux-gnu.
+    
+    Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
+
+diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h
+index 8a3772a1fe66271e..14188041c2c0ad57 100644
+--- a/sysdeps/generic/not-cancel.h
++++ b/sysdeps/generic/not-cancel.h
+@@ -49,5 +49,7 @@
+   (void) __writev (fd, iov, n)
+ #define __fcntl64_nocancel(fd, cmd, ...) \
+   __fcntl64 (fd, cmd, __VA_ARGS__)
++#define __getrandom_nocancel(buf, size, flags) \
++  __getrandom (buf, size, flags)
+ 
+ #endif /* NOT_CANCEL_H  */
+diff --git a/sysdeps/mach/hurd/not-cancel.h b/sysdeps/mach/hurd/not-cancel.h
+index cd320cb721e6ff7e..7a3d2cc3532cf866 100644
+--- a/sysdeps/mach/hurd/not-cancel.h
++++ b/sysdeps/mach/hurd/not-cancel.h
+@@ -75,6 +75,9 @@ __typeof (__fcntl) __fcntl_nocancel;
+ #define __fcntl64_nocancel(...) \
+   __fcntl_nocancel (__VA_ARGS__)
+ 
++#define __getrandom_nocancel(buf, size, flags) \
++  __getrandom (buf, size, flags)
++
+ #if IS_IN (libc)
+ hidden_proto (__close_nocancel)
+ hidden_proto (__close_nocancel_nostatus)
+diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h
+index f06d57426a40227e..d2bb59acddbcfee0 100644
+--- a/sysdeps/unix/sysv/linux/not-cancel.h
++++ b/sysdeps/unix/sysv/linux/not-cancel.h
+@@ -68,6 +68,13 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt)
+   INTERNAL_SYSCALL_CALL (writev, fd, iov, iovcnt);
+ }
+ 
++static inline int
++__getrandom_nocancel (void *buf, size_t buflen, unsigned int flags)
++{
++  return INTERNAL_SYSCALL_CALL (getrandom, buf, buflen, flags);
++}
++
++
+ /* Uncancelable fcntl.  */
+ __typeof (__fcntl) __fcntl64_nocancel;
+ 
diff --git a/SOURCES/glibc-rh2117712-6.patch b/SOURCES/glibc-rh2117712-6.patch
new file mode 100644
index 0000000..33766ff
--- /dev/null
+++ b/SOURCES/glibc-rh2117712-6.patch
@@ -0,0 +1,35 @@
+commit 7187efd0aa270c83c428ea6cd0e1cffc34b41a74
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Aug 1 15:49:07 2022 +0200
+
+    malloc: Use __getrandom_nocancel during tcache initiailization
+    
+    Cancellation currently cannot happen at this point because dlopen
+    as used by the unwind link always performs additional allocations
+    for libgcc_s.so.1, even if it has been loaded already as a dependency
+    of the main executable.  But it seems prudent not to rely on this
+    quirk.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/malloc/malloc.c b/malloc/malloc.c
+index 2edb469d5dbf1203..375f50f5db13e234 100644
+--- a/malloc/malloc.c
++++ b/malloc/malloc.c
+@@ -256,6 +256,7 @@
+ /* For tcache double-free check.  */
+ #include <random-bits.h>
+ #include <sys/random.h>
++#include <not-cancel.h>
+ 
+ /*
+   Debugging:
+@@ -3025,7 +3026,7 @@ static uintptr_t tcache_key;
+ static void
+ tcache_key_initialize (void)
+ {
+-  if (__getrandom (&tcache_key, sizeof(tcache_key), GRND_NONBLOCK)
++  if (__getrandom_nocancel (&tcache_key, sizeof(tcache_key), GRND_NONBLOCK)
+       != sizeof (tcache_key))
+     {
+       tcache_key = random_bits ();
diff --git a/SOURCES/glibc-rh2118666.patch b/SOURCES/glibc-rh2118666.patch
new file mode 100644
index 0000000..86750f6
--- /dev/null
+++ b/SOURCES/glibc-rh2118666.patch
@@ -0,0 +1,94 @@
+commit dd2315a866a4ac2b838ea1cb10c5ea1c35d51a2f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 16 08:27:50 2022 +0200
+
+    elf: Run tst-audit-tlsdesc, tst-audit-tlsdesc-dlopen everywhere
+    
+    The test is valid for all TLS models, but we want to make a reasonable
+    effort to test the GNU2 model specifically.  For example, aarch64
+    defaults to GNU2, but does not have -mtls-dialect=gnu2, and the test
+    was not run there.
+    
+    Suggested-by: Martin Coufal <mcoufal@redhat.com>
+
+Conflicts:
+	elf/Makefile
+	  (missing tst-align3 test downstream)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index ea1512549be3f628..613d244e7781d479 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -361,6 +361,8 @@ tests += \
+   tst-addr1 \
+   tst-align \
+   tst-align2 \
++  tst-audit-tlsdesc \
++  tst-audit-tlsdesc-dlopen \
+   tst-audit1 \
+   tst-audit2 \
+   tst-audit8 \
+@@ -679,6 +681,8 @@ modules-names = \
+   tst-alignmod2 \
+   tst-array2dep \
+   tst-array5dep \
++  tst-audit-tlsdesc-mod1 \
++  tst-audit-tlsdesc-mod2 \
+   tst-audit11mod1 \
+   tst-audit11mod2 \
+   tst-audit12mod1 \
+@@ -712,6 +716,7 @@ modules-names = \
+   tst-auditmanymod7 \
+   tst-auditmanymod8 \
+   tst-auditmanymod9 \
++  tst-auditmod-tlsdesc  \
+   tst-auditmod1 \
+   tst-auditmod9a \
+   tst-auditmod9b \
+@@ -889,23 +894,8 @@ modules-names += tst-gnu2-tls1mod
+ $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
+ tst-gnu2-tls1mod.so-no-z-defs = yes
+ CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
++endif # $(have-mtls-dialect-gnu2)
+ 
+-tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen
+-modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc
+-$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
+-			    $(objpfx)tst-audit-tlsdesc-mod2.so \
+-			    $(shared-thread-library)
+-CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
+-CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
+-$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
+-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
+-				       $(objpfx)tst-audit-tlsdesc-mod2.so
+-$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
+-$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
+-tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
+-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
+-tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
+-endif
+ ifeq (yes,$(have-protected-data))
+ modules-names += tst-protected1moda tst-protected1modb
+ tests += tst-protected1a tst-protected1b
+@@ -2656,3 +2646,21 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \
+ 	grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \
+ 	  && grep -q '^status: 127$$' $@; \
+ 	  $(evaluate-test)
++
++$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
++			    $(objpfx)tst-audit-tlsdesc-mod2.so \
++			    $(shared-thread-library)
++ifeq (yes,$(have-mtls-dialect-gnu2))
++# The test is valid for all TLS types, but we want to exercise GNU2
++# TLS if possible.
++CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
++CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
++endif
++$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
++$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
++				       $(objpfx)tst-audit-tlsdesc-mod2.so
++$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
++$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
++tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
++$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
++tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
diff --git a/SOURCES/glibc-rh2128615-1.patch b/SOURCES/glibc-rh2128615-1.patch
new file mode 100644
index 0000000..b4783d8
--- /dev/null
+++ b/SOURCES/glibc-rh2128615-1.patch
@@ -0,0 +1,37 @@
+commit 183d99737298bb3200f0610fdcd1c7549c8ed560
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Sep 6 07:38:10 2022 +0200
+
+    scripts/dso-ordering-test.py: Generate program run-time dependencies
+    
+    The main program needs to depend on all shared objects, even objects
+    that have link-time dependencies among shared objects.  Filtering
+    out shared objects that already have an link-time dependencies is not
+    necessary here; make will do this automatically.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
+index bde0406be9da14fc..4ffcff6136145ef1 100644
+--- a/scripts/dso-ordering-test.py
++++ b/scripts/dso-ordering-test.py
+@@ -707,13 +707,12 @@ def process_testcase(t):
+                 "\t$(compile.c) $(OUTPUT_OPTION)\n")
+         makefile.write (rule)
+ 
+-        not_depended_objs = find_objs_not_depended_on(test_descr)
+-        if not_depended_objs:
+-            depstr = ""
+-            for dep in not_depended_objs:
+-                depstr += (" $(objpfx)" + test_subdir + "/"
+-                           + test_name + "-" + dep + ".so")
+-            makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr))
++        # Ensure that all shared objects are built before running the
++        # test, whether there link-time dependencies or not.
++        depobjs = ["$(objpfx){}/{}-{}.so".format(test_subdir, test_name, dep)
++                   for dep in test_descr.objs]
++        makefile.write("$(objpfx){}.out: {}\n".format(
++            base_test_name, " ".join(depobjs)))
+ 
+         # Add main executable to test-srcs
+         makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name))
diff --git a/SOURCES/glibc-rh2128615-2.patch b/SOURCES/glibc-rh2128615-2.patch
new file mode 100644
index 0000000..2d8d4ac
--- /dev/null
+++ b/SOURCES/glibc-rh2128615-2.patch
@@ -0,0 +1,79 @@
+commit dbb75513f5cf9285c77c9e55777c5c35b653f890
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Sep 6 07:38:10 2022 +0200
+
+    elf: Rename _dl_sort_maps parameter from skip to force_first
+    
+    The new implementation will not be able to skip an arbitrary number
+    of objects.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
+index 72f4ff0e6eda3377..7c614bca5d8115c6 100644
+--- a/elf/dl-sort-maps.c
++++ b/elf/dl-sort-maps.c
+@@ -27,12 +27,12 @@
+    If FOR_FINI is true, this is called for finishing an object.  */
+ static void
+ _dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
+-			unsigned int skip, bool for_fini)
++			bool force_first, bool for_fini)
+ {
+   /* Allows caller to do the common optimization of skipping the first map,
+      usually the main binary.  */
+-  maps += skip;
+-  nmaps -= skip;
++  maps += force_first;
++  nmaps -= force_first;
+ 
+   /* A list of one element need not be sorted.  */
+   if (nmaps <= 1)
+@@ -182,7 +182,7 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
+ 
+ static void
+ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
+-		   unsigned int skip __attribute__ ((unused)), bool for_fini)
++		   bool force_first __attribute__ ((unused)), bool for_fini)
+ {
+   for (int i = nmaps - 1; i >= 0; i--)
+     maps[i]->l_visited = 0;
+@@ -286,7 +286,7 @@ _dl_sort_maps_init (void)
+ 
+ void
+ _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
+-	       unsigned int skip, bool for_fini)
++	       bool force_first, bool for_fini)
+ {
+   /* It can be tempting to use a static function pointer to store and call
+      the current selected sorting algorithm routine, but experimentation
+@@ -296,9 +296,9 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
+      input cases. A simple if-case with direct function calls appears to
+      be the fastest.  */
+   if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
+-    _dl_sort_maps_original (maps, nmaps, skip, for_fini);
++    _dl_sort_maps_original (maps, nmaps, force_first, for_fini);
+   else
+-    _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
++    _dl_sort_maps_dfs (maps, nmaps, force_first, for_fini);
+ }
+ 
+ #endif /* HAVE_TUNABLES.  */
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index 87ad2f3f4d89eb7d..8c0fe98f69a88f1e 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -1106,9 +1106,11 @@ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
+    initializer functions have completed.  */
+ extern void _dl_fini (void) attribute_hidden;
+ 
+-/* Sort array MAPS according to dependencies of the contained objects.  */
++/* Sort array MAPS according to dependencies of the contained objects.
++   If FORCE_FIRST, MAPS[0] keeps its place even if the dependencies
++   say otherwise.  */
+ extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
+-			   unsigned int skip, bool for_fini) attribute_hidden;
++			   bool force_first, bool for_fini) attribute_hidden;
+ 
+ /* The dynamic linker calls this function before and having changing
+    any shared object mappings.  The `r_state' member of `struct r_debug'
diff --git a/SOURCES/glibc-rh2128615-3.patch b/SOURCES/glibc-rh2128615-3.patch
new file mode 100644
index 0000000..bf8a9a4
--- /dev/null
+++ b/SOURCES/glibc-rh2128615-3.patch
@@ -0,0 +1,90 @@
+commit 1df71d32fe5f5905ffd5d100e5e9ca8ad6210891
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Sep 20 11:00:42 2022 +0200
+
+    elf: Implement force_first handling in _dl_sort_maps_dfs (bug 28937)
+    
+    The implementation in _dl_close_worker requires that the first
+    element of l_initfini is always this very map (“We are always the
+    zeroth entry, and since we don't include ourselves in the
+    dependency analysis start at 1.”).  Rather than fixing that
+    assumption, this commit adds an implementation of the force_first
+    argument to the new dependency sorting algorithm.  This also means
+    that the directly dlopen'ed shared object is always initialized last,
+    which is the least surprising behavior in the presence of cycles.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
+index 7c614bca5d8115c6..e8ef5e8b3588ab53 100644
+--- a/elf/dl-sort-maps.c
++++ b/elf/dl-sort-maps.c
+@@ -182,8 +182,9 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
+ 
+ static void
+ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
+-		   bool force_first __attribute__ ((unused)), bool for_fini)
++		   bool force_first, bool for_fini)
+ {
++  struct link_map *first_map = maps[0];
+   for (int i = nmaps - 1; i >= 0; i--)
+     maps[i]->l_visited = 0;
+ 
+@@ -208,14 +209,6 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
+      Adjusting the order so that maps[0] is last traversed naturally avoids
+      this problem.
+ 
+-     Further, the old "optimization" of skipping the main object at maps[0]
+-     from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
+-     no longer valid, since traversing along object dependency-links
+-     may "find" the main object even when it is not included in the initial
+-     order (e.g. a dlopen()'ed shared object can have circular dependencies
+-     linked back to itself). In such a case, traversing N-1 objects will
+-     create a N-object result, and raise problems.
+-
+      To summarize, just passing in the full list, and iterating from back
+      to front makes things much more straightforward.  */
+ 
+@@ -274,6 +267,27 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
+     }
+ 
+   memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
++
++  /* Skipping the first object at maps[0] is not valid in general,
++     since traversing along object dependency-links may "find" that
++     first object even when it is not included in the initial order
++     (e.g., a dlopen'ed shared object can have circular dependencies
++     linked back to itself).  In such a case, traversing N-1 objects
++     will create a N-object result, and raise problems.  Instead,
++     force the object back into first place after sorting.  This naive
++     approach may introduce further dependency ordering violations
++     compared to rotating the cycle until the first map is again in
++     the first position, but as there is a cycle, at least one
++     violation is already present.  */
++  if (force_first && maps[0] != first_map)
++    {
++      int i;
++      for (i = 0; maps[i] != first_map; ++i)
++	;
++      assert (i < nmaps);
++      memmove (&maps[1], maps, i * sizeof (maps[0]));
++      maps[0] = first_map;
++    }
+ }
+ 
+ void
+diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
+index 5f7f18ef270bc12d..4bf9052db16fb352 100644
+--- a/elf/dso-sort-tests-1.def
++++ b/elf/dso-sort-tests-1.def
+@@ -64,3 +64,10 @@ output: b>a>{}<a<b
+ tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
+ output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
+ output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
++
++# Test that even in the presence of dependency loops involving dlopen'ed
++# object, that object is initialized last (and not unloaded prematurely).
++# Final destructor order is indeterminate due to the cycle.
++tst-bz28937: {+a;+b;-b;+c;%c};a->a1;a->a2;a2->a;b->b1;c->a1;c=>a1
++output(glibc.rtld.dynamic_sort=1): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a<a2<c<a1
++output(glibc.rtld.dynamic_sort=2): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a2<a<c<a1
diff --git a/SOURCES/glibc-rh2129005.patch b/SOURCES/glibc-rh2129005.patch
new file mode 100644
index 0000000..10d7801
--- /dev/null
+++ b/SOURCES/glibc-rh2129005.patch
@@ -0,0 +1,589 @@
+commit 1d495912a746e2a1ffb780c9a81fd234ec2464e8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    nss_dns: Rewrite _nss_dns_gethostbyname4_r using current interfaces
+    
+    Introduce struct alloc_buffer to this function, and use it and
+    struct ns_rr_cursor in gaih_getanswer_slice.  Adjust gaih_getanswer
+    and gaih_getanswer_noaaaa accordingly.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index 1cb3be71f04d98eb..36789965c06757d0 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -101,13 +101,6 @@
+ #endif
+ #define MAXHOSTNAMELEN 256
+ 
+-/* We need this time later.  */
+-typedef union querybuf
+-{
+-  HEADER hdr;
+-  u_char buf[MAXPACKET];
+-} querybuf;
+-
+ /* For historic reasons, pointers to IP addresses are char *, so use a
+    single list type for addresses and host names.  */
+ #define DYNARRAY_STRUCT ptrlist
+@@ -126,18 +119,18 @@ static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
+ 				      char **hnamep, int *errnop,
+ 				      int *h_errnop, int32_t *ttlp);
+ 
+-static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
+-				       const querybuf *answer2, int anslen2,
+-				       const char *qname,
++static enum nss_status gaih_getanswer (unsigned char *packet1,
++				       size_t packet1len,
++				       unsigned char *packet2,
++				       size_t packet2len,
++				       struct alloc_buffer *abuf,
+ 				       struct gaih_addrtuple **pat,
+-				       char *buffer, size_t buflen,
+ 				       int *errnop, int *h_errnop,
+ 				       int32_t *ttlp);
+-static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1,
+-					      int anslen1,
+-					      const char *qname,
++static enum nss_status gaih_getanswer_noaaaa (unsigned char *packet,
++					      size_t packetlen,
++					      struct alloc_buffer *abuf,
+ 					      struct gaih_addrtuple **pat,
+-					      char *buffer, size_t buflen,
+ 					      int *errnop, int *h_errnop,
+ 					      int32_t *ttlp);
+ 
+@@ -409,17 +402,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+ 	name = cp;
+     }
+ 
+-  union
+-  {
+-    querybuf *buf;
+-    u_char *ptr;
+-  } host_buffer;
+-  querybuf *orig_host_buffer;
+-  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
++  unsigned char dns_packet_buffer[2048];
++  unsigned char *alt_dns_packet_buffer = dns_packet_buffer;
+   u_char *ans2p = NULL;
+   int nans2p = 0;
+   int resplen2 = 0;
+   int ans2p_malloced = 0;
++  struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen);
+ 
+ 
+   int olderr = errno;
+@@ -428,22 +417,21 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+   if ((ctx->resp->options & RES_NOAAAA) == 0)
+     {
+       n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
+-				host_buffer.buf->buf, 2048, &host_buffer.ptr,
+-				&ans2p, &nans2p, &resplen2, &ans2p_malloced);
++				dns_packet_buffer, sizeof (dns_packet_buffer),
++				&alt_dns_packet_buffer, &ans2p, &nans2p,
++				&resplen2, &ans2p_malloced);
+       if (n >= 0)
+-	status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
+-				 resplen2, name, pat, buffer, buflen,
+-				 errnop, herrnop, ttlp);
++	status = gaih_getanswer (alt_dns_packet_buffer, n, ans2p, resplen2,
++				 &abuf, pat, errnop, herrnop, ttlp);
+     }
+   else
+     {
+       n = __res_context_search (ctx, name, C_IN, T_A,
+-				host_buffer.buf->buf, 2048, NULL,
+-				NULL, NULL, NULL, NULL);
++				dns_packet_buffer, sizeof (dns_packet_buffer),
++				NULL, NULL, NULL, NULL, NULL);
+       if (n >= 0)
+-	status = gaih_getanswer_noaaaa (host_buffer.buf, n,
+-					name, pat, buffer, buflen,
+-					errnop, herrnop, ttlp);
++	status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n,
++					&abuf, pat, errnop, herrnop, ttlp);
+     }
+   if (n < 0)
+     {
+@@ -474,12 +462,20 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
+ 	__set_errno (olderr);
+     }
+ 
++  /* Implement the buffer resizing protocol.  */
++  if (alloc_buffer_has_failed (&abuf))
++    {
++      *errnop = ERANGE;
++      *herrnop = NETDB_INTERNAL;
++      status = NSS_STATUS_TRYAGAIN;
++    }
++
+   /* Check whether ans2p was separately allocated.  */
+   if (ans2p_malloced)
+     free (ans2p);
+ 
+-  if (host_buffer.buf != orig_host_buffer)
+-    free (host_buffer.buf);
++  if (alt_dns_packet_buffer != dns_packet_buffer)
++    free (alt_dns_packet_buffer);
+ 
+   __resolv_context_put (ctx);
+   return status;
+@@ -893,259 +889,152 @@ getanswer_ptr (unsigned char *packet, size_t packetlen,
+   return NSS_STATUS_TRYAGAIN;
+ }
+ 
++/* Parses DNS data found in PACKETLEN bytes at PACKET in struct
++   gaih_addrtuple address tuples.  The new address tuples are linked
++   from **TAILP, with backing store allocated from ABUF, and *TAILP is
++   updated to point where the next tuple pointer should be stored.  If
++   TTLP is not null, *TTLP is updated to reflect the minimum TTL.  If
++   STORE_CANON is true, the canonical name is stored as part of the
++   first address tuple being written.  */
+ static enum nss_status
+-gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
+-		      struct gaih_addrtuple ***patp,
+-		      char **bufferp, size_t *buflenp,
+-		      int *errnop, int *h_errnop, int32_t *ttlp, int *firstp)
++gaih_getanswer_slice (unsigned char *packet, size_t packetlen,
++		      struct alloc_buffer *abuf,
++		      struct gaih_addrtuple ***tailp,
++		      int *errnop, int *h_errnop, int32_t *ttlp,
++		      bool store_canon)
+ {
+-  char *buffer = *bufferp;
+-  size_t buflen = *buflenp;
+-
+-  struct gaih_addrtuple **pat = *patp;
+-  const HEADER *hp = &answer->hdr;
+-  int ancount = ntohs (hp->ancount);
+-  int qdcount = ntohs (hp->qdcount);
+-  const u_char *cp = answer->buf + HFIXEDSZ;
+-  const u_char *end_of_message = answer->buf + anslen;
+-  if (__glibc_unlikely (qdcount != 1))
+-    {
+-      *h_errnop = NO_RECOVERY;
+-      return NSS_STATUS_UNAVAIL;
+-    }
+-
+-  u_char packtmp[NS_MAXCDNAME];
+-  int n = __ns_name_unpack (answer->buf, end_of_message, cp,
+-			    packtmp, sizeof packtmp);
+-  /* We unpack the name to check it for validity.  But we do not need
+-     it later.  */
+-  if (n != -1 && __ns_name_ntop (packtmp, buffer, buflen) == -1)
+-    {
+-      if (__glibc_unlikely (errno == EMSGSIZE))
+-	{
+-	too_small:
+-	  *errnop = ERANGE;
+-	  *h_errnop = NETDB_INTERNAL;
+-	  return NSS_STATUS_TRYAGAIN;
+-	}
+-
+-      n = -1;
+-    }
+-
+-  if (__glibc_unlikely (n < 0))
+-    {
+-      *errnop = errno;
+-      *h_errnop = NO_RECOVERY;
+-      return NSS_STATUS_UNAVAIL;
+-    }
+-  if (__glibc_unlikely (__libc_res_hnok (buffer) == 0))
++  struct ns_rr_cursor c;
++  if (!__ns_rr_cursor_init (&c, packet, packetlen))
+     {
+-      errno = EBADMSG;
+-      *errnop = EBADMSG;
++      /* This should not happen because __res_context_query already
++	 perfroms response validation.  */
+       *h_errnop = NO_RECOVERY;
+       return NSS_STATUS_UNAVAIL;
+     }
+-  cp += n + QFIXEDSZ;
++  bool haveanswer = false; /* Set to true if at least one address.  */
++  uint16_t qtype = ns_rr_cursor_qtype (&c);
++  int ancount = ns_rr_cursor_ancount (&c);
++  const unsigned char *expected_name = ns_rr_cursor_qname (&c);
++  /* expected_name may be updated to point into this buffer.  */
++  unsigned char name_buffer[NS_MAXCDNAME];
+ 
+-  int haveanswer = 0;
+-  int had_error = 0;
+-  char *canon = NULL;
+-  char *h_name = NULL;
+-  int h_namelen = 0;
++  /* This is a pointer to a possibly-compressed name in the packet.
++     Eventually it is equivalent to the canonical name.  If needed, it
++     is uncompressed and translated to text form when the first
++     address tuple is encountered.  */
++  const unsigned char *compressed_alias_name = expected_name;
+ 
+-  if (ancount == 0)
++  if (ancount == 0 || !__res_binary_hnok (compressed_alias_name))
+     {
+       *h_errnop = HOST_NOT_FOUND;
+       return NSS_STATUS_NOTFOUND;
+     }
+ 
+-  while (ancount-- > 0 && cp < end_of_message && had_error == 0)
++  for (; ancount > -0; --ancount)
+     {
+-      n = __ns_name_unpack (answer->buf, end_of_message, cp,
+-			    packtmp, sizeof packtmp);
+-      if (n != -1 &&
+-	  (h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) == -1)
+-	{
+-	  if (__glibc_unlikely (errno == EMSGSIZE))
+-	    goto too_small;
+-
+-	  n = -1;
+-	}
+-      if (__glibc_unlikely (n < 0))
+-	{
+-	  ++had_error;
+-	  continue;
+-	}
+-      if (*firstp && canon == NULL && __libc_res_hnok (buffer))
+-	{
+-	  h_name = buffer;
+-	  buffer += h_namelen;
+-	  buflen -= h_namelen;
+-	}
+-
+-      cp += n;				/* name */
+-
+-      if (__glibc_unlikely (cp + 10 > end_of_message))
+-	{
+-	  ++had_error;
+-	  continue;
+-	}
+-
+-      uint16_t type;
+-      NS_GET16 (type, cp);
+-      uint16_t class;
+-      NS_GET16 (class, cp);
+-      int32_t ttl;
+-      NS_GET32 (ttl, cp);
+-      NS_GET16 (n, cp);		/* RDATA length.  */
+-
+-      if (end_of_message - cp < n)
++      struct ns_rr_wire rr;
++      if (!__ns_rr_cursor_next (&c, &rr))
+ 	{
+-	  /* RDATA extends beyond the end of the packet.  */
+-	  ++had_error;
+-	  continue;
++	  *h_errnop = NO_RECOVERY;
++	  return NSS_STATUS_UNAVAIL;
+ 	}
+ 
+-      if (class != C_IN)
+-	{
+-	  cp += n;
+-	  continue;
+-	}
++      /* Update TTL for known record types.  */
++      if ((rr.rtype == T_CNAME || rr.rtype == qtype)
++	  && ttlp != NULL && *ttlp > rr.ttl)
++	*ttlp = rr.ttl;
+ 
+-      if (type == T_CNAME)
++      if (rr.rtype == T_CNAME)
+ 	{
+-	  char tbuf[MAXDNAME];
+-
+-	  /* A CNAME could also have a TTL entry.  */
+-	  if (ttlp != NULL && ttl < *ttlp)
+-	      *ttlp = ttl;
+-
+-	  n = __libc_dn_expand (answer->buf, end_of_message, cp,
+-				tbuf, sizeof tbuf);
+-	  if (__glibc_unlikely (n < 0))
+-	    {
+-	      ++had_error;
+-	      continue;
+-	    }
+-	  cp += n;
+-
+-	  if (*firstp && __libc_res_hnok (tbuf))
++	  /* NB: No check for owner name match, based on historic
++	     precedent.  Record the CNAME target as the new expected
++	     name.  */
++	  int n = __ns_name_unpack (c.begin, c.end, rr.rdata,
++				    name_buffer, sizeof (name_buffer));
++	  if (n < 0)
+ 	    {
+-	      /* Reclaim buffer space.  */
+-	      if (h_name + h_namelen == buffer)
+-		{
+-		  buffer = h_name;
+-		  buflen += h_namelen;
+-		}
+-
+-	      n = strlen (tbuf) + 1;
+-	      if (__glibc_unlikely (n > buflen))
+-		goto too_small;
+-	      if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
+-		{
+-		  ++had_error;
+-		  continue;
+-		}
+-
+-	      canon = buffer;
+-	      buffer = __mempcpy (buffer, tbuf, n);
+-	      buflen -= n;
+-	      h_namelen = 0;
++	      *h_errnop = NO_RECOVERY;
++	      return NSS_STATUS_UNAVAIL;
+ 	    }
+-	  continue;
++	  expected_name = name_buffer;
++	  if (store_canon && __res_binary_hnok (name_buffer))
++	    /* This name can be used as a canonical name.  Do not
++	       translate to text form here to conserve buffer space.
++	       Point to the compressed name because name_buffer can be
++	       overwritten with an unusable name later.  */
++	    compressed_alias_name = rr.rdata;
+ 	}
+-
+-      /* Stop parsing if we encounter a record with incorrect RDATA
+-	 length.  */
+-      if (type == T_A || type == T_AAAA)
++      else if (rr.rtype == qtype
++	       && __ns_samebinaryname (rr.rname, expected_name)
++	       && rr.rdlength == rrtype_to_rdata_length (qtype))
+ 	{
+-	  if (n != rrtype_to_rdata_length (type))
++	  struct gaih_addrtuple *ntup
++	    = alloc_buffer_alloc (abuf, struct gaih_addrtuple);
++	  /* Delay error reporting to the callers (they implement the
++	     ERANGE buffer resizing handshake).  */
++	  if (ntup != NULL)
+ 	    {
+-	      ++had_error;
+-	      continue;
++	      ntup->next = NULL;
++	      if (store_canon && compressed_alias_name != NULL)
++		{
++		  /* This assumes that all the CNAME records come
++		     first.  Use MAXHOSTNAMELEN instead of
++		     NS_MAXCDNAME for additional length checking.
++		     However, these checks are not expected to fail
++		     because all size NS_MAXCDNAME names should into
++		     the hname buffer because no escaping is
++		     needed.  */
++		  char unsigned nbuf[NS_MAXCDNAME];
++		  char hname[MAXHOSTNAMELEN + 1];
++		  if (__ns_name_unpack (c.begin, c.end,
++					compressed_alias_name,
++					nbuf, sizeof (nbuf)) >= 0
++		      && __ns_name_ntop (nbuf, hname, sizeof (hname)) >= 0)
++		    /* Space checking is performed by the callers.  */
++		    ntup->name = alloc_buffer_copy_string (abuf, hname);
++		  store_canon = false;
++		}
++	      else
++		ntup->name = NULL;
++	      if (rr.rdlength == 4)
++		ntup->family = AF_INET;
++	      else
++		ntup->family = AF_INET6;
++	      memcpy (ntup->addr, rr.rdata, rr.rdlength);
++	      ntup->scopeid = 0;
++
++	      /* Link in the new tuple, and update the tail pointer to
++		 point to its next field.  */
++	      **tailp = ntup;
++	      *tailp = &ntup->next;
++
++	      haveanswer = true;
+ 	    }
+ 	}
+-      else
+-	{
+-	  /* Skip unknown records.  */
+-	  cp += n;
+-	  continue;
+-	}
+-
+-      assert (type == T_A || type == T_AAAA);
+-      if (*pat == NULL)
+-	{
+-	  uintptr_t pad = (-(uintptr_t) buffer
+-			   % __alignof__ (struct gaih_addrtuple));
+-	  buffer += pad;
+-	  buflen = buflen > pad ? buflen - pad : 0;
+-
+-	  if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple)))
+-	    goto too_small;
+-
+-	  *pat = (struct gaih_addrtuple *) buffer;
+-	  buffer += sizeof (struct gaih_addrtuple);
+-	  buflen -= sizeof (struct gaih_addrtuple);
+-	}
+-
+-      (*pat)->name = NULL;
+-      (*pat)->next = NULL;
+-
+-      if (*firstp)
+-	{
+-	  /* We compose a single hostent out of the entire chain of
+-	     entries, so the TTL of the hostent is essentially the lowest
+-	     TTL in the chain.  */
+-	  if (ttlp != NULL && ttl < *ttlp)
+-	    *ttlp = ttl;
+-
+-	  (*pat)->name = canon ?: h_name;
+-
+-	  *firstp = 0;
+-	}
+-
+-      (*pat)->family = type == T_A ? AF_INET : AF_INET6;
+-      memcpy ((*pat)->addr, cp, n);
+-      cp += n;
+-      (*pat)->scopeid = 0;
+-
+-      pat = &((*pat)->next);
+-
+-      haveanswer = 1;
+     }
+ 
+   if (haveanswer)
+     {
+-      *patp = pat;
+-      *bufferp = buffer;
+-      *buflenp = buflen;
+-
+       *h_errnop = NETDB_SUCCESS;
+       return NSS_STATUS_SUCCESS;
+     }
+-
+-  /* Special case here: if the resolver sent a result but it only
+-     contains a CNAME while we are looking for a T_A or T_AAAA record,
+-     we fail with NOTFOUND instead of TRYAGAIN.  */
+-  if (canon != NULL)
++  else
+     {
++      /* Special case here: if the resolver sent a result but it only
++	 contains a CNAME while we are looking for a T_A or T_AAAA
++	 record, we fail with NOTFOUND.  */
+       *h_errnop = HOST_NOT_FOUND;
+       return NSS_STATUS_NOTFOUND;
+     }
+-
+-  *h_errnop = NETDB_INTERNAL;
+-  return NSS_STATUS_TRYAGAIN;
+ }
+ 
+ 
+ static enum nss_status
+-gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
+-		int anslen2, const char *qname,
+-		struct gaih_addrtuple **pat, char *buffer, size_t buflen,
++gaih_getanswer (unsigned char *packet1, size_t packet1len,
++		unsigned char *packet2, size_t packet2len,
++		struct alloc_buffer *abuf, struct gaih_addrtuple **pat,
+ 		int *errnop, int *h_errnop, int32_t *ttlp)
+ {
+-  int first = 1;
+-
+   enum nss_status status = NSS_STATUS_NOTFOUND;
+ 
+   /* Combining the NSS status of two distinct queries requires some
+@@ -1157,7 +1046,10 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
+      between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
+      A recoverable TRYAGAIN is almost always due to buffer size issues
+      and returns ERANGE in errno and the caller is expected to retry
+-     with a larger buffer.
++     with a larger buffer.  (The caller, _nss_dns_gethostbyname4_r,
++     ignores the return status if it detects that the result buffer
++     has been exhausted and generates a TRYAGAIN failure with an
++     ERANGE code.)
+ 
+      Lastly, you may be tempted to make significant changes to the
+      conditions in this code to bring about symmetry between responses.
+@@ -1237,36 +1129,30 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
+ 	 is a recoverable error we now return TRYAGIN even if the first
+ 	 response was SUCCESS.  */
+ 
+-  if (anslen1 > 0)
+-    status = gaih_getanswer_slice(answer1, anslen1, qname,
+-				  &pat, &buffer, &buflen,
+-				  errnop, h_errnop, ttlp,
+-				  &first);
+-
+-  if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
+-       || (status == NSS_STATUS_TRYAGAIN
+-	   /* We want to look at the second answer in case of an
+-	      NSS_STATUS_TRYAGAIN only if the error is non-recoverable, i.e.
+-	      *h_errnop is NO_RECOVERY. If not, and if the failure was due to
+-	      an insufficient buffer (ERANGE), then we need to drop the results
+-	      and pass on the NSS_STATUS_TRYAGAIN to the caller so that it can
+-	      repeat the query with a larger buffer.  */
+-	   && (*errnop != ERANGE || *h_errnop == NO_RECOVERY)))
+-      && answer2 != NULL && anslen2 > 0)
++  if (packet1len > 0)
+     {
+-      enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
+-						     &pat, &buffer, &buflen,
+-						     errnop, h_errnop, ttlp,
+-						     &first);
++      status = gaih_getanswer_slice (packet1, packet1len,
++				     abuf, &pat, errnop, h_errnop, ttlp, true);
++      if (alloc_buffer_has_failed (abuf))
++	/* Do not try parsing the second packet if a larger result
++	   buffer is needed.  The caller implements the resizing
++	   protocol because *abuf has been exhausted.  */
++	return NSS_STATUS_TRYAGAIN; /* Ignored by the caller.  */
++    }
++
++  if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
++      && packet2 != NULL && packet2len > 0)
++    {
++      enum nss_status status2
++	= gaih_getanswer_slice (packet2, packet2len,
++				abuf, &pat, errnop, h_errnop, ttlp,
++				/* Success means that data with a
++				   canonical name has already been
++				   stored.  Do not store the name again.  */
++				status != NSS_STATUS_SUCCESS);
+       /* Use the second response status in some cases.  */
+       if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
+ 	status = status2;
+-      /* Do not return a truncated second response (unless it was
+-	 unavoidable e.g. unrecoverable TRYAGAIN).  */
+-      if (status == NSS_STATUS_SUCCESS
+-	  && (status2 == NSS_STATUS_TRYAGAIN
+-	      && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
+-	status = NSS_STATUS_TRYAGAIN;
+     }
+ 
+   return status;
+@@ -1274,18 +1160,13 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
+ 
+ /* Variant of gaih_getanswer without a second (AAAA) response.  */
+ static enum nss_status
+-gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname,
+-		       struct gaih_addrtuple **pat,
+-		       char *buffer, size_t buflen,
++gaih_getanswer_noaaaa (unsigned char *packet, size_t packetlen,
++		       struct alloc_buffer *abuf, struct gaih_addrtuple **pat,
+ 		       int *errnop, int *h_errnop, int32_t *ttlp)
+ {
+-  int first = 1;
+-
+   enum nss_status status = NSS_STATUS_NOTFOUND;
+-  if (anslen1 > 0)
+-    status = gaih_getanswer_slice (answer1, anslen1, qname,
+-				   &pat, &buffer, &buflen,
+-				   errnop, h_errnop, ttlp,
+-				   &first);
++  if (packetlen > 0)
++    status = gaih_getanswer_slice (packet, packetlen,
++				   abuf, &pat, errnop, h_errnop, ttlp, true);
+   return status;
+ }
diff --git a/SOURCES/glibc-rh2149102.patch b/SOURCES/glibc-rh2149102.patch
new file mode 100644
index 0000000..6516cc0
--- /dev/null
+++ b/SOURCES/glibc-rh2149102.patch
@@ -0,0 +1,19 @@
+commit b8c6166b1b75036ab3e4127a1c0aacf52ca93651
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Sep 6 19:43:37 2021 +0200
+
+    locale: Add missing second argument to _Static_assert in C-collate-seq.c
+
+diff --git a/locale/C-collate-seq.c b/locale/C-collate-seq.c
+index 4fb82cb8357936b6..40b17f4f90313144 100644
+--- a/locale/C-collate-seq.c
++++ b/locale/C-collate-seq.c
+@@ -55,7 +55,7 @@ static const char collseqmb[] =
+ 
+ /* This table must be 256 bytes in size. We index bytes into the
+    table to find the collation sequence.  */
+-_Static_assert (sizeof (collseqmb) == 256);
++_Static_assert (sizeof (collseqmb) == 256, "sizeof (collseqmb)");
+ 
+ static const uint32_t collseqwc[] =
+ {
diff --git a/SOURCES/glibc-rh2162962.patch b/SOURCES/glibc-rh2162962.patch
new file mode 100644
index 0000000..718d38c
--- /dev/null
+++ b/SOURCES/glibc-rh2162962.patch
@@ -0,0 +1,306 @@
+Maintain an explicit order of tunables, so that the tunable_list
+array and the tunable_id_t constant can remain consistent over time.
+
+Related to this upstream bug:
+
+  Internal tunables ABI depends on awk array iteration order
+  <https://sourceware.org/bugzilla/show_bug.cgi?id=30027>
+
+The new dl-tunables.list files are already on the sysdeps search
+path, which is why the existing Makeconfig rule picks them up.
+The files for RHEL 9.1z were created by applying the gen-tunables.awk
+part of this patch to RHEL 9.1.0 (glibc-2.34-40.el9_2.1, to be
+precise).  The sysdeps/unix/sysv/linux/**/dl-tunables.list files were
+created based on the generated error message during the RHEL 9.1.z
+build.
+
+Going forward, new tunables will have to be added manually to the end
+of those files.  Existing tunables should not be deleted.  For
+deletion, the script would have to be extended to be able to create
+gaps in the tunable_list array.
+
+diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
+index fa63e86d1a51fe61..c5445e95f9fc36e7 100644
+--- a/scripts/gen-tunables.awk
++++ b/scripts/gen-tunables.awk
+@@ -14,6 +14,7 @@ BEGIN {
+   top_ns=""
+   max_name_len=0
+   max_alias_len=0
++  tunable_order_count = 0
+ }
+ 
+ # Skip over blank lines and comments.
+@@ -83,6 +84,37 @@ $1 == "}" {
+   next
+ }
+ 
++$1 == "@order" {
++    if (top_ns != "") {
++	printf("%s:%d: error: invalid @order directive inside namespace %s\n",
++               FILENAME, FNR, top_ns) > "/dev/stderr"
++	exit 1
++    }
++    if (NF != 2) {
++	printf("%s:%d: error: invalid argument count in @order directive\n",
++               FILENAME, FNR) > "/dev/stderr"
++        exit 1
++    }
++    order_arg = $2
++    if (split(order_arg, indices, /\./) != 3) {
++	printf("%s:%d: error: invalid tunable syntax in @order directive\n",
++               FILENAME, FNR) > "/dev/stderr"
++        exit 1
++    }
++    t = indices[1]
++    n = indices[2]
++    m = indices[3]
++    if ((t, n, m) in tunable_order) {
++	printf("%s:%d: error: duplicate\"@order %s\"\n" \
++               FILENAME, FNR, order_arg) > "/dev/stderr"
++        exit 1
++    }
++    ++tunable_order_count
++    tunable_order[t,n,m] = tunable_order_count
++    tunable_order_list[tunable_order_count] = t SUBSEP n SUBSEP m
++    next
++}
++
+ # Everything else, which could either be a tunable without any attributes or a
+ # tunable attribute.
+ {
+@@ -145,6 +177,31 @@ END {
+     exit 1
+   }
+ 
++  missing_order = 0
++  for (tnm in types) {
++      if (!(tnm in tunable_order)) {
++	  if (!missing_order) {
++	      print "error: Missing @order directives:" > "/dev/stderr"
++	      missing_order = 1
++	  }
++	  split(tnm, indices, SUBSEP)
++	  printf("@order %s.%s.%s\n", indices[1], indices[2], indices[3]) \
++	      > "/dev/stderr"
++      }
++  }
++  for (i = 1; i <= tunable_order_count; ++i) {
++    tnm = tunable_order_list[i]
++    if (!(tnm in types)) {
++	split(tnm, indices, SUBSEP)
++	printf("error: tunable in \"@order %s.%s.%s\" not known\n", \
++	       indices[1], indices[2], indices[3]) > "/dev/stderr"
++	missing_order = 1
++    }
++  }
++  if (missing_order) {
++      exit 1
++  }
++
+   print "/* AUTOGENERATED by gen-tunables.awk.  */"
+   print "#ifndef _TUNABLES_H_"
+   print "# error \"Do not include this file directly.\""
+@@ -155,7 +212,8 @@ END {
+   # Now, the enum names
+   print "\ntypedef enum"
+   print "{"
+-  for (tnm in types) {
++  for (i = 1; i <= tunable_order_count; ++i) {
++    tnm = tunable_order_list[i]
+     split (tnm, indices, SUBSEP);
+     t = indices[1];
+     n = indices[2];
+@@ -171,7 +229,8 @@ END {
+   print "# include \"dl-tunable-types.h\""
+   # Finally, the tunable list.
+   print "static tunable_t tunable_list[] attribute_relro = {"
+-  for (tnm in types) {
++  for (i = 1; i <= tunable_order_count; ++i) {
++    tnm = tunable_order_list[i]
+     split (tnm, indices, SUBSEP);
+     t = indices[1];
+     n = indices[2];
+diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list
+new file mode 100644
+index 0000000000000000..d9d62499be4d67cb
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list
+@@ -0,0 +1,28 @@
++# Order of tunables in RHEL 9.1.z.
++@order glibc.rtld.nns
++@order glibc.elision.skip_lock_after_retries
++@order glibc.malloc.trim_threshold
++@order glibc.malloc.perturb
++@order glibc.pthread.rseq
++@order glibc.cpu.name
++@order glibc.mem.tagging
++@order glibc.elision.tries
++@order glibc.elision.enable
++@order glibc.malloc.mxfast
++@order glibc.rtld.dynamic_sort
++@order glibc.elision.skip_lock_busy
++@order glibc.malloc.top_pad
++@order glibc.pthread.stack_cache_size
++@order glibc.cpu.hwcap_mask
++@order glibc.malloc.mmap_max
++@order glibc.elision.skip_trylock_internal_abort
++@order glibc.malloc.tcache_unsorted_limit
++@order glibc.elision.skip_lock_internal_abort
++@order glibc.malloc.arena_max
++@order glibc.malloc.mmap_threshold
++@order glibc.malloc.tcache_count
++@order glibc.malloc.arena_test
++@order glibc.pthread.mutex_spin_count
++@order glibc.rtld.optional_static_tls
++@order glibc.malloc.tcache_max
++@order glibc.malloc.check
+diff --git a/sysdeps/unix/sysv/linux/i386/dl-tunables.list b/sysdeps/unix/sysv/linux/i386/dl-tunables.list
+new file mode 100644
+index 0000000000000000..e83962ec3af11691
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/i386/dl-tunables.list
+@@ -0,0 +1,35 @@
++# Order of tunables in RHEL 9.1.z.
++@order glibc.rtld.nns
++@order glibc.elision.skip_lock_after_retries
++@order glibc.malloc.trim_threshold
++@order glibc.malloc.perturb
++@order glibc.cpu.x86_shared_cache_size
++@order glibc.pthread.rseq
++@order glibc.mem.tagging
++@order glibc.elision.tries
++@order glibc.elision.enable
++@order glibc.cpu.x86_rep_movsb_threshold
++@order glibc.malloc.mxfast
++@order glibc.rtld.dynamic_sort
++@order glibc.elision.skip_lock_busy
++@order glibc.malloc.top_pad
++@order glibc.cpu.x86_rep_stosb_threshold
++@order glibc.cpu.x86_non_temporal_threshold
++@order glibc.cpu.x86_shstk
++@order glibc.pthread.stack_cache_size
++@order glibc.cpu.hwcap_mask
++@order glibc.malloc.mmap_max
++@order glibc.elision.skip_trylock_internal_abort
++@order glibc.malloc.tcache_unsorted_limit
++@order glibc.cpu.x86_ibt
++@order glibc.cpu.hwcaps
++@order glibc.elision.skip_lock_internal_abort
++@order glibc.malloc.arena_max
++@order glibc.malloc.mmap_threshold
++@order glibc.cpu.x86_data_cache_size
++@order glibc.malloc.tcache_count
++@order glibc.malloc.arena_test
++@order glibc.pthread.mutex_spin_count
++@order glibc.rtld.optional_static_tls
++@order glibc.malloc.tcache_max
++@order glibc.malloc.check
+diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list
+new file mode 100644
+index 0000000000000000..8f01840ef57874e7
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list
+@@ -0,0 +1,28 @@
++# Order of tunables in RHEL 9.1.z.
++@order glibc.rtld.nns
++@order glibc.elision.skip_lock_after_retries
++@order glibc.malloc.trim_threshold
++@order glibc.malloc.perturb
++@order glibc.pthread.rseq
++@order glibc.mem.tagging
++@order glibc.elision.tries
++@order glibc.elision.enable
++@order glibc.malloc.mxfast
++@order glibc.rtld.dynamic_sort
++@order glibc.elision.skip_lock_busy
++@order glibc.malloc.top_pad
++@order glibc.pthread.stack_cache_size
++@order glibc.cpu.hwcap_mask
++@order glibc.malloc.mmap_max
++@order glibc.elision.skip_trylock_internal_abort
++@order glibc.malloc.tcache_unsorted_limit
++@order glibc.elision.skip_lock_internal_abort
++@order glibc.malloc.arena_max
++@order glibc.malloc.mmap_threshold
++@order glibc.cpu.cached_memopt
++@order glibc.malloc.tcache_count
++@order glibc.malloc.arena_test
++@order glibc.pthread.mutex_spin_count
++@order glibc.rtld.optional_static_tls
++@order glibc.malloc.tcache_max
++@order glibc.malloc.check
+diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list
+new file mode 100644
+index 0000000000000000..c3bc83f33910af22
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list
+@@ -0,0 +1,27 @@
++# Order of tunables in RHEL 9.1.z.
++@order glibc.rtld.nns
++@order glibc.elision.skip_lock_after_retries
++@order glibc.malloc.trim_threshold
++@order glibc.malloc.perturb
++@order glibc.pthread.rseq
++@order glibc.mem.tagging
++@order glibc.elision.tries
++@order glibc.elision.enable
++@order glibc.malloc.mxfast
++@order glibc.rtld.dynamic_sort
++@order glibc.elision.skip_lock_busy
++@order glibc.malloc.top_pad
++@order glibc.pthread.stack_cache_size
++@order glibc.cpu.hwcap_mask
++@order glibc.malloc.mmap_max
++@order glibc.elision.skip_trylock_internal_abort
++@order glibc.malloc.tcache_unsorted_limit
++@order glibc.elision.skip_lock_internal_abort
++@order glibc.malloc.arena_max
++@order glibc.malloc.mmap_threshold
++@order glibc.malloc.tcache_count
++@order glibc.malloc.arena_test
++@order glibc.pthread.mutex_spin_count
++@order glibc.rtld.optional_static_tls
++@order glibc.malloc.tcache_max
++@order glibc.malloc.check
+diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
+new file mode 100644
+index 0000000000000000..e83962ec3af11691
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list
+@@ -0,0 +1,35 @@
++# Order of tunables in RHEL 9.1.z.
++@order glibc.rtld.nns
++@order glibc.elision.skip_lock_after_retries
++@order glibc.malloc.trim_threshold
++@order glibc.malloc.perturb
++@order glibc.cpu.x86_shared_cache_size
++@order glibc.pthread.rseq
++@order glibc.mem.tagging
++@order glibc.elision.tries
++@order glibc.elision.enable
++@order glibc.cpu.x86_rep_movsb_threshold
++@order glibc.malloc.mxfast
++@order glibc.rtld.dynamic_sort
++@order glibc.elision.skip_lock_busy
++@order glibc.malloc.top_pad
++@order glibc.cpu.x86_rep_stosb_threshold
++@order glibc.cpu.x86_non_temporal_threshold
++@order glibc.cpu.x86_shstk
++@order glibc.pthread.stack_cache_size
++@order glibc.cpu.hwcap_mask
++@order glibc.malloc.mmap_max
++@order glibc.elision.skip_trylock_internal_abort
++@order glibc.malloc.tcache_unsorted_limit
++@order glibc.cpu.x86_ibt
++@order glibc.cpu.hwcaps
++@order glibc.elision.skip_lock_internal_abort
++@order glibc.malloc.arena_max
++@order glibc.malloc.mmap_threshold
++@order glibc.cpu.x86_data_cache_size
++@order glibc.malloc.tcache_count
++@order glibc.malloc.arena_test
++@order glibc.pthread.mutex_spin_count
++@order glibc.rtld.optional_static_tls
++@order glibc.malloc.tcache_max
++@order glibc.malloc.check
diff --git a/SOURCES/glibc-upstream-2.34-303.patch b/SOURCES/glibc-upstream-2.34-303.patch
new file mode 100644
index 0000000..d7c929f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-303.patch
@@ -0,0 +1,24 @@
+commit 875b2414cd68df64aeead651a9b05ae9bc3d88ef
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Thu Aug 4 17:54:48 2022 +0200
+
+    dlfcn: Pass caller pointer to static dlopen implementation (bug 29446)
+    
+    Fixes commit 0c1c3a771eceec46e66ce1183cf988e2303bd373 ("dlfcn: Move
+    dlopen into libc").
+    
+    (cherry picked from commit ed0185e4129130cbe081c221efb758fb400623ce)
+
+diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
+index 9c59c751c4eaf7a7..739d17baafe928cc 100644
+--- a/dlfcn/dlopen.c
++++ b/dlfcn/dlopen.c
+@@ -90,7 +90,7 @@ compat_symbol (libdl, ___dlopen, dlopen, GLIBC_2_1);
+ void *
+ __dlopen (const char *file, int mode, void *dl_caller)
+ {
+-  return dlopen_implementation (file, mode, RETURN_ADDRESS (0));
++  return dlopen_implementation (file, mode, dl_caller);
+ }
+ 
+ void *
diff --git a/SOURCES/glibc-upstream-2.34-304.patch b/SOURCES/glibc-upstream-2.34-304.patch
new file mode 100644
index 0000000..f67a835
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-304.patch
@@ -0,0 +1,54 @@
+commit 4ab59ce4e5195f98b01748127248fed2b2b77b21
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Tue Aug 2 21:05:07 2022 +0000
+
+    Update syscall lists for Linux 5.19
+    
+    Linux 5.19 has no new syscalls, but enables memfd_secret in the uapi
+    headers for RISC-V.  Update the version number in syscall-names.list
+    to reflect that it is still current for 5.19 and regenerate the
+    arch-syscall.h headers with build-many-glibcs.py update-syscalls.
+    
+    Tested with build-many-glibcs.py.
+    
+    (cherry picked from commit fccadcdf5bed7ee67a6cef4714e0b477d6c8472c)
+
+diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+index bf4be80f8d380963..202520ee254ec02f 100644
+--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+@@ -122,6 +122,7 @@
+ #define __NR_mbind 235
+ #define __NR_membarrier 283
+ #define __NR_memfd_create 279
++#define __NR_memfd_secret 447
+ #define __NR_migrate_pages 238
+ #define __NR_mincore 232
+ #define __NR_mkdirat 34
+diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+index d656aedcc2be6009..4e65f337d486de1f 100644
+--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+@@ -127,6 +127,7 @@
+ #define __NR_mbind 235
+ #define __NR_membarrier 283
+ #define __NR_memfd_create 279
++#define __NR_memfd_secret 447
+ #define __NR_migrate_pages 238
+ #define __NR_mincore 232
+ #define __NR_mkdirat 34
+diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
+index 95370e2ec5dbc4a7..9b285d898db9ab9e 100644
+--- a/sysdeps/unix/sysv/linux/syscall-names.list
++++ b/sysdeps/unix/sysv/linux/syscall-names.list
+@@ -21,8 +21,8 @@
+ # This file can list all potential system calls.  The names are only
+ # used if the installed kernel headers also provide them.
+ 
+-# The list of system calls is current as of Linux 5.18.
+-kernel 5.18
++# The list of system calls is current as of Linux 5.19.
++kernel 5.19
+ 
+ FAST_atomic_update
+ FAST_cmpxchg
diff --git a/SOURCES/glibc-upstream-2.34-305.patch b/SOURCES/glibc-upstream-2.34-305.patch
new file mode 100644
index 0000000..8a70f75
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-305.patch
@@ -0,0 +1,85 @@
+commit a88f07f71f051021339682328103a8c75559fc5f
+Author: Noah Goldstein <goldstein.w.n@gmail.com>
+Date:   Wed Jun 22 08:24:21 2022 -0700
+
+    stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265]
+    
+    mbstows is defined if dst is NULL and is defined to special cased if
+    dst is NULL so the fortify objsize check if incorrect in that case.
+    
+    Tested on x86-64 linux.
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    
+    (cherry picked from commit 464d189b9622932a75302290625de84931656ec0)
+
+diff --git a/stdlib/Makefile b/stdlib/Makefile
+index a4ac30d1f6359561..e13f1ee33c410ae6 100644
+--- a/stdlib/Makefile
++++ b/stdlib/Makefile
+@@ -217,6 +217,9 @@ CFLAGS-tst-qsort.c += $(stack-align-test-flags)
+ CFLAGS-tst-makecontext.c += -funwind-tables
+ CFLAGS-tst-makecontext2.c += $(stack-align-test-flags)
+ 
++CFLAGS-testmb.c += -D_FORTIFY_SOURCE=2 -Wall -Werror
++
++
+ # Run a test on the header files we use.
+ tests-special += $(objpfx)isomac.out
+ 
+diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
+index ccacbdf76a08225a..f0918d5d798a6ac4 100644
+--- a/stdlib/bits/stdlib.h
++++ b/stdlib/bits/stdlib.h
+@@ -96,6 +96,11 @@ extern size_t __mbstowcs_chk (wchar_t *__restrict __dst,
+ 			      const char *__restrict __src,
+ 			      size_t __len, size_t __dstlen) __THROW
+     __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2));
++extern size_t __REDIRECT_NTH (__mbstowcs_chk_nulldst,
++			      (wchar_t *__restrict __dst,
++			       const char *__restrict __src,
++			       size_t __len), mbstowcs_chk)
++    __attr_access ((__read_only__, 2));
+ extern size_t __REDIRECT_NTH (__mbstowcs_alias,
+ 			      (wchar_t *__restrict __dst,
+ 			       const char *__restrict __src,
+@@ -108,16 +113,17 @@ extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn,
+      __warnattr ("mbstowcs called with dst buffer smaller than len "
+ 		 "* sizeof (wchar_t)");
+ 
+-__fortify_function size_t
++__always_inline __fortify_function size_t
+ __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src,
+ 		 size_t __len))
+ {
+-  return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t),
+-			    __glibc_objsize (__dst),
+-			    __dst, __src, __len);
++  if (__builtin_constant_p (__dst == NULL) && __dst == NULL)
++    return __mbstowcs_chk_nulldst (__dst, __src, __len);
++  else
++    return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t),
++			      __glibc_objsize (__dst), __dst, __src, __len);
+ }
+ 
+-
+ extern size_t __wcstombs_chk (char *__restrict __dst,
+ 			      const wchar_t *__restrict __src,
+ 			      size_t __len, size_t __dstlen) __THROW
+diff --git a/stdlib/testmb.c b/stdlib/testmb.c
+index 45dae7db61fb3e7b..6ac4dfd21d2d33b8 100644
+--- a/stdlib/testmb.c
++++ b/stdlib/testmb.c
+@@ -16,6 +16,13 @@ main (int argc, char *argv[])
+       lose = 1;
+     }
+ 
++  i = mbstowcs (NULL, "bar", 4);
++  if (!(i == 3 && w[1] == 'a'))
++    {
++      puts ("mbstowcs FAILED2!");
++      lose = 1;
++    }
++
+   mbstowcs (w, "blah", 5);
+   i = wcstombs (c, w, 10);
+   if (i != 4)
diff --git a/SOURCES/glibc-upstream-2.34-306.patch b/SOURCES/glibc-upstream-2.34-306.patch
new file mode 100644
index 0000000..b031a56
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-306.patch
@@ -0,0 +1,54 @@
+commit 4bc889c01ce68475ce36f9c67b9a445a6c0218d9
+Author: Noah Goldstein <goldstein.w.n@gmail.com>
+Date:   Wed Jun 22 16:34:42 2022 -0700
+
+    stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279]
+    
+    commit 464d189b9622932a75302290625de84931656ec0 (origin/master, origin/HEAD)
+    Author: Noah Goldstein <goldstein.w.n@gmail.com>
+    Date:   Wed Jun 22 08:24:21 2022 -0700
+    
+        stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265]
+    
+    Incorrectly called `__mbstowcs_chk` in the NULL __dst case which is
+    incorrect as in the NULL __dst case we are explicitly skipping
+    the objsize checks.
+    
+    As well, remove the `__always_inline` attribute which exists in
+    `__fortify_function`.
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    
+    (cherry picked from commit 220b83d83d32aa9e6f5659e2fa2a63a0024c3e4a)
+
+diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
+index f0918d5d798a6ac4..ac9badc81f3990c5 100644
+--- a/stdlib/bits/stdlib.h
++++ b/stdlib/bits/stdlib.h
+@@ -96,10 +96,10 @@ extern size_t __mbstowcs_chk (wchar_t *__restrict __dst,
+ 			      const char *__restrict __src,
+ 			      size_t __len, size_t __dstlen) __THROW
+     __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2));
+-extern size_t __REDIRECT_NTH (__mbstowcs_chk_nulldst,
++extern size_t __REDIRECT_NTH (__mbstowcs_nulldst,
+ 			      (wchar_t *__restrict __dst,
+ 			       const char *__restrict __src,
+-			       size_t __len), mbstowcs_chk)
++			       size_t __len), mbstowcs)
+     __attr_access ((__read_only__, 2));
+ extern size_t __REDIRECT_NTH (__mbstowcs_alias,
+ 			      (wchar_t *__restrict __dst,
+@@ -113,12 +113,12 @@ extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn,
+      __warnattr ("mbstowcs called with dst buffer smaller than len "
+ 		 "* sizeof (wchar_t)");
+ 
+-__always_inline __fortify_function size_t
++__fortify_function size_t
+ __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src,
+ 		 size_t __len))
+ {
+   if (__builtin_constant_p (__dst == NULL) && __dst == NULL)
+-    return __mbstowcs_chk_nulldst (__dst, __src, __len);
++    return __mbstowcs_nulldst (__dst, __src, __len);
+   else
+     return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t),
+ 			      __glibc_objsize (__dst), __dst, __src, __len);
diff --git a/SOURCES/glibc-upstream-2.34-307.patch b/SOURCES/glibc-upstream-2.34-307.patch
new file mode 100644
index 0000000..8e5493b
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-307.patch
@@ -0,0 +1,30 @@
+commit 1fcc7bfee22a07064508b6729cdaa6289851a2b4
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Mon Aug 22 11:04:47 2022 +0200
+
+    alpha: Fix generic brk system call emulation in __brk_call (bug 29490)
+    
+    The kernel special-cases the zero argument for alpha brk, and we can
+    use that to restore the generic Linux error handling behavior.
+    
+    Fixes commit b57ab258c1140bc45464b4b9908713e3e0ee35aa ("Linux:
+    Introduce __brk_call for invoking the brk system call").
+    
+    (cherry picked from commit e7ad26ee3cb74e61d0637c888f24dd478d77af58)
+
+diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h
+index b8088cf13f938c88..0b851b6c8664e8d5 100644
+--- a/sysdeps/unix/sysv/linux/alpha/brk_call.h
++++ b/sysdeps/unix/sysv/linux/alpha/brk_call.h
+@@ -21,8 +21,7 @@ __brk_call (void *addr)
+ {
+   unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr);
+   if (result == -ENOMEM)
+-    /* Mimic the default error reporting behavior.  */
+-    return addr;
+-  else
+-    return (void *) result;
++    /* Mimic the generic error reporting behavior.  */
++    result = INTERNAL_SYSCALL_CALL (brk, 0);
++  return (void *) result;
+ }
diff --git a/SOURCES/glibc-upstream-2.34-308.patch b/SOURCES/glibc-upstream-2.34-308.patch
new file mode 100644
index 0000000..4726bf0
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-308.patch
@@ -0,0 +1,435 @@
+commit 68507377f249d165f1f35502d96e9365edb07d9a
+Author: Arjun Shankar <arjun@redhat.com>
+Date:   Tue Aug 2 11:10:25 2022 +0200
+
+    socket: Check lengths before advancing pointer in CMSG_NXTHDR
+    
+    The inline and library functions that the CMSG_NXTHDR macro may expand
+    to increment the pointer to the header before checking the stride of
+    the increment against available space.  Since C only allows incrementing
+    pointers to one past the end of an array, the increment must be done
+    after a length check.  This commit fixes that and includes a regression
+    test for CMSG_FIRSTHDR and CMSG_NXTHDR.
+    
+    The Linux, Hurd, and generic headers are all changed.
+    
+    Tested on Linux on armv7hl, i686, x86_64, aarch64, ppc64le, and s390x.
+    
+    [BZ #28846]
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 9c443ac4559a47ed99859bd80d14dc4b6dd220a1)
+
+diff --git a/bits/socket.h b/bits/socket.h
+index 05ac0249c7da7218..781b1b2d1e0632a8 100644
+--- a/bits/socket.h
++++ b/bits/socket.h
+@@ -245,6 +245,12 @@ struct cmsghdr
+ 			 + CMSG_ALIGN (sizeof (struct cmsghdr)))
+ #define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+ 
++/* Given a length, return the additional padding necessary such that
++   len + __CMSG_PADDING(len) == CMSG_ALIGN (len).  */
++#define __CMSG_PADDING(len) ((sizeof (size_t) \
++                              - ((len) & (sizeof (size_t) - 1))) \
++                             & (sizeof (size_t) - 1))
++
+ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ 				      struct cmsghdr *__cmsg) __THROW;
+ #ifdef __USE_EXTERN_INLINES
+@@ -254,18 +260,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ _EXTERN_INLINE struct cmsghdr *
+ __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
+ {
++  /* We may safely assume that __cmsg lies between __mhdr->msg_control and
++     __mhdr->msg_controllen because the user is required to obtain the first
++     cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
++     via CMSG_NXTHDR, setting lengths along the way.  However, we don't yet
++     trust the value of __cmsg->cmsg_len and therefore do not use it in any
++     pointer arithmetic until we check its value.  */
++
++  unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control;
++  unsigned char * __cmsg_ptr = (unsigned char *) __cmsg;
++
++  size_t __size_needed = sizeof (struct cmsghdr)
++                         + __CMSG_PADDING (__cmsg->cmsg_len);
++
++  /* The current header is malformed, too small to be a full header.  */
+   if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
+-    /* The kernel header does this so there may be a reason.  */
+     return (struct cmsghdr *) 0;
+ 
++  /* There isn't enough space between __cmsg and the end of the buffer to
++  hold the current cmsg *and* the next one.  */
++  if (((size_t)
++         (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr)
++       < __size_needed)
++      || ((size_t)
++            (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr
++             - __size_needed)
++          < __cmsg->cmsg_len))
++
++    return (struct cmsghdr *) 0;
++
++  /* Now, we trust cmsg_len and can use it to find the next header.  */
+   __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ 			       + CMSG_ALIGN (__cmsg->cmsg_len));
+-  if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+-					+ __mhdr->msg_controllen)
+-      || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
+-	  > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
+-    /* No more entries.  */
+-    return (struct cmsghdr *) 0;
+   return __cmsg;
+ }
+ #endif	/* Use `extern inline'.  */
+diff --git a/socket/Makefile b/socket/Makefile
+index c2de11d73ca1e324..2fdf441bb44bf142 100644
+--- a/socket/Makefile
++++ b/socket/Makefile
+@@ -34,6 +34,7 @@ routines := accept bind connect getpeername getsockname getsockopt	\
+ tests := \
+   tst-accept4 \
+   tst-sockopt \
++  tst-cmsghdr \
+   # tests
+ 
+ tests-internal := \
+diff --git a/socket/tst-cmsghdr-skeleton.c b/socket/tst-cmsghdr-skeleton.c
+new file mode 100644
+index 0000000000000000..7accfa6e54708e2a
+--- /dev/null
++++ b/socket/tst-cmsghdr-skeleton.c
+@@ -0,0 +1,93 @@
++/* Test ancillary data header creation.
++   Copyright (C) 2022 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/>.  */
++
++/* We use the preprocessor to generate the function/macro tests instead of
++   using indirection because having all the macro expansions alongside
++   each other lets the compiler warn us about suspicious pointer
++   arithmetic across subsequent CMSG_{FIRST,NXT}HDR expansions.  */
++
++#include <stdint.h>
++#include <stddef.h>
++
++#define RUN_TEST_CONCAT(suffix) run_test_##suffix
++#define RUN_TEST_FUNCNAME(suffix) RUN_TEST_CONCAT (suffix)
++
++static void
++RUN_TEST_FUNCNAME (CMSG_NXTHDR_IMPL) (void)
++{
++  struct msghdr m = {0};
++  struct cmsghdr *cmsg;
++  char cmsgbuf[3 * CMSG_SPACE (sizeof (PAYLOAD))] = {0};
++
++  m.msg_control = cmsgbuf;
++  m.msg_controllen = sizeof (cmsgbuf);
++
++  /* First header should point to the start of the buffer.  */
++  cmsg = CMSG_FIRSTHDR (&m);
++  TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
++
++  /* If the first header length consumes the entire buffer, there is no
++     space remaining for additional headers.  */
++  cmsg->cmsg_len = sizeof (cmsgbuf);
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg == NULL);
++
++  /* The first header length is so big, using it would cause an overflow.  */
++  cmsg = CMSG_FIRSTHDR (&m);
++  TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
++  cmsg->cmsg_len = SIZE_MAX;
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg == NULL);
++
++  /* The first header leaves just enough space to hold another header.  */
++  cmsg = CMSG_FIRSTHDR (&m);
++  TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
++  cmsg->cmsg_len = sizeof (cmsgbuf) - sizeof (struct cmsghdr);
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg != NULL);
++
++  /* The first header leaves space but not enough for another header.  */
++  cmsg = CMSG_FIRSTHDR (&m);
++  TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
++  cmsg->cmsg_len ++;
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg == NULL);
++
++  /* The second header leaves just enough space to hold another header.  */
++  cmsg = CMSG_FIRSTHDR (&m);
++  TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
++  cmsg->cmsg_len = CMSG_LEN (sizeof (PAYLOAD));
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg != NULL);
++  cmsg->cmsg_len = sizeof (cmsgbuf)
++                   - CMSG_SPACE (sizeof (PAYLOAD)) /* First header.  */
++                   - sizeof (struct cmsghdr);
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg != NULL);
++
++  /* The second header leaves space but not enough for another header.  */
++  cmsg = CMSG_FIRSTHDR (&m);
++  TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg != NULL);
++  cmsg->cmsg_len ++;
++  cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
++  TEST_VERIFY_EXIT (cmsg == NULL);
++
++  return;
++}
+diff --git a/socket/tst-cmsghdr.c b/socket/tst-cmsghdr.c
+new file mode 100644
+index 0000000000000000..68c96d3c9dd2bce8
+--- /dev/null
++++ b/socket/tst-cmsghdr.c
+@@ -0,0 +1,56 @@
++/* Test ancillary data header creation.
++   Copyright (C) 2022 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 <sys/socket.h>
++#include <gnu/lib-names.h>
++#include <support/xdlfcn.h>
++#include <support/check.h>
++
++#define PAYLOAD "Hello, World!"
++
++/* CMSG_NXTHDR is a macro that calls an inline function defined in
++   bits/socket.h.  In case the function cannot be inlined, libc.so carries
++   a copy.  Both versions need to be tested.  */
++
++#define CMSG_NXTHDR_IMPL CMSG_NXTHDR
++#include "tst-cmsghdr-skeleton.c"
++#undef CMSG_NXTHDR_IMPL
++
++static struct cmsghdr * (* cmsg_nxthdr) (struct msghdr *, struct cmsghdr *);
++
++#define CMSG_NXTHDR_IMPL cmsg_nxthdr
++#include "tst-cmsghdr-skeleton.c"
++#undef CMSG_NXTHDR_IMPL
++
++static int
++do_test (void)
++{
++  static void *handle;
++
++  run_test_CMSG_NXTHDR ();
++
++  handle = xdlopen (LIBC_SO, RTLD_LAZY);
++  cmsg_nxthdr = (struct cmsghdr * (*) (struct msghdr *, struct cmsghdr *))
++                  xdlsym (handle, "__cmsg_nxthdr");
++
++  run_test_cmsg_nxthdr ();
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h
+index 5210a7b44950e957..423eb2df09c3eef9 100644
+--- a/sysdeps/mach/hurd/bits/socket.h
++++ b/sysdeps/mach/hurd/bits/socket.h
+@@ -249,6 +249,12 @@ struct cmsghdr
+ 			 + CMSG_ALIGN (sizeof (struct cmsghdr)))
+ #define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+ 
++/* Given a length, return the additional padding necessary such that
++   len + __CMSG_PADDING(len) == CMSG_ALIGN (len).  */
++#define __CMSG_PADDING(len) ((sizeof (size_t) \
++                              - ((len) & (sizeof (size_t) - 1))) \
++                             & (sizeof (size_t) - 1))
++
+ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ 				      struct cmsghdr *__cmsg) __THROW;
+ #ifdef __USE_EXTERN_INLINES
+@@ -258,18 +264,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ _EXTERN_INLINE struct cmsghdr *
+ __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
+ {
++  /* We may safely assume that __cmsg lies between __mhdr->msg_control and
++     __mhdr->msg_controllen because the user is required to obtain the first
++     cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
++     via CMSG_NXTHDR, setting lengths along the way.  However, we don't yet
++     trust the value of __cmsg->cmsg_len and therefore do not use it in any
++     pointer arithmetic until we check its value.  */
++
++  unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control;
++  unsigned char * __cmsg_ptr = (unsigned char *) __cmsg;
++
++  size_t __size_needed = sizeof (struct cmsghdr)
++                         + __CMSG_PADDING (__cmsg->cmsg_len);
++
++  /* The current header is malformed, too small to be a full header.  */
+   if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
+-    /* The kernel header does this so there may be a reason.  */
+     return (struct cmsghdr *) 0;
+ 
++  /* There isn't enough space between __cmsg and the end of the buffer to
++  hold the current cmsg *and* the next one.  */
++  if (((size_t)
++         (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr)
++       < __size_needed)
++      || ((size_t)
++            (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr
++             - __size_needed)
++          < __cmsg->cmsg_len))
++
++    return (struct cmsghdr *) 0;
++
++  /* Now, we trust cmsg_len and can use it to find the next header.  */
+   __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ 			       + CMSG_ALIGN (__cmsg->cmsg_len));
+-  if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+-					+ __mhdr->msg_controllen)
+-      || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
+-	  > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
+-    /* No more entries.  */
+-    return (struct cmsghdr *) 0;
+   return __cmsg;
+ }
+ #endif	/* Use `extern inline'.  */
+diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
+index c81fab840918924e..7d56f877e0a73acb 100644
+--- a/sysdeps/unix/sysv/linux/bits/socket.h
++++ b/sysdeps/unix/sysv/linux/bits/socket.h
+@@ -306,6 +306,12 @@ struct cmsghdr
+ 			 + CMSG_ALIGN (sizeof (struct cmsghdr)))
+ #define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+ 
++/* Given a length, return the additional padding necessary such that
++   len + __CMSG_PADDING(len) == CMSG_ALIGN (len).  */
++#define __CMSG_PADDING(len) ((sizeof (size_t) \
++                              - ((len) & (sizeof (size_t) - 1))) \
++                             & (sizeof (size_t) - 1))
++
+ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ 				      struct cmsghdr *__cmsg) __THROW;
+ #ifdef __USE_EXTERN_INLINES
+@@ -315,18 +321,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ _EXTERN_INLINE struct cmsghdr *
+ __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
+ {
++  /* We may safely assume that __cmsg lies between __mhdr->msg_control and
++     __mhdr->msg_controllen because the user is required to obtain the first
++     cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
++     via CMSG_NXTHDR, setting lengths along the way.  However, we don't yet
++     trust the value of __cmsg->cmsg_len and therefore do not use it in any
++     pointer arithmetic until we check its value.  */
++
++  unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control;
++  unsigned char * __cmsg_ptr = (unsigned char *) __cmsg;
++
++  size_t __size_needed = sizeof (struct cmsghdr)
++                         + __CMSG_PADDING (__cmsg->cmsg_len);
++
++  /* The current header is malformed, too small to be a full header.  */
+   if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
+-    /* The kernel header does this so there may be a reason.  */
+     return (struct cmsghdr *) 0;
+ 
++  /* There isn't enough space between __cmsg and the end of the buffer to
++  hold the current cmsg *and* the next one.  */
++  if (((size_t)
++         (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr)
++       < __size_needed)
++      || ((size_t)
++            (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr
++             - __size_needed)
++          < __cmsg->cmsg_len))
++
++    return (struct cmsghdr *) 0;
++
++  /* Now, we trust cmsg_len and can use it to find the next header.  */
+   __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ 			       + CMSG_ALIGN (__cmsg->cmsg_len));
+-  if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+-					+ __mhdr->msg_controllen)
+-      || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
+-	  > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
+-    /* No more entries.  */
+-    return (struct cmsghdr *) 0;
+   return __cmsg;
+ }
+ #endif	/* Use `extern inline'.  */
+diff --git a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
+index a0fe49f28563d030..535d22e9a037b9a9 100644
+--- a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
++++ b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
+@@ -23,18 +23,38 @@
+ struct cmsghdr *
+ __cmsg_nxthdr (struct msghdr *mhdr, struct cmsghdr *cmsg)
+ {
++  /* We may safely assume that cmsg lies between mhdr->msg_control and
++     mhdr->msg_controllen because the user is required to obtain the first
++     cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
++     via CMSG_NXTHDR, setting lengths along the way.  However, we don't yet
++     trust the value of cmsg->cmsg_len and therefore do not use it in any
++     pointer arithmetic until we check its value.  */
++
++  unsigned char * msg_control_ptr = (unsigned char *) mhdr->msg_control;
++  unsigned char * cmsg_ptr = (unsigned char *) cmsg;
++
++  size_t size_needed = sizeof (struct cmsghdr)
++                       + __CMSG_PADDING (cmsg->cmsg_len);
++
++  /* The current header is malformed, too small to be a full header.  */
+   if ((size_t) cmsg->cmsg_len < sizeof (struct cmsghdr))
+-    /* The kernel header does this so there may be a reason.  */
+-    return NULL;
++    return (struct cmsghdr *) 0;
++
++  /* There isn't enough space between cmsg and the end of the buffer to
++  hold the current cmsg *and* the next one.  */
++  if (((size_t)
++         (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr)
++       < size_needed)
++      || ((size_t)
++            (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr
++             - size_needed)
++          < cmsg->cmsg_len))
++
++    return (struct cmsghdr *) 0;
+ 
++  /* Now, we trust cmsg_len and can use it to find the next header.  */
+   cmsg = (struct cmsghdr *) ((unsigned char *) cmsg
+ 			     + CMSG_ALIGN (cmsg->cmsg_len));
+-  if ((unsigned char *) (cmsg + 1) > ((unsigned char *) mhdr->msg_control
+-				      + mhdr->msg_controllen)
+-      || ((unsigned char *) cmsg + CMSG_ALIGN (cmsg->cmsg_len)
+-	  > ((unsigned char *) mhdr->msg_control + mhdr->msg_controllen)))
+-    /* No more entries.  */
+-    return NULL;
+   return cmsg;
+ }
+ libc_hidden_def (__cmsg_nxthdr)
diff --git a/SOURCES/glibc-upstream-2.34-309.patch b/SOURCES/glibc-upstream-2.34-309.patch
new file mode 100644
index 0000000..1c34dc0
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-309.patch
@@ -0,0 +1,212 @@
+commit 536ddc5c02f1ee82483319863a893ccb381beece
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Aug 26 21:15:43 2022 +0200
+
+    elf: Call __libc_early_init for reused namespaces (bug 29528)
+    
+    libc_map is never reset to NULL, neither during dlclose nor on a
+    dlopen call which reuses the namespace structure.  As a result, if a
+    namespace is reused, its libc is not initialized properly.  The most
+    visible result is a crash in the <ctype.h> functions.
+    
+    To prevent similar bugs on namespace reuse from surfacing,
+    unconditionally initialize the chosen namespace to zero using memset.
+    
+    (cherry picked from commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe)
+
+Conflicts:
+	elf/Makefile
+	  (usual test differences)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 2b547d5b58f1759b..feec365e4e5fe9b3 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -399,6 +399,7 @@ tests += \
+   tst-dlmopen3 \
+   tst-dlmopen-dlerror \
+   tst-dlmopen-gethostbyname \
++  tst-dlmopen-twice \
+   tst-dlopenfail \
+   tst-dlopenfail-2 \
+   tst-dlopenrpath \
+@@ -744,6 +745,8 @@ modules-names = \
+   tst-dlmopen1mod \
+   tst-dlmopen-dlerror-mod \
+   tst-dlmopen-gethostbyname-mod \
++  tst-dlmopen-twice-mod1 \
++  tst-dlmopen-twice-mod2 \
+   tst-dlopenfaillinkmod \
+   tst-dlopenfailmod1 \
+   tst-dlopenfailmod2 \
+@@ -2665,3 +2668,7 @@ $(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
+ tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
+ $(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
+ tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
++
++$(objpfx)tst-dlmopen-twice.out: \
++  $(objpfx)tst-dlmopen-twice-mod1.so \
++  $(objpfx)tst-dlmopen-twice-mod2.so
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index bc6872632880634e..1ab3c7b5ac2fbc45 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -839,11 +839,14 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
+ 	  _dl_signal_error (EINVAL, file, NULL, N_("\
+ no more namespaces available for dlmopen()"));
+ 	}
+-      else if (nsid == GL(dl_nns))
+-	{
+-	  __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
+-	  ++GL(dl_nns);
+-	}
++
++      if (nsid == GL(dl_nns))
++	++GL(dl_nns);
++
++      /* Initialize the new namespace.  Most members are
++	 zero-initialized, only the lock needs special treatment.  */
++      memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid]));
++      __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
+ 
+       _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT;
+     }
+diff --git a/elf/tst-dlmopen-twice-mod1.c b/elf/tst-dlmopen-twice-mod1.c
+new file mode 100644
+index 0000000000000000..0eaf04948ce5263e
+--- /dev/null
++++ b/elf/tst-dlmopen-twice-mod1.c
+@@ -0,0 +1,37 @@
++/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528).  Module 1.
++   Copyright (C) 2022 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 <stdio.h>
++
++static void __attribute__ ((constructor))
++init (void)
++{
++  puts ("info: tst-dlmopen-twice-mod1.so loaded");
++  fflush (stdout);
++}
++
++static void __attribute__ ((destructor))
++fini (void)
++{
++  puts ("info: tst-dlmopen-twice-mod1.so about to be unloaded");
++  fflush (stdout);
++}
++
++/* Large allocation.  The second module does not have this, so it
++   should load libc at a different address.  */
++char large_allocate[16 * 1024 * 1024];
+diff --git a/elf/tst-dlmopen-twice-mod2.c b/elf/tst-dlmopen-twice-mod2.c
+new file mode 100644
+index 0000000000000000..40c6c01f9625e188
+--- /dev/null
++++ b/elf/tst-dlmopen-twice-mod2.c
+@@ -0,0 +1,50 @@
++/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528).  Module 2.
++   Copyright (C) 2022 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 <ctype.h>
++#include <stdio.h>
++
++static void __attribute__ ((constructor))
++init (void)
++{
++  puts ("info: tst-dlmopen-twice-mod2.so loaded");
++  fflush (stdout);
++}
++
++static void __attribute__ ((destructor))
++fini (void)
++{
++  puts ("info: tst-dlmopen-twice-mod2.so about to be unloaded");
++  fflush (stdout);
++}
++
++int
++run_check (void)
++{
++  puts ("info: about to call isalpha");
++  fflush (stdout);
++
++  volatile char ch = 'a';
++  if (!isalpha (ch))
++    {
++      puts ("error: isalpha ('a') is not true");
++      fflush (stdout);
++      return 1;
++    }
++  return 0;
++}
+diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c
+new file mode 100644
+index 0000000000000000..449f3c8fa9f2aa01
+--- /dev/null
++++ b/elf/tst-dlmopen-twice.c
+@@ -0,0 +1,34 @@
++/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528).  Main.
++   Copyright (C) 2022 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/xdlfcn.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW);
++  xdlclose (handle);
++  handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW);
++  int (*run_check) (void) = xdlsym (handle, "run_check");
++  TEST_COMPARE (run_check (), 0);
++  xdlclose (handle);
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-310.patch b/SOURCES/glibc-upstream-2.34-310.patch
new file mode 100644
index 0000000..7f949a0
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-310.patch
@@ -0,0 +1,334 @@
+commit 2a44960cbc78713c6a2721683a4319d50e71a01f
+Author: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+Date:   Thu Jul 7 18:12:58 2022 -0300
+
+    Apply asm redirections in stdio.h before first use [BZ #27087]
+    
+    Compilers may not be able to apply asm redirections to functions after
+    these functions are used for the first time, e.g. clang 13.
+    Fix [BZ #27087] by applying all long double-related asm redirections
+    before using functions in bits/stdio.h.
+    However, as these asm redirections depend on the declarations provided
+    by libio/bits/stdio2.h, this header was split in 2:
+    
+     - libio/bits/stdio2-decl.h contains all function declarations;
+     - libio/bits/stdio2.h remains with the remaining contents, including
+       redirections.
+    
+    This also adds the access attribute to __vsnprintf_chk that was missing.
+    
+    Tested with build-many-glibcs.py.
+    
+    Reviewed-by: Paul E. Murphy <murphyp@linux.ibm.com>
+    (cherry picked from commit d0fa09a7701956036ff36f8ca188e9fff81553d8)
+
+diff --git a/include/bits/stdio2-decl.h b/include/bits/stdio2-decl.h
+new file mode 100644
+index 0000000000000000..bbb052f192218219
+--- /dev/null
++++ b/include/bits/stdio2-decl.h
+@@ -0,0 +1 @@
++#include <libio/bits/stdio2-decl.h>
+diff --git a/libio/Makefile b/libio/Makefile
+index 5336b7d59584927f..981c876940f67fbf 100644
+--- a/libio/Makefile
++++ b/libio/Makefile
+@@ -23,7 +23,7 @@ subdir	:= libio
+ include ../Makeconfig
+ 
+ headers	:= stdio.h \
+-	   bits/stdio.h bits/stdio2.h bits/stdio-ldbl.h \
++	   bits/stdio.h bits/stdio2.h bits/stdio2-decl.h bits/stdio-ldbl.h \
+ 	   bits/types/FILE.h bits/types/__FILE.h bits/types/struct_FILE.h \
+ 	   bits/types/__fpos_t.h bits/types/__fpos64_t.h \
+ 	   bits/types/cookie_io_functions_t.h
+diff --git a/libio/bits/stdio2-decl.h b/libio/bits/stdio2-decl.h
+new file mode 100644
+index 0000000000000000..e398f7182b98e4d7
+--- /dev/null
++++ b/libio/bits/stdio2-decl.h
+@@ -0,0 +1,111 @@
++/* Checking macros for stdio functions. Declarations only.
++   Copyright (C) 2004-2022 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/>.  */
++
++#ifndef _BITS_STDIO2_DEC_H
++#define _BITS_STDIO2_DEC_H 1
++
++#ifndef _STDIO_H
++# error "Never include <bits/stdio2-decl.h> directly; use <stdio.h> instead."
++#endif
++
++extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
++			  const char *__restrict __format, ...) __THROW
++    __attr_access ((__write_only__, 1, 3));
++extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
++			   const char *__restrict __format,
++			   __gnuc_va_list __ap) __THROW
++    __attr_access ((__write_only__, 1, 3));
++
++#if defined __USE_ISOC99 || defined __USE_UNIX98
++
++extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag,
++			   size_t __slen, const char *__restrict __format,
++			   ...) __THROW
++    __attr_access ((__write_only__, 1, 2));
++extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
++			    size_t __slen, const char *__restrict __format,
++			    __gnuc_va_list __ap) __THROW
++    __attr_access ((__write_only__, 1, 2));
++
++#endif
++
++#if __USE_FORTIFY_LEVEL > 1
++
++extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
++			  const char *__restrict __format, ...);
++extern int __printf_chk (int __flag, const char *__restrict __format, ...);
++extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
++			   const char *__restrict __format, __gnuc_va_list __ap);
++extern int __vprintf_chk (int __flag, const char *__restrict __format,
++			  __gnuc_va_list __ap);
++
++# ifdef __USE_XOPEN2K8
++extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt,
++			  ...) __attribute__ ((__format__ (__printf__, 3, 4)));
++extern int __vdprintf_chk (int __fd, int __flag,
++			   const char *__restrict __fmt, __gnuc_va_list __arg)
++     __attribute__ ((__format__ (__printf__, 3, 0)));
++# endif
++
++# ifdef __USE_GNU
++
++extern int __asprintf_chk (char **__restrict __ptr, int __flag,
++			   const char *__restrict __fmt, ...)
++     __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur;
++extern int __vasprintf_chk (char **__restrict __ptr, int __flag,
++			    const char *__restrict __fmt, __gnuc_va_list __arg)
++     __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur;
++extern int __obstack_printf_chk (struct obstack *__restrict __obstack,
++				 int __flag, const char *__restrict __format,
++				 ...)
++     __THROW __attribute__ ((__format__ (__printf__, 3, 4)));
++extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack,
++				  int __flag,
++				  const char *__restrict __format,
++				  __gnuc_va_list __args)
++     __THROW __attribute__ ((__format__ (__printf__, 3, 0)));
++
++# endif
++#endif
++
++#if __GLIBC_USE (DEPRECATED_GETS)
++extern char *__gets_chk (char *__str, size_t) __wur;
++#endif
++
++extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
++			  FILE *__restrict __stream)
++    __wur __attr_access ((__write_only__, 1, 3));
++
++extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen,
++			   size_t __size, size_t __n,
++			   FILE *__restrict __stream) __wur;
++
++#ifdef __USE_GNU
++extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
++				   int __n, FILE *__restrict __stream)
++    __wur __attr_access ((__write_only__, 1, 3));
++#endif
++
++#ifdef __USE_MISC
++# undef fread_unlocked
++extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen,
++				    size_t __size, size_t __n,
++				    FILE *__restrict __stream) __wur;
++#endif
++
++#endif /* bits/stdio2-decl.h.  */
+diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
+index 40ff16b01b4f4876..4570f86a4496c1ee 100644
+--- a/libio/bits/stdio2.h
++++ b/libio/bits/stdio2.h
+@@ -23,14 +23,6 @@
+ # error "Never include <bits/stdio2.h> directly; use <stdio.h> instead."
+ #endif
+ 
+-extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
+-			  const char *__restrict __format, ...) __THROW
+-    __attr_access ((__write_only__, 1, 3));
+-extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
+-			   const char *__restrict __format,
+-			   __gnuc_va_list __ap) __THROW
+-    __attr_access ((__write_only__, 1, 3));
+-
+ #ifdef __va_arg_pack
+ __fortify_function int
+ __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
+@@ -54,15 +46,6 @@ __NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt,
+ }
+ 
+ #if defined __USE_ISOC99 || defined __USE_UNIX98
+-
+-extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag,
+-			   size_t __slen, const char *__restrict __format,
+-			   ...) __THROW
+-    __attr_access ((__write_only__, 1, 2));
+-extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
+-			    size_t __slen, const char *__restrict __format,
+-			    __gnuc_va_list __ap) __THROW;
+-
+ # ifdef __va_arg_pack
+ __fortify_function int
+ __NTH (snprintf (char *__restrict __s, size_t __n,
+@@ -89,15 +72,6 @@ __NTH (vsnprintf (char *__restrict __s, size_t __n,
+ #endif
+ 
+ #if __USE_FORTIFY_LEVEL > 1
+-
+-extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
+-			  const char *__restrict __format, ...);
+-extern int __printf_chk (int __flag, const char *__restrict __format, ...);
+-extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
+-			   const char *__restrict __format, __gnuc_va_list __ap);
+-extern int __vprintf_chk (int __flag, const char *__restrict __format,
+-			  __gnuc_va_list __ap);
+-
+ # ifdef __va_arg_pack
+ __fortify_function int
+ fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...)
+@@ -136,12 +110,6 @@ vfprintf (FILE *__restrict __stream,
+ }
+ 
+ # ifdef __USE_XOPEN2K8
+-extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt,
+-			  ...) __attribute__ ((__format__ (__printf__, 3, 4)));
+-extern int __vdprintf_chk (int __fd, int __flag,
+-			   const char *__restrict __fmt, __gnuc_va_list __arg)
+-     __attribute__ ((__format__ (__printf__, 3, 0)));
+-
+ #  ifdef __va_arg_pack
+ __fortify_function int
+ dprintf (int __fd, const char *__restrict __fmt, ...)
+@@ -162,23 +130,6 @@ vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap)
+ # endif
+ 
+ # ifdef __USE_GNU
+-
+-extern int __asprintf_chk (char **__restrict __ptr, int __flag,
+-			   const char *__restrict __fmt, ...)
+-     __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur;
+-extern int __vasprintf_chk (char **__restrict __ptr, int __flag,
+-			    const char *__restrict __fmt, __gnuc_va_list __arg)
+-     __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur;
+-extern int __obstack_printf_chk (struct obstack *__restrict __obstack,
+-				 int __flag, const char *__restrict __format,
+-				 ...)
+-     __THROW __attribute__ ((__format__ (__printf__, 3, 4)));
+-extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack,
+-				  int __flag,
+-				  const char *__restrict __format,
+-				  __gnuc_va_list __args)
+-     __THROW __attribute__ ((__format__ (__printf__, 3, 0)));
+-
+ #  ifdef __va_arg_pack
+ __fortify_function int
+ __NTH (asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...))
+@@ -231,7 +182,6 @@ __NTH (obstack_vprintf (struct obstack *__restrict __obstack,
+ #endif
+ 
+ #if __GLIBC_USE (DEPRECATED_GETS)
+-extern char *__gets_chk (char *__str, size_t) __wur;
+ extern char *__REDIRECT (__gets_warn, (char *__str), gets)
+      __wur __warnattr ("please use fgets or getline instead, gets can't "
+ 		       "specify buffer size");
+@@ -245,9 +195,6 @@ gets (char *__str)
+ }
+ #endif
+ 
+-extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
+-			  FILE *__restrict __stream)
+-    __wur __attr_access ((__write_only__, 1, 3));
+ extern char *__REDIRECT (__fgets_alias,
+ 			 (char *__restrict __s, int __n,
+ 			  FILE *__restrict __stream), fgets)
+@@ -269,9 +216,6 @@ fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
+   return __fgets_chk (__s, sz, __n, __stream);
+ }
+ 
+-extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen,
+-			   size_t __size, size_t __n,
+-			   FILE *__restrict __stream) __wur;
+ extern size_t __REDIRECT (__fread_alias,
+ 			  (void *__restrict __ptr, size_t __size,
+ 			   size_t __n, FILE *__restrict __stream),
+@@ -297,9 +241,6 @@ fread (void *__restrict __ptr, size_t __size, size_t __n,
+ }
+ 
+ #ifdef __USE_GNU
+-extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
+-				   int __n, FILE *__restrict __stream)
+-    __wur __attr_access ((__write_only__, 1, 3));
+ extern char *__REDIRECT (__fgets_unlocked_alias,
+ 			 (char *__restrict __s, int __n,
+ 			  FILE *__restrict __stream), fgets_unlocked)
+@@ -324,9 +265,6 @@ fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
+ 
+ #ifdef __USE_MISC
+ # undef fread_unlocked
+-extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen,
+-				    size_t __size, size_t __n,
+-				    FILE *__restrict __stream) __wur;
+ extern size_t __REDIRECT (__fread_unlocked_alias,
+ 			  (void *__restrict __ptr, size_t __size,
+ 			   size_t __n, FILE *__restrict __stream),
+diff --git a/libio/stdio.h b/libio/stdio.h
+index abefe640e52d18d5..d36e61c56bbb3117 100644
+--- a/libio/stdio.h
++++ b/libio/stdio.h
+@@ -879,20 +879,27 @@ extern void funlockfile (FILE *__stream) __THROW;
+ extern int __uflow (FILE *);
+ extern int __overflow (FILE *, int);
+ 
++#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
++/* Declare all functions from bits/stdio2-decl.h first.  */
++# include <bits/stdio2-decl.h>
++#endif
++
++/* The following headers provide asm redirections.  These redirections must
++   appear before the first usage of these functions, e.g. in bits/stdio.h.  */
++#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
++# include <bits/stdio-ldbl.h>
++#endif
++
+ /* If we are compiling with optimizing read this file.  It contains
+    several optimizing inline functions and macros.  */
+ #ifdef __USE_EXTERN_INLINES
+ # include <bits/stdio.h>
+ #endif
+ #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
++/* Now include the function definitions and redirects too.  */
+ # include <bits/stdio2.h>
+ #endif
+ 
+-#include <bits/floatn.h>
+-#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
+-# include <bits/stdio-ldbl.h>
+-#endif
+-
+ __END_DECLS
+ 
+ #endif /* <stdio.h> included.  */
diff --git a/SOURCES/glibc-upstream-2.34-311.patch b/SOURCES/glibc-upstream-2.34-311.patch
new file mode 100644
index 0000000..2307c0c
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-311.patch
@@ -0,0 +1,414 @@
+commit b41c535f46e7e7bbd8ff2ac68b94c2348e2f66e4
+Author: Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
+Date:   Wed Aug 24 11:43:37 2022 -0300
+
+    Apply asm redirections in wchar.h before first use
+    
+    Similar to d0fa09a770, but for wchar.h.  Fixes [BZ #27087] by applying
+    all long double related asm redirections before using functions in
+    bits/wchar2.h.
+    Moves the function declarations from wcsmbs/bits/wchar2.h to a new file
+    wcsmbs/bits/wchar2-decl.h that will be included first in wcsmbs/wchar.h.
+    
+    Tested with build-many-glibcs.py.
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    
+    (cherry picked from commit c7509d49c4e8fa494120c5ead21338559dad16f5)
+
+diff --git a/include/bits/wchar2-decl.h b/include/bits/wchar2-decl.h
+new file mode 100644
+index 0000000000000000..00b1b93342ef28ff
+--- /dev/null
++++ b/include/bits/wchar2-decl.h
+@@ -0,0 +1 @@
++#include <wcsmbs/bits/wchar2-decl.h>
+diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
+index f38eb5cfe16fd3d7..5fe755e65df6c621 100644
+--- a/wcsmbs/Makefile
++++ b/wcsmbs/Makefile
+@@ -22,8 +22,9 @@ subdir	:= wcsmbs
+ 
+ include ../Makeconfig
+ 
+-headers	:= wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h \
+-	   bits/types/__mbstate_t.h bits/types/mbstate_t.h bits/types/wint_t.h
++headers	:= wchar.h bits/wchar.h bits/wchar2.h bits/wchar2-decl.h \
++	   bits/wchar-ldbl.h uchar.h bits/types/__mbstate_t.h \
++	   bits/types/mbstate_t.h bits/types/wint_t.h
+ 
+ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
+ 	    wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
+diff --git a/wcsmbs/bits/wchar2-decl.h b/wcsmbs/bits/wchar2-decl.h
+new file mode 100644
+index 0000000000000000..8e1735c33b7f7e78
+--- /dev/null
++++ b/wcsmbs/bits/wchar2-decl.h
+@@ -0,0 +1,124 @@
++/* Checking macros for wchar functions.  Declarations only.
++   Copyright (C) 2004-2022 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/>.  */
++
++#ifndef _BITS_WCHAR2_DECL_H
++#define _BITS_WCHAR2_DECL_H 1
++
++#ifndef _WCHAR_H
++# error "Never include <bits/wchar2-decl.h> directly; use <wchar.h> instead."
++#endif
++
++
++extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
++			       const wchar_t *__restrict __s2, size_t __n,
++			       size_t __ns1) __THROW;
++extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2,
++				size_t __n, size_t __ns1) __THROW;
++
++
++#ifdef __USE_GNU
++
++extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1,
++				const wchar_t *__restrict __s2, size_t __n,
++				size_t __ns1) __THROW;
++
++#endif
++
++
++extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
++			       size_t __ns) __THROW;
++extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest,
++			      const wchar_t *__restrict __src,
++			      size_t __n) __THROW;
++extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest,
++			      const wchar_t *__restrict __src,
++			      size_t __destlen) __THROW;
++extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest,
++			       const wchar_t *__restrict __src, size_t __n,
++			       size_t __destlen) __THROW;
++extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest,
++			       const wchar_t *__restrict __src, size_t __n,
++			       size_t __destlen) __THROW;
++extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest,
++			      const wchar_t *__restrict __src,
++			      size_t __destlen) __THROW;
++extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest,
++			       const wchar_t *__restrict __src,
++			       size_t __n, size_t __destlen) __THROW;
++extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n,
++			   int __flag, size_t __s_len,
++			   const wchar_t *__restrict __format, ...)
++     __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
++extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
++			    int __flag, size_t __s_len,
++			    const wchar_t *__restrict __format,
++			    __gnuc_va_list __arg)
++     __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
++
++#if __USE_FORTIFY_LEVEL > 1
++
++extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag,
++			   const wchar_t *__restrict __format, ...);
++extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format,
++			  ...);
++extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag,
++			    const wchar_t *__restrict __format,
++			    __gnuc_va_list __ap);
++extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format,
++			   __gnuc_va_list __ap);
++
++#endif
++
++extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
++			      __FILE *__restrict __stream) __wur;
++
++#ifdef __USE_GNU
++
++extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size,
++				       int __n, __FILE *__restrict __stream)
++       __wur;
++
++#endif
++
++extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar,
++			     mbstate_t *__restrict __p,
++			     size_t __buflen) __THROW __wur;
++extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst,
++			       const char **__restrict __src,
++			       size_t __len, mbstate_t *__restrict __ps,
++			       size_t __dstlen) __THROW;
++extern size_t __wcsrtombs_chk (char *__restrict __dst,
++			       const wchar_t **__restrict __src,
++			       size_t __len, mbstate_t *__restrict __ps,
++			       size_t __dstlen) __THROW;
++
++#ifdef	__USE_XOPEN2K8
++
++extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
++				const char **__restrict __src, size_t __nmc,
++				size_t __len, mbstate_t *__restrict __ps,
++				size_t __dstlen) __THROW;
++extern size_t __wcsnrtombs_chk (char *__restrict __dst,
++				const wchar_t **__restrict __src,
++				size_t __nwc, size_t __len,
++				mbstate_t *__restrict __ps, size_t __dstlen)
++       __THROW;
++
++#endif
++
++#endif /* bits/wchar2-decl.h.  */
+diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
+index 88c1fdfcd34292f4..50151b424d85a032 100644
+--- a/wcsmbs/bits/wchar2.h
++++ b/wcsmbs/bits/wchar2.h
+@@ -21,9 +21,6 @@
+ #endif
+ 
+ 
+-extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
+-			       const wchar_t *__restrict __s2, size_t __n,
+-			       size_t __ns1) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wmemcpy_alias,
+ 				(wchar_t *__restrict __s1,
+ 				 const wchar_t *__restrict __s2, size_t __n),
+@@ -45,8 +42,6 @@ __NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2,
+ }
+ 
+ 
+-extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2,
+-				size_t __n, size_t __ns1) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1,
+ 						   const wchar_t *__s2,
+ 						   size_t __n), wmemmove);
+@@ -66,9 +61,6 @@ __NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n))
+ 
+ 
+ #ifdef __USE_GNU
+-extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1,
+-				const wchar_t *__restrict __s2, size_t __n,
+-				size_t __ns1) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wmempcpy_alias,
+ 				(wchar_t *__restrict __s1,
+ 				 const wchar_t *__restrict __s2,
+@@ -91,8 +83,6 @@ __NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2,
+ #endif
+ 
+ 
+-extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
+-			       size_t __ns) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c,
+ 						  size_t __n), wmemset);
+ extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn,
+@@ -110,9 +100,6 @@ __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n))
+ }
+ 
+ 
+-extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest,
+-			      const wchar_t *__restrict __src,
+-			      size_t __n) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wcscpy_alias,
+ 				(wchar_t *__restrict __dest,
+ 				 const wchar_t *__restrict __src), wcscpy);
+@@ -127,9 +114,6 @@ __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
+ }
+ 
+ 
+-extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest,
+-			      const wchar_t *__restrict __src,
+-			      size_t __destlen) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias,
+ 				(wchar_t *__restrict __dest,
+ 				 const wchar_t *__restrict __src), wcpcpy);
+@@ -144,9 +128,6 @@ __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
+ }
+ 
+ 
+-extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest,
+-			       const wchar_t *__restrict __src, size_t __n,
+-			       size_t __destlen) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wcsncpy_alias,
+ 				(wchar_t *__restrict __dest,
+ 				 const wchar_t *__restrict __src,
+@@ -168,9 +149,6 @@ __NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
+ }
+ 
+ 
+-extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest,
+-			       const wchar_t *__restrict __src, size_t __n,
+-			       size_t __destlen) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wcpncpy_alias,
+ 				(wchar_t *__restrict __dest,
+ 				 const wchar_t *__restrict __src,
+@@ -192,9 +170,6 @@ __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
+ }
+ 
+ 
+-extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest,
+-			      const wchar_t *__restrict __src,
+-			      size_t __destlen) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wcscat_alias,
+ 				(wchar_t *__restrict __dest,
+ 				 const wchar_t *__restrict __src), wcscat);
+@@ -209,9 +184,6 @@ __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
+ }
+ 
+ 
+-extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest,
+-			       const wchar_t *__restrict __src,
+-			       size_t __n, size_t __destlen) __THROW;
+ extern wchar_t *__REDIRECT_NTH (__wcsncat_alias,
+ 				(wchar_t *__restrict __dest,
+ 				 const wchar_t *__restrict __src,
+@@ -228,10 +200,6 @@ __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
+ }
+ 
+ 
+-extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n,
+-			   int __flag, size_t __s_len,
+-			   const wchar_t *__restrict __format, ...)
+-     __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
+ 
+ extern int __REDIRECT_NTH_LDBL (__swprintf_alias,
+ 				(wchar_t *__restrict __s, size_t __n,
+@@ -258,11 +226,6 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
+    : swprintf (s, n, __VA_ARGS__))
+ #endif
+ 
+-extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
+-			    int __flag, size_t __s_len,
+-			    const wchar_t *__restrict __format,
+-			    __gnuc_va_list __arg)
+-     __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
+ 
+ extern int __REDIRECT_NTH_LDBL (__vswprintf_alias,
+ 				(wchar_t *__restrict __s, size_t __n,
+@@ -283,16 +246,6 @@ __NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
+ 
+ #if __USE_FORTIFY_LEVEL > 1
+ 
+-extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag,
+-			   const wchar_t *__restrict __format, ...);
+-extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format,
+-			  ...);
+-extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag,
+-			    const wchar_t *__restrict __format,
+-			    __gnuc_va_list __ap);
+-extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format,
+-			   __gnuc_va_list __ap);
+-
+ # ifdef __va_arg_pack
+ __fortify_function int
+ wprintf (const wchar_t *__restrict __fmt, ...)
+@@ -328,8 +281,6 @@ vfwprintf (__FILE *__restrict __stream,
+ 
+ #endif
+ 
+-extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
+-			      __FILE *__restrict __stream) __wur;
+ extern wchar_t *__REDIRECT (__fgetws_alias,
+ 			    (wchar_t *__restrict __s, int __n,
+ 			     __FILE *__restrict __stream), fgetws) __wur;
+@@ -351,9 +302,6 @@ fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
+ }
+ 
+ #ifdef __USE_GNU
+-extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size,
+-				       int __n, __FILE *__restrict __stream)
+-  __wur;
+ extern wchar_t *__REDIRECT (__fgetws_unlocked_alias,
+ 			    (wchar_t *__restrict __s, int __n,
+ 			     __FILE *__restrict __stream), fgetws_unlocked)
+@@ -379,9 +327,6 @@ fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
+ #endif
+ 
+ 
+-extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar,
+-			     mbstate_t *__restrict __p,
+-			     size_t __buflen) __THROW __wur;
+ extern size_t __REDIRECT_NTH (__wcrtomb_alias,
+ 			      (char *__restrict __s, wchar_t __wchar,
+ 			       mbstate_t *__restrict __ps), wcrtomb) __wur;
+@@ -404,10 +349,6 @@ __NTH (wcrtomb (char *__restrict __s, wchar_t __wchar,
+ }
+ 
+ 
+-extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst,
+-			       const char **__restrict __src,
+-			       size_t __len, mbstate_t *__restrict __ps,
+-			       size_t __dstlen) __THROW;
+ extern size_t __REDIRECT_NTH (__mbsrtowcs_alias,
+ 			      (wchar_t *__restrict __dst,
+ 			       const char **__restrict __src,
+@@ -431,10 +372,6 @@ __NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src,
+ }
+ 
+ 
+-extern size_t __wcsrtombs_chk (char *__restrict __dst,
+-			       const wchar_t **__restrict __src,
+-			       size_t __len, mbstate_t *__restrict __ps,
+-			       size_t __dstlen) __THROW;
+ extern size_t __REDIRECT_NTH (__wcsrtombs_alias,
+ 			      (char *__restrict __dst,
+ 			       const wchar_t **__restrict __src,
+@@ -458,10 +395,6 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
+ 
+ 
+ #ifdef	__USE_XOPEN2K8
+-extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
+-				const char **__restrict __src, size_t __nmc,
+-				size_t __len, mbstate_t *__restrict __ps,
+-				size_t __dstlen) __THROW;
+ extern size_t __REDIRECT_NTH (__mbsnrtowcs_alias,
+ 			      (wchar_t *__restrict __dst,
+ 			       const char **__restrict __src, size_t __nmc,
+@@ -485,11 +418,6 @@ __NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src,
+ }
+ 
+ 
+-extern size_t __wcsnrtombs_chk (char *__restrict __dst,
+-				const wchar_t **__restrict __src,
+-				size_t __nwc, size_t __len,
+-				mbstate_t *__restrict __ps, size_t __dstlen)
+-     __THROW;
+ extern size_t __REDIRECT_NTH (__wcsnrtombs_alias,
+ 			      (char *__restrict __dst,
+ 			       const wchar_t **__restrict __src,
+diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
+index 075776890f214842..1c6d4026c46b7306 100644
+--- a/wcsmbs/wchar.h
++++ b/wcsmbs/wchar.h
+@@ -864,14 +864,21 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
+ 
+ /* Define some macros helping to catch buffer overflows.  */
+ #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
+-# include <bits/wchar2.h>
++/* Declare all functions from bits/wchar2-decl.h first.  */
++# include <bits/wchar2-decl.h>
+ #endif
+ 
+-#include <bits/floatn.h>
++/* The following headers provide asm redirections.  These redirections must
++   appear before the first usage of these functions, e.g. in bits/wchar.h.  */
+ #if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
+ # include <bits/wchar-ldbl.h>
+ #endif
+ 
++#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
++/* Now include the function definitions and redirects too.  */
++# include <bits/wchar2.h>
++#endif
++
+ __END_DECLS
+ 
+ #endif /* wchar.h  */
diff --git a/SOURCES/glibc-upstream-2.34-312.patch b/SOURCES/glibc-upstream-2.34-312.patch
new file mode 100644
index 0000000..f8add99
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-312.patch
@@ -0,0 +1,40 @@
+commit 2b3d020055bea4fbbfc0ca2362d46038487c6dfd
+Author: Fabian Vogt <fvogt@suse.de>
+Date:   Wed Jul 27 11:44:07 2022 +0200
+
+    nscd: Fix netlink cache invalidation if epoll is used [BZ #29415]
+    
+    Processes cache network interface information such as whether IPv4 or IPv6
+    are enabled. This is only checked again if the "netlink timestamp" provided
+    by nscd changed, which is triggered by netlink socket activity.
+    
+    However, in the epoll handler for the netlink socket, it was missed to
+    assign the new timestamp to the nscd database. The handler for plain poll
+    did that properly, copy that over.
+    
+    This bug caused that e.g. processes which started before network
+    configuration got unusuable addresses from getaddrinfo, like IPv6 only even
+    though only IPv4 is available:
+    https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1041
+    
+    It's a bit hard to reproduce, so I verified this by checking the timestamp
+    on calls to __check_pf manually. Without this patch it's stuck at 1, now
+    it's increasing on network changes as expected.
+    
+    Signed-off-by: Fabian Vogt <fvogt@suse.de>
+    (cherry picked from commit 02ca25fef2785974011e9c5beecc99b900b69fd7)
+
+diff --git a/nscd/connections.c b/nscd/connections.c
+index 3f0bda4e97edb9df..bc941715cff47c49 100644
+--- a/nscd/connections.c
++++ b/nscd/connections.c
+@@ -2285,7 +2285,8 @@ main_loop_epoll (int efd)
+ 					     sizeof (buf))) != -1)
+ 	      ;
+ 
+-	    __bump_nl_timestamp ();
++	    dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP]
++	      = __bump_nl_timestamp ();
+ 	  }
+ # endif
+ 	else
diff --git a/SOURCES/glibc-upstream-2.34-314.patch b/SOURCES/glibc-upstream-2.34-314.patch
new file mode 100644
index 0000000..be02589
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-314.patch
@@ -0,0 +1,55 @@
+commit 2ff6775ad341b10a08e3b27d6e1df1da637747c7
+Author: Javier Pello <devel@otheo.eu>
+Date:   Mon Sep 5 20:09:01 2022 +0200
+
+    elf: Fix hwcaps string size overestimation
+    
+    Commit dad90d528259b669342757c37dedefa8577e2636 added glibc-hwcaps
+    support for LD_LIBRARY_PATH and, for this, it adjusted the total
+    string size required in _dl_important_hwcaps. However, in doing so
+    it inadvertently altered the calculation of the size required for
+    the power set strings, as the computation of the power set string
+    size depended on the first value assigned to the total variable,
+    which is later shifted, resulting in overallocation of string
+    space. Fix this now by using a different variable to hold the
+    string size required for glibc-hwcaps.
+    
+    Signed-off-by: Javier Pello <devel@otheo.eu>
+    (cherry picked from commit a23820f6052a740246fdc7dcd9c43ce8eed0c45a)
+
+diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c
+index e3c611e005ffbc0d..045911eb6d5d315a 100644
+--- a/elf/dl-hwcaps.c
++++ b/elf/dl-hwcaps.c
+@@ -193,7 +193,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend,
+   /* Each hwcaps subdirectory has a GLIBC_HWCAPS_PREFIX string prefix
+      and a "/" suffix once stored in the result.  */
+   hwcaps_counts.maximum_length += strlen (GLIBC_HWCAPS_PREFIX) + 1;
+-  size_t total = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1)
++  size_t hwcaps_sz = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1)
+ 		  + hwcaps_counts.total_length);
+ 
+   /* Count the number of bits set in the masked value.  */
+@@ -229,11 +229,12 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend,
+   assert (m == cnt);
+ 
+   /* Determine the total size of all strings together.  */
++  size_t total;
+   if (cnt == 1)
+-    total += temp[0].len + 1;
++    total = temp[0].len + 1;
+   else
+     {
+-      total += temp[0].len + temp[cnt - 1].len + 2;
++      total = temp[0].len + temp[cnt - 1].len + 2;
+       if (cnt > 2)
+ 	{
+ 	  total <<= 1;
+@@ -255,6 +256,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend,
+   /* This is the overall result, including both glibc-hwcaps
+      subdirectories and the legacy hwcaps subdirectories using the
+      power set construction.  */
++  total += hwcaps_sz;
+   struct r_strlenpair *overall_result
+     = malloc (*sz * sizeof (*result) + total);
+   if (overall_result == NULL)
diff --git a/SOURCES/glibc-upstream-2.34-315.patch b/SOURCES/glibc-upstream-2.34-315.patch
new file mode 100644
index 0000000..89512a1
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-315.patch
@@ -0,0 +1,62 @@
+commit f50a6c843a5b5186c0aa73747de033e08ef8246d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Sep 20 12:12:43 2022 +0200
+
+    gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583)
+    
+    It's possible that inode numbers are outside the 32-bit range.
+    The existing code only handles the in-libc case correctly, and
+    still uses the legacy interfaces when building iconv.
+    
+    Suggested-by: Helge Deller <deller@gmx.de>
+    (cherry picked from commit f97905f24631097af325d6a231093071c3077a5f)
+
+diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
+index 79398a980cde84e3..741cf7c67e36eccd 100644
+--- a/iconv/gconv_parseconfdir.h
++++ b/iconv/gconv_parseconfdir.h
+@@ -29,14 +29,14 @@
+ # define isspace(__c) __isspace_l ((__c), _nl_C_locobj_ptr)
+ # define asprintf __asprintf
+ # define opendir __opendir
+-# define readdir __readdir
++# define readdir64 __readdir64
+ # define closedir __closedir
+ # define mempcpy __mempcpy
+-# define struct_stat struct __stat64_t64
+-# define lstat __lstat64_time64
++# define struct_stat64 struct __stat64_t64
++# define lstat64 __lstat64_time64
+ # define feof_unlocked __feof_unlocked
+ #else
+-# define struct_stat struct stat
++# define struct_stat64 struct stat64
+ #endif
+ 
+ /* Name of the file containing the module information in the directories
+@@ -148,8 +148,8 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
+   DIR *confdir = opendir (buf);
+   if (confdir != NULL)
+     {
+-      struct dirent *ent;
+-      while ((ent = readdir (confdir)) != NULL)
++      struct dirent64 *ent;
++      while ((ent = readdir64 (confdir)) != NULL)
+ 	{
+ 	  if (ent->d_type != DT_REG && ent->d_type != DT_UNKNOWN)
+ 	    continue;
+@@ -161,12 +161,12 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
+ 	      && strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
+ 	    {
+ 	      char *conf;
+-	      struct_stat st;
++	      struct_stat64 st;
+ 	      if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
+ 		continue;
+ 
+ 	      if (ent->d_type != DT_UNKNOWN
+-		  || (lstat (conf, &st) != -1 && S_ISREG (st.st_mode)))
++		  || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode)))
+ 		found |= read_conf_file (conf, dir, dir_len);
+ 
+ 	      free (conf);
diff --git a/SOURCES/glibc-upstream-2.34-316.patch b/SOURCES/glibc-upstream-2.34-316.patch
new file mode 100644
index 0000000..6712840
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-316.patch
@@ -0,0 +1,399 @@
+commit 1a3afdfe319a142228498f7a4ee82ac3917d97e8
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    resolv: Add tst-resolv-byaddr for testing reverse lookup
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 0b99828d54e5d1fc8f5ad3edf5ba262ad2e9c5b0)
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index e8269dcb5bcf216b..78165eb99e98b525 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -92,6 +92,7 @@ tests += \
+   tst-res_hnok \
+   tst-resolv-basic \
+   tst-resolv-binary \
++  tst-resolv-byaddr \
+   tst-resolv-edns \
+   tst-resolv-network \
+   tst-resolv-noaaaa \
+@@ -251,6 +252,7 @@ $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \
+   $(gen-locales) $(objpfx)tst-no-libidn2.so
+ $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-res_init: $(objpfx)libresolv.so
+diff --git a/resolv/tst-resolv-byaddr.c b/resolv/tst-resolv-byaddr.c
+new file mode 100644
+index 0000000000000000..6299e89837da58c6
+--- /dev/null
++++ b/resolv/tst-resolv-byaddr.c
+@@ -0,0 +1,326 @@
++/* Test reverse DNS lookup.
++   Copyright (C) 2022 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 <arpa/inet.h>
++#include <errno.h>
++#include <netdb.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/next_to_fault.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++#include "tst-resolv-maybe_insert_sig.h"
++
++/* QNAME format:
++
++   ADDRESSES.CNAMES...(lots of 0s)...8.b.d.0.1.0.0.2.ip6.arpa.
++   CNAMES|ADDRESSES.2.0.192.in-addr-arpa.
++
++   For the IPv4 reverse lookup, the address count is in the lower
++   bits.
++
++   CNAMES is the length of the CNAME chain, ADDRESSES is the number of
++   addresses in the response.  The special value 15 means that there
++   are no addresses, and the RCODE is NXDOMAIN.  */
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  TEST_COMPARE (qclass, C_IN);
++  TEST_COMPARE (qtype, T_PTR);
++
++  unsigned int addresses, cnames, bits;
++  char *tail;
++  if (strstr (qname, "ip6.arpa") != NULL
++      && sscanf (qname, "%x.%x.%ms", &addresses, &cnames, &tail) == 3)
++    TEST_COMPARE_STRING (tail, "\
++0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa");
++  else if (sscanf (qname, "%u.%ms", &bits, &tail) == 2)
++    {
++      TEST_COMPARE_STRING (tail, "2.0.192.in-addr.arpa");
++      addresses = bits & 0x0f;
++      cnames = bits >> 4;
++    }
++  else
++    FAIL_EXIT1 ("invalid QNAME: %s", qname);
++  free (tail);
++
++  int rcode;
++  if (addresses == 15)
++    {
++      /* Special case: Use no addresses with NXDOMAIN response.  */
++      rcode = ns_r_nxdomain;
++      addresses = 0;
++    }
++  else
++    rcode = 0;
++
++  struct resolv_response_flags flags = { .rcode = rcode };
++  resolv_response_init (b, flags);
++  resolv_response_add_question (b, qname, qclass, qtype);
++  resolv_response_section (b, ns_s_an);
++  maybe_insert_sig (b, qname);
++
++  /* Provide the requested number of CNAME records.  */
++  char *previous_name = (char *) qname;
++  for (int unique = 0; unique < cnames; ++unique)
++    {
++      resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60);
++      char *new_name = xasprintf ("%d.alias.example", unique);
++      resolv_response_add_name (b, new_name);
++      resolv_response_close_record (b);
++
++      maybe_insert_sig (b, qname);
++
++      if (previous_name != qname)
++        free (previous_name);
++      previous_name = new_name;
++    }
++
++  for (int unique = 0; unique < addresses; ++unique)
++    {
++      resolv_response_open_record (b, previous_name, qclass, T_PTR, 60);
++      char *ptr = xasprintf ("unique-%d.cnames-%u.addresses-%u.example",
++                             unique, cnames, addresses);
++      resolv_response_add_name (b, ptr);
++      free (ptr);
++      resolv_response_close_record (b);
++    }
++
++  if (previous_name != qname)
++    free (previous_name);
++}
++
++/* Used to check that gethostbyaddr_r does not write past the buffer
++   end.  */
++static struct support_next_to_fault ntf;
++
++/* Perform a gethostbyaddr call and check the result.  */
++static void
++check_gethostbyaddr (const char *address, const char *expected)
++{
++  unsigned char bytes[16];
++  unsigned int byteslen;
++  int family;
++  if (strchr (address, ':') != NULL)
++    {
++      family = AF_INET6;
++      byteslen = 16;
++    }
++  else
++    {
++      family = AF_INET;
++      byteslen = 4;
++    }
++  TEST_COMPARE (inet_pton (family, address, bytes), 1);
++
++  struct hostent *e = gethostbyaddr (bytes, byteslen, family);
++  check_hostent (address, e, expected);
++
++  if (e == NULL)
++    return;
++
++  /* Try gethostbyaddr_r with increasing sizes until success.  First
++     compute a reasonable minimum buffer size, to avoid many pointless
++     attempts.  */
++  size_t minimum_size = strlen (e->h_name);
++  for (int i = 0; e->h_addr_list[i] != NULL; ++i)
++    minimum_size += e->h_length + sizeof (char *);
++  for (int i = 0; e->h_aliases[i] != NULL; ++i)
++    minimum_size += strlen (e->h_aliases[i]) + 1 + sizeof (char *);
++
++  /* Gradually increase the size until success.  */
++  for (size_t size = minimum_size; size < ntf.length; ++size)
++    {
++      struct hostent result;
++      int herrno;
++      int ret = gethostbyaddr_r (bytes, byteslen, family, &result,
++                                 ntf.buffer + ntf.length - size, size,
++                                 &e, &herrno);
++      if (ret == ERANGE)
++        /* Retry with larger size.  */
++        TEST_COMPARE (herrno, NETDB_INTERNAL);
++      else if (ret == 0)
++        {
++         TEST_VERIFY (size > minimum_size);
++         check_hostent (address, e, expected);
++         return;
++        }
++      else
++        FAIL_EXIT1 ("Unexpected gethostbyaddr_r failure: %d", ret);
++    }
++
++  FAIL_EXIT1 ("gethostbyaddr_r always failed for: %s", address);
++}
++
++/* Perform a getnameinfo call and check the result.  */
++static void
++check_getnameinfo (const char *address, const char *expected)
++{
++  struct sockaddr_in sin = { };
++  struct sockaddr_in6 sin6 = { };
++  void *sa;
++  socklen_t salen;
++  if (strchr (address, ':') != NULL)
++    {
++      sin6.sin6_family = AF_INET6;
++      TEST_COMPARE (inet_pton (AF_INET6, address, &sin6.sin6_addr), 1);
++      sin6.sin6_port = htons (80);
++      sa = &sin6;
++      salen = sizeof (sin6);
++    }
++  else
++    {
++      sin.sin_family = AF_INET;
++      TEST_COMPARE (inet_pton (AF_INET, address, &sin.sin_addr), 1);
++      sin.sin_port = htons (80);
++      sa = &sin;
++      salen = sizeof (sin);
++    }
++
++  char host[64];
++  char service[64];
++  int ret = getnameinfo (sa, salen, host,
++                         sizeof (host), service, sizeof (service),
++                         NI_NAMEREQD | NI_NUMERICSERV);
++  switch (ret)
++    {
++    case 0:
++      TEST_COMPARE_STRING (host, expected);
++      TEST_COMPARE_STRING (service, "80");
++      break;
++    case EAI_SYSTEM:
++      TEST_COMPARE_STRING (strerror (errno), expected);
++      break;
++    default:
++      TEST_COMPARE_STRING (gai_strerror (ret), expected);
++    }
++}
++
++static int
++do_test (void)
++{
++  /* Some reasonably upper bound for the maximum response size.  */
++  ntf = support_next_to_fault_allocate (4096);
++
++  struct resolv_test *obj = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response
++     });
++
++  for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig)
++    {
++      insert_sig = do_insert_sig;
++
++      /* No PTR record, RCODE=0.  */
++      check_gethostbyaddr ("192.0.2.0", "error: NO_RECOVERY\n");
++      check_getnameinfo ("192.0.2.0", "Name or service not known");
++      check_gethostbyaddr ("192.0.2.16", "error: NO_RECOVERY\n");
++      check_getnameinfo ("192.0.2.16", "Name or service not known");
++      check_gethostbyaddr ("192.0.2.32", "error: NO_RECOVERY\n");
++      check_getnameinfo ("192.0.2.32", "Name or service not known");
++      check_gethostbyaddr ("2001:db8::", "error: NO_RECOVERY\n");
++      check_getnameinfo ("2001:db8::", "Name or service not known");
++      check_gethostbyaddr ("2001:db8::10", "error: NO_RECOVERY\n");
++      check_getnameinfo ("2001:db8::10", "Name or service not known");
++      check_gethostbyaddr ("2001:db8::20", "error: NO_RECOVERY\n");
++      check_getnameinfo ("2001:db8::20", "Name or service not known");
++
++      /* No PTR record, NXDOMAIN.  */
++      check_gethostbyaddr ("192.0.2.15", "error: HOST_NOT_FOUND\n");
++      check_getnameinfo ("192.0.2.15", "Name or service not known");
++      check_gethostbyaddr ("192.0.2.31", "error: HOST_NOT_FOUND\n");
++      check_getnameinfo ("192.0.2.31", "Name or service not known");
++      check_gethostbyaddr ("192.0.2.47", "error: HOST_NOT_FOUND\n");
++      check_getnameinfo ("192.0.2.47", "Name or service not known");
++      check_gethostbyaddr ("2001:db8::f", "error: HOST_NOT_FOUND\n");
++      check_getnameinfo ("2001:db8::f", "Name or service not known");
++      check_gethostbyaddr ("2001:db8::1f", "error: HOST_NOT_FOUND\n");
++      check_getnameinfo ("2001:db8::1f", "Name or service not known");
++      check_gethostbyaddr ("2001:db8::2f", "error: HOST_NOT_FOUND\n");
++      check_getnameinfo ("2001:db8::2f", "Name or service not known");
++
++      /* Actual response data.  Only the first PTR record is returned.  */
++      check_gethostbyaddr ("192.0.2.1",
++                           "name: unique-0.cnames-0.addresses-1.example\n"
++                           "address: 192.0.2.1\n");
++      check_getnameinfo ("192.0.2.1",
++                         "unique-0.cnames-0.addresses-1.example");
++      check_gethostbyaddr ("192.0.2.17",
++                           "name: unique-0.cnames-1.addresses-1.example\n"
++                           "address: 192.0.2.17\n");
++      check_getnameinfo ("192.0.2.17",
++                         "unique-0.cnames-1.addresses-1.example");
++      check_gethostbyaddr ("192.0.2.18",
++                           "name: unique-0.cnames-1.addresses-2.example\n"
++                           "address: 192.0.2.18\n");
++      check_getnameinfo ("192.0.2.18",
++                         "unique-0.cnames-1.addresses-2.example");
++      check_gethostbyaddr ("192.0.2.33",
++                           "name: unique-0.cnames-2.addresses-1.example\n"
++                           "address: 192.0.2.33\n");
++      check_getnameinfo ("192.0.2.33",
++                         "unique-0.cnames-2.addresses-1.example");
++      check_gethostbyaddr ("192.0.2.34",
++                           "name: unique-0.cnames-2.addresses-2.example\n"
++                           "address: 192.0.2.34\n");
++      check_getnameinfo ("192.0.2.34",
++                         "unique-0.cnames-2.addresses-2.example");
++
++      /* Same for IPv6 addresses.  */
++      check_gethostbyaddr ("2001:db8::1",
++                           "name: unique-0.cnames-0.addresses-1.example\n"
++                           "address: 2001:db8::1\n");
++      check_getnameinfo ("2001:db8::1",
++                         "unique-0.cnames-0.addresses-1.example");
++      check_gethostbyaddr ("2001:db8::11",
++                           "name: unique-0.cnames-1.addresses-1.example\n"
++                           "address: 2001:db8::11\n");
++      check_getnameinfo ("2001:db8::11",
++                         "unique-0.cnames-1.addresses-1.example");
++      check_gethostbyaddr ("2001:db8::12",
++                           "name: unique-0.cnames-1.addresses-2.example\n"
++                           "address: 2001:db8::12\n");
++      check_getnameinfo ("2001:db8::12",
++                         "unique-0.cnames-1.addresses-2.example");
++      check_gethostbyaddr ("2001:db8::21",
++                           "name: unique-0.cnames-2.addresses-1.example\n"
++                           "address: 2001:db8::21\n");
++      check_getnameinfo ("2001:db8::21",
++                         "unique-0.cnames-2.addresses-1.example");
++      check_gethostbyaddr ("2001:db8::22",
++                           "name: unique-0.cnames-2.addresses-2.example\n"
++                           "address: 2001:db8::22\n");
++      check_getnameinfo ("2001:db8::22",
++                         "unique-0.cnames-2.addresses-2.example");
++    }
++
++  resolv_test_end (obj);
++
++  support_next_to_fault_free (&ntf);
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/resolv/tst-resolv-maybe_insert_sig.h b/resolv/tst-resolv-maybe_insert_sig.h
+new file mode 100644
+index 0000000000000000..05725225af0818cb
+--- /dev/null
++++ b/resolv/tst-resolv-maybe_insert_sig.h
+@@ -0,0 +1,32 @@
++/* Code snippet for optionally inserting ignored SIG records in resolver tests.
++   Copyright (C) 2022 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/>.  */
++
++/* Set to true for an alternative pass that inserts (ignored) SIG
++   records.  This does not alter the response, so this property is not
++   encoded in the QNAME.  The variable needs to be volatile because
++   leaf attributes tell GCC that the response function is not
++   called.  */
++static volatile bool insert_sig;
++
++static void
++maybe_insert_sig (struct resolv_response_builder *b, const char *owner)
++{
++  resolv_response_open_record (b, owner, C_IN, T_SIG, 60);
++  resolv_response_add_data (b, "", 1);
++  resolv_response_close_record (b);
++}
diff --git a/SOURCES/glibc-upstream-2.34-317.patch b/SOURCES/glibc-upstream-2.34-317.patch
new file mode 100644
index 0000000..b99be70
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-317.patch
@@ -0,0 +1,289 @@
+commit 6a833d798e87536587cd4cc14fe8d078f80b14a0
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    resolv: Add tst-resolv-aliases
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 87aa98aa80627553a66bdcad2701fd6307723645)
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 78165eb99e98b525..567f4c2dcf5749df 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -90,6 +90,7 @@ tests += \
+   tst-ns_name_pton \
+   tst-res_hconf_reorder \
+   tst-res_hnok \
++  tst-resolv-aliases \
+   tst-resolv-basic \
+   tst-resolv-binary \
+   tst-resolv-byaddr \
+@@ -250,6 +251,7 @@ $(objpfx)tst-resolv-ai_idn.out: $(gen-locales)
+ $(objpfx)tst-resolv-ai_idn-latin1.out: $(gen-locales)
+ $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \
+   $(gen-locales) $(objpfx)tst-no-libidn2.so
++$(objpfx)tst-resolv-aliases: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library)
+diff --git a/resolv/tst-resolv-aliases.c b/resolv/tst-resolv-aliases.c
+new file mode 100644
+index 0000000000000000..b212823aa07ceb21
+--- /dev/null
++++ b/resolv/tst-resolv-aliases.c
+@@ -0,0 +1,254 @@
++/* Test alias handling (mainly for gethostbyname).
++   Copyright (C) 2022 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 <array_length.h>
++#include <arpa/inet.h>
++#include <netdb.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++
++#include "tst-resolv-maybe_insert_sig.h"
++
++/* QNAME format:
++
++   aADDRESSES-cCNAMES.example.net
++
++   CNAMES is the length of the CNAME chain, ADDRESSES is the number of
++   addresses in the response.  The special value 255 means that there
++   are no addresses, and the RCODE is NXDOMAIN.  */
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  TEST_COMPARE (qclass, C_IN);
++  if (qtype != T_A)
++    TEST_COMPARE (qtype, T_AAAA);
++
++  unsigned int addresses, cnames;
++  char *tail;
++  if (sscanf (qname, "a%u-c%u%ms", &addresses, &cnames, &tail) == 3)
++    {
++      if (strcmp (tail, ".example.com") == 0
++          || strcmp (tail, ".example.net.example.net") == 0
++          || strcmp (tail, ".example.net.example.com") == 0)
++        /* These only happen after NXDOMAIN.  */
++        TEST_VERIFY (addresses == 255);
++      else if (strcmp (tail, ".example.net") != 0)
++        FAIL_EXIT1 ("invalid QNAME: %s", qname);
++    }
++  free (tail);
++
++  int rcode;
++  if (addresses == 255)
++    {
++      /* Special case: Use no addresses with NXDOMAIN response.  */
++      rcode = ns_r_nxdomain;
++      addresses = 0;
++    }
++  else
++    rcode = 0;
++
++  struct resolv_response_flags flags = { .rcode = rcode };
++  resolv_response_init (b, flags);
++  resolv_response_add_question (b, qname, qclass, qtype);
++  resolv_response_section (b, ns_s_an);
++  maybe_insert_sig (b, qname);
++
++  /* Provide the requested number of CNAME records.  */
++  char *previous_name = (char *) qname;
++  for (int unique = 0; unique < cnames; ++unique)
++    {
++      resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60);
++      char *new_name = xasprintf ("%d.alias.example", unique);
++      resolv_response_add_name (b, new_name);
++      resolv_response_close_record (b);
++
++      maybe_insert_sig (b, qname);
++
++      if (previous_name != qname)
++        free (previous_name);
++      previous_name = new_name;
++    }
++
++  for (int unique = 0; unique < addresses; ++unique)
++    {
++      resolv_response_open_record (b, previous_name, qclass, qtype, 60);
++
++      if (qtype == T_A)
++        {
++          char ipv4[4] = {192, 0, 2, 1 + unique};
++          resolv_response_add_data (b, &ipv4, sizeof (ipv4));
++        }
++      else if (qtype == T_AAAA)
++        {
++          char ipv6[16] =
++            {
++              0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++              1 + unique
++            };
++          resolv_response_add_data (b, &ipv6, sizeof (ipv6));
++        }
++      resolv_response_close_record (b);
++    }
++
++  if (previous_name != qname)
++    free (previous_name);
++}
++
++static char *
++make_qname (bool do_search, int cnames, int addresses)
++{
++  return xasprintf ("a%d-c%d%s",
++                    addresses, cnames, do_search ? "" : ".example.net");
++}
++
++static void
++check_cnames_failure (int af, bool do_search, int cnames, int addresses)
++{
++  char *qname = make_qname (do_search, cnames, addresses);
++
++  struct hostent *e;
++  if (af == AF_UNSPEC)
++    e = gethostbyname (qname);
++  else
++    e = gethostbyname2 (qname, af);
++
++  if (addresses == 0)
++    check_hostent (qname, e, "error: NO_RECOVERY\n");
++  else
++    check_hostent (qname, e, "error: HOST_NOT_FOUND\n");
++
++  free (qname);
++}
++
++static void
++check (int af, bool do_search, int cnames, int addresses)
++{
++  char *qname = make_qname (do_search, cnames, addresses);
++  char *fqdn = make_qname (false, cnames, addresses);
++
++  struct hostent *e;
++  if (af == AF_UNSPEC)
++    e = gethostbyname (qname);
++  else
++    e = gethostbyname2 (qname, af);
++  if (e == NULL)
++    FAIL_EXIT1 ("unexpected failure for %d, %d, %d", af, cnames, addresses);
++
++  if (af == AF_UNSPEC || af == AF_INET)
++    {
++      TEST_COMPARE (e->h_addrtype, AF_INET);
++      TEST_COMPARE (e->h_length, 4);
++    }
++  else
++    {
++      TEST_COMPARE (e->h_addrtype, AF_INET6);
++      TEST_COMPARE (e->h_length, 16);
++    }
++
++  for (int i = 0; i < addresses; ++i)
++    {
++      char ipv4[4] = {192, 0, 2, 1 + i};
++      char ipv6[16] =
++        { 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + i };
++      char *expected = e->h_addrtype == AF_INET ? ipv4 : ipv6;
++      TEST_COMPARE_BLOB (e->h_addr_list[i], e->h_length,
++                         expected, e->h_length);
++    }
++  TEST_VERIFY (e->h_addr_list[addresses] == NULL);
++
++
++  if (cnames == 0)
++    {
++      /* QNAME is fully qualified.  */
++      TEST_COMPARE_STRING (e->h_name, fqdn);
++      TEST_VERIFY (e->h_aliases[0] == NULL);
++    }
++  else
++   {
++     /* Fully-qualified QNAME is demoted to an aliases.  */
++     TEST_COMPARE_STRING (e->h_aliases[0], fqdn);
++
++     for (int i = 1; i <= cnames; ++i)
++       {
++         char *expected = xasprintf ("%d.alias.example", i - 1);
++         if (i == cnames)
++           TEST_COMPARE_STRING (e->h_name, expected);
++         else
++           TEST_COMPARE_STRING (e->h_aliases[i], expected);
++         free (expected);
++       }
++     TEST_VERIFY (e->h_aliases[cnames] == NULL);
++   }
++
++  free (fqdn);
++  free (qname);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *obj = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response,
++       .search = { "example.net", "example.com" },
++     });
++
++  static const int families[] = { AF_UNSPEC, AF_INET, AF_INET6 };
++
++  for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig)
++    {
++      insert_sig = do_insert_sig;
++
++      /* If do_search is true, a bare host name (for example, a1-c1)
++         is used.  This exercises search path processing and FQDN
++         qualification.  */
++      for (int do_search = 0; do_search < 2; ++do_search)
++        for (const int *paf = families; paf != array_end (families); ++paf)
++          {
++            for (int cnames = 0; cnames <= 100; ++cnames)
++              {
++                check_cnames_failure (*paf, do_search, cnames, 0);
++                /* Now with NXDOMAIN responses.  */
++                check_cnames_failure (*paf, do_search, cnames, 255);
++              }
++
++            for (int cnames = 0; cnames <= 10; ++cnames)
++              for (int addresses = 1; addresses <= 10; ++addresses)
++                check (*paf, do_search, cnames, addresses);
++
++            /* The current implementation is limited to 47 aliases.
++               Addresses do not have such a limit.  */
++            check (*paf, do_search, 47, 60);
++          }
++    }
++
++  resolv_test_end (obj);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-318.patch b/SOURCES/glibc-upstream-2.34-318.patch
new file mode 100644
index 0000000..0dd08c0
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-318.patch
@@ -0,0 +1,58 @@
+commit 4d2e67d6e5c910114dbccd17d9b93f06552c0024
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    resolv: Add internal __res_binary_hnok function
+    
+    During package parsing, only the binary representation is available,
+    and it is convenient to check that directly for conformance with host
+    name requirements.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit c79327bf00a4be6d60259227acc78ef80ead3622)
+
+diff --git a/include/resolv.h b/include/resolv.h
+index 3590b6f496d47710..4dbbac3800b7ef30 100644
+--- a/include/resolv.h
++++ b/include/resolv.h
+@@ -70,5 +70,8 @@ libc_hidden_proto (__libc_res_nameinquery)
+ extern __typeof (__res_queriesmatch) __libc_res_queriesmatch;
+ libc_hidden_proto (__libc_res_queriesmatch)
+ 
++/* Variant of res_hnok which operates on binary (but uncompressed) names.  */
++bool __res_binary_hnok (const unsigned char *dn) attribute_hidden;
++
+ # endif /* _RESOLV_H_ && !_ISOMAC */
+ #endif
+diff --git a/resolv/res-name-checking.c b/resolv/res-name-checking.c
+index 2c603494fa3ca992..513ddb5f6b12ccb0 100644
+--- a/resolv/res-name-checking.c
++++ b/resolv/res-name-checking.c
+@@ -138,6 +138,12 @@ binary_leading_dash (const unsigned char *dn)
+   return dn[0] > 0 && dn[1] == '-';
+ }
+ 
++bool
++__res_binary_hnok (const unsigned char *dn)
++{
++  return !binary_leading_dash (dn) && binary_hnok (dn);
++}
++
+ /* Return 1 if res_hnok is a valid host name.  Labels must only
+    contain [0-9a-zA-Z_-] characters, and the name must not start with
+    a '-'.  The latter is to avoid confusion with program options.  */
+@@ -145,11 +151,9 @@ int
+ ___res_hnok (const char *dn)
+ {
+   unsigned char buf[NS_MAXCDNAME];
+-  if (!printable_string (dn)
+-      || __ns_name_pton (dn, buf, sizeof (buf)) < 0
+-      || binary_leading_dash (buf))
+-    return 0;
+-  return binary_hnok (buf);
++  return (printable_string (dn)
++	  && __ns_name_pton (dn, buf, sizeof (buf)) >= 0
++	  && __res_binary_hnok (buf));
+ }
+ versioned_symbol (libc, ___res_hnok, res_hnok, GLIBC_2_34);
+ versioned_symbol (libc, ___res_hnok, __libc_res_hnok, GLIBC_PRIVATE);
diff --git a/SOURCES/glibc-upstream-2.34-319.patch b/SOURCES/glibc-upstream-2.34-319.patch
new file mode 100644
index 0000000..e00dfbe
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-319.patch
@@ -0,0 +1,182 @@
+commit bb8adbba4f5d9237a144786ba8e504039beff161
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    resolv: Add the __ns_samebinaryname function
+    
+    During packet parsing, only the binary name is available.  If the name
+    equality check is performed before conversion to text, we can sometimes
+    skip the last step.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 394085a34d25a51513019a4dc411acd3527fbd33)
+
+diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
+index 53f1dbc7c3f659e9..bb1dede187cf1500 100644
+--- a/include/arpa/nameser.h
++++ b/include/arpa/nameser.h
+@@ -55,6 +55,12 @@ int __ns_name_ntop (const unsigned char *, char *, size_t) __THROW;
+ int __ns_name_unpack (const unsigned char *, const unsigned char *,
+ 		      const unsigned char *, unsigned char *, size_t) __THROW;
+ 
++/* Like ns_samename, but for uncompressed binary names.  Return true
++   if the two arguments compare are equal as case-insensitive domain
++   names.  */
++_Bool __ns_samebinaryname (const unsigned char *, const unsigned char *)
++  attribute_hidden;
++
+ #define ns_msg_getflag(handle, flag) \
+   (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
+ 
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 567f4c2dcf5749df..0b4fa30716af3b8a 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -46,6 +46,7 @@ routines := \
+   ns_name_skip \
+   ns_name_uncompress \
+   ns_name_unpack \
++  ns_samebinaryname \
+   ns_samename \
+   nsap_addr \
+   nss_dns_functions \
+@@ -107,6 +108,10 @@ tests += \
+ tests-internal += tst-resolv-txnid-collision
+ tests-static += tst-resolv-txnid-collision
+ 
++# Likewise for __ns_samebinaryname.
++tests-internal += tst-ns_samebinaryname
++tests-static += tst-ns_samebinaryname
++
+ # These tests need libdl.
+ ifeq (yes,$(build-shared))
+ tests += \
+diff --git a/resolv/ns_samebinaryname.c b/resolv/ns_samebinaryname.c
+new file mode 100644
+index 0000000000000000..9a47d8e97a84c759
+--- /dev/null
++++ b/resolv/ns_samebinaryname.c
+@@ -0,0 +1,55 @@
++/* Compare two binary domain names for quality.
++   Copyright (C) 2022 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 <arpa/nameser.h>
++#include <stdbool.h>
++
++/* Convert ASCII letters to upper case.  */
++static inline int
++ascii_toupper (unsigned char ch)
++{
++  if (ch >= 'a' && ch <= 'z')
++    return ch - 'a' + 'A';
++  else
++    return ch;
++}
++
++bool
++__ns_samebinaryname (const unsigned char *a, const unsigned char *b)
++{
++  while (*a != 0 && *b != 0)
++    {
++      if (*a != *b)
++        /* Different label length.  */
++        return false;
++      int labellen = *a;
++      ++a;
++      ++b;
++      for (int i = 0; i < labellen; ++i)
++        {
++          if (*a != *b && ascii_toupper (*a) != ascii_toupper (*b))
++            /* Different character in label.  */
++            return false;
++          ++a;
++          ++b;
++        }
++    }
++
++  /* Match if both names are at the root label.  */
++  return *a == 0 && *b == 0;
++}
+diff --git a/resolv/tst-ns_samebinaryname.c b/resolv/tst-ns_samebinaryname.c
+new file mode 100644
+index 0000000000000000..b06ac610b4cde8be
+--- /dev/null
++++ b/resolv/tst-ns_samebinaryname.c
+@@ -0,0 +1,62 @@
++/* Test the __ns_samebinaryname function.
++   Copyright (C) 2022 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 <arpa/nameser.h>
++#include <array_length.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <support/check.h>
++
++/* First character denotes the comparison group: All names with the
++   same first character are expected to compare equal.  */
++static const char *const cases[] =
++  {
++    " ",
++    "1\001a", "1\001A",
++    "2\002ab", "2\002aB", "2\002Ab", "2\002AB",
++    "3\001a\002ab", "3\001A\002ab",
++    "w\003www\007example\003com", "w\003Www\007Example\003Com",
++    "w\003WWW\007EXAMPLE\003COM",
++    "W\003WWW", "W\003www",
++  };
++
++static int
++do_test (void)
++{
++  for (int i = 0; i < array_length (cases); ++i)
++    for (int j = 0; j < array_length (cases); ++j)
++      {
++        unsigned char *a = (unsigned char *) &cases[i][1];
++        unsigned char *b = (unsigned char *) &cases[j][1];
++        bool actual = __ns_samebinaryname (a, b);
++        bool expected = cases[i][0] == cases[j][0];
++        if (actual != expected)
++          {
++            char a1[NS_MAXDNAME];
++            TEST_VERIFY (ns_name_ntop (a, a1, sizeof (a1)) > 0);
++            char b1[NS_MAXDNAME];
++            TEST_VERIFY (ns_name_ntop (b, b1, sizeof (b1)) > 0);
++            printf ("error: \"%s\" \"%s\": expected %s\n",
++                    a1, b1, expected ? "equal" : "unqueal");
++            support_record_failure ();
++          }
++      }
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-320.patch b/SOURCES/glibc-upstream-2.34-320.patch
new file mode 100644
index 0000000..617e31c
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-320.patch
@@ -0,0 +1,272 @@
+commit c288e032ae107c48679ef3c46fb84af6de0a6baf
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    resolv: Add internal __ns_name_length_uncompressed function
+    
+    This function is useful for checking that the question name is
+    uncompressed (as it should be).
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 78b1a4f0e49064e5dfb686c7cd87bd4df2640b29)
+
+diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
+index bb1dede187cf1500..6e4808f00d60caf9 100644
+--- a/include/arpa/nameser.h
++++ b/include/arpa/nameser.h
+@@ -95,5 +95,13 @@ libc_hidden_proto (__ns_name_unpack)
+ extern __typeof (ns_samename) __libc_ns_samename;
+ libc_hidden_proto (__libc_ns_samename)
+ 
++/* Packet parser helper functions.  */
++
++/* Verify that P points to an uncompressed domain name in wire format.
++   On success, return the length of the encoded name, including the
++   terminating null byte.  On failure, return -1 and set errno.  EOM
++   must point one past the last byte in the packet.  */
++int __ns_name_length_uncompressed (const unsigned char *p,
++				   const unsigned char *eom) attribute_hidden;
+ # endif /* !_ISOMAC */
+ #endif
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 0b4fa30716af3b8a..308f18622a04965a 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -40,6 +40,7 @@ routines := \
+   inet_pton \
+   ns_makecanon \
+   ns_name_compress \
++  ns_name_length_uncompressed \
+   ns_name_ntop \
+   ns_name_pack \
+   ns_name_pton \
+@@ -112,6 +113,10 @@ tests-static += tst-resolv-txnid-collision
+ tests-internal += tst-ns_samebinaryname
+ tests-static += tst-ns_samebinaryname
+ 
++# Likewise for __ns_name_length_uncompressed.
++tests-internal += tst-ns_name_length_uncompressed
++tests-static += tst-ns_name_length_uncompressed
++
+ # These tests need libdl.
+ ifeq (yes,$(build-shared))
+ tests += \
+diff --git a/resolv/ns_name_length_uncompressed.c b/resolv/ns_name_length_uncompressed.c
+new file mode 100644
+index 0000000000000000..51296b47efbf1849
+--- /dev/null
++++ b/resolv/ns_name_length_uncompressed.c
+@@ -0,0 +1,72 @@
++/* Skip over an uncompressed name in wire format.
++   Copyright (C) 2022 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 <arpa/nameser.h>
++#include <errno.h>
++#include <stdbool.h>
++
++int
++__ns_name_length_uncompressed (const unsigned char *p,
++                                const unsigned char *eom)
++{
++  const unsigned char *start = p;
++
++  while (true)
++    {
++      if (p == eom)
++        {
++          /* Truncated packet: no room for label length.  */
++          __set_errno (EMSGSIZE);
++          return -1;
++        }
++
++      unsigned char b = *p;
++      ++p;
++      if (b == 0)
++        {
++          /* Root label.  */
++          size_t length = p - start;
++          if (length > NS_MAXCDNAME)
++            {
++              /* Domain name too long.  */
++              __set_errno (EMSGSIZE);
++              return -1;
++            }
++          return length;
++        }
++
++      if (b <= 63)
++        {
++          /* Regular label.  */
++          if (b <= eom - p)
++            p += b;
++          else
++            {
++              /* Truncated packet: label incomplete.  */
++              __set_errno (EMSGSIZE);
++              return -1;
++            }
++        }
++      else
++        {
++          /* Compression reference or corrupted label length.  */
++          __set_errno (EMSGSIZE);
++          return -1;
++        }
++    }
++}
+diff --git a/resolv/tst-ns_name_length_uncompressed.c b/resolv/tst-ns_name_length_uncompressed.c
+new file mode 100644
+index 0000000000000000..c4a2904db75d1221
+--- /dev/null
++++ b/resolv/tst-ns_name_length_uncompressed.c
+@@ -0,0 +1,135 @@
++/* Test __ns_name_length_uncompressed.
++   Copyright (C) 2022 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 <arpa/nameser.h>
++#include <array_length.h>
++#include <errno.h>
++#include <stdio.h>
++#include <support/check.h>
++#include <support/next_to_fault.h>
++
++/* Reference implementation based on other building blocks.  */
++static int
++reference_length (const unsigned char *p, const unsigned char *eom)
++{
++  unsigned char buf[NS_MAXCDNAME];
++  int n = __ns_name_unpack (p, eom, p, buf, sizeof (buf));
++  if (n < 0)
++    return n;
++  const unsigned char *q = buf;
++  if (__ns_name_skip (&q, array_end (buf)) < 0)
++    return -1;
++  if (q - buf != n)
++    /* Compressed name.  */
++    return -1;
++  return n;
++}
++
++static int
++do_test (void)
++{
++  {
++    unsigned char buf[] = { 3, 'w', 'w', 'w', 0, 0, 0 };
++    TEST_COMPARE (reference_length (buf, array_end (buf)), sizeof (buf) - 2);
++    TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)),
++                  sizeof (buf) - 2);
++    TEST_COMPARE (reference_length (array_end (buf) - 1, array_end (buf)), 1);
++    TEST_COMPARE (__ns_name_length_uncompressed (array_end (buf) - 1,
++                                                 array_end (buf)), 1);
++    buf[4]  = 0xc0;             /* Forward compression reference.  */
++    buf[5]  = 0x06;
++    TEST_COMPARE (reference_length (buf, array_end (buf)), -1);
++    TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)), -1);
++  }
++
++  struct support_next_to_fault ntf = support_next_to_fault_allocate (300);
++
++  /* Buffer region with all possible bytes at start and end.  */
++  for (int length = 1; length <= 300; ++length)
++    {
++      unsigned char *end = (unsigned char *) ntf.buffer + ntf.length;
++      unsigned char *start = end - length;
++      memset (start, 'X', length);
++      for (int first = 0; first <= 255; ++first)
++        {
++          *start = first;
++          for (int last = 0; last <= 255; ++last)
++            {
++              start[length - 1] = last;
++              TEST_COMPARE (reference_length (start, end),
++                            __ns_name_length_uncompressed (start, end));
++            }
++        }
++    }
++
++  /* Poor man's fuzz testing: patch two bytes.   */
++  {
++    unsigned char ref[] =
++      {
++        7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'n', 'e', 't', 0, 0, 0
++      };
++    TEST_COMPARE (reference_length (ref, array_end (ref)), 13);
++    TEST_COMPARE (__ns_name_length_uncompressed (ref, array_end (ref)), 13);
++
++    int good = 0;
++    int bad = 0;
++    for (int length = 1; length <= sizeof (ref); ++length)
++      {
++        unsigned char *end = (unsigned char *) ntf.buffer + ntf.length;
++        unsigned char *start = end - length;
++        memcpy (start, ref, length);
++
++        for (int patch1_pos = 0; patch1_pos < length; ++patch1_pos)
++          {
++            for (int patch1_value = 0; patch1_value <= 255; ++patch1_value)
++              {
++                start[patch1_pos] = patch1_value;
++                for (int patch2_pos = 0; patch2_pos < length; ++patch2_pos)
++                  {
++                    for (int patch2_value = 0; patch2_value <= 255;
++                         ++patch2_value)
++                      {
++                        start[patch2_pos] = patch2_value;
++                        int expected = reference_length (start, end);
++                        errno = EINVAL;
++                        int actual
++                          =  __ns_name_length_uncompressed (start, end);
++                        if (actual > 0)
++                          ++good;
++                        else
++                          {
++                            TEST_COMPARE (errno, EMSGSIZE);
++                            ++bad;
++                          }
++                        TEST_COMPARE (expected, actual);
++                      }
++                    start[patch2_pos] = ref[patch2_pos];
++                  }
++              }
++            start[patch1_pos] = ref[patch1_pos];
++          }
++      }
++    printf ("info: patched inputs with success: %d\n", good);
++    printf ("info: patched inputs with failure: %d\n", bad);
++  }
++
++  support_next_to_fault_free (&ntf);
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-321.patch b/SOURCES/glibc-upstream-2.34-321.patch
new file mode 100644
index 0000000..c32e7ce
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-321.patch
@@ -0,0 +1,532 @@
+commit e7c03f47651bd451ebf2c3c65899491d0bf7167e
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    resolv: Add DNS packet parsing helpers geared towards wire format
+    
+    The public parser functions around the ns_rr record type produce
+    textual domain names, but usually, this is not what we need while
+    parsing DNS packets within glibc.  This commit adds two new helper
+    functions, __ns_rr_cursor_init and __ns_rr_cursor_next, for writing
+    packet parsers, and struct ns_rr_cursor, struct ns_rr_wire as
+    supporting types.
+    
+    In theory, it is possible to avoid copying the owner name
+    into the rname field in __ns_rr_cursor_next, but this would need
+    more functions that work on compressed names.
+    
+    Eventually, __res_context_send could be enhanced to preserve the
+    result of the packet parsing that is necessary for matching the
+    incoming UDP packets, so that this works does not have to be done
+    twice.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 857c890d9b42c50c8a94b76d47d4a61ab6d2f49c)
+
+diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
+index 6e4808f00d60caf9..c27e7886b7891997 100644
+--- a/include/arpa/nameser.h
++++ b/include/arpa/nameser.h
+@@ -103,5 +103,97 @@ libc_hidden_proto (__libc_ns_samename)
+    must point one past the last byte in the packet.  */
+ int __ns_name_length_uncompressed (const unsigned char *p,
+ 				   const unsigned char *eom) attribute_hidden;
++
++/* Iterator over the resource records in a DNS packet.  */
++struct ns_rr_cursor
++{
++  /* These members are not changed after initialization.  */
++  const unsigned char *begin;	/* First byte of packet.  */
++  const unsigned char *end;	/* One past the last byte of the packet.  */
++  const unsigned char *first_rr; /* First resource record (or packet end).  */
++
++  /* Advanced towards the end while reading the packet.  */
++  const unsigned char *current;
++};
++
++/* Returns the RCODE field from the DNS header.  */
++static inline int
++ns_rr_cursor_rcode (const struct ns_rr_cursor *c)
++{
++  return c->begin[3] & 0x0f;	/* Lower 4 bits at offset 3.  */
++}
++
++/* Returns the length of the answer section according to the DNS header.  */
++static inline int
++ns_rr_cursor_ancount (const struct ns_rr_cursor *c)
++{
++  return c->begin[6] * 256 + c->begin[7]; /* 16 bits at offset 6.  */
++}
++
++/* Returns the length of the authority (name server) section according
++   to the DNS header.  */
++static inline int
++ns_rr_cursor_nscount (const struct ns_rr_cursor *c)
++{
++  return c->begin[8] * 256 + c->begin[9]; /* 16 bits at offset 8.  */
++}
++
++/* Returns the length of the additional data section according to the
++   DNS header.  */
++static inline int
++ns_rr_cursor_adcount (const struct ns_rr_cursor *c)
++{
++  return c->begin[10] * 256 + c->begin[11]; /* 16 bits at offset 10.  */
++}
++
++/* Returns a pointer to the uncompressed question name in wire
++   format.  */
++static inline const unsigned char *
++ns_rr_cursor_qname (const struct ns_rr_cursor *c)
++{
++  return c->begin + 12;		/* QNAME starts right after the header.  */
++}
++
++/* Returns the question type of the first and only question.  */
++static inline const int
++ns_rr_cursor_qtype (const struct ns_rr_cursor *c)
++{
++  /* 16 bits 4 bytes back from the first RR header start.  */
++  return c->first_rr[-4] * 256 + c->first_rr[-3];
++}
++
++/* Returns the clss of the first and only question (usally C_IN).  */
++static inline const int
++ns_rr_cursor_qclass (const struct ns_rr_cursor *c)
++{
++  /* 16 bits 2 bytes back from the first RR header start.  */
++  return c->first_rr[-2] * 256 + c->first_rr[-1];
++}
++
++/* Initializes *C to cover the packet [BUF, BUF+LEN).  Returns false
++   if LEN is less than sizeof (*HD), if the packet does not contain a
++   full (uncompressed) question, or if the question count is not 1.  */
++_Bool __ns_rr_cursor_init (struct ns_rr_cursor *c,
++			   const unsigned char *buf, size_t len)
++  attribute_hidden;
++
++/* Like ns_rr, but the record owner name is not decoded into text format.  */
++struct ns_rr_wire
++{
++  unsigned char rname[NS_MAXCDNAME]; /* Owner name of the record.  */
++  uint16_t rtype;		/* Resource record type (T_*).  */
++  uint16_t rclass;		/* Resource record class (C_*).  */
++  uint32_t ttl;			/* Time-to-live field.  */
++  const unsigned char *rdata;	/* Start of resource record data.  */
++  uint16_t rdlength;		/* Length of the data at rdata, in bytes.  */
++};
++
++/* Attempts to parse the record at C into *RR.  On success, return
++   true, and C is advanced past the record, and RR->rdata points to
++   the record data.  On failure, errno is set to EMSGSIZE, and false
++   is returned.  */
++_Bool __ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr)
++  attribute_hidden;
++
+ # endif /* !_ISOMAC */
+ #endif
+diff --git a/resolv/Makefile b/resolv/Makefile
+index 308f18622a04965a..fded244d61068060 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -47,6 +47,8 @@ routines := \
+   ns_name_skip \
+   ns_name_uncompress \
+   ns_name_unpack \
++  ns_rr_cursor_init \
++  ns_rr_cursor_next \
+   ns_samebinaryname \
+   ns_samename \
+   nsap_addr \
+@@ -117,6 +119,10 @@ tests-static += tst-ns_samebinaryname
+ tests-internal += tst-ns_name_length_uncompressed
+ tests-static += tst-ns_name_length_uncompressed
+ 
++# Likewise for struct ns_rr_cursor and its functions.
++tests-internal += tst-ns_rr_cursor
++tests-static += tst-ns_rr_cursor
++
+ # These tests need libdl.
+ ifeq (yes,$(build-shared))
+ tests += \
+diff --git a/resolv/ns_rr_cursor_init.c b/resolv/ns_rr_cursor_init.c
+new file mode 100644
+index 0000000000000000..6ee80b30e927ecb7
+--- /dev/null
++++ b/resolv/ns_rr_cursor_init.c
+@@ -0,0 +1,62 @@
++/* Initialize a simple DNS packet parser.
++   Copyright (C) 2022 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 <arpa/nameser.h>
++#include <errno.h>
++#include <stdbool.h>
++#include <string.h>
++
++bool
++__ns_rr_cursor_init (struct ns_rr_cursor *c,
++                     const unsigned char *buf, size_t len)
++{
++  c->begin = buf;
++  c->end = buf + len;
++
++  /* Check for header size and 16-bit question count value (it must be 1).  */
++  if (len < 12 || buf[4] != 0 || buf[5] != 1)
++    {
++      __set_errno (EMSGSIZE);
++      c->current = c->end;
++      return false;
++    }
++  c->current = buf + 12;
++
++  int consumed = __ns_name_length_uncompressed (c->current, c->end);
++  if (consumed < 0)
++    {
++      __set_errno (EMSGSIZE);
++      c->current = c->end;
++      c->first_rr = NULL;
++      return false;
++    }
++  c->current += consumed;
++
++  /* Ensure there is room for question type and class.  */
++  if (c->end - c->current < 4)
++    {
++      __set_errno (EMSGSIZE);
++      c->current = c->end;
++      c->first_rr = NULL;
++      return false;
++    }
++  c->current += 4;
++  c->first_rr = c->current;
++
++  return true;
++}
+diff --git a/resolv/ns_rr_cursor_next.c b/resolv/ns_rr_cursor_next.c
+new file mode 100644
+index 0000000000000000..33652fc5da322d69
+--- /dev/null
++++ b/resolv/ns_rr_cursor_next.c
+@@ -0,0 +1,74 @@
++/* Simple DNS record parser without textual name decoding.
++   Copyright (C) 2022 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 <arpa/nameser.h>
++#include <errno.h>
++#include <stdbool.h>
++#include <string.h>
++
++bool
++__ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr)
++{
++  rr->rdata = NULL;
++
++  /* Extract the record owner name.  */
++  int consumed = __ns_name_unpack (c->begin, c->end, c->current,
++                                   rr->rname, sizeof (rr->rname));
++  if (consumed < 0)
++    {
++      memset (rr, 0, sizeof (*rr));
++      __set_errno (EMSGSIZE);
++      return false;
++    }
++  c->current += consumed;
++
++  /* Extract the metadata.  */
++  struct
++  {
++    uint16_t rtype;
++    uint16_t rclass;
++    uint32_t ttl;
++    uint16_t rdlength;
++  } __attribute__ ((packed)) metadata;
++  _Static_assert (sizeof (metadata) == 10, "sizeof metadata");
++  if (c->end - c->current < sizeof (metadata))
++    {
++      memset (rr, 0, sizeof (*rr));
++      __set_errno (EMSGSIZE);
++      return false;
++    }
++  memcpy (&metadata, c->current, sizeof (metadata));
++  c->current += sizeof (metadata);
++  /* Endianess conversion.  */
++  rr->rtype = ntohs (metadata.rtype);
++  rr->rclass = ntohs (metadata.rclass);
++  rr->ttl = ntohl (metadata.ttl);
++  rr->rdlength = ntohs (metadata.rdlength);
++
++  /* Extract record data.  */
++  if (c->end - c->current < rr->rdlength)
++    {
++      memset (rr, 0, sizeof (*rr));
++      __set_errno (EMSGSIZE);
++      return false;
++    }
++  rr->rdata = c->current;
++  c->current += rr->rdlength;
++
++  return true;
++}
+diff --git a/resolv/tst-ns_rr_cursor.c b/resolv/tst-ns_rr_cursor.c
+new file mode 100644
+index 0000000000000000..c3c09089053d0c40
+--- /dev/null
++++ b/resolv/tst-ns_rr_cursor.c
+@@ -0,0 +1,227 @@
++/* Tests for resource record parsing.
++   Copyright (C) 2022 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 <arpa/nameser.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/next_to_fault.h>
++
++/* Reference packet for packet parsing.  */
++static const unsigned char valid_packet[] =
++  { 0x11, 0x12, 0x13, 0x14,
++    0x00, 0x01,               /* Question count.  */
++    0x00, 0x02,               /* Answer count.  */
++    0x21, 0x22, 0x23, 0x24,   /* Other counts (not actually in packet).  */
++    3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0,
++    0x00, 0x1c,               /* Question type: AAAA.  */
++    0x00, 0x01,               /* Question class: IN.  */
++    0xc0, 0x0c,               /* Compression reference to QNAME.  */
++    0x00, 0x1c,               /* Record type: AAAA.  */
++    0x00, 0x01,               /* Record class: IN.  */
++    0x12, 0x34, 0x56, 0x78,   /* Record TTL.  */
++    0x00, 0x10,               /* Record data length (16 bytes).  */
++    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
++    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* IPv6 address.  */
++    0xc0, 0x0c,               /* Compression reference to QNAME.  */
++    0x00, 0x1c,               /* Record type: AAAA.  */
++    0x00, 0x01,               /* Record class: IN.  */
++    0x11, 0x33, 0x55, 0x77,   /* Record TTL.  */
++    0x00, 0x10,               /* Record data length (16 bytes).  */
++    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
++    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* IPv6 address.  */
++  };
++
++/* Special offsets in valid_packet.  */
++enum
++  {
++    offset_of_first_record = 29,
++    offset_of_second_record = 57,
++  };
++
++/* Check that parsing valid_packet succeeds.  */
++static void
++test_valid (void)
++{
++  struct ns_rr_cursor c;
++  TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, valid_packet,
++                                         sizeof (valid_packet)));
++  TEST_COMPARE (ns_rr_cursor_rcode (&c), 4);
++  TEST_COMPARE (ns_rr_cursor_ancount (&c), 2);
++  TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122);
++  TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324);
++  TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13);
++  TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA);
++  TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN);
++  TEST_COMPARE (c.current - valid_packet, offset_of_first_record);
++
++  struct ns_rr_wire r;
++  TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r));
++  TEST_COMPARE (r.rtype, T_AAAA);
++  TEST_COMPARE (r.rclass, C_IN);
++  TEST_COMPARE (r.ttl, 0x12345678);
++  TEST_COMPARE_BLOB (r.rdata, r.rdlength,
++                     "\x90\x91\x92\x93\x94\x95\x96\x97"
++                     "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16);
++  TEST_COMPARE (c.current - valid_packet, offset_of_second_record);
++  TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r));
++  TEST_COMPARE (r.rtype, T_AAAA);
++  TEST_COMPARE (r.rclass, C_IN);
++  TEST_COMPARE (r.ttl, 0x11335577);
++  TEST_COMPARE_BLOB (r.rdata, r.rdlength,
++                     "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
++                     "\xa8\xa9\xaa\xab\xac\xad\xae\xaf", 16);
++  TEST_VERIFY (c.current == c.end);
++}
++
++/* Check that trying to parse a packet with a compressed QNAME fails.  */
++static void
++test_compressed_qname (void)
++{
++  static const unsigned char packet[] =
++    { 0x11, 0x12, 0x13, 0x14,
++      0x00, 0x01,               /* Question count.  */
++      0x00, 0x00,               /* Answer count.  */
++      0x00, 0x00, 0x00, 0x00,   /* Other counts.  */
++      3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04,
++      0x00, 0x01,               /* Question type: A.  */
++      0x00, 0x01,               /* Question class: IN.  */
++    };
++
++  struct ns_rr_cursor c;
++  TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet)));
++}
++
++/* Check that trying to parse a packet with two questions fails.  */
++static void
++test_two_questions (void)
++{
++  static const unsigned char packet[] =
++    { 0x11, 0x12, 0x13, 0x14,
++      0x00, 0x02,               /* Question count.  */
++      0x00, 0x00,               /* Answer count.  */
++      0x00, 0x00, 0x00, 0x00,   /* Other counts.  */
++      3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04,
++      0x00, 0x01,               /* Question type: A.  */
++      0x00, 0x01,               /* Question class: IN.  */
++      3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04,
++      0x00, 0x1c,               /* Question type: AAAA.  */
++      0x00, 0x01,               /* Question class: IN.  */
++    };
++
++  struct ns_rr_cursor c;
++  TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet)));
++}
++
++/* Used to check that parsing truncated packets does not over-read.  */
++static struct support_next_to_fault ntf;
++
++/* Truncated packet in the second resource record.  */
++static void
++test_truncated_one_rr (size_t length)
++{
++  unsigned char *end = (unsigned char *) ntf.buffer - ntf.length;
++  unsigned char *start = end - length;
++
++  /* Produce the truncated packet.  */
++  memcpy (start, valid_packet, length);
++
++  struct ns_rr_cursor c;
++  TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length));
++  TEST_COMPARE (ns_rr_cursor_rcode (&c), 4);
++  TEST_COMPARE (ns_rr_cursor_ancount (&c), 2);
++  TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122);
++  TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324);
++  TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13);
++  TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA);
++  TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN);
++  TEST_COMPARE (c.current - start, offset_of_first_record);
++
++  struct ns_rr_wire r;
++  TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r));
++  TEST_COMPARE (r.rtype, T_AAAA);
++  TEST_COMPARE (r.rclass, C_IN);
++  TEST_COMPARE (r.ttl, 0x12345678);
++  TEST_COMPARE_BLOB (r.rdata, r.rdlength,
++                     "\x90\x91\x92\x93\x94\x95\x96\x97"
++                     "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16);
++  TEST_COMPARE (c.current - start, offset_of_second_record);
++  TEST_VERIFY (!__ns_rr_cursor_next (&c, &r));
++}
++
++/* Truncated packet in the first resource record.  */
++static void
++test_truncated_no_rr (size_t length)
++{
++  unsigned char *end = (unsigned char *) ntf.buffer - ntf.length;
++  unsigned char *start = end - length;
++
++  /* Produce the truncated packet.  */
++  memcpy (start, valid_packet, length);
++
++  struct ns_rr_cursor c;
++  TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length));
++  TEST_COMPARE (ns_rr_cursor_rcode (&c), 4);
++  TEST_COMPARE (ns_rr_cursor_ancount (&c), 2);
++  TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122);
++  TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324);
++  TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13);
++  TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA);
++  TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN);
++  TEST_COMPARE (c.current - start, offset_of_first_record);
++
++  struct ns_rr_wire r;
++  TEST_VERIFY (!__ns_rr_cursor_next (&c, &r));
++}
++
++/* Truncated packet before first resource record.  */
++static void
++test_truncated_before_rr (size_t length)
++{
++  unsigned char *end = (unsigned char *) ntf.buffer - ntf.length;
++  unsigned char *start = end - length;
++
++  /* Produce the truncated packet.  */
++  memcpy (start, valid_packet, length);
++
++  struct ns_rr_cursor c;
++  TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, start, length));
++}
++
++static int
++do_test (void)
++{
++  ntf = support_next_to_fault_allocate (sizeof (valid_packet));
++
++  test_valid ();
++  test_compressed_qname ();
++  test_two_questions ();
++
++  for (int length = offset_of_second_record; length < sizeof (valid_packet);
++       ++length)
++    test_truncated_one_rr (length);
++  for (int length = offset_of_first_record; length < offset_of_second_record;
++       ++length)
++    test_truncated_no_rr (length);
++  for (int length = 0; length < offset_of_first_record; ++length)
++    test_truncated_before_rr (length);
++
++  support_next_to_fault_free (&ntf);
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-322.patch b/SOURCES/glibc-upstream-2.34-322.patch
new file mode 100644
index 0000000..f590d8e
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-322.patch
@@ -0,0 +1,447 @@
+commit d9c979abf9307ef3e27dbe65317430977bb322c7
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    nss_dns: Split getanswer_ptr from getanswer_r
+    
+    And expand the use of name_ok and qtype in getanswer_ptr (the
+    former also in getanswer_r).
+    
+    After further cleanups, not much code will be shared between the
+    two functions.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 0dcc43e9981005540bf39dc7bf33fbab62cf9e84)
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index 6e83fca1c5b1f98c..a6bf73a091968358 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -117,6 +117,11 @@ static enum nss_status getanswer_r (struct resolv_context *ctx,
+ 				    struct hostent *result, char *buffer,
+ 				    size_t buflen, int *errnop, int *h_errnop,
+ 				    int map, int32_t *ttlp, char **canonp);
++static enum nss_status getanswer_ptr (const querybuf *answer, int anslen,
++				      const char *qname,
++				      struct hostent *result, char *buffer,
++				      size_t buflen, int *errnop,
++				      int *h_errnop, int32_t *ttlp);
+ 
+ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
+ 				       const querybuf *answer2, int anslen2,
+@@ -562,9 +567,8 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
+       return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
+     }
+ 
+-  status = getanswer_r
+-    (ctx, host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
+-     errnop, h_errnop, 0 /* XXX */, ttlp, NULL);
++  status = getanswer_ptr (host_buffer.buf, n, qbuf, result,
++			  buffer, buflen, errnop, h_errnop, ttlp);
+   if (host_buffer.buf != orig_host_buffer)
+     free (host_buffer.buf);
+   if (status != NSS_STATUS_SUCCESS)
+@@ -660,8 +664,6 @@ getanswer_r (struct resolv_context *ctx,
+   int haveanswer, had_error;
+   char *bp, **ap, **hap;
+   char tbuf[MAXDNAME];
+-  const char *tname;
+-  int (*name_ok) (const char *);
+   u_char packtmp[NS_MAXCDNAME];
+   int have_to_map = 0;
+   uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+@@ -680,22 +682,8 @@ getanswer_r (struct resolv_context *ctx,
+   if (buflen - sizeof (struct host_data) != linebuflen)
+     linebuflen = INT_MAX;
+ 
+-  tname = qname;
+   result->h_name = NULL;
+   end_of_message = answer->buf + anslen;
+-  switch (qtype)
+-    {
+-    case T_A:
+-    case T_AAAA:
+-      name_ok = __libc_res_hnok;
+-      break;
+-    case T_PTR:
+-      name_ok = __libc_res_dnok;
+-      break;
+-    default:
+-      *errnop = ENOENT;
+-      return NSS_STATUS_UNAVAIL;  /* XXX should be abort(); */
+-    }
+ 
+   /*
+    * find first satisfactory answer
+@@ -730,7 +718,7 @@ getanswer_r (struct resolv_context *ctx,
+       *h_errnop = NO_RECOVERY;
+       return NSS_STATUS_UNAVAIL;
+     }
+-  if (__glibc_unlikely (name_ok (bp) == 0))
++  if (__glibc_unlikely (__libc_res_hnok (bp) == 0))
+     {
+       errno = EBADMSG;
+       *errnop = EBADMSG;
+@@ -784,7 +772,7 @@ getanswer_r (struct resolv_context *ctx,
+ 	  n = -1;
+ 	}
+ 
+-      if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0))
++      if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0))
+ 	{
+ 	  ++had_error;
+ 	  continue;
+@@ -817,7 +805,7 @@ getanswer_r (struct resolv_context *ctx,
+ 	  continue;			/* XXX - had_error++ ? */
+ 	}
+ 
+-      if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME)
++      if (type == T_CNAME)
+ 	{
+ 	  /* A CNAME could also have a TTL entry.  */
+ 	  if (ttlp != NULL && ttl < *ttlp)
+@@ -827,7 +815,7 @@ getanswer_r (struct resolv_context *ctx,
+ 	    continue;
+ 	  n = __libc_dn_expand (answer->buf, end_of_message, cp,
+ 				tbuf, sizeof tbuf);
+-	  if (__glibc_unlikely (n < 0 || (*name_ok) (tbuf) == 0))
++	  if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0))
+ 	    {
+ 	      ++had_error;
+ 	      continue;
+@@ -858,7 +846,260 @@ getanswer_r (struct resolv_context *ctx,
+ 	  continue;
+ 	}
+ 
+-      if (qtype == T_PTR && type == T_CNAME)
++      if (type == T_A && qtype == T_AAAA && map)
++	have_to_map = 1;
++      else if (__glibc_unlikely (type != qtype))
++	{
++	  cp += n;
++	  continue;			/* XXX - had_error++ ? */
++	}
++
++      switch (type)
++	{
++	case T_A:
++	case T_AAAA:
++	  if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0))
++	    {
++	      cp += n;
++	      continue;			/* XXX - had_error++ ? */
++	    }
++
++	  /* Stop parsing at a record whose length is incorrect.  */
++	  if (n != rrtype_to_rdata_length (type))
++	    {
++	      ++had_error;
++	      break;
++	    }
++
++	  /* Skip records of the wrong type.  */
++	  if (n != result->h_length)
++	    {
++	      cp += n;
++	      continue;
++	    }
++	  if (!haveanswer)
++	    {
++	      int nn;
++
++	      /* We compose a single hostent out of the entire chain of
++	         entries, so the TTL of the hostent is essentially the lowest
++		 TTL in the chain.  */
++	      if (ttlp != NULL && ttl < *ttlp)
++		*ttlp = ttl;
++	      if (canonp != NULL)
++		*canonp = bp;
++	      result->h_name = bp;
++	      nn = strlen (bp) + 1;	/* for the \0 */
++	      bp += nn;
++	      linebuflen -= nn;
++	    }
++
++	  /* Provide sufficient alignment for both address
++	     families.  */
++	  enum { align = 4 };
++	  _Static_assert ((align % __alignof__ (struct in_addr)) == 0,
++			  "struct in_addr alignment");
++	  _Static_assert ((align % __alignof__ (struct in6_addr)) == 0,
++			  "struct in6_addr alignment");
++	  {
++	    char *new_bp = PTR_ALIGN_UP (bp, align);
++	    linebuflen -= new_bp - bp;
++	    bp = new_bp;
++	  }
++
++	  if (__glibc_unlikely (n > linebuflen))
++	    goto too_small;
++	  bp = __mempcpy (*hap++ = bp, cp, n);
++	  cp += n;
++	  linebuflen -= n;
++	  break;
++	default:
++	  abort ();
++	}
++      if (had_error == 0)
++	++haveanswer;
++    }
++
++  if (haveanswer > 0)
++    {
++      *ap = NULL;
++      *hap = NULL;
++      /*
++       * Note: we sort even if host can take only one address
++       * in its return structures - should give it the "best"
++       * address in that case, not some random one
++       */
++      if (haveanswer > 1 && qtype == T_A
++	  && __resolv_context_sort_count (ctx) > 0)
++	addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
++
++      if (result->h_name == NULL)
++	{
++	  n = strlen (qname) + 1;	/* For the \0.  */
++	  if (n > linebuflen)
++	    goto too_small;
++	  if (n >= MAXHOSTNAMELEN)
++	    goto no_recovery;
++	  result->h_name = bp;
++	  bp = __mempcpy (bp, qname, n);	/* Cannot overflow.  */
++	  linebuflen -= n;
++	}
++
++      if (have_to_map)
++	if (map_v4v6_hostent (result, &bp, &linebuflen))
++	  goto too_small;
++      *h_errnop = NETDB_SUCCESS;
++      return NSS_STATUS_SUCCESS;
++    }
++ no_recovery:
++  *h_errnop = NO_RECOVERY;
++  *errnop = ENOENT;
++  /* Special case here: if the resolver sent a result but it only
++     contains a CNAME while we are looking for a T_A or T_AAAA record,
++     we fail with NOTFOUND instead of TRYAGAIN.  */
++  return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
++	   ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
++}
++
++static enum nss_status
++getanswer_ptr (const querybuf *answer, int anslen, const char *qname,
++	       struct hostent *result, char *buffer, size_t buflen,
++	       int *errnop, int *h_errnop, int32_t *ttlp)
++{
++  struct host_data
++  {
++    char *aliases[MAX_NR_ALIASES];
++    unsigned char host_addr[16];	/* IPv4 or IPv6 */
++    char *h_addr_ptrs[0];
++  } *host_data;
++  int linebuflen;
++  const HEADER *hp;
++  const u_char *end_of_message, *cp;
++  int n, ancount, qdcount;
++  int haveanswer, had_error;
++  char *bp, **ap, **hap;
++  char tbuf[MAXDNAME];
++  const char *tname;
++  u_char packtmp[NS_MAXCDNAME];
++  uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
++  buffer += pad;
++  buflen = buflen > pad ? buflen - pad : 0;
++  if (__glibc_unlikely (buflen < sizeof (struct host_data)))
++    {
++      /* The buffer is too small.  */
++    too_small:
++      *errnop = ERANGE;
++      *h_errnop = NETDB_INTERNAL;
++      return NSS_STATUS_TRYAGAIN;
++    }
++  host_data = (struct host_data *) buffer;
++  linebuflen = buflen - sizeof (struct host_data);
++  if (buflen - sizeof (struct host_data) != linebuflen)
++    linebuflen = INT_MAX;
++
++  tname = qname;
++  result->h_name = NULL;
++  end_of_message = answer->buf + anslen;
++
++  /*
++   * find first satisfactory answer
++   */
++  hp = &answer->hdr;
++  ancount = ntohs (hp->ancount);
++  qdcount = ntohs (hp->qdcount);
++  cp = answer->buf + HFIXEDSZ;
++  if (__glibc_unlikely (qdcount != 1))
++    {
++      *h_errnop = NO_RECOVERY;
++      return NSS_STATUS_UNAVAIL;
++    }
++  if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen)
++    goto too_small;
++  bp = (char *) &host_data->h_addr_ptrs[ancount + 1];
++  linebuflen -= (ancount + 1) * sizeof (char *);
++
++  n = __ns_name_unpack (answer->buf, end_of_message, cp,
++			packtmp, sizeof packtmp);
++  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
++    {
++      if (__glibc_unlikely (errno == EMSGSIZE))
++	goto too_small;
++
++      n = -1;
++    }
++
++  if (__glibc_unlikely (n < 0))
++    {
++      *errnop = errno;
++      *h_errnop = NO_RECOVERY;
++      return NSS_STATUS_UNAVAIL;
++    }
++  if (__glibc_unlikely (__libc_res_dnok (bp) == 0))
++    {
++      errno = EBADMSG;
++      *errnop = EBADMSG;
++      *h_errnop = NO_RECOVERY;
++      return NSS_STATUS_UNAVAIL;
++    }
++  cp += n + QFIXEDSZ;
++
++  ap = host_data->aliases;
++  *ap = NULL;
++  result->h_aliases = host_data->aliases;
++  hap = host_data->h_addr_ptrs;
++  *hap = NULL;
++  result->h_addr_list = host_data->h_addr_ptrs;
++  haveanswer = 0;
++  had_error = 0;
++
++  while (ancount-- > 0 && cp < end_of_message && had_error == 0)
++    {
++      int type, class;
++
++      n = __ns_name_unpack (answer->buf, end_of_message, cp,
++			    packtmp, sizeof packtmp);
++      if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
++	{
++	  if (__glibc_unlikely (errno == EMSGSIZE))
++	    goto too_small;
++
++	  n = -1;
++	}
++
++      if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0))
++	{
++	  ++had_error;
++	  continue;
++	}
++      cp += n;				/* name */
++
++      if (__glibc_unlikely (cp + 10 > end_of_message))
++	{
++	  ++had_error;
++	  continue;
++	}
++
++      NS_GET16 (type, cp);
++      NS_GET16 (class, cp);
++      int32_t ttl;
++      NS_GET32 (ttl, cp);
++      NS_GET16 (n, cp);		/* RDATA length.  */
++
++      if (end_of_message - cp < n)
++	{
++	  /* RDATA extends beyond the end of the packet.  */
++	  ++had_error;
++	  continue;
++	}
++
++      if (__glibc_unlikely (class != C_IN))
++	{
++	  /* XXX - debug? syslog? */
++	  cp += n;
++	  continue;			/* XXX - had_error++ ? */
++	}
++
++      if (type == T_CNAME)
+ 	{
+ 	  /* A CNAME could also have a TTL entry.  */
+ 	  if (ttlp != NULL && ttl < *ttlp)
+@@ -887,14 +1128,6 @@ getanswer_r (struct resolv_context *ctx,
+ 	  continue;
+ 	}
+ 
+-      if (type == T_A && qtype == T_AAAA && map)
+-	have_to_map = 1;
+-      else if (__glibc_unlikely (type != qtype))
+-	{
+-	  cp += n;
+-	  continue;			/* XXX - had_error++ ? */
+-	}
+-
+       switch (type)
+ 	{
+ 	case T_PTR:
+@@ -956,8 +1189,6 @@ getanswer_r (struct resolv_context *ctx,
+ 		 TTL in the chain.  */
+ 	      if (ttlp != NULL && ttl < *ttlp)
+ 		*ttlp = ttl;
+-	      if (canonp != NULL)
+-		*canonp = bp;
+ 	      result->h_name = bp;
+ 	      nn = strlen (bp) + 1;	/* for the \0 */
+ 	      bp += nn;
+@@ -984,7 +1215,8 @@ getanswer_r (struct resolv_context *ctx,
+ 	  linebuflen -= n;
+ 	  break;
+ 	default:
+-	  abort ();
++	  cp += n;
++	  continue;			/* XXX - had_error++ ? */
+ 	}
+       if (had_error == 0)
+ 	++haveanswer;
+@@ -994,14 +1226,6 @@ getanswer_r (struct resolv_context *ctx,
+     {
+       *ap = NULL;
+       *hap = NULL;
+-      /*
+-       * Note: we sort even if host can take only one address
+-       * in its return structures - should give it the "best"
+-       * address in that case, not some random one
+-       */
+-      if (haveanswer > 1 && qtype == T_A
+-	  && __resolv_context_sort_count (ctx) > 0)
+-	addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
+ 
+       if (result->h_name == NULL)
+ 	{
+@@ -1015,23 +1239,15 @@ getanswer_r (struct resolv_context *ctx,
+ 	  linebuflen -= n;
+ 	}
+ 
+-      if (have_to_map)
+-	if (map_v4v6_hostent (result, &bp, &linebuflen))
+-	  goto too_small;
+       *h_errnop = NETDB_SUCCESS;
+       return NSS_STATUS_SUCCESS;
+     }
+  no_recovery:
+   *h_errnop = NO_RECOVERY;
+   *errnop = ENOENT;
+-  /* Special case here: if the resolver sent a result but it only
+-     contains a CNAME while we are looking for a T_A or T_AAAA record,
+-     we fail with NOTFOUND instead of TRYAGAIN.  */
+-  return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
+-	   ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
++  return NSS_STATUS_TRYAGAIN;
+ }
+ 
+-
+ static enum nss_status
+ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
+ 		      struct gaih_addrtuple ***patp,
diff --git a/SOURCES/glibc-upstream-2.34-323.patch b/SOURCES/glibc-upstream-2.34-323.patch
new file mode 100644
index 0000000..9e00022
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-323.patch
@@ -0,0 +1,507 @@
+commit 32e5db37684ffcbc6ae34fcc6cdcf28670506baa
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    nss_dns: Rewrite _nss_dns_gethostbyaddr2_r and getanswer_ptr
+    
+    The simplification takes advantage of the split from getanswer_r.
+    It fixes various aliases issues, and optimizes NSS buffer usage.
+    The new DNS packet parsing helpers are used, too.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit e32547d661a43da63368e488b6cfa9c53b4dcf92)
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index a6bf73a091968358..2cd7170f20b60588 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -70,6 +70,7 @@
+  * --Copyright--
+  */
+ 
++#include <alloc_buffer.h>
+ #include <assert.h>
+ #include <ctype.h>
+ #include <errno.h>
+@@ -117,10 +118,9 @@ static enum nss_status getanswer_r (struct resolv_context *ctx,
+ 				    struct hostent *result, char *buffer,
+ 				    size_t buflen, int *errnop, int *h_errnop,
+ 				    int map, int32_t *ttlp, char **canonp);
+-static enum nss_status getanswer_ptr (const querybuf *answer, int anslen,
+-				      const char *qname,
+-				      struct hostent *result, char *buffer,
+-				      size_t buflen, int *errnop,
++static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
++				      struct alloc_buffer *abuf,
++				      char **hnamep, int *errnop,
+ 				      int *h_errnop, int32_t *ttlp);
+ 
+ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
+@@ -457,36 +457,21 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
+   static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
+   static const u_char v6local[] = { 0,0, 0,1 };
+   const u_char *uaddr = (const u_char *)addr;
+-  struct host_data
+-  {
+-    char *aliases[MAX_NR_ALIASES];
+-    unsigned char host_addr[16];	/* IPv4 or IPv6 */
+-    char *h_addr_ptrs[MAX_NR_ADDRS + 1];
+-    char linebuffer[0];
+-  } *host_data = (struct host_data *) buffer;
+-  union
+-  {
+-    querybuf *buf;
+-    u_char *ptr;
+-  } host_buffer;
+-  querybuf *orig_host_buffer;
+   char qbuf[MAXDNAME+1], *qp = NULL;
+   size_t size;
+   int n, status;
+   int olderr = errno;
+ 
+- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+- buffer += pad;
+- buflen = buflen > pad ? buflen - pad : 0;
+-
+- if (__glibc_unlikely (buflen < sizeof (struct host_data)))
+-   {
+-     *errnop = ERANGE;
+-     *h_errnop = NETDB_INTERNAL;
+-     return NSS_STATUS_TRYAGAIN;
+-   }
+-
+- host_data = (struct host_data *) buffer;
++  /* Prepare the allocation buffer.  Store the pointer array first, to
++     benefit from buffer alignment.  */
++  struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen);
++  char **address_array = alloc_buffer_alloc_array (&abuf, char *, 2);
++  if (address_array == NULL)
++    {
++      *errnop = ERANGE;
++      *h_errnop = NETDB_INTERNAL;
++      return NSS_STATUS_TRYAGAIN;
++    }
+ 
+   struct resolv_context *ctx = __resolv_context_get ();
+   if (ctx == NULL)
+@@ -530,8 +515,6 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
+       return NSS_STATUS_UNAVAIL;
+     }
+ 
+-  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
+-
+   switch (af)
+     {
+     case AF_INET:
+@@ -555,35 +538,52 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
+       break;
+     }
+ 
+-  n = __res_context_query (ctx, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
+-			   1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
++  unsigned char dns_packet_buffer[1024];
++  unsigned char *alt_dns_packet_buffer = dns_packet_buffer;
++  n = __res_context_query (ctx, qbuf, C_IN, T_PTR,
++			   dns_packet_buffer, sizeof (dns_packet_buffer),
++			   &alt_dns_packet_buffer,
++			   NULL, NULL, NULL, NULL);
+   if (n < 0)
+     {
+       *h_errnop = h_errno;
+       __set_errno (olderr);
+-      if (host_buffer.buf != orig_host_buffer)
+-	free (host_buffer.buf);
++      if (alt_dns_packet_buffer != dns_packet_buffer)
++	free (alt_dns_packet_buffer);
+       __resolv_context_put (ctx);
+       return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
+     }
+ 
+-  status = getanswer_ptr (host_buffer.buf, n, qbuf, result,
+-			  buffer, buflen, errnop, h_errnop, ttlp);
+-  if (host_buffer.buf != orig_host_buffer)
+-    free (host_buffer.buf);
++  status = getanswer_ptr (alt_dns_packet_buffer, n,
++			  &abuf, &result->h_name, errnop, h_errnop, ttlp);
++
++  if (alt_dns_packet_buffer != dns_packet_buffer)
++    free (alt_dns_packet_buffer);
++  __resolv_context_put (ctx);
++
+   if (status != NSS_STATUS_SUCCESS)
+-    {
+-      __resolv_context_put (ctx);
+-      return status;
+-    }
++    return status;
+ 
++  /* result->h_name has already been set by getanswer_ptr.  */
+   result->h_addrtype = af;
+   result->h_length = len;
+-  memcpy (host_data->host_addr, addr, len);
+-  host_data->h_addr_ptrs[0] = (char *) host_data->host_addr;
+-  host_data->h_addr_ptrs[1] = NULL;
++  /* Increase the alignment to 4, in case there are applications out
++     there that expect at least this level of address alignment.  */
++  address_array[0] = (char *) alloc_buffer_next (&abuf, uint32_t);
++  alloc_buffer_copy_bytes (&abuf, uaddr, len);
++  address_array[1] = NULL;
++
++  /* This check also covers allocation failure in getanswer_ptr.  */
++  if (alloc_buffer_has_failed (&abuf))
++    {
++      *errnop = ERANGE;
++      *h_errnop = NETDB_INTERNAL;
++      return NSS_STATUS_TRYAGAIN;
++    }
++  result->h_addr_list = address_array;
++  result->h_aliases = &address_array[1]; /* Points to NULL.  */
++
+   *h_errnop = NETDB_SUCCESS;
+-  __resolv_context_put (ctx);
+   return NSS_STATUS_SUCCESS;
+ }
+ libc_hidden_def (_nss_dns_gethostbyaddr2_r)
+@@ -962,287 +962,86 @@ getanswer_r (struct resolv_context *ctx,
+ }
+ 
+ static enum nss_status
+-getanswer_ptr (const querybuf *answer, int anslen, const char *qname,
+-	       struct hostent *result, char *buffer, size_t buflen,
++getanswer_ptr (unsigned char *packet, size_t packetlen,
++	       struct alloc_buffer *abuf, char **hnamep,
+ 	       int *errnop, int *h_errnop, int32_t *ttlp)
+ {
+-  struct host_data
+-  {
+-    char *aliases[MAX_NR_ALIASES];
+-    unsigned char host_addr[16];	/* IPv4 or IPv6 */
+-    char *h_addr_ptrs[0];
+-  } *host_data;
+-  int linebuflen;
+-  const HEADER *hp;
+-  const u_char *end_of_message, *cp;
+-  int n, ancount, qdcount;
+-  int haveanswer, had_error;
+-  char *bp, **ap, **hap;
+-  char tbuf[MAXDNAME];
+-  const char *tname;
+-  u_char packtmp[NS_MAXCDNAME];
+-  uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+-  buffer += pad;
+-  buflen = buflen > pad ? buflen - pad : 0;
+-  if (__glibc_unlikely (buflen < sizeof (struct host_data)))
+-    {
+-      /* The buffer is too small.  */
+-    too_small:
+-      *errnop = ERANGE;
+-      *h_errnop = NETDB_INTERNAL;
+-      return NSS_STATUS_TRYAGAIN;
+-    }
+-  host_data = (struct host_data *) buffer;
+-  linebuflen = buflen - sizeof (struct host_data);
+-  if (buflen - sizeof (struct host_data) != linebuflen)
+-    linebuflen = INT_MAX;
+-
+-  tname = qname;
+-  result->h_name = NULL;
+-  end_of_message = answer->buf + anslen;
+-
+-  /*
+-   * find first satisfactory answer
+-   */
+-  hp = &answer->hdr;
+-  ancount = ntohs (hp->ancount);
+-  qdcount = ntohs (hp->qdcount);
+-  cp = answer->buf + HFIXEDSZ;
+-  if (__glibc_unlikely (qdcount != 1))
+-    {
+-      *h_errnop = NO_RECOVERY;
+-      return NSS_STATUS_UNAVAIL;
+-    }
+-  if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen)
+-    goto too_small;
+-  bp = (char *) &host_data->h_addr_ptrs[ancount + 1];
+-  linebuflen -= (ancount + 1) * sizeof (char *);
+-
+-  n = __ns_name_unpack (answer->buf, end_of_message, cp,
+-			packtmp, sizeof packtmp);
+-  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
++  struct ns_rr_cursor c;
++  if (!__ns_rr_cursor_init (&c, packet, packetlen))
+     {
+-      if (__glibc_unlikely (errno == EMSGSIZE))
+-	goto too_small;
+-
+-      n = -1;
+-    }
+-
+-  if (__glibc_unlikely (n < 0))
+-    {
+-      *errnop = errno;
+-      *h_errnop = NO_RECOVERY;
+-      return NSS_STATUS_UNAVAIL;
+-    }
+-  if (__glibc_unlikely (__libc_res_dnok (bp) == 0))
+-    {
+-      errno = EBADMSG;
+-      *errnop = EBADMSG;
++      /* This should not happen because __res_context_query already
++	 perfroms response validation.  */
+       *h_errnop = NO_RECOVERY;
+       return NSS_STATUS_UNAVAIL;
+     }
+-  cp += n + QFIXEDSZ;
++  int ancount = ns_rr_cursor_ancount (&c);
++  const unsigned char *expected_name = ns_rr_cursor_qname (&c);
++  /* expected_name may be updated to point into this buffer.  */
++  unsigned char name_buffer[NS_MAXCDNAME];
+ 
+-  ap = host_data->aliases;
+-  *ap = NULL;
+-  result->h_aliases = host_data->aliases;
+-  hap = host_data->h_addr_ptrs;
+-  *hap = NULL;
+-  result->h_addr_list = host_data->h_addr_ptrs;
+-  haveanswer = 0;
+-  had_error = 0;
+-
+-  while (ancount-- > 0 && cp < end_of_message && had_error == 0)
++  while (ancount > 0)
+     {
+-      int type, class;
+-
+-      n = __ns_name_unpack (answer->buf, end_of_message, cp,
+-			    packtmp, sizeof packtmp);
+-      if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
++      struct ns_rr_wire rr;
++      if (!__ns_rr_cursor_next (&c, &rr))
+ 	{
+-	  if (__glibc_unlikely (errno == EMSGSIZE))
+-	    goto too_small;
+-
+-	  n = -1;
+-	}
+-
+-      if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0))
+-	{
+-	  ++had_error;
+-	  continue;
+-	}
+-      cp += n;				/* name */
+-
+-      if (__glibc_unlikely (cp + 10 > end_of_message))
+-	{
+-	  ++had_error;
+-	  continue;
++	  *h_errnop = NO_RECOVERY;
++	  return NSS_STATUS_UNAVAIL;
+ 	}
+ 
+-      NS_GET16 (type, cp);
+-      NS_GET16 (class, cp);
+-      int32_t ttl;
+-      NS_GET32 (ttl, cp);
+-      NS_GET16 (n, cp);		/* RDATA length.  */
++      /* Skip over records with the wrong class.  */
++      if (rr.rclass != C_IN)
++	continue;
+ 
+-      if (end_of_message - cp < n)
+-	{
+-	  /* RDATA extends beyond the end of the packet.  */
+-	  ++had_error;
+-	  continue;
+-	}
+-
+-      if (__glibc_unlikely (class != C_IN))
+-	{
+-	  /* XXX - debug? syslog? */
+-	  cp += n;
+-	  continue;			/* XXX - had_error++ ? */
+-	}
++      /* Update TTL for known record types.  */
++      if ((rr.rtype == T_CNAME || rr.rtype == T_PTR)
++	  && ttlp != NULL && *ttlp > rr.ttl)
++	*ttlp = rr.ttl;
+ 
+-      if (type == T_CNAME)
++      if (rr.rtype == T_CNAME)
+ 	{
+-	  /* A CNAME could also have a TTL entry.  */
+-	  if (ttlp != NULL && ttl < *ttlp)
+-	      *ttlp = ttl;
+-
+-	  n = __libc_dn_expand (answer->buf, end_of_message, cp,
+-				tbuf, sizeof tbuf);
+-	  if (__glibc_unlikely (n < 0 || __libc_res_dnok (tbuf) == 0))
+-	    {
+-	      ++had_error;
+-	      continue;
+-	    }
+-	  cp += n;
+-	  /* Get canonical name.  */
+-	  n = strlen (tbuf) + 1;   /* For the \0.  */
+-	  if (__glibc_unlikely (n > linebuflen))
+-	    goto too_small;
+-	  if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
++	  /* NB: No check for owner name match, based on historic
++	     precedent.  Record the CNAME target as the new expected
++	     name.  */
++	  int n = __ns_name_unpack (c.begin, c.end, rr.rdata,
++				    name_buffer, sizeof (name_buffer));
++	  if (n < 0)
+ 	    {
+-	      ++had_error;
+-	      continue;
++	      *h_errnop = NO_RECOVERY;
++	      return NSS_STATUS_UNAVAIL;
+ 	    }
+-	  tname = bp;
+-	  bp = __mempcpy (bp, tbuf, n);	/* Cannot overflow.  */
+-	  linebuflen -= n;
+-	  continue;
++	  expected_name = name_buffer;
+ 	}
+-
+-      switch (type)
++      else if (rr.rtype == T_PTR
++	       && __ns_samebinaryname (rr.rname, expected_name))
+ 	{
+-	case T_PTR:
+-	  if (__glibc_unlikely (__strcasecmp (tname, bp) != 0))
+-	    {
+-	      cp += n;
+-	      continue;			/* XXX - had_error++ ? */
+-	    }
+-
+-	  n = __ns_name_unpack (answer->buf, end_of_message, cp,
+-				packtmp, sizeof packtmp);
+-	  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+-	    {
+-	      if (__glibc_unlikely (errno == EMSGSIZE))
+-		goto too_small;
+-
+-	      n = -1;
+-	    }
+-
+-	  if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0))
++	  /* Decompress the target of the PTR record.  This is the
++	     host name we are looking for.  We can only use it if it
++	     is syntactically valid.  Historically, only one host name
++	     is returned here.  If the recursive resolver performs DNS
++	     record rotation, the returned host name is essentially
++	     random, which is why multiple PTR records are rarely
++	     used.  Use MAXHOSTNAMELEN instead of NS_MAXCDNAME for
++	     additional length checking.  */
++	  char hname[MAXHOSTNAMELEN + 1];
++	  if (__ns_name_unpack (c.begin, c.end, rr.rdata,
++				name_buffer, sizeof (name_buffer)) < 0
++	      || !__res_binary_hnok (expected_name)
++	      || __ns_name_ntop (name_buffer, hname, sizeof (hname)) < 0)
+ 	    {
+-	      ++had_error;
+-	      break;
++	      *h_errnop = NO_RECOVERY;
++	      return NSS_STATUS_UNAVAIL;
+ 	    }
+-	  if (ttlp != NULL && ttl < *ttlp)
+-	      *ttlp = ttl;
+-	  /* bind would put multiple PTR records as aliases, but we don't do
+-	     that.  */
+-	  result->h_name = bp;
+-	  *h_errnop = NETDB_SUCCESS;
++	  /* Successful allocation is checked by the caller.  */
++	  *hnamep = alloc_buffer_copy_string (abuf, hname);
+ 	  return NSS_STATUS_SUCCESS;
+-	case T_A:
+-	case T_AAAA:
+-	  if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0))
+-	    {
+-	      cp += n;
+-	      continue;			/* XXX - had_error++ ? */
+-	    }
+-
+-	  /* Stop parsing at a record whose length is incorrect.  */
+-	  if (n != rrtype_to_rdata_length (type))
+-	    {
+-	      ++had_error;
+-	      break;
+-	    }
+-
+-	  /* Skip records of the wrong type.  */
+-	  if (n != result->h_length)
+-	    {
+-	      cp += n;
+-	      continue;
+-	    }
+-	  if (!haveanswer)
+-	    {
+-	      int nn;
+-
+-	      /* We compose a single hostent out of the entire chain of
+-	         entries, so the TTL of the hostent is essentially the lowest
+-		 TTL in the chain.  */
+-	      if (ttlp != NULL && ttl < *ttlp)
+-		*ttlp = ttl;
+-	      result->h_name = bp;
+-	      nn = strlen (bp) + 1;	/* for the \0 */
+-	      bp += nn;
+-	      linebuflen -= nn;
+-	    }
+-
+-	  /* Provide sufficient alignment for both address
+-	     families.  */
+-	  enum { align = 4 };
+-	  _Static_assert ((align % __alignof__ (struct in_addr)) == 0,
+-			  "struct in_addr alignment");
+-	  _Static_assert ((align % __alignof__ (struct in6_addr)) == 0,
+-			  "struct in6_addr alignment");
+-	  {
+-	    char *new_bp = PTR_ALIGN_UP (bp, align);
+-	    linebuflen -= new_bp - bp;
+-	    bp = new_bp;
+-	  }
+-
+-	  if (__glibc_unlikely (n > linebuflen))
+-	    goto too_small;
+-	  bp = __mempcpy (*hap++ = bp, cp, n);
+-	  cp += n;
+-	  linebuflen -= n;
+-	  break;
+-	default:
+-	  cp += n;
+-	  continue;			/* XXX - had_error++ ? */
+ 	}
+-      if (had_error == 0)
+-	++haveanswer;
+     }
+ 
+-  if (haveanswer > 0)
+-    {
+-      *ap = NULL;
+-      *hap = NULL;
+-
+-      if (result->h_name == NULL)
+-	{
+-	  n = strlen (qname) + 1;	/* For the \0.  */
+-	  if (n > linebuflen)
+-	    goto too_small;
+-	  if (n >= MAXHOSTNAMELEN)
+-	    goto no_recovery;
+-	  result->h_name = bp;
+-	  bp = __mempcpy (bp, qname, n);	/* Cannot overflow.  */
+-	  linebuflen -= n;
+-	}
++  /* No PTR record found.  */
++  if (ttlp != NULL)
++    /* No caching of negative responses.  */
++    *ttlp = 0;
+ 
+-      *h_errnop = NETDB_SUCCESS;
+-      return NSS_STATUS_SUCCESS;
+-    }
+- no_recovery:
+   *h_errnop = NO_RECOVERY;
+   *errnop = ENOENT;
+   return NSS_STATUS_TRYAGAIN;
diff --git a/SOURCES/glibc-upstream-2.34-324.patch b/SOURCES/glibc-upstream-2.34-324.patch
new file mode 100644
index 0000000..b77de6e
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-324.patch
@@ -0,0 +1,311 @@
+commit 7267341ec1b5c591c2e7946d0604d3cf1423db7d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    nss_dns: Remove remnants of IPv6 address mapping
+    
+    res_use_inet6 always returns false since commit 3f8b44be0a658266adff5
+    ("resolv: Remove support for RES_USE_INET6 and the inet6 option").
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit a7fc30b522a0cd7c8c5e7e285b9531b704e02f04)
+
+diff --git a/resolv/README b/resolv/README
+index 514e9bb617e710f1..2146bc3b27a6dc56 100644
+--- a/resolv/README
++++ b/resolv/README
+@@ -146,6 +146,3 @@ res_libc.c is home-brewn, although parts of it are taken from res_data.c.
+ 
+ res_hconf.c and res_hconf.h were contributed by David Mosberger, and
+ do not come from BIND.
+-
+-The files gethnamaddr.c, mapv4v6addr.h and mapv4v6hostent.h are
+-leftovers from BIND 4.9.7.
+diff --git a/resolv/mapv4v6addr.h b/resolv/mapv4v6addr.h
+deleted file mode 100644
+index 7f85f7d5e393ec5f..0000000000000000
+--- a/resolv/mapv4v6addr.h
++++ /dev/null
+@@ -1,69 +0,0 @@
+-/*
+- * ++Copyright++ 1985, 1988, 1993
+- * -
+- * Copyright (c) 1985, 1988, 1993
+- *    The Regents of the University of California.  All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- *    notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- *    notice, this list of conditions and the following disclaimer in the
+- *    documentation and/or other materials provided with the distribution.
+- * 4. Neither the name of the University nor the names of its contributors
+- *    may be used to endorse or promote products derived from this software
+- *    without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+- * SUCH DAMAGE.
+- * -
+- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+- *
+- * Permission to use, copy, modify, and distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies, and that
+- * the name of Digital Equipment Corporation not be used in advertising or
+- * publicity pertaining to distribution of the document or software without
+- * specific, written prior permission.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+- * SOFTWARE.
+- * -
+- * --Copyright--
+- */
+-
+-#include <string.h>
+-#include <arpa/nameser.h>
+-
+-static void
+-map_v4v6_address (const char *src, char *dst)
+-{
+-  u_char *p = (u_char *) dst;
+-  int i;
+-
+-  /* Move the IPv4 part to the right position.  */
+-  memcpy (dst + 12, src, INADDRSZ);
+-
+-  /* Mark this ipv6 addr as a mapped ipv4. */
+-  for (i = 0; i < 10; i++)
+-    *p++ = 0x00;
+-  *p++ = 0xff;
+-  *p = 0xff;
+-}
+diff --git a/resolv/mapv4v6hostent.h b/resolv/mapv4v6hostent.h
+deleted file mode 100644
+index c11038adf33f154d..0000000000000000
+--- a/resolv/mapv4v6hostent.h
++++ /dev/null
+@@ -1,84 +0,0 @@
+-/*
+- * ++Copyright++ 1985, 1988, 1993
+- * -
+- * Copyright (c) 1985, 1988, 1993
+- *    The Regents of the University of California.  All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- *    notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- *    notice, this list of conditions and the following disclaimer in the
+- *    documentation and/or other materials provided with the distribution.
+- * 4. Neither the name of the University nor the names of its contributors
+- *    may be used to endorse or promote products derived from this software
+- *    without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+- * SUCH DAMAGE.
+- * -
+- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+- *
+- * Permission to use, copy, modify, and distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies, and that
+- * the name of Digital Equipment Corporation not be used in advertising or
+- * publicity pertaining to distribution of the document or software without
+- * specific, written prior permission.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+- * SOFTWARE.
+- * -
+- * --Copyright--
+- */
+-
+-#include <arpa/nameser.h>
+-#include <sys/socket.h>
+-
+-typedef union {
+-    int32_t al;
+-    char ac;
+-} align;
+-
+-static int
+-map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp)
+-{
+-  char **ap;
+-
+-  if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
+-    return 0;
+-  hp->h_addrtype = AF_INET6;
+-  hp->h_length = IN6ADDRSZ;
+-  for (ap = hp->h_addr_list; *ap; ap++)
+-    {
+-      int i = sizeof (align) - ((u_long) *bpp % sizeof (align));
+-
+-      if (*lenp < (i + IN6ADDRSZ))
+-	/* Out of memory.  */
+-	return 1;
+-      *bpp += i;
+-      *lenp -= i;
+-      map_v4v6_address (*ap, *bpp);
+-      *ap = *bpp;
+-      *bpp += IN6ADDRSZ;
+-      *lenp -= IN6ADDRSZ;
+-    }
+-  return 0;
+-}
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index 2cd7170f20b60588..f8dc5a0a7d1eb156 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -88,10 +88,6 @@
+ #include <resolv/resolv-internal.h>
+ #include <resolv/resolv_context.h>
+ 
+-/* Get implementations of some internal functions.  */
+-#include <resolv/mapv4v6addr.h>
+-#include <resolv/mapv4v6hostent.h>
+-
+ #define RESOLVSORT
+ 
+ #if PACKETSZ > 65536
+@@ -117,7 +113,7 @@ static enum nss_status getanswer_r (struct resolv_context *ctx,
+ 				    const char *qname, int qtype,
+ 				    struct hostent *result, char *buffer,
+ 				    size_t buflen, int *errnop, int *h_errnop,
+-				    int map, int32_t *ttlp, char **canonp);
++				    int32_t *ttlp, char **canonp);
+ static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
+ 				      struct alloc_buffer *abuf,
+ 				      char **hnamep, int *errnop,
+@@ -198,7 +194,6 @@ gethostbyname3_context (struct resolv_context *ctx,
+   char tmp[NS_MAXDNAME];
+   int size, type, n;
+   const char *cp;
+-  int map = 0;
+   int olderr = errno;
+   enum nss_status status;
+ 
+@@ -259,32 +254,12 @@ gethostbyname3_context (struct resolv_context *ctx,
+ 	*errnop = EAGAIN;
+       else
+ 	__set_errno (olderr);
+-
+-      /* If we are looking for an IPv6 address and mapping is enabled
+-	 by having the RES_USE_INET6 bit in _res.options set, we try
+-	 another lookup.  */
+-      if (af == AF_INET6 && res_use_inet6 ())
+-	n = __res_context_search (ctx, name, C_IN, T_A, host_buffer.buf->buf,
+-				  host_buffer.buf != orig_host_buffer
+-				  ? MAXPACKET : 1024, &host_buffer.ptr,
+-				  NULL, NULL, NULL, NULL);
+-
+-      if (n < 0)
+-	{
+-	  if (host_buffer.buf != orig_host_buffer)
+-	    free (host_buffer.buf);
+-	  return status;
+-	}
+-
+-      map = 1;
+-
+-      result->h_addrtype = AF_INET;
+-      result->h_length = INADDRSZ;
+     }
++  else
++    status = getanswer_r
++      (ctx, host_buffer.buf, n, name, type, result, buffer, buflen,
++       errnop, h_errnop, ttlp, canonp);
+ 
+-  status = getanswer_r
+-    (ctx, host_buffer.buf, n, name, type, result, buffer, buflen,
+-     errnop, h_errnop, map, ttlp, canonp);
+   if (host_buffer.buf != orig_host_buffer)
+     free (host_buffer.buf);
+   return status;
+@@ -330,13 +305,8 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
+       *h_errnop = NETDB_INTERNAL;
+       return NSS_STATUS_UNAVAIL;
+     }
+-  status = NSS_STATUS_NOTFOUND;
+-  if (res_use_inet6 ())
+-    status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer,
+-				     buflen, errnop, h_errnop, NULL, NULL);
+-  if (status == NSS_STATUS_NOTFOUND)
+-    status = gethostbyname3_context (ctx, name, AF_INET, result, buffer,
+-				     buflen, errnop, h_errnop, NULL, NULL);
++  status = gethostbyname3_context (ctx, name, AF_INET, result, buffer,
++				   buflen, errnop, h_errnop, NULL, NULL);
+   __resolv_context_put (ctx);
+   return status;
+ }
+@@ -649,7 +619,7 @@ static enum nss_status
+ getanswer_r (struct resolv_context *ctx,
+ 	     const querybuf *answer, int anslen, const char *qname, int qtype,
+ 	     struct hostent *result, char *buffer, size_t buflen,
+-	     int *errnop, int *h_errnop, int map, int32_t *ttlp, char **canonp)
++	     int *errnop, int *h_errnop, int32_t *ttlp, char **canonp)
+ {
+   struct host_data
+   {
+@@ -665,7 +635,6 @@ getanswer_r (struct resolv_context *ctx,
+   char *bp, **ap, **hap;
+   char tbuf[MAXDNAME];
+   u_char packtmp[NS_MAXCDNAME];
+-  int have_to_map = 0;
+   uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+   buffer += pad;
+   buflen = buflen > pad ? buflen - pad : 0;
+@@ -846,9 +815,7 @@ getanswer_r (struct resolv_context *ctx,
+ 	  continue;
+ 	}
+ 
+-      if (type == T_A && qtype == T_AAAA && map)
+-	have_to_map = 1;
+-      else if (__glibc_unlikely (type != qtype))
++      if (__glibc_unlikely (type != qtype))
+ 	{
+ 	  cp += n;
+ 	  continue;			/* XXX - had_error++ ? */
+@@ -945,9 +912,6 @@ getanswer_r (struct resolv_context *ctx,
+ 	  linebuflen -= n;
+ 	}
+ 
+-      if (have_to_map)
+-	if (map_v4v6_hostent (result, &bp, &linebuflen))
+-	  goto too_small;
+       *h_errnop = NETDB_SUCCESS;
+       return NSS_STATUS_SUCCESS;
+     }
diff --git a/SOURCES/glibc-upstream-2.34-325.patch b/SOURCES/glibc-upstream-2.34-325.patch
new file mode 100644
index 0000000..7a282c5
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-325.patch
@@ -0,0 +1,565 @@
+commit 9abc40d9b514fc51cd1a052d32d092a827c6e21a
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    nss_dns: Rewrite getanswer_r to match getanswer_ptr (bug 12154, bug 29305)
+    
+    Allocate the pointer arrays only at the end, when their sizes
+    are known.  This addresses bug 29305.
+    
+    Skip over invalid names instead of failing lookups.  This partially
+    fixes bug 12154 (for gethostbyname, fixing getaddrinfo requires
+    different changes).
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit d101d836e7e4bd1d4e4972b0e0bd0a55c9b650fa)
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index f8dc5a0a7d1eb156..10c21e1e827cde12 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -108,12 +108,19 @@ typedef union querybuf
+   u_char buf[MAXPACKET];
+ } querybuf;
+ 
+-static enum nss_status getanswer_r (struct resolv_context *ctx,
+-				    const querybuf *answer, int anslen,
+-				    const char *qname, int qtype,
+-				    struct hostent *result, char *buffer,
+-				    size_t buflen, int *errnop, int *h_errnop,
+-				    int32_t *ttlp, char **canonp);
++/* For historic reasons, pointers to IP addresses are char *, so use a
++   single list type for addresses and host names.  */
++#define DYNARRAY_STRUCT ptrlist
++#define DYNARRAY_ELEMENT char *
++#define DYNARRAY_PREFIX ptrlist_
++#include <malloc/dynarray-skeleton.c>
++
++static enum nss_status getanswer_r (unsigned char *packet, size_t packetlen,
++				    uint16_t qtype, struct alloc_buffer *abuf,
++				    struct ptrlist *addresses,
++				    struct ptrlist *aliases,
++				    int *errnop, int *h_errnop, int32_t *ttlp);
++static void addrsort (struct resolv_context *ctx, char **ap, int num);
+ static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
+ 				      struct alloc_buffer *abuf,
+ 				      char **hnamep, int *errnop,
+@@ -185,12 +192,6 @@ gethostbyname3_context (struct resolv_context *ctx,
+ 			char *buffer, size_t buflen, int *errnop,
+ 			int *h_errnop, int32_t *ttlp, char **canonp)
+ {
+-  union
+-  {
+-    querybuf *buf;
+-    u_char *ptr;
+-  } host_buffer;
+-  querybuf *orig_host_buffer;
+   char tmp[NS_MAXDNAME];
+   int size, type, n;
+   const char *cp;
+@@ -224,10 +225,12 @@ gethostbyname3_context (struct resolv_context *ctx,
+       && (cp = __res_context_hostalias (ctx, name, tmp, sizeof (tmp))) != NULL)
+     name = cp;
+ 
+-  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
++  unsigned char dns_packet_buffer[1024];
++  unsigned char *alt_dns_packet_buffer = dns_packet_buffer;
+ 
+-  n = __res_context_search (ctx, name, C_IN, type, host_buffer.buf->buf,
+-			    1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
++  n = __res_context_search (ctx, name, C_IN, type,
++			    dns_packet_buffer, sizeof (dns_packet_buffer),
++			    &alt_dns_packet_buffer, NULL, NULL, NULL, NULL);
+   if (n < 0)
+     {
+       switch (errno)
+@@ -256,12 +259,77 @@ gethostbyname3_context (struct resolv_context *ctx,
+ 	__set_errno (olderr);
+     }
+   else
+-    status = getanswer_r
+-      (ctx, host_buffer.buf, n, name, type, result, buffer, buflen,
+-       errnop, h_errnop, ttlp, canonp);
++    {
++      struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen);
+ 
+-  if (host_buffer.buf != orig_host_buffer)
+-    free (host_buffer.buf);
++      struct ptrlist addresses;
++      ptrlist_init (&addresses);
++      struct ptrlist aliases;
++      ptrlist_init (&aliases);
++
++      status = getanswer_r (alt_dns_packet_buffer, n, type,
++			    &abuf, &addresses, &aliases,
++			    errnop, h_errnop, ttlp);
++      if (status == NSS_STATUS_SUCCESS)
++	{
++	  if (ptrlist_has_failed (&addresses)
++	      || ptrlist_has_failed (&aliases))
++	    {
++	      /* malloc failure.  Do not retry using the ERANGE protocol.  */
++	      *errnop = ENOMEM;
++	      *h_errnop = NETDB_INTERNAL;
++	      status = NSS_STATUS_UNAVAIL;
++	    }
++
++	  /* Reserve the address and alias arrays in the result
++	     buffer.  Both are NULL-terminated, but the first element
++	     of the alias array is stored in h_name, so no extra space
++	     for the NULL terminator is needed there.  */
++	  result->h_addr_list
++	    = alloc_buffer_alloc_array (&abuf, char *,
++					ptrlist_size (&addresses) + 1);
++	  result->h_aliases
++	    = alloc_buffer_alloc_array (&abuf, char *,
++					ptrlist_size (&aliases));
++	  if (alloc_buffer_has_failed (&abuf))
++	    {
++	      /* Retry using the ERANGE protocol.  */
++	      *errnop = ERANGE;
++	      *h_errnop = NETDB_INTERNAL;
++	      status = NSS_STATUS_TRYAGAIN;
++	    }
++	  else
++	    {
++	      /* Copy the address list and NULL-terminate it.  */
++	      memcpy (result->h_addr_list, ptrlist_begin (&addresses),
++		      ptrlist_size (&addresses) * sizeof (char *));
++	      result->h_addr_list[ptrlist_size (&addresses)] = NULL;
++
++	      /* Sort the address list if requested.  */
++	      if (type == T_A && __resolv_context_sort_count (ctx) > 0)
++		addrsort (ctx, result->h_addr_list, ptrlist_size (&addresses));
++
++	      /* Copy the aliases,  excluding the last one. */
++	      memcpy (result->h_aliases, ptrlist_begin (&aliases),
++		      (ptrlist_size (&aliases) - 1) * sizeof (char *));
++	      result->h_aliases[ptrlist_size (&aliases) - 1] = NULL;
++
++	      /* The last alias goes into h_name.  */
++	      assert (ptrlist_size (&aliases) >= 1);
++	      result->h_name = ptrlist_end (&aliases)[-1];
++
++	      /* This is also the canonical name.  */
++	      if (canonp != NULL)
++		*canonp = result->h_name;
++	    }
++	}
++
++      ptrlist_free (&aliases);
++      ptrlist_free (&addresses);
++    }
++
++  if (alt_dns_packet_buffer != dns_packet_buffer)
++    free (alt_dns_packet_buffer);
+   return status;
+ }
+ 
+@@ -615,314 +683,128 @@ addrsort (struct resolv_context *ctx, char **ap, int num)
+ 	break;
+ }
+ 
+-static enum nss_status
+-getanswer_r (struct resolv_context *ctx,
+-	     const querybuf *answer, int anslen, const char *qname, int qtype,
+-	     struct hostent *result, char *buffer, size_t buflen,
+-	     int *errnop, int *h_errnop, int32_t *ttlp, char **canonp)
++/* Convert the uncompressed, binary domain name CDNAME into its
++   textual representation and add it to the end of ALIASES, allocating
++   space for a copy of the name from ABUF.  Skip adding the name if it
++   is not a valid host name, and return false in that case, otherwise
++   true.  */
++static bool
++getanswer_r_store_alias (const unsigned char *cdname,
++			 struct alloc_buffer *abuf,
++			 struct ptrlist *aliases)
+ {
+-  struct host_data
+-  {
+-    char *aliases[MAX_NR_ALIASES];
+-    unsigned char host_addr[16];	/* IPv4 or IPv6 */
+-    char *h_addr_ptrs[0];
+-  } *host_data;
+-  int linebuflen;
+-  const HEADER *hp;
+-  const u_char *end_of_message, *cp;
+-  int n, ancount, qdcount;
+-  int haveanswer, had_error;
+-  char *bp, **ap, **hap;
+-  char tbuf[MAXDNAME];
+-  u_char packtmp[NS_MAXCDNAME];
+-  uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+-  buffer += pad;
+-  buflen = buflen > pad ? buflen - pad : 0;
+-  if (__glibc_unlikely (buflen < sizeof (struct host_data)))
+-    {
+-      /* The buffer is too small.  */
+-    too_small:
+-      *errnop = ERANGE;
+-      *h_errnop = NETDB_INTERNAL;
+-      return NSS_STATUS_TRYAGAIN;
+-    }
+-  host_data = (struct host_data *) buffer;
+-  linebuflen = buflen - sizeof (struct host_data);
+-  if (buflen - sizeof (struct host_data) != linebuflen)
+-    linebuflen = INT_MAX;
+-
+-  result->h_name = NULL;
+-  end_of_message = answer->buf + anslen;
+-
+-  /*
+-   * find first satisfactory answer
+-   */
+-  hp = &answer->hdr;
+-  ancount = ntohs (hp->ancount);
+-  qdcount = ntohs (hp->qdcount);
+-  cp = answer->buf + HFIXEDSZ;
+-  if (__glibc_unlikely (qdcount != 1))
+-    {
+-      *h_errnop = NO_RECOVERY;
+-      return NSS_STATUS_UNAVAIL;
+-    }
+-  if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen)
+-    goto too_small;
+-  bp = (char *) &host_data->h_addr_ptrs[ancount + 1];
+-  linebuflen -= (ancount + 1) * sizeof (char *);
+-
+-  n = __ns_name_unpack (answer->buf, end_of_message, cp,
+-			packtmp, sizeof packtmp);
+-  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+-    {
+-      if (__glibc_unlikely (errno == EMSGSIZE))
+-	goto too_small;
+-
+-      n = -1;
+-    }
++  /* Filter out domain names that are not host names.  */
++  if (!__res_binary_hnok (cdname))
++    return false;
++
++  /* Note: Not NS_MAXCDNAME, so that __ns_name_ntop implicitly checks
++     for length.  */
++  char dname[MAXHOSTNAMELEN + 1];
++  if (__ns_name_ntop (cdname, dname, sizeof (dname)) < 0)
++    return false;
++  /* Do not report an error on allocation failure, instead store NULL
++     or do nothing.  getanswer_r's caller will see NSS_STATUS_SUCCESS
++     and detect the memory allocation failure or buffer space
++     exhaustion, and report it accordingly.  */
++  ptrlist_add (aliases, alloc_buffer_copy_string (abuf, dname));
++  return true;
++}
+ 
+-  if (__glibc_unlikely (n < 0))
+-    {
+-      *errnop = errno;
+-      *h_errnop = NO_RECOVERY;
+-      return NSS_STATUS_UNAVAIL;
+-    }
+-  if (__glibc_unlikely (__libc_res_hnok (bp) == 0))
++static enum nss_status __attribute__ ((noinline))
++getanswer_r (unsigned char *packet, size_t packetlen, uint16_t qtype,
++	     struct alloc_buffer *abuf,
++	     struct ptrlist *addresses, struct ptrlist *aliases,
++	     int *errnop, int *h_errnop, int32_t *ttlp)
++{
++  struct ns_rr_cursor c;
++  if (!__ns_rr_cursor_init (&c, packet, packetlen))
+     {
+-      errno = EBADMSG;
+-      *errnop = EBADMSG;
++      /* This should not happen because __res_context_query already
++	 perfroms response validation.  */
+       *h_errnop = NO_RECOVERY;
+       return NSS_STATUS_UNAVAIL;
+     }
+-  cp += n + QFIXEDSZ;
+ 
+-  if (qtype == T_A || qtype == T_AAAA)
++  /* Treat the QNAME just like an alias.  Error out if it is not a
++     valid host name.  */
++  if (ns_rr_cursor_rcode (&c) == NXDOMAIN
++      || !getanswer_r_store_alias (ns_rr_cursor_qname (&c), abuf, aliases))
+     {
+-      /* res_send() has already verified that the query name is the
+-       * same as the one we sent; this just gets the expanded name
+-       * (i.e., with the succeeding search-domain tacked on).
+-       */
+-      n = strlen (bp) + 1;             /* for the \0 */
+-      if (n >= MAXHOSTNAMELEN)
+-	{
+-	  *h_errnop = NO_RECOVERY;
+-	  *errnop = ENOENT;
+-	  return NSS_STATUS_TRYAGAIN;
+-	}
+-      result->h_name = bp;
+-      bp += n;
+-      linebuflen -= n;
+-      if (linebuflen < 0)
+-	goto too_small;
+-      /* The qname can be abbreviated, but h_name is now absolute. */
+-      qname = result->h_name;
++      if (ttlp != NULL)
++	/* No negative caching.  */
++	*ttlp = 0;
++      *h_errnop = HOST_NOT_FOUND;
++      *errnop = ENOENT;
++      return NSS_STATUS_NOTFOUND;
+     }
+ 
+-  ap = host_data->aliases;
+-  *ap = NULL;
+-  result->h_aliases = host_data->aliases;
+-  hap = host_data->h_addr_ptrs;
+-  *hap = NULL;
+-  result->h_addr_list = host_data->h_addr_ptrs;
+-  haveanswer = 0;
+-  had_error = 0;
++  int ancount = ns_rr_cursor_ancount (&c);
++  const unsigned char *expected_name = ns_rr_cursor_qname (&c);
++  /* expected_name may be updated to point into this buffer.  */
++  unsigned char name_buffer[NS_MAXCDNAME];
+ 
+-  while (ancount-- > 0 && cp < end_of_message && had_error == 0)
++  for (; ancount > 0; --ancount)
+     {
+-      int type, class;
+-
+-      n = __ns_name_unpack (answer->buf, end_of_message, cp,
+-			    packtmp, sizeof packtmp);
+-      if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+-	{
+-	  if (__glibc_unlikely (errno == EMSGSIZE))
+-	    goto too_small;
+-
+-	  n = -1;
+-	}
+-
+-      if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0))
+-	{
+-	  ++had_error;
+-	  continue;
+-	}
+-      cp += n;				/* name */
+-
+-      if (__glibc_unlikely (cp + 10 > end_of_message))
++      struct ns_rr_wire rr;
++      if (!__ns_rr_cursor_next (&c, &rr))
+ 	{
+-	  ++had_error;
+-	  continue;
++	  *h_errnop = NO_RECOVERY;
++	  return NSS_STATUS_UNAVAIL;
+ 	}
+ 
+-      NS_GET16 (type, cp);
+-      NS_GET16 (class, cp);
+-      int32_t ttl;
+-      NS_GET32 (ttl, cp);
+-      NS_GET16 (n, cp);		/* RDATA length.  */
+-
+-      if (end_of_message - cp < n)
+-	{
+-	  /* RDATA extends beyond the end of the packet.  */
+-	  ++had_error;
+-	  continue;
+-	}
++      /* Skip over records with the wrong class.  */
++      if (rr.rclass != C_IN)
++	continue;
+ 
+-      if (__glibc_unlikely (class != C_IN))
+-	{
+-	  /* XXX - debug? syslog? */
+-	  cp += n;
+-	  continue;			/* XXX - had_error++ ? */
+-	}
++      /* Update TTL for recognized record types.  */
++      if ((rr.rtype == T_CNAME || rr.rtype == qtype)
++	  && ttlp != NULL && *ttlp > rr.ttl)
++	*ttlp = rr.ttl;
+ 
+-      if (type == T_CNAME)
++      if (rr.rtype == T_CNAME)
+ 	{
+-	  /* A CNAME could also have a TTL entry.  */
+-	  if (ttlp != NULL && ttl < *ttlp)
+-	      *ttlp = ttl;
+-
+-	  if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
+-	    continue;
+-	  n = __libc_dn_expand (answer->buf, end_of_message, cp,
+-				tbuf, sizeof tbuf);
+-	  if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0))
+-	    {
+-	      ++had_error;
+-	      continue;
+-	    }
+-	  cp += n;
+-	  /* Store alias.  */
+-	  *ap++ = bp;
+-	  n = strlen (bp) + 1;		/* For the \0.  */
+-	  if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
+-	    {
+-	      ++had_error;
+-	      continue;
+-	    }
+-	  bp += n;
+-	  linebuflen -= n;
+-	  /* Get canonical name.  */
+-	  n = strlen (tbuf) + 1;	/* For the \0.  */
+-	  if (__glibc_unlikely (n > linebuflen))
+-	    goto too_small;
+-	  if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
++	  /* NB: No check for owner name match, based on historic
++	     precedent.  Record the CNAME target as the new expected
++	     name.  */
++	  int n = __ns_name_unpack (c.begin, c.end, rr.rdata,
++				    name_buffer, sizeof (name_buffer));
++	  if (n < 0)
+ 	    {
+-	      ++had_error;
+-	      continue;
++	      *h_errnop = NO_RECOVERY;
++	      return NSS_STATUS_UNAVAIL;
+ 	    }
+-	  result->h_name = bp;
+-	  bp = __mempcpy (bp, tbuf, n);	/* Cannot overflow.  */
+-	  linebuflen -= n;
+-	  continue;
++	  /* And store the new name as an alias.  */
++	  getanswer_r_store_alias (name_buffer, abuf, aliases);
++	  expected_name = name_buffer;
+ 	}
+-
+-      if (__glibc_unlikely (type != qtype))
++      else if (rr.rtype == qtype
++	       && __ns_samebinaryname (rr.rname, expected_name)
++	       && rr.rdlength == rrtype_to_rdata_length (qtype))
+ 	{
+-	  cp += n;
+-	  continue;			/* XXX - had_error++ ? */
++	  /* Make a copy of the address and store it.  Increase the
++	     alignment to 4, in case there are applications out there
++	     that expect at least this level of address alignment.  */
++	  ptrlist_add (addresses, (char *) alloc_buffer_next (abuf, uint32_t));
++	  alloc_buffer_copy_bytes (abuf, rr.rdata, rr.rdlength);
+ 	}
+-
+-      switch (type)
+-	{
+-	case T_A:
+-	case T_AAAA:
+-	  if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0))
+-	    {
+-	      cp += n;
+-	      continue;			/* XXX - had_error++ ? */
+-	    }
+-
+-	  /* Stop parsing at a record whose length is incorrect.  */
+-	  if (n != rrtype_to_rdata_length (type))
+-	    {
+-	      ++had_error;
+-	      break;
+-	    }
+-
+-	  /* Skip records of the wrong type.  */
+-	  if (n != result->h_length)
+-	    {
+-	      cp += n;
+-	      continue;
+-	    }
+-	  if (!haveanswer)
+-	    {
+-	      int nn;
+-
+-	      /* We compose a single hostent out of the entire chain of
+-	         entries, so the TTL of the hostent is essentially the lowest
+-		 TTL in the chain.  */
+-	      if (ttlp != NULL && ttl < *ttlp)
+-		*ttlp = ttl;
+-	      if (canonp != NULL)
+-		*canonp = bp;
+-	      result->h_name = bp;
+-	      nn = strlen (bp) + 1;	/* for the \0 */
+-	      bp += nn;
+-	      linebuflen -= nn;
+-	    }
+-
+-	  /* Provide sufficient alignment for both address
+-	     families.  */
+-	  enum { align = 4 };
+-	  _Static_assert ((align % __alignof__ (struct in_addr)) == 0,
+-			  "struct in_addr alignment");
+-	  _Static_assert ((align % __alignof__ (struct in6_addr)) == 0,
+-			  "struct in6_addr alignment");
+-	  {
+-	    char *new_bp = PTR_ALIGN_UP (bp, align);
+-	    linebuflen -= new_bp - bp;
+-	    bp = new_bp;
+-	  }
+-
+-	  if (__glibc_unlikely (n > linebuflen))
+-	    goto too_small;
+-	  bp = __mempcpy (*hap++ = bp, cp, n);
+-	  cp += n;
+-	  linebuflen -= n;
+-	  break;
+-	default:
+-	  abort ();
+-	}
+-      if (had_error == 0)
+-	++haveanswer;
+     }
+ 
+-  if (haveanswer > 0)
++  if (ptrlist_size (addresses) == 0)
+     {
+-      *ap = NULL;
+-      *hap = NULL;
+-      /*
+-       * Note: we sort even if host can take only one address
+-       * in its return structures - should give it the "best"
+-       * address in that case, not some random one
+-       */
+-      if (haveanswer > 1 && qtype == T_A
+-	  && __resolv_context_sort_count (ctx) > 0)
+-	addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
+-
+-      if (result->h_name == NULL)
+-	{
+-	  n = strlen (qname) + 1;	/* For the \0.  */
+-	  if (n > linebuflen)
+-	    goto too_small;
+-	  if (n >= MAXHOSTNAMELEN)
+-	    goto no_recovery;
+-	  result->h_name = bp;
+-	  bp = __mempcpy (bp, qname, n);	/* Cannot overflow.  */
+-	  linebuflen -= n;
+-	}
++      /* No address record found.  */
++      if (ttlp != NULL)
++	/* No caching of negative responses.  */
++	*ttlp = 0;
+ 
++      *h_errnop = NO_RECOVERY;
++      *errnop = ENOENT;
++      return NSS_STATUS_TRYAGAIN;
++    }
++  else
++    {
+       *h_errnop = NETDB_SUCCESS;
+       return NSS_STATUS_SUCCESS;
+     }
+- no_recovery:
+-  *h_errnop = NO_RECOVERY;
+-  *errnop = ENOENT;
+-  /* Special case here: if the resolver sent a result but it only
+-     contains a CNAME while we are looking for a T_A or T_AAAA record,
+-     we fail with NOTFOUND instead of TRYAGAIN.  */
+-  return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
+-	   ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
+ }
+ 
+ static enum nss_status
diff --git a/SOURCES/glibc-upstream-2.34-326.patch b/SOURCES/glibc-upstream-2.34-326.patch
new file mode 100644
index 0000000..3784a3e
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-326.patch
@@ -0,0 +1,51 @@
+commit c36e7cca3571b0c92b09409c1df86a142596c210
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    nss_dns: In gaih_getanswer_slice, skip strange aliases (bug 12154)
+    
+    If the name is not a host name, skip adding it to the result, instead
+    of reporting query failure.  This fixes bug 12154 for getaddrinfo.
+    
+    This commit still keeps the old parsing code, and only adjusts when
+    a host name is copied.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 32b599ac8c21c4c332cc3900a792a1395bca79c7)
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index 10c21e1e827cde12..1cb3be71f04d98eb 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -971,12 +971,12 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
+ 
+ 	  n = -1;
+ 	}
+-      if (__glibc_unlikely (n < 0 || __libc_res_hnok (buffer) == 0))
++      if (__glibc_unlikely (n < 0))
+ 	{
+ 	  ++had_error;
+ 	  continue;
+ 	}
+-      if (*firstp && canon == NULL)
++      if (*firstp && canon == NULL && __libc_res_hnok (buffer))
+ 	{
+ 	  h_name = buffer;
+ 	  buffer += h_namelen;
+@@ -1022,14 +1022,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
+ 
+ 	  n = __libc_dn_expand (answer->buf, end_of_message, cp,
+ 				tbuf, sizeof tbuf);
+-	  if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0))
++	  if (__glibc_unlikely (n < 0))
+ 	    {
+ 	      ++had_error;
+ 	      continue;
+ 	    }
+ 	  cp += n;
+ 
+-	  if (*firstp)
++	  if (*firstp && __libc_res_hnok (tbuf))
+ 	    {
+ 	      /* Reclaim buffer space.  */
+ 	      if (h_name + h_namelen == buffer)
diff --git a/SOURCES/glibc-upstream-2.34-327.patch b/SOURCES/glibc-upstream-2.34-327.patch
new file mode 100644
index 0000000..8019ca3
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-327.patch
@@ -0,0 +1,449 @@
+commit 480c820493add16e8dda6f3189d834223e1f4f39
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 10:02:49 2022 +0200
+
+    resolv: Add new tst-resolv-invalid-cname
+    
+    This test checks resolution through CNAME chains that do not contain
+    host names (bug 12154).
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 9caf782276ecea4bc86fc94fbb52779736f3106d)
+
+Conflicts:
+	resolv/Makefile
+	  (usual test differences)
+
+diff --git a/resolv/Makefile b/resolv/Makefile
+index fded244d61068060..ea1518ec2da860c1 100644
+--- a/resolv/Makefile
++++ b/resolv/Makefile
+@@ -99,6 +99,7 @@ tests += \
+   tst-resolv-binary \
+   tst-resolv-byaddr \
+   tst-resolv-edns \
++  tst-resolv-invalid-cname \
+   tst-resolv-network \
+   tst-resolv-noaaaa \
+   tst-resolv-nondecimal \
+@@ -279,6 +280,8 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
+ $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
+   $(shared-thread-library)
+ $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library)
++$(objpfx)tst-resolv-invalid-cname: $(objpfx)libresolv.so \
++  $(shared-thread-library)
+ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
+ $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
+diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c
+new file mode 100644
+index 0000000000000000..ae2d4419b1978c02
+--- /dev/null
++++ b/resolv/tst-resolv-invalid-cname.c
+@@ -0,0 +1,406 @@
++/* Test handling of CNAMEs with non-host domain names (bug 12154).
++   Copyright (C) 2022 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 <errno.h>
++#include <netdb.h>
++#include <resolv.h>
++#include <stdlib.h>
++#include <string.h>
++#include <support/check.h>
++#include <support/check_nss.h>
++#include <support/resolv_test.h>
++#include <support/support.h>
++#include <support/xmemstream.h>
++
++/* Query strings describe the CNAME chain in the response.  They have
++   the format "bitsBITS.countCOUNT.example.", where BITS and COUNT are
++   replaced by unsigned decimal numbers.  COUNT is the number of CNAME
++   records in the response.  BITS has two bits for each CNAME record,
++   describing a special prefix that is added to that CNAME.
++
++   0: No special leading label.
++   1: Starting with "*.".
++   2: Starting with "-x.".
++   3: Starting with "star.*.".
++
++   The first CNAME in the response using the two least significant
++   bits.
++
++   For PTR queries, the QNAME format is different, it is either
++   COUNT.BITS.168.192.in-addr.arpa. (with BITS and COUNT still
++   decimal), or:
++
++COUNT.BITS0.BITS1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
++
++   where BITS and COUNT are hexadecimal.  */
++
++static void
++response (const struct resolv_response_context *ctx,
++          struct resolv_response_builder *b,
++          const char *qname, uint16_t qclass, uint16_t qtype)
++{
++  TEST_COMPARE (qclass, C_IN);
++
++  /* The only other query type besides A is PTR.  */
++  if (qtype != T_A && qtype != T_AAAA)
++    TEST_COMPARE (qtype, T_PTR);
++
++  unsigned int bits, bits1, count;
++  char *tail = NULL;
++  if (sscanf (qname, "bits%u.count%u.%ms", &bits, &count, &tail) == 3)
++    TEST_COMPARE_STRING (tail, "example");
++  else if (strstr (qname, "in-addr.arpa") != NULL
++           && sscanf (qname, "%u.%u.%ms", &bits, &count, &tail) == 3)
++    TEST_COMPARE_STRING (tail, "168.192.in-addr.arpa");
++  else if (sscanf (qname, "%x.%x.%x.%ms", &bits, &bits1, &count, &tail) == 4)
++    {
++      TEST_COMPARE_STRING (tail, "\
++0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa");
++      bits |= bits1 << 4;
++    }
++  else
++    FAIL_EXIT1 ("invalid QNAME: %s\n", qname);
++  free (tail);
++
++  struct resolv_response_flags flags = {};
++  resolv_response_init (b, flags);
++  resolv_response_add_question (b, qname, qclass, qtype);
++  resolv_response_section (b, ns_s_an);
++
++  /* Provide the requested number of CNAME records.  */
++  char *previous_name = (char *) qname;
++  unsigned int original_bits = bits;
++  for (int unique = 0; unique < count; ++unique)
++    {
++      resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60);
++
++      static const char bits_to_prefix[4][8] = { "", "*.", "-x.", "star.*." };
++      char *new_name = xasprintf ("%sunique%d.example",
++                                  bits_to_prefix[bits & 3], unique);
++      bits >>= 2;
++      resolv_response_add_name (b, new_name);
++      resolv_response_close_record (b);
++
++      if (previous_name != qname)
++        free (previous_name);
++      previous_name = new_name;
++    }
++
++  /* Actual answer record.  */
++  resolv_response_open_record (b, previous_name, qclass, qtype, 60);
++  switch (qtype)
++    {
++    case T_A:
++      {
++        char ipv4[4] = {192, 168, count, original_bits};
++        resolv_response_add_data (b, &ipv4, sizeof (ipv4));
++      }
++      break;
++    case T_AAAA:
++      {
++        char ipv6[16] =
++          {
++            0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++            count, original_bits
++          };
++        resolv_response_add_data (b, &ipv6, sizeof (ipv6));
++      }
++      break;
++
++    case T_PTR:
++      {
++        char *name = xasprintf ("bits%u.count%u.example",
++                                original_bits, count);
++        resolv_response_add_name (b, name);
++        free (name);
++      }
++      break;
++    }
++  resolv_response_close_record (b);
++
++  if (previous_name != qname)
++    free (previous_name);
++}
++
++/* Controls which name resolution function is invoked.  */
++enum test_mode
++  {
++    byname,                     /* gethostbyname.  */
++    byname2,                    /* gethostbyname2.  */
++    gai,                        /* getaddrinfo without AI_CANONNAME.  */
++    gai_canon,                  /* getaddrinfo with AI_CANONNAME.  */
++
++    test_mode_num               /* Number of enum values.  */
++  };
++
++static const char *
++test_mode_to_string (enum test_mode mode)
++{
++  switch (mode)
++    {
++    case byname:
++      return "byname";
++    case byname2:
++      return "byname2";
++    case gai:
++      return "gai";
++    case gai_canon:
++      return "gai_canon";
++    case test_mode_num:
++      /* Report error below.  */
++    }
++  FAIL_EXIT1 ("invalid test_mode: %d", mode);
++}
++
++/* Append the name and aliases to OUT.  */
++static void
++append_names (FILE *out, const char *qname, int bits, int count,
++              enum test_mode mode)
++{
++  /* Largest valid index which has a corresponding zero in bits
++     (meaning a syntactically valid CNAME).  */
++  int last_valid_cname = -1;
++
++  for (int i = 0; i < count; ++i)
++    if ((bits & (3 << (i * 2))) == 0)
++      last_valid_cname = i;
++
++  if (mode != gai)
++    {
++      const char *label;
++      if (mode == gai_canon)
++        label = "canonname";
++      else
++        label = "name";
++      if (last_valid_cname >= 0)
++        fprintf (out, "%s: unique%d.example\n", label, last_valid_cname);
++      else
++        fprintf (out, "%s: %s\n", label, qname);
++    }
++
++  if (mode == byname || mode == byname2)
++    {
++      if (last_valid_cname >= 0)
++        fprintf (out, "alias: %s\n", qname);
++      for (int i = 0; i < count; ++i)
++        {
++          if ((bits & (3 << (i * 2))) == 0 && i != last_valid_cname)
++            fprintf (out, "alias: unique%d.example\n", i);
++        }
++    }
++}
++
++/* Append the address information to OUT.  */
++static void
++append_addresses (FILE *out, int af, int bits, int count, enum test_mode mode)
++{
++  int last = count * 256 + bits;
++  if (mode == gai || mode == gai_canon)
++    {
++      if (af == AF_INET || af == AF_UNSPEC)
++        fprintf (out, "address: STREAM/TCP 192.168.%d.%d 80\n", count, bits);
++      if (af == AF_INET6 || af == AF_UNSPEC)
++        {
++          if (last == 0)
++            fprintf (out, "address: STREAM/TCP 2001:db8:: 80\n");
++          else
++            fprintf (out, "address: STREAM/TCP 2001:db8::%x 80\n", last);
++        }
++    }
++  else
++    {
++      TEST_VERIFY (af != AF_UNSPEC);
++      if (af == AF_INET)
++        fprintf (out, "address: 192.168.%d.%d\n", count, bits);
++      if (af == AF_INET6)
++        {
++          if (last == 0)
++            fprintf (out, "address: 2001:db8::\n");
++          else
++            fprintf (out, "address: 2001:db8::%x\n", last);
++        }
++    }
++}
++
++/* Perform one test using a forward lookup.  */
++static void
++check_forward (int af, int bits, int count, enum test_mode mode)
++{
++  char *qname = xasprintf ("bits%d.count%d.example", bits, count);
++  char *label = xasprintf ("af=%d bits=%d count=%d mode=%s qname=%s",
++                           af, bits, count, test_mode_to_string (mode), qname);
++
++  struct xmemstream expected;
++  xopen_memstream (&expected);
++  if (mode == gai_canon)
++    fprintf (expected.out, "flags: AI_CANONNAME\n");
++  append_names (expected.out, qname, bits, count, mode);
++  append_addresses (expected.out, af, bits, count, mode);
++  xfclose_memstream (&expected);
++
++  if (mode == gai || mode == gai_canon)
++    {
++      struct addrinfo *ai;
++      struct addrinfo hints =
++        {
++          .ai_family = af,
++          .ai_socktype = SOCK_STREAM,
++        };
++      if (mode == gai_canon)
++        hints.ai_flags |= AI_CANONNAME;
++      int ret = getaddrinfo (qname, "80", &hints, &ai);
++      check_addrinfo (label, ai, ret, expected.buffer);
++      if (ret == 0)
++        freeaddrinfo (ai);
++    }
++  else
++    {
++      struct hostent *e;
++      if (mode == gai)
++        {
++          TEST_COMPARE (af, AF_INET);
++          e = gethostbyname (qname);
++        }
++      else
++        {
++          if (af != AF_INET)
++            TEST_COMPARE (af, AF_INET6);
++          e = gethostbyname2 (qname, af);
++        }
++      check_hostent (label, e, expected.buffer);
++    }
++
++  free (expected.buffer);
++  free (label);
++  free (qname);
++}
++
++/* Perform one check using a reverse lookup.  */
++
++static void
++check_reverse (int af, int bits, int count)
++{
++  TEST_VERIFY (af == AF_INET || af == AF_INET6);
++
++  char *label = xasprintf ("af=%d bits=%d count=%d", af, bits, count);
++  char *fqdn = xasprintf ("bits%d.count%d.example", bits, count);
++
++  struct xmemstream expected;
++  xopen_memstream (&expected);
++  fprintf (expected.out, "name: %s\n", fqdn);
++  append_addresses (expected.out, af, bits, count, byname);
++  xfclose_memstream (&expected);
++
++  char addr[16] = { 0 };
++  socklen_t addrlen;
++  if (af == AF_INET)
++    {
++      addr[0] = 192;
++      addr[1] = 168;
++      addr[2] = count;
++      addr[3] = bits;
++      addrlen = 4;
++    }
++  else
++    {
++      addr[0] = 0x20;
++      addr[1] = 0x01;
++      addr[2] = 0x0d;
++      addr[3] = 0xb8;
++      addr[14] = count;
++      addr[15] = bits;
++      addrlen = 16;
++    }
++
++  struct hostent *e = gethostbyaddr (addr, addrlen, af);
++  check_hostent (label, e, expected.buffer);
++
++  /* getnameinfo check is different.  There is no generic check_*
++     function for it.  */
++  {
++    struct sockaddr_in sin = { };
++    struct sockaddr_in6 sin6 = { };
++    void *sa;
++    socklen_t salen;
++    if (af == AF_INET)
++      {
++        sin.sin_family = AF_INET;
++        memcpy (&sin.sin_addr, addr, addrlen);
++        sin.sin_port = htons (80);
++        sa = &sin;
++        salen = sizeof (sin);
++      }
++    else
++      {
++        sin6.sin6_family = AF_INET6;
++        memcpy (&sin6.sin6_addr, addr, addrlen);
++        sin6.sin6_port = htons (80);
++        sa = &sin6;
++        salen = sizeof (sin6);
++      }
++
++    char host[64];
++    char service[64];
++    int ret = getnameinfo (sa, salen, host,
++                           sizeof (host), service, sizeof (service),
++                           NI_NAMEREQD | NI_NUMERICSERV);
++    TEST_COMPARE (ret, 0);
++    TEST_COMPARE_STRING (host, fqdn);
++    TEST_COMPARE_STRING (service, "80");
++  }
++
++  free (expected.buffer);
++  free (fqdn);
++  free (label);
++}
++
++static int
++do_test (void)
++{
++  struct resolv_test *obj = resolv_test_start
++    ((struct resolv_redirect_config)
++     {
++       .response_callback = response
++     });
++
++  for (int count = 0; count <= 3; ++count)
++    for (int bits = 0; bits <= 1 << (count * 2); ++bits)
++      {
++        if (count > 0 && bits == count)
++          /* The last bits value is only checked if count == 0.  */
++          continue;
++
++        for (enum test_mode mode = 0; mode < test_mode_num; ++mode)
++          {
++            check_forward (AF_INET, bits, count, mode);
++            if (mode != byname)
++              check_forward (AF_INET6, bits, count, mode);
++            if (mode == gai || mode == gai_canon)
++              check_forward (AF_UNSPEC, bits, count, mode);
++          }
++
++        check_reverse (AF_INET, bits, count);
++        check_reverse (AF_INET6, bits, count);
++      }
++
++  resolv_test_end (obj);
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-329.patch b/SOURCES/glibc-upstream-2.34-329.patch
new file mode 100644
index 0000000..d718c5f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-329.patch
@@ -0,0 +1,31 @@
+commit 044755e2faeeca13bb77b2e9e638a45e6e90a5fa
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Aug 30 13:30:03 2022 +0200
+
+    resolv: Fix building tst-resolv-invalid-cname for earlier C standards
+    
+    This fixes this compiler error:
+    
+    tst-resolv-invalid-cname.c: In function ‘test_mode_to_string’:
+    tst-resolv-invalid-cname.c:164:10: error: label at end of compound statement
+         case test_mode_num:
+              ^~~~~~~~~~~~~
+    
+    Fixes commit 9caf782276ecea4bc86fc94fbb52779736f3106d
+    ("resolv: Add new tst-resolv-invalid-cname").
+    
+    (cherry picked from commit d09aa4a17229bcaa2ec7642006b12612498582e7)
+
+diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c
+index ae2d4419b1978c02..63dac90e02d6cbc7 100644
+--- a/resolv/tst-resolv-invalid-cname.c
++++ b/resolv/tst-resolv-invalid-cname.c
+@@ -162,7 +162,7 @@ test_mode_to_string (enum test_mode mode)
+     case gai_canon:
+       return "gai_canon";
+     case test_mode_num:
+-      /* Report error below.  */
++      break;                    /* Report error below.  */
+     }
+   FAIL_EXIT1 ("invalid test_mode: %d", mode);
+ }
diff --git a/SOURCES/glibc-upstream-2.34-330.patch b/SOURCES/glibc-upstream-2.34-330.patch
new file mode 100644
index 0000000..4fb22ef
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-330.patch
@@ -0,0 +1,33 @@
+commit a2e259014f8a0e5f3ff938314f3087b74255804d
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Nov 11 06:31:51 2021 -0800
+
+    Avoid extra load with CAS in __pthread_mutex_lock_full [BZ #28537]
+    
+    Replace boolean CAS with value CAS to avoid the extra load.
+    
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+    (cherry picked from commit 0b82747dc48d5bf0871bdc6da8cb6eec1256355f)
+
+diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
+index da624f322d06d0ee..a04e0158451c8fff 100644
+--- a/nptl/pthread_mutex_lock.c
++++ b/nptl/pthread_mutex_lock.c
+@@ -298,12 +298,12 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
+ 	     meantime.  */
+ 	  if ((oldval & FUTEX_WAITERS) == 0)
+ 	    {
+-	      if (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
+-							oldval | FUTEX_WAITERS,
+-							oldval)
+-		  != 0)
++	      int val;
++	      if ((val = atomic_compare_and_exchange_val_acq
++		   (&mutex->__data.__lock, oldval | FUTEX_WAITERS,
++		    oldval)) != oldval)
+ 		{
+-		  oldval = mutex->__data.__lock;
++		  oldval = val;
+ 		  continue;
+ 		}
+ 	      oldval |= FUTEX_WAITERS;
diff --git a/SOURCES/glibc-upstream-2.34-331.patch b/SOURCES/glibc-upstream-2.34-331.patch
new file mode 100644
index 0000000..59c359f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-331.patch
@@ -0,0 +1,33 @@
+commit ed8300c054cae4aeb0bbfa043f5fccc91a4adbf5
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Thu Nov 11 06:54:01 2021 -0800
+
+    Avoid extra load with CAS in __pthread_mutex_clocklock_common [BZ #28537]
+    
+    Replace boolean CAS with value CAS to avoid the extra load.
+    
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+    (cherry picked from commit 49302b8fdf9103b6fc0a398678668a22fa19574c)
+
+diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
+index 11ad7005d07afc6e..90cede9446e33fcf 100644
+--- a/nptl/pthread_mutex_timedlock.c
++++ b/nptl/pthread_mutex_timedlock.c
+@@ -234,12 +234,12 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex,
+ 	     meantime.  */
+ 	  if ((oldval & FUTEX_WAITERS) == 0)
+ 	    {
+-	      if (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
+-							oldval | FUTEX_WAITERS,
+-							oldval)
+-		  != 0)
++	      int val;
++	      if ((val = atomic_compare_and_exchange_val_acq
++		   (&mutex->__data.__lock, oldval | FUTEX_WAITERS,
++		    oldval)) != oldval)
+ 		{
+-		  oldval = mutex->__data.__lock;
++		  oldval = val;
+ 		  continue;
+ 		}
+ 	      oldval |= FUTEX_WAITERS;
diff --git a/SOURCES/glibc-upstream-2.34-332.patch b/SOURCES/glibc-upstream-2.34-332.patch
new file mode 100644
index 0000000..2a8d15a
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-332.patch
@@ -0,0 +1,46 @@
+commit a6b81f605dfba8650ea1f80122f41eb8e6c73dc7
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Tue Nov 2 18:33:07 2021 -0700
+
+    Add LLL_MUTEX_READ_LOCK [BZ #28537]
+    
+    CAS instruction is expensive.  From the x86 CPU's point of view, getting
+    a cache line for writing is more expensive than reading.  See Appendix
+    A.2 Spinlock in:
+    
+    https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/xeon-lock-scaling-analysis-paper.pdf
+    
+    The full compare and swap will grab the cache line exclusive and cause
+    excessive cache line bouncing.
+    
+    Add LLL_MUTEX_READ_LOCK to do an atomic load and skip CAS in spinlock
+    loop if compare may fail to reduce cache line bouncing on contended locks.
+    
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+    (cherry picked from commit d672a98a1af106bd68deb15576710cd61363f7a6)
+
+diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
+index a04e0158451c8fff..9f40928cc6b9a067 100644
+--- a/nptl/pthread_mutex_lock.c
++++ b/nptl/pthread_mutex_lock.c
+@@ -65,6 +65,11 @@ lll_mutex_lock_optimized (pthread_mutex_t *mutex)
+ # define PTHREAD_MUTEX_VERSIONS 1
+ #endif
+ 
++#ifndef LLL_MUTEX_READ_LOCK
++# define LLL_MUTEX_READ_LOCK(mutex) \
++  atomic_load_relaxed (&(mutex)->__data.__lock)
++#endif
++
+ static int __pthread_mutex_lock_full (pthread_mutex_t *mutex)
+      __attribute_noinline__;
+ 
+@@ -142,6 +147,8 @@ PTHREAD_MUTEX_LOCK (pthread_mutex_t *mutex)
+ 		  break;
+ 		}
+ 	      atomic_spin_nop ();
++	      if (LLL_MUTEX_READ_LOCK (mutex) != 0)
++		continue;
+ 	    }
+ 	  while (LLL_MUTEX_TRYLOCK (mutex) != 0);
+ 
diff --git a/SOURCES/glibc-upstream-2.34-333.patch b/SOURCES/glibc-upstream-2.34-333.patch
new file mode 100644
index 0000000..71f9e2a
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-333.patch
@@ -0,0 +1,66 @@
+commit 6bcfbee7277e4faa4b693bd965931f0d1883005d
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Fri Nov 12 11:47:42 2021 -0800
+
+    Move assignment out of the CAS condition
+    
+    Update
+    
+    commit 49302b8fdf9103b6fc0a398678668a22fa19574c
+    Author: H.J. Lu <hjl.tools@gmail.com>
+    Date:   Thu Nov 11 06:54:01 2021 -0800
+    
+        Avoid extra load with CAS in __pthread_mutex_clocklock_common [BZ #28537]
+    
+        Replace boolean CAS with value CAS to avoid the extra load.
+    
+    and
+    
+    commit 0b82747dc48d5bf0871bdc6da8cb6eec1256355f
+    Author: H.J. Lu <hjl.tools@gmail.com>
+    Date:   Thu Nov 11 06:31:51 2021 -0800
+    
+        Avoid extra load with CAS in __pthread_mutex_lock_full [BZ #28537]
+    
+        Replace boolean CAS with value CAS to avoid the extra load.
+    
+    by moving assignment out of the CAS condition.
+    
+    (cherry picked from commit 120ac6d238825452e8024e2f627da33b2508dfd3)
+
+diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
+index 9f40928cc6b9a067..49901ffa0a96d659 100644
+--- a/nptl/pthread_mutex_lock.c
++++ b/nptl/pthread_mutex_lock.c
+@@ -305,10 +305,9 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
+ 	     meantime.  */
+ 	  if ((oldval & FUTEX_WAITERS) == 0)
+ 	    {
+-	      int val;
+-	      if ((val = atomic_compare_and_exchange_val_acq
+-		   (&mutex->__data.__lock, oldval | FUTEX_WAITERS,
+-		    oldval)) != oldval)
++	      int val = atomic_compare_and_exchange_val_acq
++		(&mutex->__data.__lock, oldval | FUTEX_WAITERS, oldval);
++	      if (val != oldval)
+ 		{
+ 		  oldval = val;
+ 		  continue;
+diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
+index 90cede9446e33fcf..2e5506db06ccb1ec 100644
+--- a/nptl/pthread_mutex_timedlock.c
++++ b/nptl/pthread_mutex_timedlock.c
+@@ -234,10 +234,9 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex,
+ 	     meantime.  */
+ 	  if ((oldval & FUTEX_WAITERS) == 0)
+ 	    {
+-	      int val;
+-	      if ((val = atomic_compare_and_exchange_val_acq
+-		   (&mutex->__data.__lock, oldval | FUTEX_WAITERS,
+-		    oldval)) != oldval)
++	      int val = atomic_compare_and_exchange_val_acq
++		(&mutex->__data.__lock, oldval | FUTEX_WAITERS, oldval);
++	      if (val != oldval)
+ 		{
+ 		  oldval = val;
+ 		  continue;
diff --git a/SOURCES/glibc-upstream-2.34-334.patch b/SOURCES/glibc-upstream-2.34-334.patch
new file mode 100644
index 0000000..1138256
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-334.patch
@@ -0,0 +1,38 @@
+commit 43760d33d78f9ea8c8af942b570112ee801b99df
+Author: Jangwoong Kim <6812skiii@gmail.com>
+Date:   Tue Dec 14 21:30:51 2021 +0900
+
+    nptl: Effectively skip CAS in spinlock loop
+    
+    The commit:
+    "Add LLL_MUTEX_READ_LOCK [BZ #28537]"
+    SHA1: d672a98a1af106bd68deb15576710cd61363f7a6
+    
+    introduced LLL_MUTEX_READ_LOCK, to skip CAS in spinlock loop
+    if atomic load fails. But, "continue" inside of do-while loop
+    does not skip the evaluation of escape expression, thus CAS
+    is not skipped.
+    
+    Replace do-while with while and skip LLL_MUTEX_TRYLOCK if
+    LLL_MUTEX_READ_LOCK fails.
+    
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    (cherry picked from commit 6b8dbbd03ac88f169b65b5c7d7278576a11d2e44)
+
+diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
+index 49901ffa0a96d659..bbe754a272b97d91 100644
+--- a/nptl/pthread_mutex_lock.c
++++ b/nptl/pthread_mutex_lock.c
+@@ -147,10 +147,9 @@ PTHREAD_MUTEX_LOCK (pthread_mutex_t *mutex)
+ 		  break;
+ 		}
+ 	      atomic_spin_nop ();
+-	      if (LLL_MUTEX_READ_LOCK (mutex) != 0)
+-		continue;
+ 	    }
+-	  while (LLL_MUTEX_TRYLOCK (mutex) != 0);
++	  while (LLL_MUTEX_READ_LOCK (mutex) != 0
++		 || LLL_MUTEX_TRYLOCK (mutex) != 0);
+ 
+ 	  mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
+ 	}
diff --git a/SOURCES/glibc-upstream-2.34-335.patch b/SOURCES/glibc-upstream-2.34-335.patch
new file mode 100644
index 0000000..fdf1241
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-335.patch
@@ -0,0 +1,68 @@
+commit 04efdcfac405723c23b25d124817bcfc1697e2d8
+Author: Noah Goldstein <goldstein.w.n@gmail.com>
+Date:   Wed Apr 27 15:13:02 2022 -0500
+
+    sysdeps: Add 'get_fast_jitter' interace in fast-jitter.h
+    
+    'get_fast_jitter' is meant to be used purely for performance
+    purposes. In all cases it's used it should be acceptable to get no
+    randomness (see default case). An example use case is in setting
+    jitter for retries between threads at a lock. There is a
+    performance benefit to having jitter, but only if the jitter can
+    be generated very quickly and ultimately there is no serious issue
+    if no jitter is generated.
+    
+    The implementation generally uses 'HP_TIMING_NOW' iff it is
+    inlined (avoid any potential syscall paths).
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    
+    (cherry picked from commit 911c63a51c690dd1a97dfc587097277029baf00f)
+
+diff --git a/sysdeps/generic/fast-jitter.h b/sysdeps/generic/fast-jitter.h
+new file mode 100644
+index 0000000000000000..4dd53e3475c3dfe6
+--- /dev/null
++++ b/sysdeps/generic/fast-jitter.h
+@@ -0,0 +1,42 @@
++/* Fallback for fast jitter just return 0.
++   Copyright (C) 2019-2022 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/>.  */
++
++#ifndef _FAST_JITTER_H
++# define _FAST_JITTER_H
++
++# include <stdint.h>
++# include <hp-timing.h>
++
++/* Baseline just return 0.  We could create jitter using a clock or
++   'random_bits' but that may imply a syscall and the goal of
++   'get_fast_jitter' is minimal overhead "randomness" when such
++   randomness helps performance.  Adding high overhead the function
++   defeats the purpose.  */
++static inline uint32_t
++get_fast_jitter (void)
++{
++# if HP_TIMING_INLINE
++  hp_timing_t jitter;
++  HP_TIMING_NOW (jitter);
++  return (uint32_t) jitter;
++# else
++  return 0;
++# endif
++}
++
++#endif
diff --git a/SOURCES/glibc-upstream-2.34-336.patch b/SOURCES/glibc-upstream-2.34-336.patch
new file mode 100644
index 0000000..94b39f2
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-336.patch
@@ -0,0 +1,209 @@
+commit ea69248445fb9b80da02ee0c7261cba4b1a5532e
+Author: Wangyang Guo <wangyang.guo@intel.com>
+Date:   Fri May 6 01:50:10 2022 +0000
+
+    nptl: Add backoff mechanism to spinlock loop
+    
+    When mutiple threads waiting for lock at the same time, once lock owner
+    releases the lock, waiters will see lock available and all try to lock,
+    which may cause an expensive CAS storm.
+    
+    Binary exponential backoff with random jitter is introduced. As try-lock
+    attempt increases, there is more likely that a larger number threads
+    compete for adaptive mutex lock, so increase wait time in exponential.
+    A random jitter is also added to avoid synchronous try-lock from other
+    threads.
+    
+    v2: Remove read-check before try-lock for performance.
+    
+    v3:
+    1. Restore read-check since it works well in some platform.
+    2. Make backoff arch dependent, and enable it for x86_64.
+    3. Limit max backoff to reduce latency in large critical section.
+    
+    v4: Fix strict-prototypes error in sysdeps/nptl/pthread_mutex_backoff.h
+    
+    v5: Commit log updated for regression in large critical section.
+    
+    Result of pthread-mutex-locks bench
+    
+    Test Platform: Xeon 8280L (2 socket, 112 CPUs in total)
+    First Row: thread number
+    First Col: critical section length
+    Values: backoff vs upstream, time based, low is better
+    
+    non-critical-length: 1
+            1       2       4       8       16      32      64      112     140
+    0       0.99    0.58    0.52    0.49    0.43    0.44    0.46    0.52    0.54
+    1       0.98    0.43    0.56    0.50    0.44    0.45    0.50    0.56    0.57
+    2       0.99    0.41    0.57    0.51    0.45    0.47    0.48    0.60    0.61
+    4       0.99    0.45    0.59    0.53    0.48    0.49    0.52    0.64    0.65
+    8       1.00    0.66    0.71    0.63    0.56    0.59    0.66    0.72    0.71
+    16      0.97    0.78    0.91    0.73    0.67    0.70    0.79    0.80    0.80
+    32      0.95    1.17    0.98    0.87    0.82    0.86    0.89    0.90    0.90
+    64      0.96    0.95    1.01    1.01    0.98    1.00    1.03    0.99    0.99
+    128     0.99    1.01    1.01    1.17    1.08    1.12    1.02    0.97    1.02
+    
+    non-critical-length: 32
+            1       2       4       8       16      32      64      112     140
+    0       1.03    0.97    0.75    0.65    0.58    0.58    0.56    0.70    0.70
+    1       0.94    0.95    0.76    0.65    0.58    0.58    0.61    0.71    0.72
+    2       0.97    0.96    0.77    0.66    0.58    0.59    0.62    0.74    0.74
+    4       0.99    0.96    0.78    0.66    0.60    0.61    0.66    0.76    0.77
+    8       0.99    0.99    0.84    0.70    0.64    0.66    0.71    0.80    0.80
+    16      0.98    0.97    0.95    0.76    0.70    0.73    0.81    0.85    0.84
+    32      1.04    1.12    1.04    0.89    0.82    0.86    0.93    0.91    0.91
+    64      0.99    1.15    1.07    1.00    0.99    1.01    1.05    0.99    0.99
+    128     1.00    1.21    1.20    1.22    1.25    1.31    1.12    1.10    0.99
+    
+    non-critical-length: 128
+            1       2       4       8       16      32      64      112     140
+    0       1.02    1.00    0.99    0.67    0.61    0.61    0.61    0.74    0.73
+    1       0.95    0.99    1.00    0.68    0.61    0.60    0.60    0.74    0.74
+    2       1.00    1.04    1.00    0.68    0.59    0.61    0.65    0.76    0.76
+    4       1.00    0.96    0.98    0.70    0.63    0.63    0.67    0.78    0.77
+    8       1.01    1.02    0.89    0.73    0.65    0.67    0.71    0.81    0.80
+    16      0.99    0.96    0.96    0.79    0.71    0.73    0.80    0.84    0.84
+    32      0.99    0.95    1.05    0.89    0.84    0.85    0.94    0.92    0.91
+    64      1.00    0.99    1.16    1.04    1.00    1.02    1.06    0.99    0.99
+    128     1.00    1.06    0.98    1.14    1.39    1.26    1.08    1.02    0.98
+    
+    There is regression in large critical section. But adaptive mutex is
+    aimed for "quick" locks. Small critical section is more common when
+    users choose to use adaptive pthread_mutex.
+    
+    Signed-off-by: Wangyang Guo <wangyang.guo@intel.com>
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    (cherry picked from commit 8162147872491bb5b48e91543b19c49a29ae6b6d)
+
+diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
+index bbe754a272b97d91..8f3f687f2a151d16 100644
+--- a/nptl/pthread_mutex_lock.c
++++ b/nptl/pthread_mutex_lock.c
+@@ -139,14 +139,26 @@ PTHREAD_MUTEX_LOCK (pthread_mutex_t *mutex)
+ 	  int cnt = 0;
+ 	  int max_cnt = MIN (max_adaptive_count (),
+ 			     mutex->__data.__spins * 2 + 10);
++	  int spin_count, exp_backoff = 1;
++	  unsigned int jitter = get_jitter ();
+ 	  do
+ 	    {
+-	      if (cnt++ >= max_cnt)
++	      /* In each loop, spin count is exponential backoff plus
++		 random jitter, random range is [0, exp_backoff-1].  */
++	      spin_count = exp_backoff + (jitter & (exp_backoff - 1));
++	      cnt += spin_count;
++	      if (cnt >= max_cnt)
+ 		{
++		  /* If cnt exceeds max spin count, just go to wait
++		     queue.  */
+ 		  LLL_MUTEX_LOCK (mutex);
+ 		  break;
+ 		}
+-	      atomic_spin_nop ();
++	      do
++		atomic_spin_nop ();
++	      while (--spin_count > 0);
++	      /* Prepare for next loop.  */
++	      exp_backoff = get_next_backoff (exp_backoff);
+ 	    }
+ 	  while (LLL_MUTEX_READ_LOCK (mutex) != 0
+ 		 || LLL_MUTEX_TRYLOCK (mutex) != 0);
+diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h
+index b968afc4c6b61b92..ed186ce3df1fde0c 100644
+--- a/sysdeps/nptl/pthreadP.h
++++ b/sysdeps/nptl/pthreadP.h
+@@ -34,6 +34,7 @@
+ #include <kernel-features.h>
+ #include <errno.h>
+ #include <internal-signals.h>
++#include <pthread_mutex_backoff.h>
+ #include "pthread_mutex_conf.h"
+ 
+ 
+diff --git a/sysdeps/nptl/pthread_mutex_backoff.h b/sysdeps/nptl/pthread_mutex_backoff.h
+new file mode 100644
+index 0000000000000000..5b26c22ac789f54f
+--- /dev/null
++++ b/sysdeps/nptl/pthread_mutex_backoff.h
+@@ -0,0 +1,35 @@
++/* Pthread mutex backoff configuration.
++   Copyright (C) 2022 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/>.  */
++#ifndef _PTHREAD_MUTEX_BACKOFF_H
++#define _PTHREAD_MUTEX_BACKOFF_H 1
++
++static inline unsigned int
++get_jitter (void)
++{
++  /* Arch dependent random jitter, return 0 disables random.  */
++  return 0;
++}
++
++static inline int
++get_next_backoff (int backoff)
++{
++  /* Next backoff, return 1 disables mutex backoff.  */
++  return 1;
++}
++
++#endif
+diff --git a/sysdeps/x86_64/nptl/pthread_mutex_backoff.h b/sysdeps/x86_64/nptl/pthread_mutex_backoff.h
+new file mode 100644
+index 0000000000000000..ec74c3d9db61864e
+--- /dev/null
++++ b/sysdeps/x86_64/nptl/pthread_mutex_backoff.h
+@@ -0,0 +1,39 @@
++/* Pthread mutex backoff configuration.
++   Copyright (C) 2022 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/>.  */
++#ifndef _PTHREAD_MUTEX_BACKOFF_H
++#define _PTHREAD_MUTEX_BACKOFF_H 1
++
++#include <fast-jitter.h>
++
++static inline unsigned int
++get_jitter (void)
++{
++  return get_fast_jitter ();
++}
++
++#define MAX_BACKOFF 16
++
++static inline int
++get_next_backoff (int backoff)
++{
++  /* Binary expontial backoff. Limiting max backoff
++     can reduce latency in large critical section.  */
++  return (backoff < MAX_BACKOFF) ? backoff << 1 : backoff;
++}
++
++#endif
diff --git a/SOURCES/glibc-upstream-2.34-337.patch b/SOURCES/glibc-upstream-2.34-337.patch
new file mode 100644
index 0000000..41aea50
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-337.patch
@@ -0,0 +1,26 @@
+commit 95f5089d4a57cd1e738be908c7a628cb7d0ce512
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86: include BMI1 and BMI2 in x86-64-v3 level
+    
+    The "System V Application Binary Interface AMD64 Architecture Processor
+    Supplement" mandates the BMI1 and BMI2 CPU features for the x86-64-v3
+    level.
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit b80f16adbd979831bf25ea491e1261e81885c2b6)
+
+diff --git a/sysdeps/x86/get-isa-level.h b/sysdeps/x86/get-isa-level.h
+index aa80f56ca635e54b..785c25a835edf004 100644
+--- a/sysdeps/x86/get-isa-level.h
++++ b/sysdeps/x86/get-isa-level.h
+@@ -47,6 +47,8 @@ get_isa_level (const struct cpu_features *cpu_features)
+ 	  isa_level |= GNU_PROPERTY_X86_ISA_1_V2;
+ 	  if (CPU_FEATURE_USABLE_P (cpu_features, AVX)
+ 	      && CPU_FEATURE_USABLE_P (cpu_features, AVX2)
++	      && CPU_FEATURE_USABLE_P (cpu_features, BMI1)
++	      && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+ 	      && CPU_FEATURE_USABLE_P (cpu_features, F16C)
+ 	      && CPU_FEATURE_USABLE_P (cpu_features, FMA)
+ 	      && CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
diff --git a/SOURCES/glibc-upstream-2.34-338.patch b/SOURCES/glibc-upstream-2.34-338.patch
new file mode 100644
index 0000000..44dec62
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-338.patch
@@ -0,0 +1,111 @@
+commit 414fc856ff4e011e62b88a21d30294637a152dc7
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86-64: Require BMI2 for AVX2 str(n)casecmp implementations
+    
+    The AVX2 str(n)casecmp implementations use the 'bzhi' instruction, which
+    belongs to the BMI2 CPU feature.
+    
+    NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
+    as BSF if the CPU doesn't support TZCNT, and produces the same result
+    for non-zero input.
+    
+    Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
+    Partially resolves: BZ #29611
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit 10f79d3670b036925da63dc532b122d27ce65ff8)
+
+diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+index 8d649e263eb24b8a..ca64b34c146a76f9 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+@@ -386,13 +386,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   IFUNC_IMPL (i, name, strcasecmp,
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+-			       && CPU_FEATURE_USABLE (AVX512BW)),
++			       && CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strcasecmp_evex)
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strcasecmp_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __strcasecmp_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+@@ -407,13 +410,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   IFUNC_IMPL (i, name, strcasecmp_l,
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+-			       && CPU_FEATURE_USABLE (AVX512BW)),
++			       && CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strcasecmp_l_evex)
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strcasecmp_l_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __strcasecmp_l_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, strcasecmp_l,
+@@ -542,13 +548,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   IFUNC_IMPL (i, name, strncasecmp,
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+-			       && CPU_FEATURE_USABLE (AVX512BW)),
++			       && CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strncasecmp_evex)
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strncasecmp_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __strncasecmp_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+@@ -564,13 +573,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   IFUNC_IMPL (i, name, strncasecmp_l,
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+-			       && CPU_FEATURE_USABLE (AVX512BW)),
++			       & CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strncasecmp_l_evex)
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strncasecmp_l_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __strncasecmp_l_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, strncasecmp_l,
+diff --git a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
+index 40819caf5ab10337..e61d6e9497bce9d9 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
++++ b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
+@@ -32,6 +32,7 @@ IFUNC_SELECTOR (void)
+   const struct cpu_features* cpu_features = __get_cpu_features ();
+ 
+   if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
++      && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+       && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+     {
+       if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
diff --git a/SOURCES/glibc-upstream-2.34-339.patch b/SOURCES/glibc-upstream-2.34-339.patch
new file mode 100644
index 0000000..4820b0f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-339.patch
@@ -0,0 +1,55 @@
+commit e1561d8cf005a23bcaf514802854b493829a25b1
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86-64: Require BMI2 for AVX2 strcmp implementation
+    
+    The AVX2 strcmp implementation uses the 'bzhi' instruction, which
+    belongs to the BMI2 CPU feature.
+    
+    NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
+    as BSF if the CPU doesn't support TZCNT, and produces the same result
+    for non-zero input.
+    
+    Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
+    Partially resolves: BZ #29611
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit 4d64c6445735e9b34e2ac8e369312cbfc2f88e17)
+
+diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+index ca64b34c146a76f9..70931f15985334af 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+@@ -503,10 +503,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/strcmp.c.  */
+   IFUNC_IMPL (i, name, strcmp,
+ 	      IFUNC_IMPL_ADD (array, i, strcmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strcmp_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, strcmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __strcmp_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, strcmp,
+diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c
+index b457fb4c150e4407..0c0cd20a03278a2b 100644
+--- a/sysdeps/x86_64/multiarch/strcmp.c
++++ b/sysdeps/x86_64/multiarch/strcmp.c
+@@ -40,11 +40,11 @@ IFUNC_SELECTOR (void)
+   const struct cpu_features* cpu_features = __get_cpu_features ();
+ 
+   if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
++      && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+       && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+     {
+       if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+-	  && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
+-	  && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
++	  && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
+ 	return OPTIMIZE (evex);
+ 
+       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
diff --git a/SOURCES/glibc-upstream-2.34-340.patch b/SOURCES/glibc-upstream-2.34-340.patch
new file mode 100644
index 0000000..077c288
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-340.patch
@@ -0,0 +1,62 @@
+commit b9cbb8dd48b545f3b36b5d411481dc0bd118ee94
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86-64: Require BMI2 for AVX2 strncmp implementation
+    
+    The AVX2 strncmp implementations uses the 'bzhi' instruction, which
+    belongs to the BMI2 CPU feature.
+    
+    NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
+    as BSF if the CPU doesn't support TZCNT, and produces the same result
+    for non-zero input.
+    
+    Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
+    Partially resolves: BZ #29611
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit fc7de1d9b99ae1676bc626ddca422d7abee0eb48)
+
+diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+index 70931f15985334af..34d5f6efe5421014 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+@@ -1022,15 +1022,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/strncmp.c.  */
+   IFUNC_IMPL (i, name, strncmp,
+ 	      IFUNC_IMPL_ADD (array, i, strncmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strncmp_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, strncmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __strncmp_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, strncmp,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+-			       && CPU_FEATURE_USABLE (AVX512BW)),
++			       && CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strncmp_evex)
+ 	      IFUNC_IMPL_ADD (array, i, strncmp, CPU_FEATURE_USABLE (SSE4_2),
+ 			      __strncmp_sse42)
+diff --git a/sysdeps/x86_64/multiarch/strncmp.c b/sysdeps/x86_64/multiarch/strncmp.c
+index f94a421784bfe923..7632d7b2dd4447aa 100644
+--- a/sysdeps/x86_64/multiarch/strncmp.c
++++ b/sysdeps/x86_64/multiarch/strncmp.c
+@@ -39,11 +39,11 @@ IFUNC_SELECTOR (void)
+   const struct cpu_features* cpu_features = __get_cpu_features ();
+ 
+   if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
++      && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+       && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+     {
+       if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+-	  && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
+-	  && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
++	  && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
+ 	return OPTIMIZE (evex);
+ 
+       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
diff --git a/SOURCES/glibc-upstream-2.34-341.patch b/SOURCES/glibc-upstream-2.34-341.patch
new file mode 100644
index 0000000..6e9814a
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-341.patch
@@ -0,0 +1,51 @@
+commit 67e863742d98c990b3d3b814b80042c0fa0d50a5
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86-64: Require BMI2 for AVX2 wcs(n)cmp implementations
+    
+    The AVX2 wcs(n)cmp implementations use the 'bzhi' instruction, which
+    belongs to the BMI2 CPU feature.
+    
+    NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
+    as BSF if the CPU doesn't support TZCNT, and produces the same result
+    for non-zero input.
+    
+    Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
+    Partially resolves: BZ #29611
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit f31a5a884ed84bd37032729d4d1eb9d06c9f3c29)
+
+diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+index 34d5f6efe5421014..e76a991dc671c1a9 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+@@ -693,10 +693,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/wcscmp.c.  */
+   IFUNC_IMPL (i, name, wcscmp,
+ 	      IFUNC_IMPL_ADD (array, i, wcscmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __wcscmp_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, wcscmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __wcscmp_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, wcscmp,
+@@ -709,10 +711,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/wcsncmp.c.  */
+   IFUNC_IMPL (i, name, wcsncmp,
+ 	      IFUNC_IMPL_ADD (array, i, wcsncmp,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __wcsncmp_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, wcsncmp,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __wcsncmp_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, wcsncmp,
diff --git a/SOURCES/glibc-upstream-2.34-342.patch b/SOURCES/glibc-upstream-2.34-342.patch
new file mode 100644
index 0000000..8750786
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-342.patch
@@ -0,0 +1,61 @@
+commit 94b9c1b6409e34f3f0b2339f77d7ee78087422eb
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86-64: Require BMI2 for AVX2 (raw|w)memchr implementations
+    
+    The AVX2 memchr, rawmemchr and wmemchr implementations use the 'bzhi'
+    and 'sarx' instructions, which belongs to the BMI2 CPU feature.
+    
+    Fixes: acfd088a1963 ("x86: Optimize memchr-avx2.S")
+    Partially resolves: BZ #29611
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit e3e7fab7fe5186d18ca2046d99ba321c27db30ad)
+
+diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+index e76a991dc671c1a9..81640cf00664e3ed 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+@@ -41,10 +41,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/memchr.c.  */
+   IFUNC_IMPL (i, name, memchr,
+ 	      IFUNC_IMPL_ADD (array, i, memchr,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __memchr_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, memchr,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __memchr_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, memchr,
+@@ -283,10 +285,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/rawmemchr.c.  */
+   IFUNC_IMPL (i, name, rawmemchr,
+ 	      IFUNC_IMPL_ADD (array, i, rawmemchr,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __rawmemchr_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, rawmemchr,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __rawmemchr_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, rawmemchr,
+@@ -787,10 +791,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/wmemchr.c.  */
+   IFUNC_IMPL (i, name, wmemchr,
+ 	      IFUNC_IMPL_ADD (array, i, wmemchr,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __wmemchr_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, wmemchr,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __wmemchr_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, wmemchr,
diff --git a/SOURCES/glibc-upstream-2.34-343.patch b/SOURCES/glibc-upstream-2.34-343.patch
new file mode 100644
index 0000000..dd9d4b8
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-343.patch
@@ -0,0 +1,56 @@
+commit 36d6b9be3d7008a78e1f6e2e2db1947b76b206d8
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86-64: Require BMI2 and LZCNT for AVX2 memrchr implementation
+    
+    The AVX2 memrchr implementation uses the 'shlxl' instruction, which
+    belongs to the BMI2 CPU feature and uses the 'lzcnt' instruction, which
+    belongs to the LZCNT CPU feature.
+    
+    Fixes: af5306a735eb ("x86: Optimize memrchr-avx2.S")
+    Partially resolves: BZ #29611
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit 3c0c78afabfed4b6fc161c159e628fbf14ff370b)
+
+diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h b/sysdeps/x86_64/multiarch/ifunc-avx2.h
+index 6de72f72724b81ba..52bd00ea5cab6b22 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-avx2.h
++++ b/sysdeps/x86_64/multiarch/ifunc-avx2.h
+@@ -31,6 +31,7 @@ IFUNC_SELECTOR (void)
+ 
+   if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+       && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
++      && CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
+       && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+     {
+       if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+index 81640cf00664e3ed..d1fc1e75d6706413 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+@@ -174,15 +174,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/memrchr.c.  */
+   IFUNC_IMPL (i, name, memrchr,
+ 	      IFUNC_IMPL_ADD (array, i, memrchr,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
++			       && CPU_FEATURE_USABLE (LZCNT)),
+ 			      __memrchr_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, memrchr,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI2)
++			       && CPU_FEATURE_USABLE (LZCNT)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __memrchr_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, memrchr,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+-			       && CPU_FEATURE_USABLE (AVX512BW)),
++			       && CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI2)
++			       && CPU_FEATURE_USABLE (LZCNT)),
+ 			      __memrchr_evex)
+ 
+ 	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_sse2))
diff --git a/SOURCES/glibc-upstream-2.34-344.patch b/SOURCES/glibc-upstream-2.34-344.patch
new file mode 100644
index 0000000..754168f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-344.patch
@@ -0,0 +1,78 @@
+commit e570b865b53f33453d97160791a7d97e38bcc6e8
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Mon Oct 3 23:16:46 2022 +0200
+
+    x86-64: Require BMI1/BMI2 for AVX2 strrchr and wcsrchr implementations
+    
+    The AVX2 strrchr and wcsrchr implementation uses the 'blsmsk'
+    instruction which belongs to the BMI1 CPU feature and the 'shrx'
+    instruction, which belongs to the BMI2 CPU feature.
+    
+    Fixes: df7e295d18ff ("x86: Optimize {str|wcs}rchr-avx2")
+    Partially resolves: BZ #29611
+    
+    Reviewed-by: Noah Goldstein  <goldstein.w.n@gmail.com>
+    (cherry picked from commit 7e8283170c5d6805b609a040801d819e362a6292)
+
+diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h b/sysdeps/x86_64/multiarch/ifunc-avx2.h
+index 52bd00ea5cab6b22..877f007dd6e38fe8 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-avx2.h
++++ b/sysdeps/x86_64/multiarch/ifunc-avx2.h
+@@ -30,6 +30,7 @@ IFUNC_SELECTOR (void)
+   const struct cpu_features* cpu_features = __get_cpu_features ();
+ 
+   if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
++      && CPU_FEATURE_USABLE_P (cpu_features, BMI1)
+       && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+       && CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
+       && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+index d1fc1e75d6706413..84f9e73e2b7df816 100644
+--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
++++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+@@ -498,15 +498,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/strrchr.c.  */
+   IFUNC_IMPL (i, name, strrchr,
+ 	      IFUNC_IMPL_ADD (array, i, strrchr,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI1)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strrchr_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, strrchr,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI1)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __strrchr_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, strrchr,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+-			       && CPU_FEATURE_USABLE (AVX512BW)),
++			       && CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI1)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __strrchr_evex)
+ 	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_sse2))
+ 
+@@ -687,15 +693,20 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+   /* Support sysdeps/x86_64/multiarch/wcsrchr.c.  */
+   IFUNC_IMPL (i, name, wcsrchr,
+ 	      IFUNC_IMPL_ADD (array, i, wcsrchr,
+-			      CPU_FEATURE_USABLE (AVX2),
++			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI1)
++			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __wcsrchr_avx2)
+ 	      IFUNC_IMPL_ADD (array, i, wcsrchr,
+ 			      (CPU_FEATURE_USABLE (AVX2)
++			       && CPU_FEATURE_USABLE (BMI1)
++			       && CPU_FEATURE_USABLE (BMI2)
+ 			       && CPU_FEATURE_USABLE (RTM)),
+ 			      __wcsrchr_avx2_rtm)
+ 	      IFUNC_IMPL_ADD (array, i, wcsrchr,
+ 			      (CPU_FEATURE_USABLE (AVX512VL)
+ 			       && CPU_FEATURE_USABLE (AVX512BW)
++			       && CPU_FEATURE_USABLE (BMI1)
+ 			       && CPU_FEATURE_USABLE (BMI2)),
+ 			      __wcsrchr_evex)
+ 	      IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_sse2))
diff --git a/SOURCES/glibc-upstream-2.34-345.patch b/SOURCES/glibc-upstream-2.34-345.patch
new file mode 100644
index 0000000..c0028eb
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-345.patch
@@ -0,0 +1,46 @@
+commit e3976287b22422787f3cc6fc9adda58304b55bd9
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Tue Oct 4 18:40:25 2022 -0400
+
+    nscd: Drop local address tuple variable [BZ #29607]
+    
+    When a request needs to be resent (e.g. due to insufficient buffer
+    space), the references to subsequent tuples in the local variable are
+    stale and should not be used.  This used to work by accident before, but
+    since 1d495912a it no longer does.  Instead of trying to reset it, just
+    let gethostbyname4_r write into TUMPBUF6 for us, thus maintaining a
+    consistent state at all times.  This is now consistent with what is done
+    in gaih_inet for getaddrinfo.
+    
+    Resolves: BZ #29607
+    Reported-by: Holger Hoffstätte <holger@applied-asynchrony.com>
+    Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 6e33e5c4b73cea7b8aa3de0947123db16200fb65)
+
+diff --git a/nscd/aicache.c b/nscd/aicache.c
+index 737ace11cc276021..3b300ad9b7db2297 100644
+--- a/nscd/aicache.c
++++ b/nscd/aicache.c
+@@ -111,11 +111,10 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
+ 							  "gethostbyname4_r");
+       if (fct4 != NULL)
+ 	{
+-	  struct gaih_addrtuple atmem;
+ 	  struct gaih_addrtuple *at;
+ 	  while (1)
+ 	    {
+-	      at = &atmem;
++	      at = NULL;
+ 	      rc6 = 0;
+ 	      herrno = 0;
+ 	      status[1] = DL_CALL_FCT (fct4, (key, &at,
+@@ -138,7 +137,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
+ 	    goto next_nip;
+ 
+ 	  /* We found the data.  Count the addresses and the size.  */
+-	  for (const struct gaih_addrtuple *at2 = at = &atmem; at2 != NULL;
++	  for (const struct gaih_addrtuple *at2 = at; at2 != NULL;
+ 	       at2 = at2->next)
+ 	    {
+ 	      ++naddrs;
diff --git a/SOURCES/glibc-upstream-2.34-346.patch b/SOURCES/glibc-upstream-2.34-346.patch
new file mode 100644
index 0000000..a0fe300
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-346.patch
@@ -0,0 +1,55 @@
+commit c95ef423d78d9a2ec0a8e4141c78165434685c6f
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Sep 13 16:10:20 2022 +0200
+
+    nss: Implement --no-addrconfig option for getent
+    
+    The ahosts, ahostsv4, ahostsv6 commands unconditionally pass
+    AI_ADDRCONFIG to getaddrinfo, which is not always desired.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit a623f13adfac47c8634a7288e08f821a846bc650)
+
+diff --git a/nss/getent.c b/nss/getent.c
+index ec48ba4bf1f5f788..0f4d549b05da73ac 100644
+--- a/nss/getent.c
++++ b/nss/getent.c
+@@ -59,6 +59,8 @@ static const struct argp_option args_options[] =
+   {
+     { "service", 's', N_("CONFIG"), 0, N_("Service configuration to be used") },
+     { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") },
++    { "no-addrconfig", 'A', NULL, 0,
++      N_("do not filter out unsupported IPv4/IPv6 addresses (with ahosts*)") },
+     { NULL, 0, NULL, 0, NULL },
+   };
+ 
+@@ -80,6 +82,9 @@ static struct argp argp =
+ /* Additional getaddrinfo flags for IDN encoding.  */
+ static int idn_flags = AI_IDN | AI_CANONIDN;
+ 
++/* Set to 0 by --no-addrconfig.  */
++static int addrconfig_flags = AI_ADDRCONFIG;
++
+ /* Print the version information.  */
+ static void
+ print_version (FILE *stream, struct argp_state *state)
+@@ -347,7 +352,7 @@ ahosts_keys_int (int af, int xflags, int number, char *key[])
+ 
+   struct addrinfo hint;
+   memset (&hint, '\0', sizeof (hint));
+-  hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME
++  hint.ai_flags = (AI_V4MAPPED | addrconfig_flags | AI_CANONNAME
+ 		   | idn_flags | xflags);
+   hint.ai_family = af;
+ 
+@@ -906,6 +911,10 @@ parse_option (int key, char *arg, struct argp_state *state)
+       idn_flags = 0;
+       break;
+ 
++    case 'A':
++      addrconfig_flags = 0;
++      break;
++
+     default:
+       return ARGP_ERR_UNKNOWN;
+     }
diff --git a/SOURCES/glibc-upstream-2.34-347.patch b/SOURCES/glibc-upstream-2.34-347.patch
new file mode 100644
index 0000000..408e38f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-347.patch
@@ -0,0 +1,38 @@
+commit 16c7ed6e68c13e5a5efd8ab464ebf9d07b4b0bb3
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Sep 13 16:11:40 2022 +0200
+
+    nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816)
+    
+    getent implicitly passes AI_ADDRCONFIG to getaddrinfo by default.
+    Use --no-addrconfig to suppress that, so that both IPv4 and IPv6
+    lookups succeed even if the address family is not supported by the
+    host.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit c75d20b5b27b0a60f0678236f51a4d3b0b058c00)
+
+diff --git a/nss/tst-nss-files-hosts-long.c b/nss/tst-nss-files-hosts-long.c
+index 00f8bea409e0b4cb..42676ba4056dbde2 100644
+--- a/nss/tst-nss-files-hosts-long.c
++++ b/nss/tst-nss-files-hosts-long.c
+@@ -28,14 +28,15 @@ do_test (void)
+ {
+   int ret;
+ 
+-  /* Run getent to fetch the IPv4 address for host test4.
+-     This forces /etc/hosts to be parsed.  */
+-  ret = system("getent ahostsv4 test4");
++  /* Run getent to fetch the IPv4 address for host test4.  This forces
++     /etc/hosts to be parsed.  Use --no-addrconfig to return addresses
++     even in an IPv6-only environment.  */
++  ret = system("getent --no-addrconfig ahostsv4 test4");
+   if (ret != 0)
+     FAIL_EXIT1("ahostsv4 failed");
+ 
+   /* Likewise for IPv6.  */
+-  ret = system("getent ahostsv6 test6");
++  ret = system("getent --no-addrconfig  ahostsv6 test6");
+   if (ret != 0)
+     FAIL_EXIT1("ahostsv6 failed");
+ 
diff --git a/SOURCES/glibc-upstream-2.34-348.patch b/SOURCES/glibc-upstream-2.34-348.patch
new file mode 100644
index 0000000..c33b026
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-348.patch
@@ -0,0 +1,47 @@
+commit d5313bcb7e56cd949ca920bb0c741a1d1d4093cf
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Sep 23 19:30:57 2022 +0200
+
+    nss: Use shared prefix in IPv4 address in tst-reload1
+    
+    Otherwise, sorting based on the longest-matching prefix in
+    getaddrinfo can reorder the addresses in ways the test does not
+    expect, depending on the IPv4 address of the host.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit c02e29a0ba47d636281e1a026444a1a0a254aa12)
+
+diff --git a/nss/tst-reload1.c b/nss/tst-reload1.c
+index 27a18ed9c37607bb..844cfcddc5e0f638 100644
+--- a/nss/tst-reload1.c
++++ b/nss/tst-reload1.c
+@@ -43,12 +43,12 @@ static struct passwd pwd_table_1[] = {
+ 
+ static const char *hostaddr_5[] =
+   {
+-   "ABCD", "abcd", "1234", NULL
++   "ABCd", "ABCD", "ABC4", NULL
+   };
+ 
+ static const char *hostaddr_15[] =
+   {
+-   "4321", "ghij", NULL
++   "4321", "4322", NULL
+   };
+ 
+ static const char *hostaddr_25[] =
+@@ -86,12 +86,12 @@ static const char *hostaddr_6[] =
+ 
+ static const char *hostaddr_16[] =
+   {
+-   "7890", "a1b2", NULL
++   "7890", "7891", NULL
+   };
+ 
+ static const char *hostaddr_26[] =
+   {
+-   "qwer", "tyui", NULL
++   "qwer", "qweR", NULL
+   };
+ 
+ static struct hostent host_table_2[] = {
diff --git a/SOURCES/glibc-upstream-2.34-349.patch b/SOURCES/glibc-upstream-2.34-349.patch
new file mode 100644
index 0000000..0b05961
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-349.patch
@@ -0,0 +1,92 @@
+commit 9f55d2e7c42e6ca862a25d3ee3eb2b367811c30d
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Oct 14 12:43:07 2022 +0200
+
+    elf: Do not completely clear reused namespace in dlmopen (bug 29600)
+    
+    The data in the _ns_debug member must be preserved, otherwise
+    _dl_debug_initialize enters an infinite loop.  To be conservative,
+    only clear the libc_map member for now, to fix bug 29528.
+    
+    Fixes commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe
+    ("elf: Call __libc_early_init for reused namespaces (bug 29528)"),
+    by reverting most of it.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    Tested-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 2c42257314536b94cc8d52edede86e94e98c1436)
+    (Conflict in elf/dl-open.c due to missing _r_debug namespace support.)
+
+diff --git a/elf/dl-open.c b/elf/dl-open.c
+index 1ab3c7b5ac2fbc45..633b047ad2497296 100644
+--- a/elf/dl-open.c
++++ b/elf/dl-open.c
+@@ -839,15 +839,13 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
+ 	  _dl_signal_error (EINVAL, file, NULL, N_("\
+ no more namespaces available for dlmopen()"));
+ 	}
++      else if (nsid == GL(dl_nns))
++	{
++	  __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
++	  ++GL(dl_nns);
++	}
+ 
+-      if (nsid == GL(dl_nns))
+-	++GL(dl_nns);
+-
+-      /* Initialize the new namespace.  Most members are
+-	 zero-initialized, only the lock needs special treatment.  */
+-      memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid]));
+-      __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
+-
++      GL(dl_ns)[nsid].libc_map = NULL;
+       _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT;
+     }
+   /* Never allow loading a DSO in a namespace which is empty.  Such
+diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c
+index 449f3c8fa9f2aa01..70c71fe19c7d0bf9 100644
+--- a/elf/tst-dlmopen-twice.c
++++ b/elf/tst-dlmopen-twice.c
+@@ -16,18 +16,38 @@
+    License along with the GNU C Library; if not, see
+    <https://www.gnu.org/licenses/>.  */
+ 
+-#include <support/xdlfcn.h>
++#include <stdio.h>
+ #include <support/check.h>
++#include <support/xdlfcn.h>
+ 
+-static int
+-do_test (void)
++/* Run the test multiple times, to check finding a new namespace while
++   another namespace is already in use.  This used to trigger bug 29600.  */
++static void
++recurse (int depth)
+ {
+-  void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW);
++  if (depth == 0)
++    return;
++
++  printf ("info: running at depth %d\n", depth);
++  void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so",
++                           RTLD_NOW);
+   xdlclose (handle);
+   handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW);
+   int (*run_check) (void) = xdlsym (handle, "run_check");
+   TEST_COMPARE (run_check (), 0);
++  recurse (depth - 1);
+   xdlclose (handle);
++}
++
++static int
++do_test (void)
++{
++  /* First run the test without nesting.  */
++  recurse (1);
++
++  /* Then with nesting.  The constant needs to be less than the
++     internal DL_NNS namespace constant.  */
++  recurse (10);
+   return 0;
+ }
+ 
diff --git a/SOURCES/glibc-upstream-2.34-350.patch b/SOURCES/glibc-upstream-2.34-350.patch
new file mode 100644
index 0000000..7ab515b
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-350.patch
@@ -0,0 +1,861 @@
+commit ca5df795459b9242cd7d787ebf71a09be2244577
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Oct 19 19:14:04 2022 -0300
+
+    linux: Fix generic struct_stat for 64 bit time (BZ# 29657)
+    
+    The generic Linux struct_stat misses the conditionals to use
+    bits/struct_stat_time64_helper.h in the __USE_TIME_BITS64 for
+    architecture that uses __TIMESIZE == 32 (currently csky and nios2).
+    
+    Since newer ports should not support 32 bit time_t, the generic
+    implementation should be used as default.
+    
+    For arm, hppa, and sh a copy of default struct_stat is added,
+    while for csky and nios a new one based on generic is used, along
+    with conditionals to use bits/struct_stat_time64_helper.h.
+    
+    The default struct_stat is also replaced with the generic one.
+    
+    Checked on aarch64-linux-gnu and arm-linux-gnueabihf.
+    
+    (cherry picked from commit 7a6ca82f8007ddbd43e2b8fce806ba7101ee47f5)
+
+diff --git a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
+new file mode 100644
+index 0000000000000000..30ee6279d2701242
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
+@@ -0,0 +1,139 @@
++/* Definition for struct stat.  Linux/arm version.
++   Copyright (C) 2020-2022 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/>.  */
++
++#if !defined _SYS_STAT_H && !defined _FCNTL_H
++# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
++#endif
++
++#ifndef _BITS_STRUCT_STAT_H
++#define _BITS_STRUCT_STAT_H	1
++
++#include <bits/endian.h>
++#include <bits/wordsize.h>
++
++struct stat
++  {
++#ifdef __USE_TIME_BITS64
++# include <bits/struct_stat_time64_helper.h>
++#else
++    __dev_t st_dev;			/* Device.  */
++    unsigned short int __pad1;
++# ifndef __USE_FILE_OFFSET64
++    __ino_t st_ino;			/* File serial number.	*/
++# else
++    __ino_t __st_ino;			/* 32bit file serial number.	*/
++# endif
++    __mode_t st_mode;			/* File mode.  */
++    __nlink_t st_nlink;			/* Link count.  */
++    __uid_t st_uid;			/* User ID of the file's owner.	*/
++    __gid_t st_gid;			/* Group ID of the file's group.*/
++    __dev_t st_rdev;			/* Device number, if device.  */
++    unsigned short int __pad2;
++# ifndef __USE_FILE_OFFSET64
++    __off_t st_size;			/* Size of file, in bytes.  */
++# else
++    __off64_t st_size;			/* Size of file, in bytes.  */
++# endif
++    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
++
++# ifndef __USE_FILE_OFFSET64
++    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
++# else
++    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
++# endif
++# ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
++#  define st_mtime st_mtim.tv_sec
++#  define st_ctime st_ctim.tv_sec
++# else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++# endif
++# ifndef __USE_FILE_OFFSET64
++    unsigned long int __glibc_reserved4;
++    unsigned long int __glibc_reserved5;
++# else
++    __ino64_t st_ino;			/* File serial number.	*/
++# endif
++#endif /* __USE_TIME_BITS64  */
++  };
++
++#ifdef __USE_LARGEFILE64
++struct stat64
++  {
++# ifdef __USE_TIME_BITS64
++#  include <bits/struct_stat_time64_helper.h>
++# else
++    __dev_t st_dev;			/* Device.  */
++    unsigned int __pad1;
++
++    __ino_t __st_ino;			/* 32bit file serial number.	*/
++    __mode_t st_mode;			/* File mode.  */
++    __nlink_t st_nlink;			/* Link count.  */
++    __uid_t st_uid;			/* User ID of the file's owner.	*/
++    __gid_t st_gid;			/* Group ID of the file's group.*/
++    __dev_t st_rdev;			/* Device number, if device.  */
++    unsigned int __pad2;
++    __off64_t st_size;			/* Size of file, in bytes.  */
++    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
++
++    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
++#  ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++#  endif
++    __ino64_t st_ino;			/* File serial number.		*/
++# endif /* __USE_TIME_BITS64  */
++  };
++#endif
++
++/* Tell code we have these members.  */
++#define	_STATBUF_ST_BLKSIZE
++#define _STATBUF_ST_RDEV
++/* Nanosecond resolution time values are supported.  */
++#define _STATBUF_ST_NSEC
++
++
++#endif /* _BITS_STRUCT_STAT_H  */
+diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat.h b/sysdeps/unix/sysv/linux/bits/struct_stat.h
+index 298418966f4d6e0b..32ef511ae5728276 100644
+--- a/sysdeps/unix/sysv/linux/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/bits/struct_stat.h
+@@ -26,37 +26,36 @@
+ #include <bits/endian.h>
+ #include <bits/wordsize.h>
+ 
+-struct stat
+-  {
+-#ifdef __USE_TIME_BITS64
+-# include <bits/struct_stat_time64_helper.h>
+-#else
+-    __dev_t st_dev;			/* Device.  */
+-    unsigned short int __pad1;
+-# ifndef __USE_FILE_OFFSET64
+-    __ino_t st_ino;			/* File serial number.	*/
+-# else
+-    __ino_t __st_ino;			/* 32bit file serial number.	*/
++#if defined __USE_FILE_OFFSET64
++# define __field64(type, type64, name) type64 name
++#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T
++# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T
++#  error "ino_t and off_t must both be the same type"
+ # endif
+-    __mode_t st_mode;			/* File mode.  */
+-    __nlink_t st_nlink;			/* Link count.  */
+-    __uid_t st_uid;			/* User ID of the file's owner.	*/
+-    __gid_t st_gid;			/* Group ID of the file's group.*/
+-    __dev_t st_rdev;			/* Device number, if device.  */
+-    unsigned short int __pad2;
+-# ifndef __USE_FILE_OFFSET64
+-    __off_t st_size;			/* Size of file, in bytes.  */
+-# else
+-    __off64_t st_size;			/* Size of file, in bytes.  */
+-# endif
+-    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
++# define __field64(type, type64, name) type name
++#elif __BYTE_ORDER == __LITTLE_ENDIAN
++# define __field64(type, type64, name) \
++  type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad
++#else
++# define __field64(type, type64, name) \
++  int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name
++#endif
+ 
+-# ifndef __USE_FILE_OFFSET64
+-    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+-# else
+-    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+-# endif
+-# ifdef __USE_XOPEN2K8
++struct stat
++  {
++    __dev_t st_dev;		/* Device.  */
++    __field64(__ino_t, __ino64_t, st_ino);  /* File serial number. */
++    __mode_t st_mode;		/* File mode.  */
++    __nlink_t st_nlink;		/* Link count.  */
++    __uid_t st_uid;		/* User ID of the file's owner.	*/
++    __gid_t st_gid;		/* Group ID of the file's group.*/
++    __dev_t st_rdev;		/* Device number, if device.  */
++    __dev_t __pad1;
++    __field64(__off_t, __off64_t, st_size);  /* Size of file, in bytes. */
++    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
++    int __pad2;
++    __field64(__blkcnt_t, __blkcnt64_t, st_blocks);  /* 512-byte blocks */
++#ifdef __USE_XOPEN2K8
+     /* Nanosecond resolution timestamps are stored in a format
+        equivalent to 'struct timespec'.  This is the type used
+        whenever possible but the Unix namespace rules do not allow the
+@@ -66,47 +65,38 @@ struct stat
+     struct timespec st_atim;		/* Time of last access.  */
+     struct timespec st_mtim;		/* Time of last modification.  */
+     struct timespec st_ctim;		/* Time of last status change.  */
+-#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+-#  define st_mtime st_mtim.tv_sec
+-#  define st_ctime st_ctim.tv_sec
+-# else
++# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
++# define st_mtime st_mtim.tv_sec
++# define st_ctime st_ctim.tv_sec
++#else
+     __time_t st_atime;			/* Time of last access.  */
+     unsigned long int st_atimensec;	/* Nscecs of last access.  */
+     __time_t st_mtime;			/* Time of last modification.  */
+     unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+     __time_t st_ctime;			/* Time of last status change.  */
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+-# endif
+-# ifndef __USE_FILE_OFFSET64
+-    unsigned long int __glibc_reserved4;
+-    unsigned long int __glibc_reserved5;
+-# else
+-    __ino64_t st_ino;			/* File serial number.	*/
+-# endif
+-#endif /* __USE_TIME_BITS64  */
++#endif
++    int __glibc_reserved[2];
+   };
+ 
++#undef __field64
++
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
+-# ifdef __USE_TIME_BITS64
+-#  include <bits/struct_stat_time64_helper.h>
+-# else
+-    __dev_t st_dev;			/* Device.  */
+-    unsigned int __pad1;
+-
+-    __ino_t __st_ino;			/* 32bit file serial number.	*/
+-    __mode_t st_mode;			/* File mode.  */
+-    __nlink_t st_nlink;			/* Link count.  */
+-    __uid_t st_uid;			/* User ID of the file's owner.	*/
+-    __gid_t st_gid;			/* Group ID of the file's group.*/
+-    __dev_t st_rdev;			/* Device number, if device.  */
+-    unsigned int __pad2;
+-    __off64_t st_size;			/* Size of file, in bytes.  */
+-    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+-
+-    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+-#  ifdef __USE_XOPEN2K8
++    __dev_t st_dev;		/* Device.  */
++    __ino64_t st_ino;		/* File serial number.	*/
++    __mode_t st_mode;		/* File mode.  */
++    __nlink_t st_nlink;		/* Link count.  */
++    __uid_t st_uid;		/* User ID of the file's owner.	*/
++    __gid_t st_gid;		/* Group ID of the file's group.*/
++    __dev_t st_rdev;		/* Device number, if device.  */
++    __dev_t __pad1;
++    __off64_t st_size;		/* Size of file, in bytes.  */
++    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
++    int __pad2;
++    __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated.  */
++#ifdef __USE_XOPEN2K8
+     /* Nanosecond resolution timestamps are stored in a format
+        equivalent to 'struct timespec'.  This is the type used
+        whenever possible but the Unix namespace rules do not allow the
+@@ -116,16 +106,15 @@ struct stat64
+     struct timespec st_atim;		/* Time of last access.  */
+     struct timespec st_mtim;		/* Time of last modification.  */
+     struct timespec st_ctim;		/* Time of last status change.  */
+-#  else
++#else
+     __time_t st_atime;			/* Time of last access.  */
+     unsigned long int st_atimensec;	/* Nscecs of last access.  */
+     __time_t st_mtime;			/* Time of last modification.  */
+     unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+     __time_t st_ctime;			/* Time of last status change.  */
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+-#  endif
+-    __ino64_t st_ino;			/* File serial number.		*/
+-# endif /* __USE_TIME_BITS64  */
++#endif
++    int __glibc_reserved[2];
+   };
+ #endif
+ 
+@@ -135,5 +124,4 @@ struct stat64
+ /* Nanosecond resolution time values are supported.  */
+ #define _STATBUF_ST_NSEC
+ 
+-
+ #endif /* _BITS_STRUCT_STAT_H  */
+diff --git a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
+similarity index 91%
+rename from sysdeps/unix/sysv/linux/generic/bits/struct_stat.h
+rename to sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
+index 32ef511ae5728276..f0ee455748d3ee41 100644
+--- a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h
++++ b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
+@@ -1,5 +1,5 @@
+-/* Definition for struct stat.
+-   Copyright (C) 2020-2021 Free Software Foundation, Inc.
++/* Definition for struct stat.  Linux/csky version.
++   Copyright (C) 2020-2022 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
+@@ -43,6 +43,9 @@
+ 
+ struct stat
+   {
++#ifdef __USE_TIME_BITS64
++# include <bits/struct_stat_time64_helper.h>
++#else
+     __dev_t st_dev;		/* Device.  */
+     __field64(__ino_t, __ino64_t, st_ino);  /* File serial number. */
+     __mode_t st_mode;		/* File mode.  */
+@@ -55,7 +58,7 @@ struct stat
+     __blksize_t st_blksize;	/* Optimal block size for I/O.  */
+     int __pad2;
+     __field64(__blkcnt_t, __blkcnt64_t, st_blocks);  /* 512-byte blocks */
+-#ifdef __USE_XOPEN2K8
++# ifdef __USE_XOPEN2K8
+     /* Nanosecond resolution timestamps are stored in a format
+        equivalent to 'struct timespec'.  This is the type used
+        whenever possible but the Unix namespace rules do not allow the
+@@ -65,18 +68,19 @@ struct stat
+     struct timespec st_atim;		/* Time of last access.  */
+     struct timespec st_mtim;		/* Time of last modification.  */
+     struct timespec st_ctim;		/* Time of last status change.  */
+-# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+-# define st_mtime st_mtim.tv_sec
+-# define st_ctime st_ctim.tv_sec
+-#else
++#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
++#  define st_mtime st_mtim.tv_sec
++#  define st_ctime st_ctim.tv_sec
++# else
+     __time_t st_atime;			/* Time of last access.  */
+     unsigned long int st_atimensec;	/* Nscecs of last access.  */
+     __time_t st_mtime;			/* Time of last modification.  */
+     unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+     __time_t st_ctime;			/* Time of last status change.  */
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+-#endif
++# endif
+     int __glibc_reserved[2];
++#endif
+   };
+ 
+ #undef __field64
+@@ -84,6 +88,9 @@ struct stat
+ #ifdef __USE_LARGEFILE64
+ struct stat64
+   {
++# ifdef __USE_TIME_BITS64
++#  include <bits/struct_stat_time64_helper.h>
++# else
+     __dev_t st_dev;		/* Device.  */
+     __ino64_t st_ino;		/* File serial number.	*/
+     __mode_t st_mode;		/* File mode.  */
+@@ -96,7 +103,7 @@ struct stat64
+     __blksize_t st_blksize;	/* Optimal block size for I/O.  */
+     int __pad2;
+     __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated.  */
+-#ifdef __USE_XOPEN2K8
++#  ifdef __USE_XOPEN2K8
+     /* Nanosecond resolution timestamps are stored in a format
+        equivalent to 'struct timespec'.  This is the type used
+        whenever possible but the Unix namespace rules do not allow the
+@@ -106,15 +113,16 @@ struct stat64
+     struct timespec st_atim;		/* Time of last access.  */
+     struct timespec st_mtim;		/* Time of last modification.  */
+     struct timespec st_ctim;		/* Time of last status change.  */
+-#else
++#  else
+     __time_t st_atime;			/* Time of last access.  */
+     unsigned long int st_atimensec;	/* Nscecs of last access.  */
+     __time_t st_mtime;			/* Time of last modification.  */
+     unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+     __time_t st_ctime;			/* Time of last status change.  */
+     unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+-#endif
++#  endif
+     int __glibc_reserved[2];
++# endif
+   };
+ #endif
+ 
+diff --git a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
+new file mode 100644
+index 0000000000000000..38b6e13e68890c29
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
+@@ -0,0 +1,139 @@
++/* Definition for struct stat.  Linux/hppa version.
++   Copyright (C) 2020-2022 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/>.  */
++
++#if !defined _SYS_STAT_H && !defined _FCNTL_H
++# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
++#endif
++
++#ifndef _BITS_STRUCT_STAT_H
++#define _BITS_STRUCT_STAT_H	1
++
++#include <bits/endian.h>
++#include <bits/wordsize.h>
++
++struct stat
++  {
++#ifdef __USE_TIME_BITS64
++# include <bits/struct_stat_time64_helper.h>
++#else
++    __dev_t st_dev;			/* Device.  */
++    unsigned short int __pad1;
++# ifndef __USE_FILE_OFFSET64
++    __ino_t st_ino;			/* File serial number.	*/
++# else
++    __ino_t __st_ino;			/* 32bit file serial number.	*/
++# endif
++    __mode_t st_mode;			/* File mode.  */
++    __nlink_t st_nlink;			/* Link count.  */
++    __uid_t st_uid;			/* User ID of the file's owner.	*/
++    __gid_t st_gid;			/* Group ID of the file's group.*/
++    __dev_t st_rdev;			/* Device number, if device.  */
++    unsigned short int __pad2;
++# ifndef __USE_FILE_OFFSET64
++    __off_t st_size;			/* Size of file, in bytes.  */
++# else
++    __off64_t st_size;			/* Size of file, in bytes.  */
++# endif
++    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
++
++# ifndef __USE_FILE_OFFSET64
++    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
++# else
++    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
++# endif
++# ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
++#  define st_mtime st_mtim.tv_sec
++#  define st_ctime st_ctim.tv_sec
++# else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++# endif
++# ifndef __USE_FILE_OFFSET64
++    unsigned long int __glibc_reserved4;
++    unsigned long int __glibc_reserved5;
++# else
++    __ino64_t st_ino;			/* File serial number.	*/
++# endif
++#endif /* __USE_TIME_BITS64  */
++  };
++
++#ifdef __USE_LARGEFILE64
++struct stat64
++  {
++# ifdef __USE_TIME_BITS64
++#  include <bits/struct_stat_time64_helper.h>
++# else
++    __dev_t st_dev;			/* Device.  */
++    unsigned int __pad1;
++
++    __ino_t __st_ino;			/* 32bit file serial number.	*/
++    __mode_t st_mode;			/* File mode.  */
++    __nlink_t st_nlink;			/* Link count.  */
++    __uid_t st_uid;			/* User ID of the file's owner.	*/
++    __gid_t st_gid;			/* Group ID of the file's group.*/
++    __dev_t st_rdev;			/* Device number, if device.  */
++    unsigned int __pad2;
++    __off64_t st_size;			/* Size of file, in bytes.  */
++    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
++
++    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
++#  ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++#  endif
++    __ino64_t st_ino;			/* File serial number.		*/
++# endif /* __USE_TIME_BITS64  */
++  };
++#endif
++
++/* Tell code we have these members.  */
++#define	_STATBUF_ST_BLKSIZE
++#define _STATBUF_ST_RDEV
++/* Nanosecond resolution time values are supported.  */
++#define _STATBUF_ST_NSEC
++
++
++#endif /* _BITS_STRUCT_STAT_H  */
+diff --git a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
+new file mode 100644
+index 0000000000000000..e00e71173e184b48
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
+@@ -0,0 +1,135 @@
++/* Definition for struct stat.  Linux/nios2 version.
++   Copyright (C) 2020-2022 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/>.  */
++
++#if !defined _SYS_STAT_H && !defined _FCNTL_H
++# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
++#endif
++
++#ifndef _BITS_STRUCT_STAT_H
++#define _BITS_STRUCT_STAT_H	1
++
++#include <bits/endian.h>
++#include <bits/wordsize.h>
++
++#if defined __USE_FILE_OFFSET64
++# define __field64(type, type64, name) type64 name
++#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T
++# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T
++#  error "ino_t and off_t must both be the same type"
++# endif
++# define __field64(type, type64, name) type name
++#elif __BYTE_ORDER == __LITTLE_ENDIAN
++# define __field64(type, type64, name) \
++  type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad
++#else
++# define __field64(type, type64, name) \
++  int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name
++#endif
++
++struct stat
++  {
++#ifdef __USE_TIME_BITS64
++# include <bits/struct_stat_time64_helper.h>
++#else
++    __dev_t st_dev;		/* Device.  */
++    __field64(__ino_t, __ino64_t, st_ino);  /* File serial number. */
++    __mode_t st_mode;		/* File mode.  */
++    __nlink_t st_nlink;		/* Link count.  */
++    __uid_t st_uid;		/* User ID of the file's owner.	*/
++    __gid_t st_gid;		/* Group ID of the file's group.*/
++    __dev_t st_rdev;		/* Device number, if device.  */
++    __dev_t __pad1;
++    __field64(__off_t, __off64_t, st_size);  /* Size of file, in bytes. */
++    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
++    int __pad2;
++    __field64(__blkcnt_t, __blkcnt64_t, st_blocks);  /* 512-byte blocks */
++# ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
++#  define st_mtime st_mtim.tv_sec
++#  define st_ctime st_ctim.tv_sec
++# else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++# endif
++    int __glibc_reserved[2];
++#endif
++  };
++
++#undef __field64
++
++#ifdef __USE_LARGEFILE64
++struct stat64
++  {
++# ifdef __USE_TIME_BITS64
++#  include <bits/struct_stat_time64_helper.h>
++# else
++    __dev_t st_dev;		/* Device.  */
++    __ino64_t st_ino;		/* File serial number.	*/
++    __mode_t st_mode;		/* File mode.  */
++    __nlink_t st_nlink;		/* Link count.  */
++    __uid_t st_uid;		/* User ID of the file's owner.	*/
++    __gid_t st_gid;		/* Group ID of the file's group.*/
++    __dev_t st_rdev;		/* Device number, if device.  */
++    __dev_t __pad1;
++    __off64_t st_size;		/* Size of file, in bytes.  */
++    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
++    int __pad2;
++    __blkcnt64_t st_blocks;	/* Nr. 512-byte blocks allocated.  */
++#  ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++#  endif
++    int __glibc_reserved[2];
++# endif
++  };
++#endif
++
++/* Tell code we have these members.  */
++#define	_STATBUF_ST_BLKSIZE
++#define _STATBUF_ST_RDEV
++/* Nanosecond resolution time values are supported.  */
++#define _STATBUF_ST_NSEC
++
++#endif /* _BITS_STRUCT_STAT_H  */
+diff --git a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
+new file mode 100644
+index 0000000000000000..0f7c9cdc89ebf686
+--- /dev/null
++++ b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
+@@ -0,0 +1,139 @@
++/* Definition for struct stat.  Linux/sh version.
++   Copyright (C) 2020-2022 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/>.  */
++
++#if !defined _SYS_STAT_H && !defined _FCNTL_H
++# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
++#endif
++
++#ifndef _BITS_STRUCT_STAT_H
++#define _BITS_STRUCT_STAT_H	1
++
++#include <bits/endian.h>
++#include <bits/wordsize.h>
++
++struct stat
++  {
++#ifdef __USE_TIME_BITS64
++# include <bits/struct_stat_time64_helper.h>
++#else
++    __dev_t st_dev;			/* Device.  */
++    unsigned short int __pad1;
++# ifndef __USE_FILE_OFFSET64
++    __ino_t st_ino;			/* File serial number.	*/
++# else
++    __ino_t __st_ino;			/* 32bit file serial number.	*/
++# endif
++    __mode_t st_mode;			/* File mode.  */
++    __nlink_t st_nlink;			/* Link count.  */
++    __uid_t st_uid;			/* User ID of the file's owner.	*/
++    __gid_t st_gid;			/* Group ID of the file's group.*/
++    __dev_t st_rdev;			/* Device number, if device.  */
++    unsigned short int __pad2;
++# ifndef __USE_FILE_OFFSET64
++    __off_t st_size;			/* Size of file, in bytes.  */
++# else
++    __off64_t st_size;			/* Size of file, in bytes.  */
++# endif
++    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
++
++# ifndef __USE_FILE_OFFSET64
++    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
++# else
++    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
++# endif
++# ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
++#  define st_mtime st_mtim.tv_sec
++#  define st_ctime st_ctim.tv_sec
++# else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++# endif
++# ifndef __USE_FILE_OFFSET64
++    unsigned long int __glibc_reserved4;
++    unsigned long int __glibc_reserved5;
++# else
++    __ino64_t st_ino;			/* File serial number.	*/
++# endif
++#endif /* __USE_TIME_BITS64  */
++  };
++
++#ifdef __USE_LARGEFILE64
++struct stat64
++  {
++# ifdef __USE_TIME_BITS64
++#  include <bits/struct_stat_time64_helper.h>
++# else
++    __dev_t st_dev;			/* Device.  */
++    unsigned int __pad1;
++
++    __ino_t __st_ino;			/* 32bit file serial number.	*/
++    __mode_t st_mode;			/* File mode.  */
++    __nlink_t st_nlink;			/* Link count.  */
++    __uid_t st_uid;			/* User ID of the file's owner.	*/
++    __gid_t st_gid;			/* Group ID of the file's group.*/
++    __dev_t st_rdev;			/* Device number, if device.  */
++    unsigned int __pad2;
++    __off64_t st_size;			/* Size of file, in bytes.  */
++    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
++
++    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
++#  ifdef __USE_XOPEN2K8
++    /* Nanosecond resolution timestamps are stored in a format
++       equivalent to 'struct timespec'.  This is the type used
++       whenever possible but the Unix namespace rules do not allow the
++       identifier 'timespec' to appear in the <sys/stat.h> header.
++       Therefore we have to handle the use of this header in strictly
++       standard-compliant sources special.  */
++    struct timespec st_atim;		/* Time of last access.  */
++    struct timespec st_mtim;		/* Time of last modification.  */
++    struct timespec st_ctim;		/* Time of last status change.  */
++#  else
++    __time_t st_atime;			/* Time of last access.  */
++    unsigned long int st_atimensec;	/* Nscecs of last access.  */
++    __time_t st_mtime;			/* Time of last modification.  */
++    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
++    __time_t st_ctime;			/* Time of last status change.  */
++    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
++#  endif
++    __ino64_t st_ino;			/* File serial number.		*/
++# endif /* __USE_TIME_BITS64  */
++  };
++#endif
++
++/* Tell code we have these members.  */
++#define	_STATBUF_ST_BLKSIZE
++#define _STATBUF_ST_RDEV
++/* Nanosecond resolution time values are supported.  */
++#define _STATBUF_ST_NSEC
++
++
++#endif /* _BITS_STRUCT_STAT_H  */
diff --git a/SOURCES/glibc-upstream-2.34-351.patch b/SOURCES/glibc-upstream-2.34-351.patch
new file mode 100644
index 0000000..91141b0
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-351.patch
@@ -0,0 +1,107 @@
+commit f42d871b22f7eb5330e77ed9bccbb447c44e7101
+Author: Sergei Trofimovich <slyich@gmail.com>
+Date:   Tue Sep 13 13:39:13 2022 -0400
+
+    Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564]
+    
+    make-4.4 will add long flags to MAKEFLAGS variable:
+    
+        * WARNING: Backward-incompatibility!
+          Previously only simple (one-letter) options were added to the MAKEFLAGS
+          variable that was visible while parsing makefiles.  Now, all options
+          are available in MAKEFLAGS.
+    
+    This causes locale builds to fail when long options are used:
+    
+        $ make --shuffle
+        ...
+        make  -C localedata install-locales
+        make: invalid shuffle mode: '1662724426r'
+    
+    The change fixes it by passing eash option via whitespace and dashes.
+    That way option is appended to both single-word form and whitespace
+    separated form.
+    
+    While at it fixed --silent mode detection in $(MAKEFLAGS) by filtering
+    out --long-options. Otherwise options like --shuffle flag enable silent
+    mode unintentionally. $(silent-make) variable consolidates the checks.
+    
+    Resolves: BZ# 29564
+    
+    CC: Paul Smith <psmith@gnu.org>
+    CC: Siddhesh Poyarekar <siddhesh@gotplt.org>
+    Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 2d7ed98add14f75041499ac189696c9bd3d757fe)
+
+diff --git a/Makeconfig b/Makeconfig
+index 99898a632a64be91..4e04dafb76a1e1a1 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -43,6 +43,22 @@ else
+ $(error objdir must be defined by the build-directory Makefile)
+ endif
+ 
++# Did we request 'make -s' run? "yes" or "no".
++# Starting from make-4.4 MAKEFLAGS now contains long
++# options like '--shuffle'. To detect presence of 's'
++# we pick first word with short options. Long options
++# are guaranteed to come after whitespace. We use '-'
++# prefix to always have a word before long options
++# even if no short options were passed.
++# Typical MAKEFLAGS values to watch for:
++#   "rs --shuffle=42" (silent)
++#   " --shuffle" (not silent)
++ifeq ($(findstring s, $(firstword -$(MAKEFLAGS))),)
++silent-make := no
++else
++silent-make := yes
++endif
++
+ # Root of the sysdeps tree.
+ sysdep_dir := $(..)sysdeps
+ export sysdep_dir := $(sysdep_dir)
+@@ -918,7 +934,7 @@ endif
+ # umpteen zillion filenames along with it (we use `...' instead)
+ # but we don't want this echoing done when the user has said
+ # he doesn't want to see commands echoed by using -s.
+-ifneq	"$(findstring s,$(MAKEFLAGS))" ""	# if -s
++ifeq ($(silent-make),yes)			# if -s
+ +cmdecho	:= echo >/dev/null
+ else						# not -s
+ +cmdecho	:= echo
+diff --git a/Makerules b/Makerules
+index 7fbe85719aacc230..e5916f29fa0d4593 100644
+--- a/Makerules
++++ b/Makerules
+@@ -810,7 +810,7 @@ endif
+ # Maximize efficiency by minimizing the number of rules.
+ .SUFFIXES:	# Clear the suffix list.  We don't use suffix rules.
+ # Don't define any builtin rules.
+-MAKEFLAGS := $(MAKEFLAGS)r
++MAKEFLAGS := $(MAKEFLAGS) -r
+ 
+ # Generic rule for making directories.
+ %/:
+@@ -827,7 +827,7 @@ MAKEFLAGS := $(MAKEFLAGS)r
+ .PRECIOUS: $(foreach l,$(libtypes),$(patsubst %,$(common-objpfx)$l,c))
+ 
+ # Use the verbose option of ar and tar when not running silently.
+-ifeq	"$(findstring s,$(MAKEFLAGS))" ""	# if not -s
++ifeq ($(silent-make),no)			# if not -s
+ verbose := v
+ else	   					# -s
+ verbose	:=
+diff --git a/elf/rtld-Rules b/elf/rtld-Rules
+index 10de81918c07670f..a452536d39b5c198 100644
+--- a/elf/rtld-Rules
++++ b/elf/rtld-Rules
+@@ -52,7 +52,7 @@ $(objpfx)rtld-libc.a: $(foreach dir,$(rtld-subdirs),\
+ 	mv -f $@T $@
+ 
+ # Use the verbose option of ar and tar when not running silently.
+-ifeq	"$(findstring s,$(MAKEFLAGS))" ""	# if not -s
++ifeq ($(silent-make),no)			# if not -s
+ verbose := v
+ else						# -s
+ verbose	:=
diff --git a/SOURCES/glibc-upstream-2.34-352.patch b/SOURCES/glibc-upstream-2.34-352.patch
new file mode 100644
index 0000000..5c4006e
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-352.patch
@@ -0,0 +1,73 @@
+commit 675ba1f361ea424626b48a40cfd24d113dfc1b65
+Author: Paul Eggert <eggert@cs.ucla.edu>
+Date:   Thu Sep 8 20:08:32 2022 -0500
+
+    mktime: improve heuristic for ca-1986 Indiana DST
+    
+    This patch syncs mktime.c from Gnulib, fixing a
+    problem reported by Mark Krenz <https://bugs.gnu.org/48085>,
+    and it should fix BZ#29035 too.
+    * time/mktime.c (__mktime_internal): Be more generous about
+    accepting arguments with the wrong value of tm_isdst, by falling
+    back to a one-hour DST difference if we find no nearby DST that is
+    unusual.  This fixes a problem where "1986-04-28 00:00 EDT" was
+    rejected when TZ="America/Indianapolis" because the nearest DST
+    timestamp occurred in 1970, a temporal distance too great for the
+    old heuristic.  This also also narrows the search a bit, which
+    is a minor performance win.
+    
+    (cherry picked from commit 83859e1115269cf56d21669361d4ddbe2687831c)
+
+diff --git a/time/mktime.c b/time/mktime.c
+index 8e78006eea7e693b..74d9bbaa5b375723 100644
+--- a/time/mktime.c
++++ b/time/mktime.c
+@@ -429,8 +429,13 @@ __mktime_internal (struct tm *tp,
+ 	 time with the right value, and use its UTC offset.
+ 
+ 	 Heuristic: probe the adjacent timestamps in both directions,
+-	 looking for the desired isdst.  This should work for all real
+-	 time zone histories in the tz database.  */
++	 looking for the desired isdst.  If none is found within a
++	 reasonable duration bound, assume a one-hour DST difference.
++	 This should work for all real time zone histories in the tz
++	 database.  */
++
++      /* +1 if we wanted standard time but got DST, -1 if the reverse.  */
++      int dst_difference = (isdst == 0) - (tm.tm_isdst == 0);
+ 
+       /* Distance between probes when looking for a DST boundary.  In
+ 	 tzdata2003a, the shortest period of DST is 601200 seconds
+@@ -441,12 +446,14 @@ __mktime_internal (struct tm *tp,
+ 	 periods when probing.  */
+       int stride = 601200;
+ 
+-      /* The longest period of DST in tzdata2003a is 536454000 seconds
+-	 (e.g., America/Jujuy starting 1946-10-01 01:00).  The longest
+-	 period of non-DST is much longer, but it makes no real sense
+-	 to search for more than a year of non-DST, so use the DST
+-	 max.  */
+-      int duration_max = 536454000;
++      /* In TZDB 2021e, the longest period of DST (or of non-DST), in
++	 which the DST (or adjacent DST) difference is not one hour,
++	 is 457243209 seconds: e.g., America/Cambridge_Bay with leap
++	 seconds, starting 1965-10-31 00:00 in a switch from
++	 double-daylight time (-05) to standard time (-07), and
++	 continuing to 1980-04-27 02:00 in a switch from standard time
++	 (-07) to daylight time (-06).  */
++      int duration_max = 457243209;
+ 
+       /* Search in both directions, so the maximum distance is half
+ 	 the duration; add the stride to avoid off-by-1 problems.  */
+@@ -483,6 +490,11 @@ __mktime_internal (struct tm *tp,
+ 	      }
+ 	  }
+ 
++      /* No unusual DST offset was found nearby.  Assume one-hour DST.  */
++      t += 60 * 60 * dst_difference;
++      if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm))
++	goto offset_found;
++
+       __set_errno (EOVERFLOW);
+       return -1;
+     }
diff --git a/SOURCES/glibc-upstream-2.34-353.patch b/SOURCES/glibc-upstream-2.34-353.patch
new file mode 100644
index 0000000..2bf6250
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-353.patch
@@ -0,0 +1,86 @@
+commit 6e8044e910600f71f4802dba2d105007af8428c3
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Mon Nov 8 19:11:51 2021 +0000
+
+    Fix memmove call in vfprintf-internal.c:group_number
+    
+    A recent GCC mainline change introduces errors of the form:
+    
+    vfprintf-internal.c: In function 'group_number':
+    vfprintf-internal.c:2093:15: error: 'memmove' specified bound between 9223372036854775808 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=]
+     2093 |               memmove (w, s, (front_ptr -s) * sizeof (CHAR_T));
+          |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    
+    This is a genuine bug in the glibc code: s > front_ptr is always true
+    at this point in the code, and the intent is clearly for the
+    subtraction to be the other way round.  The other arguments to the
+    memmove call here also appear to be wrong; w and s point just *after*
+    the destination and source for copying the rest of the number, so the
+    size needs to be subtracted to get appropriate pointers for the
+    copying.  Adjust the memmove call to conform to the apparent intent of
+    the code, so fixing the -Wstringop-overflow error.
+    
+    Now, if the original code were ever executed, a buffer overrun would
+    result.  However, I believe this code (introduced in commit
+    edc1686af0c0fc2eb535f1d38cdf63c1a5a03675, "vfprintf: Reuse work_buffer
+    in group_number", so in glibc 2.26) is unreachable in prior glibc
+    releases (so there is no need for a bug in Bugzilla, no need to
+    consider any backports unless someone wants to build older glibc
+    releases with GCC 12 and no possibility of this buffer overrun
+    resulting in a security issue).
+    
+    work_buffer is 1000 bytes / 250 wide characters.  This case is only
+    reachable if an initial part of the number, plus a grouped copy of the
+    rest of the number, fail to fit in that space; that is, if the grouped
+    number fails to fit in the space.  In the wide character case,
+    grouping is always one wide character, so even with a locale (of which
+    there aren't any in glibc) grouping every digit, a number would need
+    to occupy at least 125 wide characters to overflow, and a 64-bit
+    integer occupies at most 23 characters in octal including a leading 0.
+    In the narrow character case, the multibyte encoding of the grouping
+    separator would need to be at least 42 bytes to overflow, again
+    supposing grouping every digit, but MB_LEN_MAX is 16.  So even if we
+    admit the case of artificially constructed locales not shipped with
+    glibc, given that such a locale would need to use one of the character
+    sets supported by glibc, this code cannot be reached at present.  (And
+    POSIX only actually specifies the ' flag for grouping for decimal
+    output, though glibc acts on it for other bases as well.)
+    
+    With binary output (if you consider use of grouping there to be
+    valid), you'd need a 15-byte multibyte character for overflow; I don't
+    know if any supported character set has such a character (if, again,
+    we admit constructed locales using grouping every digit and a grouping
+    separator chosen to have a multibyte encoding as long as possible, as
+    well as accepting use of grouping with binary), but given that we have
+    this code at all (clearly it's not *correct*, or in accordance with
+    the principle of avoiding arbitrary limits, to skip grouping on
+    running out of internal space like that), I don't think it should need
+    any further changes for binary printf support to go in.
+    
+    On the other hand, support for large sizes of _BitInt in printf (see
+    the N2858 proposal) *would* require something to be done about such
+    arbitrary limits (presumably using dynamic allocation in printf again,
+    for sufficiently large _BitInt arguments only - currently only
+    floating-point uses dynamic allocation, and, as previously discussed,
+    that could actually be replaced by bounded allocation given smarter
+    code).
+    
+    Tested with build-many-glibcs.py for aarch64-linux-gnu (GCC mainline).
+    Also tested natively for x86_64.
+    
+    (cherry picked from commit db6c4935fae6005d46af413b32aa92f4f6059dce)
+
+diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c
+index 3f3d1e148a8e7fda..53d93b2f07ecb261 100644
+--- a/stdio-common/vfprintf-internal.c
++++ b/stdio-common/vfprintf-internal.c
+@@ -2154,7 +2154,8 @@ group_number (CHAR_T *front_ptr, CHAR_T *w, CHAR_T *rear_ptr,
+ 	    copy_rest:
+ 	      /* No further grouping to be done.  Copy the rest of the
+ 		 number.  */
+-	      memmove (w, s, (front_ptr -s) * sizeof (CHAR_T));
++	      w -= s - front_ptr;
++	      memmove (w, front_ptr, (s - front_ptr) * sizeof (CHAR_T));
+ 	      break;
+ 	    }
+ 	  else if (*grouping != '\0')
diff --git a/SOURCES/glibc-upstream-2.34-354.patch b/SOURCES/glibc-upstream-2.34-354.patch
new file mode 100644
index 0000000..0ac8827
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-354.patch
@@ -0,0 +1,35 @@
+commit 291d4402067760edb7c0f339f9e451787a25e20a
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Fri Aug 27 17:47:46 2021 +0000
+
+    Allow #pragma GCC in headers in conformtest
+    
+    No "#pragma GCC" pragma allows macro-expansion of its arguments, so no
+    namespace issues arise from use of such pragmas in installed headers.
+    Ignore them in conformtest tests of header namespace.
+    
+    Tested for x86_64, in conjunction with Paul's patch
+    <https://sourceware.org/pipermail/libc-alpha/2021-August/130571.html>
+    adding use of such pragmas to installed headers shared with gnulib.
+    
+    (cherry picked from commit 6090a4a1b32fd7859d0ad5b7e9b240bd5fa04b3f)
+
+diff --git a/conform/conformtest.py b/conform/conformtest.py
+index 4898e16c9fb96503..164cf2917d464aa1 100644
+--- a/conform/conformtest.py
++++ b/conform/conformtest.py
+@@ -631,6 +631,14 @@ class HeaderTests(object):
+                     continue
+                 if re.match(r'# [1-9]', line):
+                     continue
++                if line.startswith('#pragma GCC '):
++                    # No GCC pragma uses macro expansion, so no
++                    # namespace issues arise from such pragmas.  (Some
++                    # pragmas not in the GCC namespace do macro-expand
++                    # their arguments and so could be affected by
++                    # macros defined by user code including the
++                    # header.)
++                    continue
+                 match = re.match(r'#define (.*)', line)
+                 if match:
+                     self.check_token(bad_tokens, match.group(1))
diff --git a/SOURCES/glibc-upstream-2.34-355.patch b/SOURCES/glibc-upstream-2.34-355.patch
new file mode 100644
index 0000000..4ba03a0
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-355.patch
@@ -0,0 +1,629 @@
+commit 86a701a20479dfbc23540b3143fd5b28660a2447
+Author: Paul Eggert <eggert@cs.ucla.edu>
+Date:   Tue Sep 21 07:47:45 2021 -0700
+
+    regex: copy back from Gnulib
+    
+    Copy regex-related files back from Gnulib, to fix a problem with
+    static checking of regex calls noted by Martin Sebor.  This merges the
+    following changes:
+    
+    * New macro __attribute_nonnull__ in misc/sys/cdefs.h, for use later
+    when copying other files back from Gnulib.
+    
+    * Use __GNULIB_CDEFS instead of __GLIBC__ when deciding
+    whether to include bits/wordsize.h etc.
+    
+    * Avoid duplicate entries in epsilon closure table.
+    
+    * New regex.h macro _REGEX_NELTS to let regexec say that its pmatch
+    arg should contain nmatch elts.  Use that for regexec, instead of
+    __attr_access (which is incorrect).
+    
+    * New regex.h macro _Attr_access_ which is like __attr_access except
+    portable to non-glibc platforms.
+    
+    * Add some DEBUG_ASSERTs to pacify gcc -fanalyzer and to catch
+    recently-fixed performance bugs if they recur.
+    
+    * Add Gnulib-specific stuff to port the dynarray- and lock-using parts
+    of regex code to non-glibc platforms.
+    
+    * Fix glibc bug 11053.
+    
+    * Avoid some undefined behavior when popping an empty fail stack.
+    
+    (cherry picked from commit 0b5ca7c3e551e5502f3be3b06453324fe8604e82)
+
+diff --git a/include/intprops.h b/include/intprops.h
+index 967e32ea0cbedd56..9d10028a5966c1c6 100644
+--- a/include/intprops.h
++++ b/include/intprops.h
+@@ -133,7 +133,8 @@
+    operators might not yield numerically correct answers due to
+    arithmetic overflow.  They do not rely on undefined or
+    implementation-defined behavior.  Their implementations are simple
+-   and straightforward, but they are a bit harder to use than the
++   and straightforward, but they are harder to use and may be less
++   efficient than the INT_<op>_WRAPV, INT_<op>_OK, and
+    INT_<op>_OVERFLOW macros described below.
+ 
+    Example usage:
+@@ -158,6 +159,9 @@
+    must have minimum value MIN and maximum MAX.  Unsigned types should
+    use a zero MIN of the proper type.
+ 
++   Because all arguments are subject to integer promotions, these
++   macros typically do not work on types narrower than 'int'.
++
+    These macros are tuned for constant MIN and MAX.  For commutative
+    operations such as A + B, they are also tuned for constant B.  */
+ 
+@@ -339,9 +343,15 @@
+    arguments should not have side effects.
+ 
+    The WRAPV macros are not constant expressions.  They support only
+-   +, binary -, and *.  Because the WRAPV macros convert the result,
+-   they report overflow in different circumstances than the OVERFLOW
+-   macros do.
++   +, binary -, and *.
++
++   Because the WRAPV macros convert the result, they report overflow
++   in different circumstances than the OVERFLOW macros do.  For
++   example, in the typical case with 16-bit 'short' and 32-bit 'int',
++   if A, B and R are all of type 'short' then INT_ADD_OVERFLOW (A, B)
++   returns false because the addition cannot overflow after A and B
++   are converted to 'int', whereas INT_ADD_WRAPV (A, B, &R) returns
++   true or false depending on whether the sum fits into 'short'.
+ 
+    These macros are tuned for their last input argument being a constant.
+ 
+diff --git a/include/regex.h b/include/regex.h
+index 24eca2c297bb6043..34fb67d85536bcb9 100644
+--- a/include/regex.h
++++ b/include/regex.h
+@@ -37,7 +37,8 @@ extern int __regcomp (regex_t *__preg, const char *__pattern, int __cflags);
+ libc_hidden_proto (__regcomp)
+ 
+ extern int __regexec (const regex_t *__preg, const char *__string,
+-		      size_t __nmatch, regmatch_t __pmatch[], int __eflags);
++		      size_t __nmatch, regmatch_t __pmatch[__nmatch],
++		      int __eflags);
+ libc_hidden_proto (__regexec)
+ 
+ extern size_t __regerror (int __errcode, const regex_t *__preg,
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index e0ecd9147ee3ce48..b166f3d209fe361f 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -366,16 +366,18 @@
+ #endif
+ 
+ /* The nonnull function attribute marks pointer parameters that
+-   must not be NULL.  */
+-#ifndef __nonnull
++   must not be NULL.  This has the name __nonnull in glibc,
++   and __attribute_nonnull__ in files shared with Gnulib to avoid
++   collision with a different __nonnull in DragonFlyBSD 5.9.  */
++#ifndef __attribute_nonnull__
+ # if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__)
+-#  define __nonnull(params) __attribute__ ((__nonnull__ params))
++#  define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params))
+ # else
+-#  define __nonnull(params)
++#  define __attribute_nonnull__(params)
+ # endif
+-#elif !defined __GLIBC__
+-# undef __nonnull
+-# define __nonnull(params) _GL_ATTRIBUTE_NONNULL (params)
++#endif
++#ifndef __nonnull
++# define __nonnull(params) __attribute_nonnull__ (params)
+ #endif
+ 
+ /* The returns_nonnull function attribute marks the return type of the function
+@@ -541,9 +543,9 @@
+       [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
+ #endif
+ 
+-/* The #ifndef lets Gnulib avoid including these on non-glibc
+-   platforms, where the includes typically do not exist.  */
+-#ifdef __GLIBC__
++/* Gnulib avoids including these, as they don't work on non-glibc or
++   older glibc platforms.  */
++#ifndef __GNULIB_CDEFS
+ # include <bits/wordsize.h>
+ # include <bits/long-double.h>
+ #endif
+diff --git a/posix/regcomp.c b/posix/regcomp.c
+index d93698ae78447b46..887e5b50684e22f5 100644
+--- a/posix/regcomp.c
++++ b/posix/regcomp.c
+@@ -1695,12 +1695,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
+   reg_errcode_t err;
+   Idx i;
+   re_node_set eclosure;
+-  bool ok;
+   bool incomplete = false;
+   err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
+   if (__glibc_unlikely (err != REG_NOERROR))
+     return err;
+ 
++  /* An epsilon closure includes itself.  */
++  eclosure.elems[eclosure.nelem++] = node;
++
+   /* This indicates that we are calculating this node now.
+      We reference this value to avoid infinite loop.  */
+   dfa->eclosures[node].nelem = -1;
+@@ -1753,10 +1755,6 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
+ 	  }
+       }
+ 
+-  /* An epsilon closure includes itself.  */
+-  ok = re_node_set_insert (&eclosure, node);
+-  if (__glibc_unlikely (! ok))
+-    return REG_ESPACE;
+   if (incomplete && !root)
+     dfa->eclosures[node].nelem = 0;
+   else
+diff --git a/posix/regex.c b/posix/regex.c
+index 7296be0f08da88d8..d32863972c7bcdcf 100644
+--- a/posix/regex.c
++++ b/posix/regex.c
+@@ -24,6 +24,7 @@
+ 
+ # if __GNUC_PREREQ (4, 6)
+ #  pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
++#  pragma GCC diagnostic ignored "-Wvla"
+ # endif
+ # if __GNUC_PREREQ (4, 3)
+ #  pragma GCC diagnostic ignored "-Wold-style-definition"
+diff --git a/posix/regex.h b/posix/regex.h
+index 14fb1d8364a11d29..adb69768ee520554 100644
+--- a/posix/regex.h
++++ b/posix/regex.h
+@@ -522,6 +522,30 @@ typedef struct
+ 
+ /* Declarations for routines.  */
+ 
++#ifndef _REGEX_NELTS
++# if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \
++	&& !defined __STDC_NO_VLA__)
++#  define _REGEX_NELTS(n) n
++# else
++#  define _REGEX_NELTS(n)
++# endif
++#endif
++
++#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
++# pragma GCC diagnostic push
++# pragma GCC diagnostic ignored "-Wvla"
++#endif
++
++#ifndef _Attr_access_
++# ifdef __attr_access
++#  define _Attr_access_(arg) __attr_access (arg)
++# elif defined __GNUC__ && 10 <= __GNUC__
++#  define _Attr_access_(x) __attribute__ ((__access__ x))
++# else
++#  define _Attr_access_(x)
++# endif
++#endif
++
+ #ifdef __USE_GNU
+ /* Sets the current default syntax to SYNTAX, and return the old syntax.
+    You can also simply assign to the 're_syntax_options' variable.  */
+@@ -537,7 +561,7 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
+    'regfree'.  */
+ extern const char *re_compile_pattern (const char *__pattern, size_t __length,
+ 				       struct re_pattern_buffer *__buffer)
+-    __attr_access ((__read_only__, 1, 2));
++    _Attr_access_ ((__read_only__, 1, 2));
+ 
+ 
+ /* Compile a fastmap for the compiled pattern in BUFFER; used to
+@@ -555,7 +579,7 @@ extern regoff_t re_search (struct re_pattern_buffer *__buffer,
+ 			   const char *__String, regoff_t __length,
+ 			   regoff_t __start, regoff_t __range,
+ 			   struct re_registers *__regs)
+-    __attr_access ((__read_only__, 2, 3));
++    _Attr_access_ ((__read_only__, 2, 3));
+ 
+ 
+ /* Like 're_search', but search in the concatenation of STRING1 and
+@@ -566,8 +590,8 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
+ 			     regoff_t __start, regoff_t __range,
+ 			     struct re_registers *__regs,
+ 			     regoff_t __stop)
+-    __attr_access ((__read_only__, 2, 3))
+-    __attr_access ((__read_only__, 4, 5));
++    _Attr_access_ ((__read_only__, 2, 3))
++    _Attr_access_ ((__read_only__, 4, 5));
+ 
+ 
+ /* Like 're_search', but return how many characters in STRING the regexp
+@@ -575,7 +599,7 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
+ extern regoff_t re_match (struct re_pattern_buffer *__buffer,
+ 			  const char *__String, regoff_t __length,
+ 			  regoff_t __start, struct re_registers *__regs)
+-    __attr_access ((__read_only__, 2, 3));
++    _Attr_access_ ((__read_only__, 2, 3));
+ 
+ 
+ /* Relates to 're_match' as 're_search_2' relates to 're_search'.  */
+@@ -584,8 +608,8 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
+ 			    const char *__string2, regoff_t __length2,
+ 			    regoff_t __start, struct re_registers *__regs,
+ 			    regoff_t __stop)
+-    __attr_access ((__read_only__, 2, 3))
+-    __attr_access ((__read_only__, 4, 5));
++    _Attr_access_ ((__read_only__, 2, 3))
++    _Attr_access_ ((__read_only__, 4, 5));
+ 
+ 
+ /* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+@@ -654,16 +678,19 @@ extern int regcomp (regex_t *_Restrict_ __preg,
+ 
+ extern int regexec (const regex_t *_Restrict_ __preg,
+ 		    const char *_Restrict_ __String, size_t __nmatch,
+-		    regmatch_t __pmatch[_Restrict_arr_],
+-		    int __eflags)
+-    __attr_access ((__write_only__, 4, 3));
++		    regmatch_t __pmatch[_Restrict_arr_
++					_REGEX_NELTS (__nmatch)],
++		    int __eflags);
+ 
+ extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
+ 			char *_Restrict_ __errbuf, size_t __errbuf_size)
+-    __attr_access ((__write_only__, 3, 4));
++    _Attr_access_ ((__write_only__, 3, 4));
+ 
+ extern void regfree (regex_t *__preg);
+ 
++#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
++# pragma GCC diagnostic pop
++#endif
+ 
+ #ifdef __cplusplus
+ }
+diff --git a/posix/regex_internal.c b/posix/regex_internal.c
+index 9dd387ef85d64e62..aefcfa2f52e68c6a 100644
+--- a/posix/regex_internal.c
++++ b/posix/regex_internal.c
+@@ -1211,6 +1211,10 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
+ 
+   if (__glibc_unlikely (dest->nelem == 0))
+     {
++      /* Although we already guaranteed above that dest->alloc != 0 and
++         therefore dest->elems != NULL, add a debug assertion to pacify
++         GCC 11.2.1's -fanalyzer.  */
++      DEBUG_ASSERT (dest->elems);
+       dest->nelem = src->nelem;
+       memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
+       return REG_NOERROR;
+@@ -1286,7 +1290,10 @@ re_node_set_insert (re_node_set *set, Idx elem)
+ 
+   if (__glibc_unlikely (set->nelem) == 0)
+     {
+-      /* We already guaranteed above that set->alloc != 0.  */
++      /* Although we already guaranteed above that set->alloc != 0 and
++         therefore set->elems != NULL, add a debug assertion to pacify
++         GCC 11.2 -fanalyzer.  */
++      DEBUG_ASSERT (set->elems);
+       set->elems[0] = elem;
+       ++set->nelem;
+       return true;
+@@ -1314,6 +1321,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
+     {
+       for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
+ 	set->elems[idx] = set->elems[idx - 1];
++      DEBUG_ASSERT (set->elems[idx - 1] < elem);
+     }
+ 
+   /* Insert the new element.  */
+diff --git a/posix/regex_internal.h b/posix/regex_internal.h
+index edcdc07e999694ac..1245e782ffc69086 100644
+--- a/posix/regex_internal.h
++++ b/posix/regex_internal.h
+@@ -32,6 +32,10 @@
+ #include <stdbool.h>
+ #include <stdint.h>
+ 
++#ifndef _LIBC
++# include <dynarray.h>
++#endif
++
+ #include <intprops.h>
+ #include <verify.h>
+ 
+@@ -49,14 +53,14 @@
+ # define lock_fini(lock) ((void) 0)
+ # define lock_lock(lock) __libc_lock_lock (lock)
+ # define lock_unlock(lock) __libc_lock_unlock (lock)
+-#elif defined GNULIB_LOCK && !defined USE_UNLOCKED_IO
++#elif defined GNULIB_LOCK && !defined GNULIB_REGEX_SINGLE_THREAD
+ # include "glthread/lock.h"
+ # define lock_define(name) gl_lock_define (, name)
+ # define lock_init(lock) glthread_lock_init (&(lock))
+ # define lock_fini(lock) glthread_lock_destroy (&(lock))
+ # define lock_lock(lock) glthread_lock_lock (&(lock))
+ # define lock_unlock(lock) glthread_lock_unlock (&(lock))
+-#elif defined GNULIB_PTHREAD && !defined USE_UNLOCKED_IO
++#elif defined GNULIB_PTHREAD && !defined GNULIB_REGEX_SINGLE_THREAD
+ # include <pthread.h>
+ # define lock_define(name) pthread_mutex_t name;
+ # define lock_init(lock) pthread_mutex_init (&(lock), 0)
+diff --git a/posix/regexec.c b/posix/regexec.c
+index f7b4f9cfc3f030df..83e9aaf8cad956a2 100644
+--- a/posix/regexec.c
++++ b/posix/regexec.c
+@@ -59,7 +59,7 @@ static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+ 			 Idx cur_idx, Idx nmatch);
+ static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
+ 				      Idx str_idx, Idx dest_node, Idx nregs,
+-				      regmatch_t *regs,
++				      regmatch_t *regs, regmatch_t *prevregs,
+ 				      re_node_set *eps_via_nodes);
+ static reg_errcode_t set_regs (const regex_t *preg,
+ 			       const re_match_context_t *mctx,
+@@ -186,11 +186,12 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len);
+    REG_NOTBOL is set, then ^ does not match at the beginning of the
+    string; if REG_NOTEOL is set, then $ does not match at the end.
+ 
+-   We return 0 if we find a match and REG_NOMATCH if not.  */
++   Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if
++   EFLAGS is invalid.  */
+ 
+ int
+ regexec (const regex_t *__restrict preg, const char *__restrict string,
+-	 size_t nmatch, regmatch_t pmatch[], int eflags)
++	 size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags)
+ {
+   reg_errcode_t err;
+   Idx start, length;
+@@ -234,7 +235,7 @@ int
+ attribute_compat_text_section
+ __compat_regexec (const regex_t *__restrict preg,
+ 		  const char *__restrict string, size_t nmatch,
+-		  regmatch_t pmatch[], int eflags)
++		  regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags)
+ {
+   return regexec (preg, string, nmatch, pmatch,
+ 		  eflags & (REG_NOTBOL | REG_NOTEOL));
+@@ -269,8 +270,8 @@ compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+    strings.)
+ 
+    On success, re_match* functions return the length of the match, re_search*
+-   return the position of the start of the match.  Return value -1 means no
+-   match was found and -2 indicates an internal error.  */
++   return the position of the start of the match.  They return -1 on
++   match failure, -2 on error.  */
+ 
+ regoff_t
+ re_match (struct re_pattern_buffer *bufp, const char *string, Idx length,
+@@ -1206,27 +1207,30 @@ check_halt_state_context (const re_match_context_t *mctx,
+ /* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
+    corresponding to the DFA).
+    Return the destination node, and update EPS_VIA_NODES;
+-   return -1 in case of errors.  */
++   return -1 on match failure, -2 on error.  */
+ 
+ static Idx
+ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
++		   regmatch_t *prevregs,
+ 		   Idx *pidx, Idx node, re_node_set *eps_via_nodes,
+ 		   struct re_fail_stack_t *fs)
+ {
+   const re_dfa_t *const dfa = mctx->dfa;
+-  Idx i;
+-  bool ok;
+   if (IS_EPSILON_NODE (dfa->nodes[node].type))
+     {
+       re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
+       re_node_set *edests = &dfa->edests[node];
+-      Idx dest_node;
+-      ok = re_node_set_insert (eps_via_nodes, node);
+-      if (__glibc_unlikely (! ok))
+-	return -2;
+-      /* Pick up a valid destination, or return -1 if none
+-	 is found.  */
+-      for (dest_node = -1, i = 0; i < edests->nelem; ++i)
++
++      if (! re_node_set_contains (eps_via_nodes, node))
++        {
++          bool ok = re_node_set_insert (eps_via_nodes, node);
++          if (__glibc_unlikely (! ok))
++            return -2;
++        }
++
++      /* Pick a valid destination, or return -1 if none is found.  */
++      Idx dest_node = -1;
++      for (Idx i = 0; i < edests->nelem; i++)
+ 	{
+ 	  Idx candidate = edests->elems[i];
+ 	  if (!re_node_set_contains (cur_nodes, candidate))
+@@ -1244,7 +1248,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
+ 	      /* Otherwise, push the second epsilon-transition on the fail stack.  */
+ 	      else if (fs != NULL
+ 		       && push_fail_stack (fs, *pidx, candidate, nregs, regs,
+-					   eps_via_nodes))
++					   prevregs, eps_via_nodes))
+ 		return -2;
+ 
+ 	      /* We know we are going to exit.  */
+@@ -1288,7 +1292,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
+ 	  if (naccepted == 0)
+ 	    {
+ 	      Idx dest_node;
+-	      ok = re_node_set_insert (eps_via_nodes, node);
++	      bool ok = re_node_set_insert (eps_via_nodes, node);
+ 	      if (__glibc_unlikely (! ok))
+ 		return -2;
+ 	      dest_node = dfa->edests[node].elems[0];
+@@ -1317,7 +1321,8 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
+ static reg_errcode_t
+ __attribute_warn_unused_result__
+ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
+-		 Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
++		 Idx nregs, regmatch_t *regs, regmatch_t *prevregs,
++		 re_node_set *eps_via_nodes)
+ {
+   reg_errcode_t err;
+   Idx num = fs->num++;
+@@ -1333,25 +1338,30 @@ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
+     }
+   fs->stack[num].idx = str_idx;
+   fs->stack[num].node = dest_node;
+-  fs->stack[num].regs = re_malloc (regmatch_t, nregs);
++  fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs);
+   if (fs->stack[num].regs == NULL)
+     return REG_ESPACE;
+   memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
++  memcpy (fs->stack[num].regs + nregs, prevregs, sizeof (regmatch_t) * nregs);
+   err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
+   return err;
+ }
+ 
+ static Idx
+ pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
+-		regmatch_t *regs, re_node_set *eps_via_nodes)
++		regmatch_t *regs, regmatch_t *prevregs,
++		re_node_set *eps_via_nodes)
+ {
++  if (fs == NULL || fs->num == 0)
++    return -1;
+   Idx num = --fs->num;
+-  DEBUG_ASSERT (num >= 0);
+   *pidx = fs->stack[num].idx;
+   memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
++  memcpy (prevregs, fs->stack[num].regs + nregs, sizeof (regmatch_t) * nregs);
+   re_node_set_free (eps_via_nodes);
+   re_free (fs->stack[num].regs);
+   *eps_via_nodes = fs->stack[num].eps_via_nodes;
++  DEBUG_ASSERT (0 <= fs->stack[num].node);
+   return fs->stack[num].node;
+ }
+ 
+@@ -1407,33 +1417,32 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
+     {
+       update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
+ 
+-      if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
++      if ((idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
++	  || (fs && re_node_set_contains (&eps_via_nodes, cur_node)))
+ 	{
+ 	  Idx reg_idx;
++	  cur_node = -1;
+ 	  if (fs)
+ 	    {
+ 	      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+ 		if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
+-		  break;
+-	      if (reg_idx == nmatch)
+-		{
+-		  re_node_set_free (&eps_via_nodes);
+-		  regmatch_list_free (&prev_match);
+-		  return free_fail_stack_return (fs);
+-		}
+-	      cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+-					 &eps_via_nodes);
++		  {
++		    cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
++					       prev_idx_match, &eps_via_nodes);
++		    break;
++		  }
+ 	    }
+-	  else
++	  if (cur_node < 0)
+ 	    {
+ 	      re_node_set_free (&eps_via_nodes);
+ 	      regmatch_list_free (&prev_match);
+-	      return REG_NOERROR;
++	      return free_fail_stack_return (fs);
+ 	    }
+ 	}
+ 
+       /* Proceed to next node.  */
+-      cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
++      cur_node = proceed_next_node (mctx, nmatch, pmatch, prev_idx_match,
++				    &idx, cur_node,
+ 				    &eps_via_nodes, fs);
+ 
+       if (__glibc_unlikely (cur_node < 0))
+@@ -1445,13 +1454,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
+ 	      free_fail_stack_return (fs);
+ 	      return REG_ESPACE;
+ 	    }
+-	  if (fs)
+-	    cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+-				       &eps_via_nodes);
+-	  else
++	  cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
++				     prev_idx_match, &eps_via_nodes);
++	  if (cur_node < 0)
+ 	    {
+ 	      re_node_set_free (&eps_via_nodes);
+ 	      regmatch_list_free (&prev_match);
++	      free_fail_stack_return (fs);
+ 	      return REG_NOMATCH;
+ 	    }
+ 	}
+@@ -1495,10 +1504,10 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+     }
+   else if (type == OP_CLOSE_SUBEXP)
+     {
++      /* We are at the last node of this sub expression.  */
+       Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
+       if (reg_num < nmatch)
+ 	{
+-	  /* We are at the last node of this sub expression.  */
+ 	  if (pmatch[reg_num].rm_so < cur_idx)
+ 	    {
+ 	      pmatch[reg_num].rm_eo = cur_idx;
+@@ -2195,6 +2204,7 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
+ 
+ /* Return the next state to which the current state STATE will transit by
+    accepting the current input byte, and update STATE_LOG if necessary.
++   Return NULL on failure.
+    If STATE can accept a multibyte char/collating element/back reference
+    update the destination of STATE_LOG.  */
+ 
+@@ -2395,7 +2405,7 @@ check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,
+ 
+ #if 0
+ /* Return the next state to which the current state STATE will transit by
+-   accepting the current input byte.  */
++   accepting the current input byte.  Return NULL on failure.  */
+ 
+ static re_dfastate_t *
+ transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
+@@ -2817,7 +2827,8 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+ /* Check whether the node TOP_NODE at TOP_STR can arrive to the node
+    LAST_NODE at LAST_STR.  We record the path onto PATH since it will be
+    heavily reused.
+-   Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
++   Return REG_NOERROR if it can arrive, REG_NOMATCH if it cannot,
++   REG_ESPACE if memory is exhausted.  */
+ 
+ static reg_errcode_t
+ __attribute_warn_unused_result__
+@@ -3433,7 +3444,8 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
+ /* Group all nodes belonging to STATE into several destinations.
+    Then for all destinations, set the nodes belonging to the destination
+    to DESTS_NODE[i] and set the characters accepted by the destination
+-   to DEST_CH[i].  This function return the number of destinations.  */
++   to DEST_CH[i].  Return the number of destinations if successful,
++   -1 on internal error.  */
+ 
+ static Idx
+ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+@@ -4211,7 +4223,8 @@ match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
+ }
+ 
+ /* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
+-   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
++   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.
++   Return the new entry if successful, NULL if memory is exhausted.  */
+ 
+ static re_sub_match_last_t *
+ match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
diff --git a/SOURCES/glibc-upstream-2.34-356.patch b/SOURCES/glibc-upstream-2.34-356.patch
new file mode 100644
index 0000000..fcaa4ad
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-356.patch
@@ -0,0 +1,30 @@
+commit fa5044f1e38f4f6515253449b6ca77fd14f53b8e
+Author: Paul Eggert <eggert@cs.ucla.edu>
+Date:   Wed Nov 24 14:16:09 2021 -0800
+
+    regex: fix buffer read overrun in search [BZ#28470]
+    
+    Problem reported by Benno Schulenberg in:
+    https://lists.gnu.org/r/bug-gnulib/2021-10/msg00035.html
+    * posix/regexec.c (re_search_internal): Use better bounds check.
+    
+    (cherry picked from commit c52ef24829f95a819965214eeae28e3289a91a61)
+
+diff --git a/posix/regexec.c b/posix/regexec.c
+index 83e9aaf8cad956a2..6aeba3c0b4da23cc 100644
+--- a/posix/regexec.c
++++ b/posix/regexec.c
+@@ -758,10 +758,9 @@ re_search_internal (const regex_t *preg, const char *string, Idx length,
+ 
+ 		  offset = match_first - mctx.input.raw_mbs_idx;
+ 		}
+-	      /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+-		 Note that MATCH_FIRST must not be smaller than 0.  */
+-	      ch = (match_first >= length
+-		    ? 0 : re_string_byte_at (&mctx.input, offset));
++	      /* Use buffer byte if OFFSET is in buffer, otherwise '\0'.  */
++	      ch = (offset < mctx.input.valid_len
++		    ? re_string_byte_at (&mctx.input, offset) : 0);
+ 	      if (fastmap[ch])
+ 		break;
+ 	      match_first += incr;
diff --git a/SOURCES/glibc-upstream-2.34-357.patch b/SOURCES/glibc-upstream-2.34-357.patch
new file mode 100644
index 0000000..732e8af
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-357.patch
@@ -0,0 +1,203 @@
+commit 06afa5e09fbd984ed45ae6fc6ca050d544aba780
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Aug 25 11:17:06 2021 -0300
+
+    io: Fix ftw internal realloc buffer (BZ #28126)
+    
+    The 106ff08526d3ca did not take in consideration the buffer might be
+    reallocated if the total path is larger than PATH_MAX.  The realloc
+    uses 'dirbuf', where 'dirstreams' is the allocated buffer.
+    
+    Checked on x86_64-linux-gnu.
+    
+    Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
+    (cherry picked from commit 1836bb2ebf62bd9a3588f2ed2d851c8ae810097a)
+
+diff --git a/io/Makefile b/io/Makefile
+index 01968b81042e01e4..5284a1282dd07e3d 100644
+--- a/io/Makefile
++++ b/io/Makefile
+@@ -79,6 +79,7 @@ tests		:= test-utime test-stat test-stat2 test-lfs tst-getcwd \
+ 		   tst-futimens \
+ 		   tst-utimensat \
+ 		   tst-closefrom \
++		   tst-ftw-bz28126
+ 
+ tests-time64 := \
+   tst-fcntl-time64 \
+diff --git a/io/ftw.c b/io/ftw.c
+index ce1c6a14a306152a..cf08d9f101657df0 100644
+--- a/io/ftw.c
++++ b/io/ftw.c
+@@ -204,6 +204,20 @@ struct ftw_data
+   void *known_objects;
+ };
+ 
++static bool
++ftw_allocate (struct ftw_data *data, size_t newsize)
++{
++  void *newp = realloc (data->dirstreams, data->maxdir
++					  * sizeof (struct dir_data *)
++					  + newsize);
++  if (newp == NULL)
++    return false;
++  data->dirstreams = newp;
++  data->dirbufsize = newsize;
++  data->dirbuf = (char *) data->dirstreams
++		 + data->maxdir * sizeof (struct dir_data *);
++  return true;
++}
+ 
+ /* Internally we use the FTW_* constants used for `nftw'.  When invoked
+    as `ftw', map each flag to the subset of values used by `ftw'.  */
+@@ -389,17 +403,9 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
+     return 0;
+ 
+   new_buflen = data->ftw.base + namlen + 2;
+-  if (data->dirbufsize < new_buflen)
+-    {
+-      /* Enlarge the buffer.  */
+-      char *newp;
+-
+-      data->dirbufsize = 2 * new_buflen;
+-      newp = (char *) realloc (data->dirbuf, data->dirbufsize);
+-      if (newp == NULL)
+-	return -1;
+-      data->dirbuf = newp;
+-    }
++  if (data->dirbufsize < new_buflen
++      && !ftw_allocate (data, 2 * new_buflen))
++    return -1;
+ 
+   *((char *) __mempcpy (data->dirbuf + data->ftw.base, name, namlen)) = '\0';
+ 
+@@ -629,7 +635,7 @@ __attribute ((noinline))
+ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
+ 	     int flags)
+ {
+-  struct ftw_data data;
++  struct ftw_data data = { .dirstreams = NULL };
+   struct STRUCT_STAT st;
+   int result = 0;
+   int save_err;
+@@ -647,16 +653,9 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
+   data.maxdir = descriptors < 1 ? 1 : descriptors;
+   data.actdir = 0;
+   /* PATH_MAX is always defined when we get here.  */
+-  data.dirbufsize = MAX (2 * strlen (dir), PATH_MAX);
+-  data.dirstreams = malloc (data.maxdir * sizeof (struct dir_data *)
+-                            + data.dirbufsize);
+-  if (data.dirstreams == NULL)
++  if (!ftw_allocate (&data, MAX (2 * strlen (dir), PATH_MAX)))
+     return -1;
+-
+   memset (data.dirstreams, '\0', data.maxdir * sizeof (struct dir_data *));
+-
+-  data.dirbuf = (char *) data.dirstreams
+-                + data.maxdir * sizeof (struct dir_data *);
+   cp = __stpcpy (data.dirbuf, dir);
+   /* Strip trailing slashes.  */
+   while (cp > data.dirbuf + 1 && cp[-1] == '/')
+diff --git a/io/tst-ftw-bz28126.c b/io/tst-ftw-bz28126.c
+new file mode 100644
+index 0000000000000000..94044ab9d1d0275b
+--- /dev/null
++++ b/io/tst-ftw-bz28126.c
+@@ -0,0 +1,97 @@
++/* Check if internal buffer reallocation work for large paths (BZ #28126)
++   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 <errno.h>
++#include <ftw.h>
++#include <limits.h>
++#include <string.h>
++#include <stdlib.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/temp_file.h>
++#include <support/xunistd.h>
++#include <stdio.h>
++
++static int
++my_func (const char *file, const struct stat *sb, int flag)
++{
++  return 0;
++}
++
++static const char folder[NAME_MAX] = { [0 ... 253] = 'a', [254] = '\0' };
++
++#define NSUBFOLDERS 16
++static int nsubfolders;
++
++static void
++do_cleanup (void)
++{
++  xchdir ("..");
++  for (int i = 0; i < nsubfolders; i++)
++    {
++      remove (folder);
++      xchdir ("..");
++    }
++  remove (folder);
++}
++#define CLEANUP_HANDLER do_cleanup
++
++static void
++check_mkdir (const char *path)
++{
++  int r = mkdir (path, 0777);
++  /* Some filesystem such as overlayfs does not support larger path required
++     to trigger the internal buffer reallocation.  */
++  if (r != 0)
++    {
++      if (errno == ENAMETOOLONG)
++	FAIL_UNSUPPORTED ("the filesystem does not support the required"
++			  "large path");
++      else
++	FAIL_EXIT1 ("mkdir (\"%s\", 0%o): %m", folder, 0777);
++    }
++}
++
++static int
++do_test (void)
++{
++  char *tempdir = support_create_temp_directory ("tst-bz28126");
++
++  /* Create path with various subfolders to force an internal buffer
++     reallocation within ntfw.  */
++  char *path = xasprintf ("%s/%s", tempdir, folder);
++  check_mkdir (path);
++  xchdir (path);
++  free (path);
++  for (int i = 0; i < NSUBFOLDERS - 1; i++)
++    {
++      check_mkdir (folder);
++      xchdir (folder);
++      nsubfolders++;
++    }
++
++  TEST_COMPARE (ftw (tempdir, my_func, 20), 0);
++
++  free (tempdir);
++
++  do_cleanup ();
++
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-358.patch b/SOURCES/glibc-upstream-2.34-358.patch
new file mode 100644
index 0000000..fb4f91e
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-358.patch
@@ -0,0 +1,25 @@
+commit deea6ab1bcb2696be514e579f3263c234ecc1683
+Author: Martin Sebor <msebor@redhat.com>
+Date:   Tue Jan 25 17:39:02 2022 -0700
+
+    io: Fix use-after-free in ftw [BZ #26779]
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit ee52ab25ba875f458981fce22c54e3c04c7a17d3)
+
+diff --git a/io/ftw.c b/io/ftw.c
+index cf08d9f101657df0..91a4e8e6de151ca1 100644
+--- a/io/ftw.c
++++ b/io/ftw.c
+@@ -324,8 +324,9 @@ open_dir_stream (int *dfdp, struct ftw_data *data, struct dir_data *dirp)
+ 	  buf[actsize++] = '\0';
+ 
+ 	  /* Shrink the buffer to what we actually need.  */
+-	  data->dirstreams[data->actdir]->content = realloc (buf, actsize);
+-	  if (data->dirstreams[data->actdir]->content == NULL)
++	  void *content = realloc (buf, actsize);
++	  data->dirstreams[data->actdir]->content = content;
++	  if (content == NULL)
+ 	    {
+ 	      int save_err = errno;
+ 	      free (buf);
diff --git a/SOURCES/glibc-upstream-2.34-359.patch b/SOURCES/glibc-upstream-2.34-359.patch
new file mode 100644
index 0000000..25fdf9f
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-359.patch
@@ -0,0 +1,221 @@
+commit d57cdc1b5a52b5468b9259c0b9a215e22a1fa1f6
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Tue Nov 8 14:15:02 2022 +0100
+
+    Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771)
+    
+    Old applications pass __IPC_64 as part of the command argument because
+    old glibc did not check for unknown commands, and passed through the
+    arguments directly to the kernel, without adding __IPC_64.
+    Applications need to continue doing that for old glibc compatibility,
+    so this commit enables this approach in current glibc.
+    
+    For msgctl and shmctl, if no translation is required, make
+    direct system calls, as we did before the time64 changes.  If
+    translation is required, mask __IPC_64 from the command argument.
+    
+    For semctl, the union-in-vararg argument handling means that
+    translation is needed on all architectures.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    (cherry picked from commit 22a46dee24351fd5f4f188ad80554cad79c82524)
+
+diff --git a/sysdeps/unix/sysv/linux/ipc_priv.h b/sysdeps/unix/sysv/linux/ipc_priv.h
+index f9852367a466cea9..d4efb9f3483daa9f 100644
+--- a/sysdeps/unix/sysv/linux/ipc_priv.h
++++ b/sysdeps/unix/sysv/linux/ipc_priv.h
+@@ -63,4 +63,10 @@ struct __old_ipc_perm
+ # define __IPC_TIME64 0
+ #endif
+ 
++#if __IPC_TIME64 || defined __ASSUME_SYSVIPC_BROKEN_MODE_T
++# define IPC_CTL_NEED_TRANSLATION 1
++#else
++# define IPC_CTL_NEED_TRANSLATION 0
++#endif
++
+ #include <ipc_ops.h>
+diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
+index 9f38c06d53936390..ba7b94c22d17bc7f 100644
+--- a/sysdeps/unix/sysv/linux/msgctl.c
++++ b/sysdeps/unix/sysv/linux/msgctl.c
+@@ -86,11 +86,19 @@ msgctl_syscall (int msqid, int cmd, msgctl_arg_t *buf)
+ int
+ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
+ {
+-#if __IPC_TIME64
++#if IPC_CTL_NEED_TRANSLATION
++# if __IPC_TIME64
+   struct kernel_msqid64_ds ksemid, *arg = NULL;
+-#else
++# else
+   msgctl_arg_t *arg;
+-#endif
++# endif
++
++  /* Some applications pass the __IPC_64 flag in cmd, to invoke
++     previously unsupported commands back when there was no EINVAL
++     error checking in glibc.  Mask the flag for the switch statements
++     below.  msgctl_syscall adds back the __IPC_64 flag for the actual
++     system call.  */
++  cmd &= ~__IPC_64;
+ 
+   switch (cmd)
+     {
+@@ -102,19 +110,19 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
+     case IPC_STAT:
+     case MSG_STAT:
+     case MSG_STAT_ANY:
+-#if __IPC_TIME64
++# if __IPC_TIME64
+       if (buf != NULL)
+ 	{
+ 	  msqid64_to_kmsqid64 (buf, &ksemid);
+ 	  arg = &ksemid;
+ 	}
+-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
++#  ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+       if (cmd == IPC_SET)
+ 	arg->msg_perm.mode *= 0x10000U;
+-# endif
+-#else
++#  endif
++# else
+       arg = buf;
+-#endif
++# endif
+       break;
+ 
+     case IPC_INFO:
+@@ -138,21 +146,25 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
+     case IPC_STAT:
+     case MSG_STAT:
+     case MSG_STAT_ANY:
+-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+       arg->msg_perm.mode >>= 16;
+-#else
++# else
+       /* Old Linux kernel versions might not clear the mode padding.  */
+       if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
+           != sizeof (__kernel_mode_t))
+ 	arg->msg_perm.mode &= 0xFFFF;
+-#endif
++# endif
+ 
+-#if __IPC_TIME64
++# if __IPC_TIME64
+       kmsqid64_to_msqid64 (arg, buf);
+-#endif
++# endif
+     }
+ 
+   return ret;
++
++#else /* !IPC_CTL_NEED_TRANSLATION */
++  return msgctl_syscall (msqid, cmd, buf);
++#endif
+ }
+ #if __TIMESIZE != 64
+ libc_hidden_def (__msgctl64)
+diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
+index bb2690d30f80bb22..97fa411547fdd81e 100644
+--- a/sysdeps/unix/sysv/linux/semctl.c
++++ b/sysdeps/unix/sysv/linux/semctl.c
+@@ -141,6 +141,13 @@ __semctl64 (int semid, int semnum, int cmd, ...)
+   union semun64 arg64 = { 0 };
+   va_list ap;
+ 
++  /* Some applications pass the __IPC_64 flag in cmd, to invoke
++     previously unsupported commands back when there was no EINVAL
++     error checking in glibc.  Mask the flag for the switch statements
++     below.  semctl_syscall adds back the __IPC_64 flag for the actual
++     system call.  */
++  cmd &= ~__IPC_64;
++
+   /* Get the argument only if required.  */
+   switch (cmd)
+     {
+diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
+index f52018bfae4b3364..c44cbd6e4ac890a5 100644
+--- a/sysdeps/unix/sysv/linux/shmctl.c
++++ b/sysdeps/unix/sysv/linux/shmctl.c
+@@ -86,11 +86,19 @@ shmctl_syscall (int shmid, int cmd, shmctl_arg_t *buf)
+ int
+ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
+ {
+-#if __IPC_TIME64
++#if IPC_CTL_NEED_TRANSLATION
++# if __IPC_TIME64
+   struct kernel_shmid64_ds kshmid, *arg = NULL;
+-#else
++# else
+   shmctl_arg_t *arg;
+-#endif
++# endif
++
++  /* Some applications pass the __IPC_64 flag in cmd, to invoke
++     previously unsupported commands back when there was no EINVAL
++     error checking in glibc.  Mask the flag for the switch statements
++     below.  shmctl_syscall adds back the __IPC_64 flag for the actual
++     system call.  */
++  cmd &= ~__IPC_64;
+ 
+   switch (cmd)
+     {
+@@ -104,19 +112,19 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
+     case IPC_STAT:
+     case SHM_STAT:
+     case SHM_STAT_ANY:
+-#if __IPC_TIME64
++# if __IPC_TIME64
+       if (buf != NULL)
+ 	{
+ 	  shmid64_to_kshmid64 (buf, &kshmid);
+ 	  arg = &kshmid;
+ 	}
+-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
++#  ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+       if (cmd == IPC_SET)
+         arg->shm_perm.mode *= 0x10000U;
+-# endif
+-#else
++#  endif
++# else
+       arg = buf;
+-#endif
++# endif
+       break;
+ 
+     case IPC_INFO:
+@@ -141,21 +149,25 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
+       case IPC_STAT:
+       case SHM_STAT:
+       case SHM_STAT_ANY:
+-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+         arg->shm_perm.mode >>= 16;
+-#else
++# else
+       /* Old Linux kernel versions might not clear the mode padding.  */
+       if (sizeof ((struct shmid_ds){0}.shm_perm.mode)
+ 	  != sizeof (__kernel_mode_t))
+ 	arg->shm_perm.mode &= 0xFFFF;
+-#endif
++# endif
+ 
+-#if __IPC_TIME64
++# if __IPC_TIME64
+       kshmid64_to_shmid64 (arg, buf);
+-#endif
++# endif
+     }
+ 
+   return ret;
++
++#else /* !IPC_CTL_NEED_TRANSLATION */
++  return shmctl_syscall (shmid, cmd, buf);
++#endif
+ }
+ #if __TIMESIZE != 64
+ libc_hidden_def (__shmctl64)
diff --git a/SOURCES/glibc-upstream-2.34-361.patch b/SOURCES/glibc-upstream-2.34-361.patch
new file mode 100644
index 0000000..b6b86ca
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-361.patch
@@ -0,0 +1,46 @@
+commit 691f70b84a1284f35c8cf9fbf3ef3b1cec41c234
+Author: Vladislav Khmelevsky <och95@yandex.ru>
+Date:   Thu Nov 17 12:47:29 2022 +0400
+
+    elf: Fix rtld-audit trampoline for aarch64
+    
+    This patch fixes two problems with audit:
+    
+      1. The DL_OFFSET_RV_VPCS offset was mixed up with DL_OFFSET_RG_VPCS,
+         resulting in x2 register value nulling in RG structure.
+    
+      2. We need to preserve the x8 register before function call, but
+         don't have to save it's new value and restore it before return.
+    
+    Anyway the final restore was using OFFSET_RV instead of OFFSET_RG value
+    which is wrong (althoug doesn't affect anything).
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    (cherry picked from commit eb4181e9f4a512de37dad4ba623c921671584dea)
+
+diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
+index 457570e7df5148c0..b84c53d1a544c1b1 100644
+--- a/sysdeps/aarch64/dl-trampoline.S
++++ b/sysdeps/aarch64/dl-trampoline.S
+@@ -298,12 +298,11 @@ _dl_runtime_profile:
+ 	stp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
+ 	stp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
+ 	stp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
+-	str	x8,     [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
+ 	stp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
+ 	stp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
+ 	stp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
+ 	stp	q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]
+-	str	xzr,    [X29, #OFFSET_RV + DL_OFFSET_RG_VPCS]
++	str	xzr,    [X29, #OFFSET_RV + DL_OFFSET_RV_VPCS]
+ 
+ 	/* Setup call to pltexit  */
+ 	ldp	x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
+@@ -315,7 +314,6 @@ _dl_runtime_profile:
+ 	ldp	x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
+ 	ldp	x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
+ 	ldp	x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
+-	ldr	x8,     [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4]
+ 	ldp	q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
+ 	ldp	q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
+ 	ldp	q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
diff --git a/SOURCES/glibc-upstream-2.34-362.patch b/SOURCES/glibc-upstream-2.34-362.patch
new file mode 100644
index 0000000..d7b4767
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-362.patch
@@ -0,0 +1,128 @@
+commit e3255e7d2188d1731aad83ad0dc147513560aa1e
+Author: Noah Goldstein <goldstein.w.n@gmail.com>
+Date:   Tue Sep 20 17:58:04 2022 -0700
+
+    x86: Fix wcsnlen-avx2 page cross length comparison [BZ #29591]
+    
+    Previous implementation was adjusting length (rsi) to match
+    bytes (eax), but since there is no bound to length this can cause
+    overflow.
+    
+    Fix is to just convert the byte-count (eax) to length by dividing by
+    sizeof (wchar_t) before the comparison.
+    
+    Full check passes on x86-64 and build succeeds w/ and w/o multiarch.
+    
+    (cherry picked from commit b0969fa53a28b4ab2159806bf6c99a98999502ee)
+
+diff --git a/string/test-strnlen.c b/string/test-strnlen.c
+index bb5d9b5f04fa6586..eac84cd17526d5d9 100644
+--- a/string/test-strnlen.c
++++ b/string/test-strnlen.c
+@@ -75,7 +75,7 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char)
+ {
+   size_t i;
+ 
+-  align &= 63;
++  align &= (getpagesize () / sizeof (CHAR) - 1);
+   if ((align + len) * sizeof (CHAR) >= page_size)
+     return;
+ 
+@@ -92,36 +92,50 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char)
+ static void
+ do_overflow_tests (void)
+ {
+-  size_t i, j, len;
++  size_t i, j, al_idx, repeats, len;
+   const size_t one = 1;
+   uintptr_t buf_addr = (uintptr_t) buf1;
++  const size_t alignments[] = { 0, 1, 7, 9, 31, 33, 63, 65, 95, 97, 127, 129 };
+ 
+-  for (i = 0; i < 750; ++i)
++  for (al_idx = 0; al_idx < sizeof (alignments) / sizeof (alignments[0]);
++       al_idx++)
+     {
+-      do_test (0, i, SIZE_MAX - i, BIG_CHAR);
+-      do_test (0, i, i - buf_addr, BIG_CHAR);
+-      do_test (0, i, -buf_addr - i, BIG_CHAR);
+-      do_test (0, i, SIZE_MAX - buf_addr - i, BIG_CHAR);
+-      do_test (0, i, SIZE_MAX - buf_addr + i, BIG_CHAR);
+-
+-      len = 0;
+-      for (j = 8 * sizeof(size_t) - 1; j ; --j)
+-        {
+-          len |= one << j;
+-          do_test (0, i, len - i, BIG_CHAR);
+-          do_test (0, i, len + i, BIG_CHAR);
+-          do_test (0, i, len - buf_addr - i, BIG_CHAR);
+-          do_test (0, i, len - buf_addr + i, BIG_CHAR);
+-
+-          do_test (0, i, ~len - i, BIG_CHAR);
+-          do_test (0, i, ~len + i, BIG_CHAR);
+-          do_test (0, i, ~len - buf_addr - i, BIG_CHAR);
+-          do_test (0, i, ~len - buf_addr + i, BIG_CHAR);
+-
+-          do_test (0, i, -buf_addr, BIG_CHAR);
+-          do_test (0, i, j - buf_addr, BIG_CHAR);
+-          do_test (0, i, -buf_addr - j, BIG_CHAR);
+-        }
++      for (repeats = 0; repeats < 2; ++repeats)
++	{
++	  size_t align = repeats ? (getpagesize () - alignments[al_idx])
++				 : alignments[al_idx];
++	  align /= sizeof (CHAR);
++	  for (i = 0; i < 750; ++i)
++	    {
++	      do_test (align, i, SIZE_MAX, BIG_CHAR);
++
++	      do_test (align, i, SIZE_MAX - i, BIG_CHAR);
++	      do_test (align, i, i - buf_addr, BIG_CHAR);
++	      do_test (align, i, -buf_addr - i, BIG_CHAR);
++	      do_test (align, i, SIZE_MAX - buf_addr - i, BIG_CHAR);
++	      do_test (align, i, SIZE_MAX - buf_addr + i, BIG_CHAR);
++
++	      len = 0;
++	      for (j = 8 * sizeof (size_t) - 1; j; --j)
++		{
++		  len |= one << j;
++		  do_test (align, i, len, BIG_CHAR);
++		  do_test (align, i, len - i, BIG_CHAR);
++		  do_test (align, i, len + i, BIG_CHAR);
++		  do_test (align, i, len - buf_addr - i, BIG_CHAR);
++		  do_test (align, i, len - buf_addr + i, BIG_CHAR);
++
++		  do_test (align, i, ~len - i, BIG_CHAR);
++		  do_test (align, i, ~len + i, BIG_CHAR);
++		  do_test (align, i, ~len - buf_addr - i, BIG_CHAR);
++		  do_test (align, i, ~len - buf_addr + i, BIG_CHAR);
++
++		  do_test (align, i, -buf_addr, BIG_CHAR);
++		  do_test (align, i, j - buf_addr, BIG_CHAR);
++		  do_test (align, i, -buf_addr - j, BIG_CHAR);
++		}
++	    }
++	}
+     }
+ }
+ 
+diff --git a/sysdeps/x86_64/multiarch/strlen-avx2.S b/sysdeps/x86_64/multiarch/strlen-avx2.S
+index b282a75613bf52ab..4d7d68396bcd4049 100644
+--- a/sysdeps/x86_64/multiarch/strlen-avx2.S
++++ b/sysdeps/x86_64/multiarch/strlen-avx2.S
+@@ -542,14 +542,11 @@ L(return_vzeroupper):
+ L(cross_page_less_vec):
+ 	tzcntl	%eax, %eax
+ #  ifdef USE_AS_WCSLEN
+-	/* NB: Multiply length by 4 to get byte count.  */
+-	sall	$2, %esi
++	/* NB: Divide by 4 to convert from byte-count to length.  */
++	shrl	$2, %eax
+ #  endif
+ 	cmpq	%rax, %rsi
+ 	cmovb	%esi, %eax
+-#  ifdef USE_AS_WCSLEN
+-	shrl	$2, %eax
+-#  endif
+ 	VZEROUPPER_RETURN
+ # endif
+ 
diff --git a/SOURCES/glibc-upstream-2.34-363.patch b/SOURCES/glibc-upstream-2.34-363.patch
new file mode 100644
index 0000000..4428f12
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-363.patch
@@ -0,0 +1,26 @@
+commit 309c4708aca762f57263a66e5bea926fdbfd82eb
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Fri Mar 25 11:16:49 2022 -0300
+
+    elf: Fix wrong fscanf usage on tst-pldd
+    
+    To take in consideration the extra '\0'.
+    
+    Checked on x86_64-linux-gnu.
+    
+    (cherry picked from commit b2cd93fce666fdc8c9a5c64af2741a8a6940ac99)
+
+diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c
+index 210ca4d24b8338ab..72b7a99b369a105d 100644
+--- a/elf/tst-pldd.c
++++ b/elf/tst-pldd.c
+@@ -113,7 +113,8 @@ do_test (void)
+     TEST_VERIFY (out != NULL);
+ 
+     /* First line is in the form of <pid>: <full path of executable>  */
+-    TEST_COMPARE (fscanf (out, "%u: " STRINPUT (512), &pid, buffer), 2);
++    TEST_COMPARE (fscanf (out, "%u: " STRINPUT (sizeof (buffer) - 1), &pid,
++			  buffer), 2);
+ 
+     TEST_COMPARE (pid, *target_pid_ptr);
+     TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0);
diff --git a/SOURCES/glibc-upstream-2.34-364.patch b/SOURCES/glibc-upstream-2.34-364.patch
new file mode 100644
index 0000000..cf76f9b
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-364.patch
@@ -0,0 +1,362 @@
+commit 42b9d7def8fd7d26f1926cbc801923aa2c8a386a
+Author: DJ Delorie <dj@redhat.com>
+Date:   Mon Mar 28 23:53:33 2022 -0400
+
+    Allow for unpriviledged nested containers
+    
+    If the build itself is run in a container, we may not be able to
+    fully set up a nested container for test-container testing.
+    Notably is the mounting of /proc, since it's critical that it
+    be mounted from within the same PID namespace as its users, and
+    thus cannot be bind mounted from outside the container like other
+    mounts.
+    
+    This patch defaults to using the parent's PID namespace instead of
+    creating a new one, as this is more likely to be allowed.
+    
+    If the test needs an isolated PID namespace, it should add the "pidns"
+    command to its init script.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 2fe64148a81f0d78050c302f34a6853d21f7cae4)
+
+diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c
+index 72b7a99b369a105d..6e4174cbf95b15c0 100644
+--- a/elf/tst-pldd.c
++++ b/elf/tst-pldd.c
+@@ -85,6 +85,8 @@ in_str_list (const char *libname, const char *const strlist[])
+ static int
+ do_test (void)
+ {
++  support_need_proc ("needs /proc/sys/kernel/yama/ptrace_scope and /proc/$child");
++
+   /* Check if our subprocess can be debugged with ptrace.  */
+   {
+     int ptrace_scope = support_ptrace_scope ();
+diff --git a/nptl/tst-pthread-getattr.c b/nptl/tst-pthread-getattr.c
+index 5f60cf9722b77a1a..6128402b2673c010 100644
+--- a/nptl/tst-pthread-getattr.c
++++ b/nptl/tst-pthread-getattr.c
+@@ -28,6 +28,8 @@
+ #include <unistd.h>
+ #include <inttypes.h>
+ 
++#include <support/support.h>
++
+ /* There is an obscure bug in the kernel due to which RLIMIT_STACK is sometimes
+    returned as unlimited when it is not, which may cause this test to fail.
+    There is also the other case where RLIMIT_STACK is intentionally set as
+@@ -153,6 +155,8 @@ check_stack_top (void)
+ static int
+ do_test (void)
+ {
++  support_need_proc ("Reads /proc/self/maps to get stack size.");
++
+   pagesize = sysconf (_SC_PAGESIZE);
+   return check_stack_top ();
+ }
+diff --git a/nss/tst-reload2.c b/nss/tst-reload2.c
+index 5ecb032e9fcd6868..a494145dd679099d 100644
+--- a/nss/tst-reload2.c
++++ b/nss/tst-reload2.c
+@@ -95,6 +95,8 @@ do_test (void)
+   char buf1[PATH_MAX];
+   char buf2[PATH_MAX];
+ 
++  support_need_proc ("Our xmkdirp fails if we can't map our uid, which requires /proc.");
++
+   sprintf (buf1, "/subdir%s", support_slibdir_prefix);
+   xmkdirp (buf1, 0777);
+ 
+diff --git a/support/Makefile b/support/Makefile
+index 6a5fc9faf2ca2e2d..0aa9d41c5a890087 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -63,6 +63,7 @@ libsupport-routines = \
+   support_format_hostent \
+   support_format_netent \
+   support_isolate_in_subprocess \
++  support_need_proc \
+   support_path_support_time64 \
+   support_process_state \
+   support_ptrace \
+diff --git a/support/support.h b/support/support.h
+index ecfc9a336d272a30..b69f588e2edce6be 100644
+--- a/support/support.h
++++ b/support/support.h
+@@ -90,6 +90,11 @@ char *support_quote_string (const char *);
+    regular file open for writing, and initially empty.  */
+ int support_descriptor_supports_holes (int fd);
+ 
++/* Predicates that a test requires a working /proc filesystem.  This
++   call will exit with UNSUPPORTED if /proc is not available, printing
++   WHY_MSG as part of the diagnostic.  */
++void support_need_proc (const char *why_msg);
++
+ /* Error-checking wrapper functions which terminate the process on
+    error.  */
+ 
+diff --git a/support/support_need_proc.c b/support/support_need_proc.c
+new file mode 100644
+index 0000000000000000..9b4eab7539b2d6c3
+--- /dev/null
++++ b/support/support_need_proc.c
+@@ -0,0 +1,35 @@
++/* Indicate that a test requires a working /proc.
++   Copyright (C) 2022 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 <unistd.h>
++#include <support/check.h>
++#include <support/support.h>
++
++/* We test for /proc/self/maps since that's one of the files that one
++   of our tests actually uses, but the general idea is if Linux's
++   /proc/ (procfs) filesystem is mounted.  If not, the process exits
++   with an UNSUPPORTED result code.  */
++
++void
++support_need_proc (const char *why_msg)
++{
++#ifdef __linux__
++  if (access ("/proc/self/maps", R_OK))
++    FAIL_UNSUPPORTED ("/proc is not available, %s", why_msg);
++#endif
++}
+diff --git a/support/test-container.c b/support/test-container.c
+index 94498d39019a4776..7310335f7566b41e 100644
+--- a/support/test-container.c
++++ b/support/test-container.c
+@@ -97,6 +97,7 @@ int verbose = 0;
+    * mytest.root/mytest.script has a list of "commands" to run:
+        syntax:
+          # comment
++	 pidns <comment>
+          su
+          mv FILE FILE
+ 	 cp FILE FILE
+@@ -122,6 +123,8 @@ int verbose = 0;
+ 
+        details:
+          - '#': A comment.
++	 - 'pidns': Require a separate PID namespace, prints comment if it can't
++	    (default is a shared pid namespace)
+          - 'su': Enables running test as root in the container.
+          - 'mv': A minimal move files command.
+          - 'cp': A minimal copy files command.
+@@ -148,7 +151,7 @@ int verbose = 0;
+    * Simple, easy to review code (i.e. prefer simple naive code over
+      complex efficient code)
+ 
+-   * The current implementation ist parallel-make-safe, but only in
++   * The current implementation is parallel-make-safe, but only in
+      that it uses a lock to prevent parallel access to the testroot.  */
+ 
+ 
+@@ -227,11 +230,37 @@ concat (const char *str, ...)
+   return bufs[n];
+ }
+ 
++/* Like the above, but put spaces between words.  Caller frees.  */
++static char *
++concat_words (char **words, int num_words)
++{
++  int len = 0;
++  int i;
++  char *rv, *p;
++
++  for (i = 0; i < num_words; i ++)
++    {
++      len += strlen (words[i]);
++      len ++;
++    }
++
++  p = rv = (char *) xmalloc (len);
++
++  for (i = 0; i < num_words; i ++)
++    {
++      if (i > 0)
++	p = stpcpy (p, " ");
++      p = stpcpy (p, words[i]);
++    }
++
++  return rv;
++}
++
+ /* Try to mount SRC onto DEST.  */
+ static void
+ trymount (const char *src, const char *dest)
+ {
+-  if (mount (src, dest, "", MS_BIND, NULL) < 0)
++  if (mount (src, dest, "", MS_BIND | MS_REC, NULL) < 0)
+     FAIL_EXIT1 ("can't mount %s onto %s\n", src, dest);
+ }
+ 
+@@ -726,6 +755,9 @@ main (int argc, char **argv)
+   gid_t original_gid;
+   /* If set, the test runs as root instead of the user running the testsuite.  */
+   int be_su = 0;
++  int require_pidns = 0;
++  const char *pidns_comment = NULL;
++  int do_proc_mounts = 0;
+   int UMAP;
+   int GMAP;
+   /* Used for "%lld %lld 1" so need not be large.  */
+@@ -1011,6 +1043,12 @@ main (int argc, char **argv)
+ 	      {
+ 		be_su = 1;
+ 	      }
++	    else if (nt >= 1 && strcmp (the_words[0], "pidns") == 0)
++	      {
++		require_pidns = 1;
++		if (nt > 1)
++		  pidns_comment = concat_words (the_words + 1, nt - 1);
++	      }
+ 	    else if (nt == 3 && strcmp (the_words[0], "mkdirp") == 0)
+ 	      {
+ 		long int m;
+@@ -1068,7 +1106,8 @@ main (int argc, char **argv)
+ 
+ #ifdef CLONE_NEWNS
+   /* The unshare here gives us our own spaces and capabilities.  */
+-  if (unshare (CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS) < 0)
++  if (unshare (CLONE_NEWUSER | CLONE_NEWNS
++	       | (require_pidns ? CLONE_NEWPID : 0)) < 0)
+     {
+       /* Older kernels may not support all the options, or security
+ 	 policy may block this call.  */
+@@ -1079,6 +1118,11 @@ main (int argc, char **argv)
+ 	    check_for_unshare_hints ();
+ 	  FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (saved_errno));
+ 	}
++      /* We're about to exit anyway, it's "safe" to call unshare again
++	 just to see if the CLONE_NEWPID caused the error.  */
++      else if (require_pidns && unshare (CLONE_NEWUSER | CLONE_NEWNS) >= 0)
++	FAIL_EXIT1 ("unable to unshare pid ns: %s : %s", strerror (errno),
++		    pidns_comment ? pidns_comment : "required by test");
+       else
+ 	FAIL_EXIT1 ("unable to unshare user/fs: %s", strerror (errno));
+     }
+@@ -1094,6 +1138,15 @@ main (int argc, char **argv)
+   trymount (support_srcdir_root, new_srcdir_path);
+   trymount (support_objdir_root, new_objdir_path);
+ 
++  /* It may not be possible to mount /proc directly.  */
++  if (! require_pidns)
++  {
++    char *new_proc = concat (new_root_path, "/proc", NULL);
++    xmkdirp (new_proc, 0755);
++    trymount ("/proc", new_proc);
++    do_proc_mounts = 1;
++  }
++
+   xmkdirp (concat (new_root_path, "/dev", NULL), 0755);
+   devmount (new_root_path, "null");
+   devmount (new_root_path, "zero");
+@@ -1163,42 +1216,60 @@ main (int argc, char **argv)
+ 
+   maybe_xmkdir ("/tmp", 0755);
+ 
+-  /* Now that we're pid 1 (effectively "root") we can mount /proc  */
+-  maybe_xmkdir ("/proc", 0777);
+-  if (mount ("proc", "/proc", "proc", 0, NULL) < 0)
+-    FAIL_EXIT1 ("Unable to mount /proc: ");
+-
+-  /* We map our original UID to the same UID in the container so we
+-     can own our own files normally.  */
+-  UMAP = open ("/proc/self/uid_map", O_WRONLY);
+-  if (UMAP < 0)
+-    FAIL_EXIT1 ("can't write to /proc/self/uid_map\n");
+-
+-  sprintf (tmp, "%lld %lld 1\n",
+-	   (long long) (be_su ? 0 : original_uid), (long long) original_uid);
+-  write (UMAP, tmp, strlen (tmp));
+-  xclose (UMAP);
+-
+-  /* We must disable setgroups () before we can map our groups, else we
+-     get EPERM.  */
+-  GMAP = open ("/proc/self/setgroups", O_WRONLY);
+-  if (GMAP >= 0)
++  if (require_pidns)
+     {
+-      /* We support kernels old enough to not have this.  */
+-      write (GMAP, "deny\n", 5);
+-      xclose (GMAP);
++      /* Now that we're pid 1 (effectively "root") we can mount /proc  */
++      maybe_xmkdir ("/proc", 0777);
++      if (mount ("proc", "/proc", "proc", 0, NULL) != 0)
++	{
++	  /* This happens if we're trying to create a nested container,
++	     like if the build is running under podman, and we lack
++	     priviledges.
++
++	     Ideally we would WARN here, but that would just add noise to
++	     *every* test-container test, and the ones that care should
++	     have their own relevent diagnostics.
++
++	     FAIL_EXIT1 ("Unable to mount /proc: ");  */
++	}
++      else
++	do_proc_mounts = 1;
+     }
+ 
+-  /* We map our original GID to the same GID in the container so we
+-     can own our own files normally.  */
+-  GMAP = open ("/proc/self/gid_map", O_WRONLY);
+-  if (GMAP < 0)
+-    FAIL_EXIT1 ("can't write to /proc/self/gid_map\n");
++  if (do_proc_mounts)
++    {
++      /* We map our original UID to the same UID in the container so we
++	 can own our own files normally.  */
++      UMAP = open ("/proc/self/uid_map", O_WRONLY);
++      if (UMAP < 0)
++	FAIL_EXIT1 ("can't write to /proc/self/uid_map\n");
++
++      sprintf (tmp, "%lld %lld 1\n",
++	       (long long) (be_su ? 0 : original_uid), (long long) original_uid);
++      write (UMAP, tmp, strlen (tmp));
++      xclose (UMAP);
++
++      /* We must disable setgroups () before we can map our groups, else we
++	 get EPERM.  */
++      GMAP = open ("/proc/self/setgroups", O_WRONLY);
++      if (GMAP >= 0)
++	{
++	  /* We support kernels old enough to not have this.  */
++	  write (GMAP, "deny\n", 5);
++	  xclose (GMAP);
++	}
+ 
+-  sprintf (tmp, "%lld %lld 1\n",
+-	   (long long) (be_su ? 0 : original_gid), (long long) original_gid);
+-  write (GMAP, tmp, strlen (tmp));
+-  xclose (GMAP);
++      /* We map our original GID to the same GID in the container so we
++	 can own our own files normally.  */
++      GMAP = open ("/proc/self/gid_map", O_WRONLY);
++      if (GMAP < 0)
++	FAIL_EXIT1 ("can't write to /proc/self/gid_map\n");
++
++      sprintf (tmp, "%lld %lld 1\n",
++	       (long long) (be_su ? 0 : original_gid), (long long) original_gid);
++      write (GMAP, tmp, strlen (tmp));
++      xclose (GMAP);
++    }
+ 
+   if (change_cwd)
+     {
diff --git a/SOURCES/glibc-upstream-2.34-365.patch b/SOURCES/glibc-upstream-2.34-365.patch
new file mode 100644
index 0000000..1fd3d7c
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-365.patch
@@ -0,0 +1,39 @@
+commit 405b8ae13540e9fd614df614e3361ebf9abd14cf
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Tue Jul 5 12:58:40 2022 -0300
+
+    elf: Fix wrong fscanf usage on tst-pldd
+    
+    The fix done b2cd93fce666fdc8c9a5c64af2741a8a6940ac99 does not really
+    work since macro strification does not expand the sizeof nor the
+    arithmetic operation.
+    
+    Checked on x86_64-linux-gnu.
+    
+    (cherry picked from commit c353689e49e72f3aafa1a9e68d4f7a4f33a79cbe)
+
+diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c
+index 6e4174cbf95b15c0..d3ecb99149d619c6 100644
+--- a/elf/tst-pldd.c
++++ b/elf/tst-pldd.c
+@@ -108,15 +108,16 @@ do_test (void)
+      loader and libc.  */
+   {
+     pid_t pid;
+-    char buffer[512];
+-#define STRINPUT(size) "%" # size "s"
++#define BUFFERLEN 511
++    char buffer[BUFFERLEN + 1];
++#define STRINPUT(size)  XSTRINPUT(size)
++#define XSTRINPUT(size) "%" # size "s"
+ 
+     FILE *out = fmemopen (pldd.out.buffer, pldd.out.length, "r");
+     TEST_VERIFY (out != NULL);
+ 
+     /* First line is in the form of <pid>: <full path of executable>  */
+-    TEST_COMPARE (fscanf (out, "%u: " STRINPUT (sizeof (buffer) - 1), &pid,
+-			  buffer), 2);
++    TEST_COMPARE (fscanf (out, "%u: " STRINPUT (BUFFERLEN), &pid, buffer), 2);
+ 
+     TEST_COMPARE (pid, *target_pid_ptr);
+     TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0);
diff --git a/SOURCES/glibc-upstream-2.34-366.patch b/SOURCES/glibc-upstream-2.34-366.patch
new file mode 100644
index 0000000..dec7dc4
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-366.patch
@@ -0,0 +1,29 @@
+commit a1c12fdf3f9b8665719835ce8330b3b2e2574b37
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Fri Sep 10 13:18:36 2021 +0200
+
+    _Static_assert needs two arguments for compatibility with GCC before 9
+    
+    This macro definition enforces two arguments even with newer compilers
+    that accept the single-argument form, too.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit c9fef4b7d1d0f2dad192c74f06102752247677a9)
+
+diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h
+index 6a76160ed4e4cabb..56adb231aa8f8cbe 100644
+--- a/include/sys/cdefs.h
++++ b/include/sys/cdefs.h
+@@ -1,5 +1,12 @@
+ #ifndef _SYS_CDEFS_H
+ 
++/* This is outside of _ISOMAC to enforce that _Static_assert always
++   uses the two-argument form.  This can be removed once the minimum
++   GCC version used to compile glibc is GCC 9.1.  */
++#ifndef __cplusplus
++# define _Static_assert(expr, diagnostic) _Static_assert (expr, diagnostic)
++#endif
++
+ #include <misc/sys/cdefs.h>
+ 
+ #ifndef _ISOMAC
diff --git a/SOURCES/glibc-upstream-2.34-367.patch b/SOURCES/glibc-upstream-2.34-367.patch
new file mode 100644
index 0000000..7df9998
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-367.patch
@@ -0,0 +1,72 @@
+commit a4217408a3d6050a7f42ac23adb6ac7218dca85f
+Author: Tulio Magno Quites Machado Filho <tuliom@redhat.com>
+Date:   Fri Nov 11 17:00:15 2022 -0300
+
+    Apply asm redirections in syslog.h before first use [BZ #27087]
+    
+    Similar to d0fa09a770, but for syslog.h when _FORTIFY_SOURCE > 0.
+    Fixes [BZ #27087] by applying long double-related asm redirections
+    before using functions in bits/syslog.h.
+    
+    Tested with build-many-glibcs.py.
+    
+    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+    (cherry picked from commit 227df6243a2b5b4d70d11772d12c02eb9cb666ca)
+
+diff --git a/misc/bits/syslog.h b/misc/bits/syslog.h
+index 6f3137a98ee593f3..10c9c1151382a51c 100644
+--- a/misc/bits/syslog.h
++++ b/misc/bits/syslog.h
+@@ -24,6 +24,20 @@
+ extern void __syslog_chk (int __pri, int __flag, const char *__fmt, ...)
+      __attribute__ ((__format__ (__printf__, 3, 4)));
+ 
++#ifdef __USE_MISC
++extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt,
++			   __gnuc_va_list __ap)
++     __attribute__ ((__format__ (__printf__, 3, 0)));
++#endif
++
++#include <bits/floatn.h>
++#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
++# include <bits/syslog-ldbl.h>
++#endif
++
++/* The following functions must be used only after applying all asm
++   redirections, e.g. long double asm redirections.  */
++
+ #ifdef __va_arg_pack
+ __fortify_function void
+ syslog (int __pri, const char *__fmt, ...)
+@@ -37,10 +51,6 @@ syslog (int __pri, const char *__fmt, ...)
+ 
+ 
+ #ifdef __USE_MISC
+-extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt,
+-			   __gnuc_va_list __ap)
+-     __attribute__ ((__format__ (__printf__, 3, 0)));
+-
+ __fortify_function void
+ vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
+ {
+diff --git a/misc/sys/syslog.h b/misc/sys/syslog.h
+index dc3b0e7ef81de812..e7a98fb9b13ce132 100644
+--- a/misc/sys/syslog.h
++++ b/misc/sys/syslog.h
+@@ -205,11 +205,11 @@ extern void vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
+ /* Define some macros helping to catch buffer overflows.  */
+ #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
+ # include <bits/syslog.h>
+-#endif
+-
+-#include <bits/floatn.h>
+-#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
+-# include <bits/syslog-ldbl.h>
++#else
++# include <bits/floatn.h>
++# if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
++#  include <bits/syslog-ldbl.h>
++# endif
+ #endif
+ 
+ __END_DECLS
diff --git a/SOURCES/glibc-upstream-2.34-368.patch b/SOURCES/glibc-upstream-2.34-368.patch
new file mode 100644
index 0000000..3f61281
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-368.patch
@@ -0,0 +1,241 @@
+commit 42eb735a5d3458a24a44ace9eca87c8b61573d97
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Thu May 20 14:20:18 2021 -0300
+
+    Use LFS and 64 bit time for installed programs (BZ #15333)
+    
+    The installed programs are built with a combination of different
+    values for MODULE_NAME, as below.  To enable both Long File Support
+    and 64 bt time, -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 is added for
+    nonlibi, nscd, lddlibc4, libresolv, ldconfig, locale_programs,
+    iconvprogs, libnss_files, libnss_compat, libnss_db, libnss_hesiod,
+    libutil, libpcprofile, and libSegFault.
+    
+      nscd/nscd
+        nscd/nscd.o                           MODULE_NAME=nscd
+        nscd/connections.o                    MODULE_NAME=nscd
+        nscd/pwdcache.o                       MODULE_NAME=nscd
+        nscd/getpwnam_r.o                     MODULE_NAME=nscd
+        nscd/getpwuid_r.o                     MODULE_NAME=nscd
+        nscd/grpcache.o                       MODULE_NAME=nscd
+        nscd/getgrnam_r.o                     MODULE_NAME=nscd
+        nscd/getgrgid_r.o                     MODULE_NAME=nscd
+        nscd/hstcache.o                       MODULE_NAME=nscd
+        nscd/gethstbyad_r.o                   MODULE_NAME=nscd
+        nscd/gethstbynm3_r.o                  MODULE_NAME=nscd
+        nscd/getsrvbynm_r.o                   MODULE_NAME=nscd
+        nscd/getsrvbypt_r.o                   MODULE_NAME=nscd
+        nscd/servicescache.o                  MODULE_NAME=nscd
+        nscd/dbg_log.o                        MODULE_NAME=nscd
+        nscd/nscd_conf.o                      MODULE_NAME=nscd
+        nscd/nscd_stat.o                      MODULE_NAME=nscd
+        nscd/cache.o                          MODULE_NAME=nscd
+        nscd/mem.o                            MODULE_NAME=nscd
+        nscd/nscd_setup_thread.o              MODULE_NAME=nscd
+        nscd/xmalloc.o                        MODULE_NAME=nscd
+        nscd/xstrdup.o                        MODULE_NAME=nscd
+        nscd/aicache.o                        MODULE_NAME=nscd
+        nscd/initgrcache.o                    MODULE_NAME=nscd
+        nscd/gai.o                            MODULE_NAME=nscd
+        nscd/res_hconf.o                      MODULE_NAME=nscd
+        nscd/netgroupcache.o                  MODULE_NAME=nscd
+        nscd/cachedumper.o                    MODULE_NAME=nscd
+      elf/lddlibc4
+        elf/lddlibc4                          MODULE_NAME=lddlibc4
+      elf/pldd
+        elf/pldd.o                            MODULE_NAME=nonlib
+        elf/xmalloc.o                         MODULE_NAME=nonlib
+      elf/sln
+        elf/sln.o                             MODULE_NAME=nonlib
+        elf/static-stubs.o                    MODULE_NAME=nonlib
+      elf/sprof                               MODULE_NAME=nonlib
+      elf/ldconfig
+        elf/ldconfig.o                        MODULE_NAME=ldconfig
+        elf/cache.o                           MODULE_NAME=nonlib
+        elf/readlib.o                         MODULE_NAME=nonlib
+        elf/xmalloc.o                         MODULE_NAME=nonlib
+        elf/xstrdup.o                         MODULE_NAME=nonlib
+        elf/chroot_canon.o                    MODULE_NAME=nonlib
+        elf/static-stubs.o                    MODULE_NAME=nonlib
+        elf/stringtable.o                     MODULE_NAME=nonlib
+      io/pwd
+        io/pwd.o                              MODULE_NAME=nonlib
+      locale/locale
+        locale/locale.o                       MODULE_NAME=locale_programs
+        locale/locale-spec.o                  MODULE_NAME=locale_programs
+        locale/charmap-dir.o                  MODULE_NAME=locale_programs
+        locale/simple-hash.o                  MODULE_NAME=locale_programs
+        locale/xmalloc.o                      MODULE_NAME=locale_programs
+        locale/xstrdup.o                      MODULE_NAME=locale_programs
+        locale/record-status.o                MODULE_NAME=locale_programs
+        locale/xasprintf.o                    MODULE_NAME=locale_programs
+      locale/localedef
+        locale/localedef.o                    MODULE_NAME=locale_programs
+        locale/ld-ctype.o                     MODULE_NAME=locale_programs
+        locale/ld-messages.o                  MODULE_NAME=locale_programs
+        locale/ld-monetary.o                  MODULE_NAME=locale_programs
+        locale/ld-numeric.o                   MODULE_NAME=locale_programs
+        locale/ld-time.o                      MODULE_NAME=locale_programs
+        locale/ld-paper.o                     MODULE_NAME=locale_programs
+        locale/ld-name.o                      MODULE_NAME=locale_programs
+        locale/ld-address.o                   MODULE_NAME=locale_programs
+        locale/ld-telephone.o                 MODULE_NAME=locale_programs
+        locale/ld-measurement.o               MODULE_NAME=locale_programs
+        locale/ld-identification.o            MODULE_NAME=locale_programs
+        locale/ld-collate.o                   MODULE_NAME=locale_programs
+        locale/charmap.o                      MODULE_NAME=locale_programs
+        locale/linereader.o                   MODULE_NAME=locale_programs
+        locale/locfile.o                      MODULE_NAME=locale_programs
+        locale/repertoire.o                   MODULE_NAME=locale_programs
+        locale/locarchive.o                   MODULE_NAME=locale_programs
+        locale/md5.o                          MODULE_NAME=locale_programs
+        locale/charmap-dir.o                  MODULE_NAME=locale_programs
+        locale/simple-hash.o                  MODULE_NAME=locale_programs
+        locale/xmalloc.o                      MODULE_NAME=locale_programs
+        locale/xstrdup.o                      MODULE_NAME=locale_programs
+        locale/record-status.o                MODULE_NAME=locale_programs
+        locale/xasprintf.o                    MODULE_NAME=locale_programs
+      catgets/gencat
+        catgets/gencat.o                      MODULE_NAME=nonlib
+        catgets/xmalloc.o                     MODULE_NAME=nonlib
+      nss/makedb
+        nss/makedb.o                          MODULE_NAME=nonlib
+        nss/xmalloc.o                         MODULE_NAME=nonlib
+        nss/hash-string.o                     MODULE_NAME=nonlib
+      nss/getent
+        nss/getent.o                          MODULE_NAME=nonlib
+      posix/getconf
+        posix/getconf.o                       MODULE_NAME=nonlib
+      login/utmpdump
+        login/utmpdump.o                      MODULE_NAME=nonlib
+      debug/pcprofiledump
+        debug/pcprofiledump.o                 MODULE_NAME=nonlib
+      timezone/zic
+        timezone/zic.o                        MODULE_NAME=nonlib
+      timezone/zdump
+        timezone/zdump.o                      MODULE_NAME=nonlib
+      iconv/iconv_prog
+        iconv/iconv_prog.o                    MODULE_NAME=nonlib
+        iconv/iconv_charmap.o                 MODULE_NAME=iconvprogs
+        iconv/charmap.o                       MODULE_NAME=iconvprogs
+        iconv/charmap-dir.o                   MODULE_NAME=iconvprogs
+        iconv/linereader.o                    MODULE_NAME=iconvprogs
+        iconv/dummy-repertoire.o              MODULE_NAME=iconvprogs
+        iconv/simple-hash.o                   MODULE_NAME=iconvprogs
+        iconv/xstrdup.o                       MODULE_NAME=iconvprogs
+        iconv/xmalloc.o                       MODULE_NAME=iconvprogs
+        iconv/record-status.o                 MODULE_NAME=iconvprogs
+      iconv/iconvconfig
+        iconv/iconvconfig.o                   MODULE_NAME=nonlib
+        iconv/strtab.o                        MODULE_NAME=iconvprogs
+        iconv/xmalloc.o                       MODULE_NAME=iconvprogs
+        iconv/hash-string.o                   MODULE_NAME=iconvprogs
+      nss/libnss_files.so                     MODULE_NAME=libnss_files
+      nss/libnss_compat.so.2                  MODULE_NAME=libnss_compat
+      nss/libnss_db.so                        MODULE_NAME=libnss_db
+      hesiod/libnss_hesiod.so                 MODULE_NAME=libnss_hesiod
+      login/libutil.so                        MODULE_NAME=libutil
+      debug/libpcprofile.so                   MODULE_NAME=libpcprofile
+      debug/libSegFault.so                    MODULE_NAME=libSegFault
+    
+    Also, to avoid adding both LFS and 64 bit time support on internal
+    tests they are moved to a newer 'testsuite-internal' module.  It
+    should be similar to 'nonlib' regarding internal definition and
+    linking namespace.
+    
+    This patch also enables LFS and 64 bit support of libsupport container
+    programs (echo-container, test-container, shell-container, and
+    true-container).
+    
+    Checked on x86_64-linux-gnu and i686-linux-gnu.
+    
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+    (cherry picked from commit a6d2f948b71adcb5ea395cb04833bc645eab45e6)
+
+diff --git a/Makeconfig b/Makeconfig
+index 4e04dafb76a1e1a1..9accb5b38d1d37b3 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -882,6 +882,13 @@ endif
+ # -fno-math-errno.
+ +extra-math-flags = $(if $(filter libm,$(in-module)),-fno-math-errno,-fmath-errno)
+ 
++# Use 64 bit time_t support for installed programs
++installed-modules = nonlib nscd lddlibc4 libresolv ldconfig locale_programs \
++		    iconvprogs libnss_files libnss_compat libnss_db libnss_hesiod \
++		    libutil libpcprofile libSegFault
+++extra-time-flags = $(if $(filter $(installed-modules),\
++                           $(in-module)),-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64)
++
+ # We might want to compile with some stack-protection flag.
+ ifneq ($(stack-protector),)
+ +stack-protector=$(stack-protector)
+@@ -986,7 +993,7 @@ libio-include = -I$(..)libio
+ built-modules = iconvprogs iconvdata ldconfig lddlibc4 libmemusage \
+ 		libSegFault libpcprofile librpcsvc locale-programs \
+ 		memusagestat nonlib nscd extramodules libnldbl libsupport \
+-		testsuite
++		testsuite testsuite-internal
+ 
+ in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \
+ 				    $(libof-$(<F)) \
+@@ -1026,7 +1033,7 @@ endif
+ 
+ override CFLAGS	= -std=gnu11 -fgnu89-inline $(config-extra-cflags) \
+ 		  $(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \
+-		  $(+extra-math-flags) \
++		  $(+extra-math-flags) $(+extra-time-flags) \
+ 		  $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \
+ 		  $(CFLAGS-$(@F)) $(tls-model) \
+ 		  $(foreach lib,$(libof-$(basename $(@F))) \
+diff --git a/Makerules b/Makerules
+index e5916f29fa0d4593..689842ba56c71b0d 100644
+--- a/Makerules
++++ b/Makerules
+@@ -1266,14 +1266,22 @@ lib := testsuite
+ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
+ endif
+ 
+-all-nonlib := $(strip $(tests-internal) $(test-internal-extras) \
+-		      $(others) $(others-extras))
++all-nonlib := $(strip $(others) $(others-extras))
+ ifneq (,$(all-nonlib))
+ cpp-srcs-left = $(all-nonlib)
+ lib := nonlib
+ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
+ endif
+ 
++# All internal tests use testsuite-internal module since for 64 bit time
++# support is set as default for MODULE_NAME=nonlib (which include some
++# installed programs).
++all-testsuite-internal := $(strip $(tests-internal) $(test-internal-extras))
++ifneq (,$(all-testsuite-internal))
++cpp-srcs-left = $(all-testsuite-internal)
++lib := testsuite-internal
++include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
++endif
+ 
+ ifeq ($(build-shared),yes)
+ # Generate normalized lists of symbols, versions, and data sizes.
+diff --git a/elf/sotruss-lib.c b/elf/sotruss-lib.c
+index e4ebc8dbc697df3f..45dc6d5ffe819475 100644
+--- a/elf/sotruss-lib.c
++++ b/elf/sotruss-lib.c
+@@ -91,7 +91,7 @@ init (void)
+ 	  if (which_process == NULL || which_process[0] == '\0')
+ 	    snprintf (endp, 13, ".%ld", (long int) pid);
+ 
+-	  out_fd = open (fullname, O_RDWR | O_CREAT | O_TRUNC, 0666);
++	  out_fd = open64 (fullname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ 	  if (out_fd != -1)
+ 	    print_pid = 0;
+ 	}
+@@ -104,7 +104,7 @@ init (void)
+      program.  */
+   if (out_fd == -1)
+     {
+-      out_fd = fcntl (STDERR_FILENO, F_DUPFD, 1000);
++      out_fd = fcntl64 (STDERR_FILENO, F_DUPFD, 1000);
+       if (out_fd == -1)
+ 	out_fd = dup (STDERR_FILENO);
+     }
diff --git a/SOURCES/glibc-upstream-2.34-369.patch b/SOURCES/glibc-upstream-2.34-369.patch
new file mode 100644
index 0000000..3c9be95
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-369.patch
@@ -0,0 +1,73 @@
+commit d910ba48f47158d21c322b9f7e96831c83f69c67
+Author: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
+Date:   Wed Oct 26 16:04:23 2022 -0300
+
+    nis: Build libnsl with 64 bit time_t
+    
+    And remove the usage of glibc reserved names.
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+    
+    (cherry picked from commit 545eefc2f5da61801ba82b7a32ca2589b769ec90)
+
+diff --git a/Makeconfig b/Makeconfig
+index 9accb5b38d1d37b3..89a2881b1ef605e4 100644
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -885,7 +885,7 @@ endif
+ # Use 64 bit time_t support for installed programs
+ installed-modules = nonlib nscd lddlibc4 libresolv ldconfig locale_programs \
+ 		    iconvprogs libnss_files libnss_compat libnss_db libnss_hesiod \
+-		    libutil libpcprofile libSegFault
++		    libutil libpcprofile libSegFault libnsl
+ +extra-time-flags = $(if $(filter $(installed-modules),\
+                            $(in-module)),-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64)
+ 
+diff --git a/nis/nis_call.c b/nis/nis_call.c
+index 043f1bd4316aa284..37feba201c37cbca 100644
+--- a/nis/nis_call.c
++++ b/nis/nis_call.c
+@@ -575,7 +575,7 @@ static struct nis_server_cache
+   unsigned int size;
+   unsigned int server_used;
+   unsigned int current_ep;
+-  __time64_t expires;
++  time_t expires;
+   char name[];
+ } *nis_server_cache[16];
+ static time_t nis_cold_start_mtime;
+@@ -584,7 +584,7 @@ __libc_lock_define_initialized (static, nis_server_cache_lock)
+ static directory_obj *
+ nis_server_cache_search (const_nis_name name, int search_parent,
+ 			 unsigned int *server_used, unsigned int *current_ep,
+-			 struct __timespec64 *now)
++			 struct timespec *now)
+ {
+   directory_obj *ret = NULL;
+   int i;
+@@ -642,7 +642,7 @@ nis_server_cache_search (const_nis_name name, int search_parent,
+ static void
+ nis_server_cache_add (const_nis_name name, int search_parent,
+ 		      directory_obj *dir, unsigned int server_used,
+-		      unsigned int current_ep, struct __timespec64 *now)
++		      unsigned int current_ep, struct timespec *now)
+ {
+   struct nis_server_cache **loc;
+   struct nis_server_cache *new;
+@@ -708,7 +708,7 @@ __nisfind_server (const_nis_name name, int search_parent,
+   nis_error result = NIS_SUCCESS;
+   nis_error status;
+   directory_obj *obj;
+-  struct __timespec64 ts;
++  struct timespec ts;
+   unsigned int server_used = ~0;
+   unsigned int current_ep = ~0;
+ 
+@@ -718,7 +718,7 @@ __nisfind_server (const_nis_name name, int search_parent,
+   if (*dir != NULL)
+     return NIS_SUCCESS;
+ 
+-  __clock_gettime64 (CLOCK_REALTIME, &ts);
++  clock_gettime (CLOCK_REALTIME, &ts);
+ 
+   if ((flags & NO_CACHE) == 0)
+     *dir = nis_server_cache_search (name, search_parent, &server_used,
diff --git a/SOURCES/glibc-upstream-2.34-370.patch b/SOURCES/glibc-upstream-2.34-370.patch
new file mode 100644
index 0000000..41037ec
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-370.patch
@@ -0,0 +1,38 @@
+commit 01c0a0405c5ea63d9b528e062b935d2ff6a6e2ed
+Author: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
+Date:   Wed Oct 26 16:04:24 2022 -0300
+
+    nscd: Use 64 bit time_t on libc nscd routines (BZ# 29402)
+    
+    Although the nscd module is built with 64 bit time_t, the routines
+    linked direct to libc.so need to use the internal symbols.
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+    
+    (cherry picked from commit fa4a19277842fd09a4815a986f70e0fe0903836f)
+
+diff --git a/nscd/nscd.h b/nscd/nscd.h
+index b5da5be98a11d4de..1ce4c1f7fdb215f0 100644
+--- a/nscd/nscd.h
++++ b/nscd/nscd.h
+@@ -66,7 +66,7 @@ typedef enum
+ struct traced_file
+ {
+   /* Tracks the last modified time of the traced file.  */
+-  time_t mtime;
++  __time64_t mtime;
+   /* Support multiple registered files per database.  */
+   struct traced_file *next;
+   int call_res_init;
+diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
+index 81bf324256384de7..b6baa8abf881461c 100644
+--- a/nscd/nscd_gethst_r.c
++++ b/nscd/nscd_gethst_r.c
+@@ -113,7 +113,7 @@ __nscd_get_nl_timestamp (void)
+   if (map == NULL
+       || (map != NO_MAPPING
+ 	  && map->head->nscd_certainly_running == 0
+-	  && map->head->timestamp + MAPPING_TIMEOUT < time_now ()))
++	  && map->head->timestamp + MAPPING_TIMEOUT < time64_now ()))
+     map = __nscd_get_mapping (GETFDHST, "hosts", &__hst_map_handle.mapped);
+ 
+   if (map == NO_MAPPING)
diff --git a/SOURCES/glibc-upstream-2.34-371.patch b/SOURCES/glibc-upstream-2.34-371.patch
new file mode 100644
index 0000000..b4ded31
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-371.patch
@@ -0,0 +1,24 @@
+commit e14a91e59d35bf2fa649a9726ccce838b8c6e4b7
+Author: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
+Date:   Wed Oct 26 16:04:25 2022 -0300
+
+    time: Use 64 bit time on tzfile
+    
+    The tzfile_mtime is already compared to 64 bit time_t stat call.
+    Reviewed-by: DJ Delorie <dj@redhat.com>
+    
+    (cherry picked from commit 4e21c2075193e406a92c0d1cb091a7c804fda4d9)
+
+diff --git a/time/tzfile.c b/time/tzfile.c
+index 8668392ad387af05..84fd9df65f76f148 100644
+--- a/time/tzfile.c
++++ b/time/tzfile.c
+@@ -32,7 +32,7 @@
+ int __use_tzfile;
+ static dev_t tzfile_dev;
+ static ino64_t tzfile_ino;
+-static time_t tzfile_mtime;
++static __time64_t tzfile_mtime;
+ 
+ struct ttinfo
+   {
diff --git a/SOURCES/glibc-upstream-2.34-372.patch b/SOURCES/glibc-upstream-2.34-372.patch
new file mode 100644
index 0000000..dd41022
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-372.patch
@@ -0,0 +1,28 @@
+commit d0e2ac0c5902bd0e671863cc6cb14024d0365e67
+Author: Alan Modra <amodra@gmail.com>
+Date:   Sat Nov 12 11:20:31 2022 +1030
+
+    elf/tst-tlsopt-powerpc fails when compiled with -mcpu=power10 (BZ# 29776)
+    
+    Supports pcrel addressing of TLS GOT entry.  Also tweak the non-pcrel
+    asm constraint to better reflect how the reg is used.
+    
+    (cherry picked from commit 94628de77888c3292fc103840731ff85f283368e)
+
+diff --git a/sysdeps/powerpc/mod-tlsopt-powerpc.c b/sysdeps/powerpc/mod-tlsopt-powerpc.c
+index ee0db12a737d6ab5..51cc502f2860e969 100644
+--- a/sysdeps/powerpc/mod-tlsopt-powerpc.c
++++ b/sysdeps/powerpc/mod-tlsopt-powerpc.c
+@@ -24,7 +24,11 @@ tls_get_addr_opt_test (void)
+   tls_index *tls_arg;
+ #ifdef __powerpc64__
+   register unsigned long thread_pointer __asm__ ("r13");
+-  asm ("addi %0,2,foo@got@tlsgd" : "=r" (tls_arg));
++# ifdef __PCREL__
++  asm ("paddi %0,0,foo@got@tlsgd@pcrel,1" : "=b" (tls_arg));
++# else
++  asm ("addi %0,2,foo@got@tlsgd" : "=b" (tls_arg));
++# endif
+ #else
+   register unsigned long thread_pointer __asm__ ("r2");
+   asm ("bcl 20,31,1f\n1:\t"
diff --git a/SOURCES/glibc-upstream-2.34-373.patch b/SOURCES/glibc-upstream-2.34-373.patch
new file mode 100644
index 0000000000000000000000000000000000000000..01b400783c45c68c1e4b6a1482da7fb1354433f3
GIT binary patch
literal 6973
zcmb_hOOG5^6`mw4aPd&s5FP=JAF*cKud3?TJTk_U@t8~)kIhUwiIZ64dfb}6adlOx
zs@mfj6cq6jV8sF<mMjoLio^o3V8bdB5<7%I6Nv~3BxKkiv4QX0s_L$qmkH3e`*z*B
z_uO;7^SI|6JK<;~Q|cRT#}f-3%W%79*R#!T*Tj@ziS~kLW9W8z9Z$Ekm2o-@<3+mR
zhq1H*dQHfYi0MUdPyM(S3wLOxO(z^()vjBqSR|ssa7?dYZI_JsMblU`yJYHSn`*kD
z>zalYl!D44ZHts#Yu}f<!<5pH4D!O5Mpo(!Ww1-vw+F4z^AfCbhE}jEXx1L@lDV+Z
zHRco<^)(oZDV2v7*tC5?GNEJ~MPVXbCT$C1I_ePVF=<{Q9zqrwC^F+jsN++RbH;Hj
z0xSocbPxujN%Yb<rJbGhz>~h%iG}47b|~6zNa;`}i&K^eD<^_2Q#{6&By}MSozEZL
zB*o*>bk6`JAg6F1kOS~MOZv<%b6p}<2*6yj5LVz)5C#qWR-`h#5*k`jB!XOWUYuAX
z(VU((i<9DbpCaizfD~RFjtEL*+h})<j^VZSj%XVThQ8pmP1EZy^exdh9Nk{%n7ZTG
zdUsCKTnUL9ja}@rS`1bz!>8$xU47PM;EG2y-|^f9*Xwn?e$O*H^UY?@aBNH1Zd>5c
zg{~mjNUzh;8jZ$Lnp&+^J4W}~HEQ&XdXH-OHgv*sl3J;BD3J$ZC#7IK+VO=ICBV9P
zlg48wC7z`#N8Z8GV!DzZB$05iL#wr}(4Ab-v4GNI0d1dTaqc)~t5r7RgaJ$|kzr6L
zD<SD=HMaT#*5(kVV+$z9v3y^+Fs&;st(LPUVReP&>?GDh;Vx-4jV{W-@yD*97e(O0
z51YfQ<w<)#70I3zscDTN>9ptTZGh70nDus-QK{PQEI3S*UqM<n>3V^ec$CIgojne3
zuBfL-c^lkjmWc$gq&JOww7g84cQ!UMPgLY5Z>CTBJq02i5sH>cSGLbYSwlE8NMs7Y
z5+<zYR5S1u;GT@ZFuM}X?hU0gq+}S5eU~ghQU1+Z2?Kv0Ut%spl|xO%`zp={Cer;#
zByZ~Xnwj4ymV}=O<tX$`t)VC&M5M4C_TL@WAo#0O=D@}CQn9q`>qk$6$ZQ7qR9EqQ
z@dgra3oC|r91B?{-zwzZlj)Eww&K9GV#FQ}PZ{Tsmjj4aJ4buc_c`9F@Kg}l^+Vf2
zK*0`<XH>+=5>7-Ck{wk>gA9cVbM1y&;~YRaho#Wl`4S|TFVp!9O#a@H?xW;QdGB6R
zCctS<Z6U@JTlrJkxy%O?^Hp3<B3LLY+wqRt$r{TzDk%jVowWZHhDsZcGnBoYm`hc{
zlNe%jN+N=lDg8O<NTGKIchDlh;_suTa?+-P15)d4+)WP{(RUO9{#F*v)T)sM0!?)b
zmtxP72)kF|e(be{@w2MS{5Q@iHBC?{DQ#llFypTa5#jn`TUK$A?=qz(7&U?@ZaYg|
zVZ6O$zA}K#A_qVysG4$q8L~^{)?A3gf>sSWceAQc#70`|$$~2@qdIenmX+D$j_^)~
zP3cxX`-%rMm9^Ca6;Z_1!ZVktQ2~??i(I(uqKfPNwo&g>t>5loC`WZ%-qARP1~XE<
z4z50?8P`?xLNM6zL)<t#SJw#E!GzT($*#jRW$5XO`d+5XnW;$x@Z1n8LX>zsmeb_u
zSJs~(G#~y1!4-e(Et88!FI_yx(hm-8t((>Z!8cl-Dpcn3G{n;vj9#y8&)c@`2-j*h
zEz2?-(`|Q6y>B_*{P8rTN@tpiROk8bHQTHr^^M15Y`Zc(w}{IoSFr|-WVd;<skp^m
z?8#kLNXWjC@Ztk^Jc{T*I$8sFd#dL6M<YF;l!wAz)PqVa_?LZP&iD1cR{JkDDY_uQ
z`86}MD*_QCr*|6=AfXy000XX-T6oKX&iCquK{X!QY>by?L;LN>do)*Ouo;fiMZB_H
zH;SQ{NBCXPnQPVQEf^y{O4CGZ<2Z~&Ya<L`^GE`!Bw5U}>AgOvql_@AO`W5=b7+eF
zQyyL)bhTRLpd5sgmi8DK-U~%E);3>7ycoQ3eSK@WBo!8vH1vd3EYsOba>h?xRLd35
zdOLLyxV}i6AtD6VDl{5%_7@_5NCeE!g-K><t%wrxC0=soa0vyM^wUNZhr6*gYB(cz
zj%$j&Fn-X~*g6|7Z&;q{33GT*Nwp%J%+WsX08m6;aJ*np-czWe_4=S!_S*8i7KlAk
zZaoT-2j^8nR#oUnKFy}yx7!PC+wQxz(Q$;Q%88aM9=3w9@0SXRW9KWw*6TXejJgS<
z)@p+{q-V~Y`60ah82)|chkyU&rQiSjr_cW3;*alt@aQ+se()!8_+jg-(T6{J|L`xH
zzk2-H@4R&XxsU%NdhVaK!_WQs%Hz-fZs-0N-v7ztFaF|>_n&|7;PID!@Z8~-zx#>k
zE8qU>eTrU*&RgF)ys-7_=;HNf4li|{e*D4<{ri`%{p_*1`M3M+>%FMcef#kC_rEvu
zjlpl<-IDLU`}9-l&olX$J@GeY`0vcjC*NX8o~Nh4@28)gImf?eKDBXkFtfV0&0m9=
zHT?T1LjMaN7Mw>Go<|0NM+QNS0D?ybLyZ80M+Su%Vqkb=aMTEZcw~@xWT1Ftuy|y^
zcx2FcWZ-yY@OWeZd1MfIWFUEDFnMG^d1O#|WMFw@aCu~ad1R1zWT1Iuu=&G)^Z0)S
zU8@25hIyKoWZ|8?d{SR$=39R8(fq_h;oa`^=G(T@H;sAy34T&Jh;M-0QF`;rQ;_tn
zss=`ip3o%ORIM0PO}NG<<qWqjrX?S_lDim_HcwvCsFG+kjP_&IAevpB%lb$+V&swA
zp_lGi$RlrrV^l+&F4k#1aGGkDYNn`Yfmjz=af&iYo&L4WJG4q0(vGcoA8Yf~f+{bV
zWsgru@>7;*KOC#R3>sdDWwEq5+2X!O;I_h8kwIXR-ab!)BQ%y++Em1&q<r{>ND{pJ
znz~zkx;?gi-0_?-ZAeE1C}hwth<G*`qA_FdD>A2vyhH*up~%k9I}T(vjpD?dW}Ohs
zXQ2~F5mOj3T6181AH^j&q<rU@cud8fToyxI)nE^FA#<th^u~T&i3E`7we`Wvx9$vR
zW%Dk*wz9RgvN^cBgw^OP;w?IG*~KGAkuM=Ibc$9$iYh+qncQ64T74ONR$f})SRdSF
zL2j%MHrKYd>Bg-sTA|x3TZ8r0I~yxobo<WM?OWSxC?>X{JBA-x&9FTQ^$Fs9)s48Z
z<BAk*x1_+~E_9wZ8HQ-ZP%IoF(UL*o;=n8mklA$p1GV}gx<jgj&pDeK;u1Rt8~{xi
zAr!+e4%0MB7F(^oy}jmcFm8tNZVQ&e7Lv5CW@S69x6~Ml;~?Y)P-za?nlJ66liU`K
z)0XNr9(l)ErJ7QGuWfiO^UA$2>9KbBy=sVNf}n*6=oBH8csWyfC+lG-U9`1CIxTG~
zO($*^q5MLbi`E6Mo}E|Mw$^XlMd2(`5j>>X3xhW<)QOiNrJKvTLaM&RsX>UGBWtH*
zO|@B6tOcRfTQ^}8Yc#7C)>SoILmgahvS~Fp+~NF!W|`4~5k#;7PjXx(+v2_-%1~r_
zXkeSWg`cqESG-s{R%;N;DD<VOU$a(?QXi?xwiMx<5IMhe*}$_VPTtYZ)2>QOC#R4_
z!8!@g6HW@dLu+efJ>XiJ;|}bl5k`fn(h-KTF8nQYIn554?Zxf_{vv!LQNJ_D4<KN8
zBbKCAbxAkMt2i4#7(|i3Y|!qAo7KyG6aD+FxT}g!6*~H&&VQe9nps|jdoMpsKXw>*
zN6|5=7}5n~iWf>MFKnl%GPxw>CdM(7D9WZfHCP&6!i%am*Q8K}$2Vkvwxs2wnVcwR
zNcX}?vmwb%e%e_9q{R{VY4jBfJj3NUX68E`y^Vipys%Jt<vl{jd4#vqgJ&<NCHDUp
z@pA8)I7K>YTunzioRrsTp;tQP=#mj%sq<$o0Ni!_f6N(65ae-;**;^*NaC22m6frI
z3WX!UN!rX7Wae3?b}!TDDIzOt&W~dBW08*IK!p(%9j38V{m&6XBnOCw8^ibFrgK&M
EHz$fkBLDyZ

literal 0
HcmV?d00001

diff --git a/SOURCES/glibc-upstream-2.34-374.patch b/SOURCES/glibc-upstream-2.34-374.patch
new file mode 100644
index 0000000..709b5c2
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-374.patch
@@ -0,0 +1,526 @@
+commit bbe4bbb6e8997b5ff9843bd3f32ac77dbaec7284
+Author: Fangrui Song <maskray@google.com>
+Date:   Mon Aug 16 09:59:30 2021 -0700
+
+    elf: Drop elf/tls-macros.h in favor of __thread and tls_model attributes [BZ #28152] [BZ #28205]
+    
+    elf/tls-macros.h was added for TLS testing when GCC did not support
+    __thread. __thread and tls_model attributes are mature now and have been
+    used by many newer tests.
+    
+    Also delete tst-tls2.c which tests .tls_common (unused by modern GCC and
+    unsupported by Clang/LLD). .tls_common and .tbss definition are almost
+    identical after linking, so the runtime test doesn't add additional
+    coverage.  Assembler and linker tests should be on the binutils side.
+    
+    When LLD 13.0.0 is allowed in configure.ac
+    (https://sourceware.org/pipermail/libc-alpha/2021-August/129866.html),
+    `make check` result is on par with glibc built with GNU ld on aarch64
+    and x86_64.
+    
+    As a future clean-up, TLS_GD/TLS_LD/TLS_IE/TLS_IE macros can be removed from
+    sysdeps/*/tls-macros.h. We can add optional -mtls-dialect={gnu2,trad}
+    tests to ensure coverage.
+    
+    Tested on aarch64-linux-gnu, powerpc64le-linux-gnu, and x86_64-linux-gnu.
+    
+    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+    (cherry picked from commit 33c50ef42878b07ee6ead8b3f1a81d8c2c74697c)
+
+Conflicts:
+	elf/Makefile
+	  (different backport order)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index feec365e4e5fe9b3..3a8590e0d3cc33ab 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -275,7 +275,6 @@ tests-static-internal := \
+   tst-ptrguard1-static \
+   tst-stackguard1-static \
+   tst-tls1-static \
+-  tst-tls2-static \
+   tst-tls1-static-non-pie \
+   # tests-static-internal
+ 
+@@ -308,7 +307,6 @@ tests := \
+ tests-internal := \
+   $(tests-static-internal) \
+   tst-tls1 \
+-  tst-tls2 \
+   # tests-internal
+ 
+ tests-static := $(tests-static-normal) $(tests-static-internal)
+diff --git a/elf/tls-macros.h b/elf/tls-macros.h
+deleted file mode 100644
+index e25e33b0f032099d..0000000000000000
+--- a/elf/tls-macros.h
++++ /dev/null
+@@ -1,25 +0,0 @@
+-/* Macros to support TLS testing in times of missing compiler support.  */
+-
+-#define COMMON_INT_DEF(x) \
+-  asm (".tls_common " #x ",4,4")
+-/* XXX Until we get compiler support we don't need declarations.  */
+-#define COMMON_INT_DECL(x)
+-
+-/* XXX This definition will probably be machine specific, too.  */
+-#define VAR_INT_DEF(x) \
+-  asm (".section .tdata\n\t"						      \
+-       ".globl " #x "\n"						      \
+-       ".balign 4\n"							      \
+-       #x ":\t.long 0\n\t"						      \
+-       ".size " #x ",4\n\t"						      \
+-       ".previous")
+-/* XXX Until we get compiler support we don't need declarations.  */
+-#define VAR_INT_DECL(x)
+-
+-#include_next <tls-macros.h>
+-
+-  /* XXX Each architecture must have its own asm for now.  */
+-#if !defined TLS_LE || !defined TLS_IE \
+-      || !defined TLS_LD || !defined TLS_GD
+-# error "No support for this architecture so far."
+-#endif
+diff --git a/elf/tst-tls1.c b/elf/tst-tls1.c
+index c31da56ce9cb3e8f..b3412213ee9eaa7e 100644
+--- a/elf/tst-tls1.c
++++ b/elf/tst-tls1.c
+@@ -1,13 +1,14 @@
+ /* glibc test for TLS in ld.so.  */
+ #include <stdio.h>
+ 
+-#include "tls-macros.h"
+-
+-
+-/* Two common 'int' variables in TLS.  */
+-COMMON_INT_DEF(foo);
+-COMMON_INT_DEF(bar);
+ 
++__thread int foo, bar __attribute__ ((tls_model("local-exec")));
++extern __thread int foo_gd asm ("foo") __attribute__ ((tls_model("global-dynamic")));
++extern __thread int foo_ld asm ("foo") __attribute__ ((tls_model("local-dynamic")));
++extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
++extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic")));
++extern __thread int bar_ld asm ("bar") __attribute__ ((tls_model("local-dynamic")));
++extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
+ 
+ static int
+ do_test (void)
+@@ -18,63 +19,48 @@ do_test (void)
+ 
+   /* Set the variable using the local exec model.  */
+   puts ("set bar to 1 (LE)");
+-  ap = TLS_LE (bar);
+-  *ap = 1;
++  bar = 1;
+ 
+ 
+   /* Get variables using initial exec model.  */
+   fputs ("get sum of foo and bar (IE)", stdout);
+-  ap = TLS_IE (foo);
+-  bp = TLS_IE (bar);
++  ap = &foo_ie;
++  bp = &bar_ie;
+   printf (" = %d\n", *ap + *bp);
+   result |= *ap + *bp != 1;
+-  if (*ap != 0)
+-    {
+-      printf ("foo = %d\n", *ap);
+-      result = 1;
+-    }
+-  if (*bp != 1)
++  if (*ap != 0 || *bp != 1)
+     {
+-      printf ("bar = %d\n", *bp);
++      printf ("foo = %d\nbar = %d\n", *ap, *bp);
+       result = 1;
+     }
+ 
+ 
+-  /* Get variables using local dynamic model.  */
+-  fputs ("get sum of foo and bar (LD)", stdout);
+-  ap = TLS_LD (foo);
+-  bp = TLS_LD (bar);
++  /* Get variables using local dynamic model or TLSDESC.  */
++  fputs ("get sum of foo and bar (LD or TLSDESC)", stdout);
++  ap = &foo_ld;
++  bp = &bar_ld;
+   printf (" = %d\n", *ap + *bp);
+   result |= *ap + *bp != 1;
+-  if (*ap != 0)
+-    {
+-      printf ("foo = %d\n", *ap);
+-      result = 1;
+-    }
+-  if (*bp != 1)
++  if (*ap != 0 || *bp != 1)
+     {
+-      printf ("bar = %d\n", *bp);
++      printf ("foo = %d\nbar = %d\n", *ap, *bp);
+       result = 1;
+     }
+ 
+ 
+-  /* Get variables using generic dynamic model.  */
+-  fputs ("get sum of foo and bar (GD)", stdout);
+-  ap = TLS_GD (foo);
+-  bp = TLS_GD (bar);
++  /* Get variables using general dynamic model or TLSDESC.  */
++  fputs ("get sum of foo and bar (GD or TLSDESC)", stdout);
++  ap = &foo_gd;
++  bp = &bar_gd;
+   printf (" = %d\n", *ap + *bp);
+   result |= *ap + *bp != 1;
+-  if (*ap != 0)
+-    {
+-      printf ("foo = %d\n", *ap);
+-      result = 1;
+-    }
+-  if (*bp != 1)
++  if (*ap != 0 || *bp != 1)
+     {
+-      printf ("bar = %d\n", *bp);
++      printf ("foo = %d\nbar = %d\n", *ap, *bp);
+       result = 1;
+     }
+ 
++
+   return result;
+ }
+ 
+diff --git a/elf/tst-tls2.c b/elf/tst-tls2.c
+deleted file mode 100644
+index 963b8d6c88bba0b5..0000000000000000
+--- a/elf/tst-tls2.c
++++ /dev/null
+@@ -1,82 +0,0 @@
+-/* glibc test for TLS in ld.so.  */
+-#include <stdio.h>
+-
+-#include "tls-macros.h"
+-
+-
+-/* Two 'int' variables in TLS.  */
+-VAR_INT_DEF(foo);
+-VAR_INT_DEF(bar);
+-
+-
+-static int
+-do_test (void)
+-{
+-  int result = 0;
+-  int *ap, *bp;
+-
+-
+-  /* Set the variable using the local exec model.  */
+-  puts ("set bar to 1 (LE)");
+-  ap = TLS_LE (bar);
+-  *ap = 1;
+-
+-
+-  /* Get variables using initial exec model.  */
+-  fputs ("get sum of foo and bar (IE)", stdout);
+-  ap = TLS_IE (foo);
+-  bp = TLS_IE (bar);
+-  printf (" = %d\n", *ap + *bp);
+-  result |= *ap + *bp != 1;
+-  if (*ap != 0)
+-    {
+-      printf ("foo = %d\n", *ap);
+-      result = 1;
+-    }
+-  if (*bp != 1)
+-    {
+-      printf ("bar = %d\n", *bp);
+-      result = 1;
+-    }
+-
+-
+-  /* Get variables using local dynamic model.  */
+-  fputs ("get sum of foo and bar (LD)", stdout);
+-  ap = TLS_LD (foo);
+-  bp = TLS_LD (bar);
+-  printf (" = %d\n", *ap + *bp);
+-  result |= *ap + *bp != 1;
+-  if (*ap != 0)
+-    {
+-      printf ("foo = %d\n", *ap);
+-      result = 1;
+-    }
+-  if (*bp != 1)
+-    {
+-      printf ("bar = %d\n", *bp);
+-      result = 1;
+-    }
+-
+-
+-  /* Get variables using generic dynamic model.  */
+-  fputs ("get sum of foo and bar (GD)", stdout);
+-  ap = TLS_GD (foo);
+-  bp = TLS_GD (bar);
+-  printf (" = %d\n", *ap + *bp);
+-  result |= *ap + *bp != 1;
+-  if (*ap != 0)
+-    {
+-      printf ("foo = %d\n", *ap);
+-      result = 1;
+-    }
+-  if (*bp != 1)
+-    {
+-      printf ("bar = %d\n", *bp);
+-      result = 1;
+-    }
+-
+-  return result;
+-}
+-
+-
+-#include <support/test-driver.c>
+diff --git a/elf/tst-tls3.c b/elf/tst-tls3.c
+index 7e0abb4c58c8ff50..222b179626161897 100644
+--- a/elf/tst-tls3.c
++++ b/elf/tst-tls3.c
+@@ -1,13 +1,12 @@
+ /* glibc test for TLS in ld.so.  */
+ #include <stdio.h>
+ 
+-#include "tls-macros.h"
+ 
+-
+-/* One define int variable, two externs.  */
+-COMMON_INT_DECL(foo);
+-VAR_INT_DECL(bar);
+-VAR_INT_DEF(baz);
++__thread int foo, bar __attribute__ ((tls_model("initial-exec")));
++__thread int baz __attribute__ ((tls_model("local-exec")));
++extern __thread int foo_gd __attribute__ ((alias("foo"), tls_model("global-dynamic")));
++extern __thread int bar_gd __attribute__ ((alias("bar"), tls_model("global-dynamic")));
++extern __thread int baz_ld __attribute__ ((alias("baz"), tls_model("local-dynamic")));
+ 
+ 
+ extern int in_dso (void);
+@@ -22,23 +21,20 @@ do_test (void)
+ 
+   /* Set the variable using the local exec model.  */
+   puts ("set baz to 3 (LE)");
+-  ap = TLS_LE (baz);
+-  *ap = 3;
++  baz = 3;
+ 
+ 
+   /* Get variables using initial exec model.  */
+   puts ("set variables foo and bar (IE)");
+-  ap = TLS_IE (foo);
+-  *ap = 1;
+-  bp = TLS_IE (bar);
+-  *bp = 2;
++  foo = 1;
++  bar = 2;
+ 
+ 
+   /* Get variables using local dynamic model.  */
+   fputs ("get sum of foo, bar (GD) and baz (LD)", stdout);
+-  ap = TLS_GD (foo);
+-  bp = TLS_GD (bar);
+-  cp = TLS_LD (baz);
++  ap = &foo_gd;
++  bp = &bar_gd;
++  cp = &baz_ld;
+   printf (" = %d\n", *ap + *bp + *cp);
+   result |= *ap + *bp + *cp != 6;
+   if (*ap != 1)
+diff --git a/elf/tst-tlsmod1.c b/elf/tst-tlsmod1.c
+index 8d9156791be9eabf..a448c4dc37eaf01b 100644
+--- a/elf/tst-tlsmod1.c
++++ b/elf/tst-tlsmod1.c
+@@ -1,12 +1,12 @@
+ #include <stdio.h>
+ 
+-#include "tls-macros.h"
+ 
++__thread int foo, bar __attribute__ ((tls_model("global-dynamic")));
++extern __thread int baz __attribute__ ((tls_model("global-dynamic")));
++extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
++extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
++extern __thread int baz_ie asm ("baz") __attribute__ ((tls_model("initial-exec")));
+ 
+-/* One define int variable, two externs.  */
+-COMMON_INT_DEF(foo);
+-VAR_INT_DEF(bar);
+-VAR_INT_DECL(baz);
+ 
+ extern int in_dso (void);
+ 
+@@ -19,8 +19,8 @@ in_dso (void)
+   /* Get variables using initial exec model.  */
+   fputs ("get sum of foo and bar (IE)", stdout);
+   asm ("" ::: "memory");
+-  ap = TLS_IE (foo);
+-  bp = TLS_IE (bar);
++  ap = &foo_ie;
++  bp = &bar_ie;
+   printf (" = %d\n", *ap + *bp);
+   result |= *ap + *bp != 3;
+   if (*ap != 1)
+@@ -35,11 +35,11 @@ in_dso (void)
+     }
+ 
+ 
+-  /* Get variables using generic dynamic model.  */
+-  fputs ("get sum of foo and bar and baz (GD)", stdout);
+-  ap = TLS_GD (foo);
+-  bp = TLS_GD (bar);
+-  cp = TLS_GD (baz);
++  /* Get variables using generic dynamic model or TLSDESC.  */
++  fputs ("get sum of foo and bar and baz (GD or TLSDESC)", stdout);
++  ap = &foo;
++  bp = &bar;
++  cp = &baz;
+   printf (" = %d\n", *ap + *bp + *cp);
+   result |= *ap + *bp + *cp != 6;
+   if (*ap != 1)
+diff --git a/elf/tst-tlsmod2.c b/elf/tst-tlsmod2.c
+index 40eb1407f864f64a..3223fe494bb7e1f0 100644
+--- a/elf/tst-tlsmod2.c
++++ b/elf/tst-tlsmod2.c
+@@ -1,9 +1,7 @@
+ #include <stdio.h>
+ 
+-#include "tls-macros.h"
+ 
+-
+-COMMON_INT_DEF(foo);
++__thread int foo;
+ 
+ 
+ int
+@@ -15,7 +13,7 @@ in_dso (int n, int *caller_foop)
+   puts ("foo");			/* Make sure PLT is used before macros.  */
+   asm ("" ::: "memory");
+ 
+-  foop = TLS_GD (foo);
++  foop = &foo;
+ 
+   if (caller_foop != NULL && foop != caller_foop)
+     {
+diff --git a/elf/tst-tlsmod3.c b/elf/tst-tlsmod3.c
+index 6d186c47ee6ba104..d6e7498fd8331cb7 100644
+--- a/elf/tst-tlsmod3.c
++++ b/elf/tst-tlsmod3.c
+@@ -1,10 +1,10 @@
+ #include <stdio.h>
+ 
+-#include "tls-macros.h"
+ 
+ extern int in_dso (int n, int *caller_foop);
+ 
+-COMMON_INT_DEF(comm_n);
++extern __thread int foo;
++__thread int comm_n;
+ 
+ 
+ 
+@@ -20,8 +20,8 @@ in_dso2 (void)
+   puts ("foo");			/* Make sure PLT is used before macros.  */
+   asm ("" ::: "memory");
+ 
+-  foop = TLS_GD (foo);
+-  np = TLS_GD (comm_n);
++  foop = &foo;
++  np = &comm_n;
+ 
+   if (n != *np)
+     {
+diff --git a/elf/tst-tlsmod4.c b/elf/tst-tlsmod4.c
+index 86889aac7e58bcf5..f38919a8a94861c1 100644
+--- a/elf/tst-tlsmod4.c
++++ b/elf/tst-tlsmod4.c
+@@ -1,9 +1,7 @@
+ #include <stdio.h>
+ 
+-#include "tls-macros.h"
+ 
+-
+-COMMON_INT_DEF(baz);
++__thread int baz;
+ 
+ 
+ int
+@@ -15,7 +13,7 @@ in_dso (int n, int *caller_bazp)
+   puts ("foo");			/* Make sure PLT is used before macros.  */
+   asm ("" ::: "memory");
+ 
+-  bazp = TLS_GD (baz);
++  bazp = &baz;
+ 
+   if (caller_bazp != NULL && bazp != caller_bazp)
+     {
+diff --git a/elf/tst-tlsmod5.c b/elf/tst-tlsmod5.c
+index a97c7e5e0c69de26..3f39c5bdb76e0b5c 100644
+--- a/elf/tst-tlsmod5.c
++++ b/elf/tst-tlsmod5.c
+@@ -1,3 +1 @@
+-#include "tls-macros.h"
+-
+-COMMON_INT_DEF(foo);
++__thread int foo;
+diff --git a/elf/tst-tlsmod6.c b/elf/tst-tlsmod6.c
+index e968596dd4ef7756..7b3571f428b7243b 100644
+--- a/elf/tst-tlsmod6.c
++++ b/elf/tst-tlsmod6.c
+@@ -1,3 +1 @@
+-#include "tls-macros.h"
+-
+-COMMON_INT_DEF(bar);
++__thread int bar;
+diff --git a/sysdeps/powerpc/mod-tlsopt-powerpc.c b/sysdeps/powerpc/mod-tlsopt-powerpc.c
+index 51cc502f2860e969..d941024963fc7e6a 100644
+--- a/sysdeps/powerpc/mod-tlsopt-powerpc.c
++++ b/sysdeps/powerpc/mod-tlsopt-powerpc.c
+@@ -1,11 +1,9 @@
+ /* shared library to test for __tls_get_addr optimization.  */
+ #include <stdio.h>
+ 
+-#include "../../elf/tls-macros.h"
+ #include "dl-tls.h"
+ 
+-/* common 'int' variable in TLS.  */
+-COMMON_INT_DEF(foo);
++__thread int foo __attribute__ ((tls_model("global-dynamic")));
+ 
+ 
+ int
+@@ -14,7 +12,7 @@ tls_get_addr_opt_test (void)
+   int result = 0;
+ 
+   /* Get variable using general dynamic model.  */
+-  int *ap = TLS_GD (foo);
++  int *ap = &foo;
+   if (*ap != 0)
+     {
+       printf ("foo = %d\n", *ap);
+diff --git a/sysdeps/powerpc/tst-tlsifunc.c b/sysdeps/powerpc/tst-tlsifunc.c
+index 3095d41a68320d72..c8c0bada4547e1a4 100644
+--- a/sysdeps/powerpc/tst-tlsifunc.c
++++ b/sysdeps/powerpc/tst-tlsifunc.c
+@@ -21,9 +21,9 @@
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <libc-symbols.h>
+-#include <tls-macros.h>
+ 
+ __thread int bar;
++extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic")));
+ static int *bar_ptr = NULL;
+ 
+ static uint32_t resolver_platform = 0;
+@@ -57,7 +57,7 @@ get_platform (void)
+ void
+ init_foo (void)
+ {
+-  bar_ptr = TLS_GD (bar);
++  bar_ptr = &bar_gd;
+ }
+ 
+ int
diff --git a/SOURCES/glibc-upstream-2.34-375.patch b/SOURCES/glibc-upstream-2.34-375.patch
new file mode 100644
index 0000000..a02bbb3
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-375.patch
@@ -0,0 +1,39 @@
+commit d36f457870a807f6f29880a2f2bde5e9b761f00c
+Author: Martin Sebor <msebor@redhat.com>
+Date:   Tue Jan 25 17:38:31 2022 -0700
+
+    intl: Avoid -Wuse-after-free [BZ #26779]
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 7845064d2d5a50e347ee9f4b78ec5e6316190154)
+
+diff --git a/intl/localealias.c b/intl/localealias.c
+index 375af2b03153acce..28041f2a48f643fa 100644
+--- a/intl/localealias.c
++++ b/intl/localealias.c
+@@ -318,7 +318,15 @@ read_alias_file (const char *fname, int fname_len)
+ 
+ 		  if (string_space_act + alias_len + value_len > string_space_max)
+ 		    {
+-		      /* Increase size of memory pool.  */
++#pragma GCC diagnostic push
++
++#if defined __GNUC__ && __GNUC__ >= 12
++  /* Suppress the valid GCC 12 warning until the code below is changed
++     to avoid using pointers to the reallocated block.  */
++#  pragma GCC diagnostic ignored "-Wuse-after-free"
++#endif
++
++		    /* Increase size of memory pool.  */
+ 		      size_t new_size = (string_space_max
+ 					 + (alias_len + value_len > 1024
+ 					    ? alias_len + value_len : 1024));
+@@ -351,6 +359,8 @@ read_alias_file (const char *fname, int fname_len)
+ 					   value, value_len);
+ 		  string_space_act += value_len;
+ 
++#pragma GCC diagnostic pop
++
+ 		  ++nmap;
+ 		  ++added;
+ 		}
diff --git a/SOURCES/glibc-upstream-2.34-376.patch b/SOURCES/glibc-upstream-2.34-376.patch
new file mode 100644
index 0000000..d0513d9
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-376.patch
@@ -0,0 +1,27 @@
+commit 92d5c52aaac0fa8e58b92e96bf2025d6848a2845
+Author: Martin Sebor <msebor@redhat.com>
+Date:   Mon Oct 11 09:36:57 2021 -0600
+
+    resolv: Avoid GCC 12 false positive warning [BZ #28439].
+    
+    Replace a call to sprintf with an equivalent pair of stpcpy/strcpy calls
+    to avoid a GCC 12 -Wformat-overflow false positive due to recent optimizer
+    improvements.
+    
+    (cherry picked from commit eb73b87897798de981dbbf019aa957045d768adb)
+
+diff --git a/resolv/res_query.c b/resolv/res_query.c
+index 2f3c28cfc8c0d832..1d2c81737bc889c9 100644
+--- a/resolv/res_query.c
++++ b/resolv/res_query.c
+@@ -626,7 +626,9 @@ __res_context_querydomain (struct resolv_context *ctx,
+ 			RES_SET_H_ERRNO(statp, NO_RECOVERY);
+ 			return (-1);
+ 		}
+-		sprintf(nbuf, "%s.%s", name, domain);
++		char *p = __stpcpy (nbuf, name);
++		*p++ = '.';
++		strcpy (p, domain);
+ 	}
+ 	return __res_context_query (ctx, longname, class, type, answer,
+ 				    anslen, answerp, answerp2, nanswerp2,
diff --git a/SOURCES/glibc-upstream-2.34-377.patch b/SOURCES/glibc-upstream-2.34-377.patch
new file mode 100644
index 0000000..90cff64
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-377.patch
@@ -0,0 +1,34 @@
+commit 26c7c6bac9da305b634a661aa491dae2756581ec
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Tue Oct 5 14:25:40 2021 +0000
+
+    Fix stdlib/tst-setcontext.c for GCC 12 -Warray-compare
+    
+    Building stdlib/tst-setcontext.c fails with GCC mainline:
+    
+    tst-setcontext.c: In function 'f2':
+    tst-setcontext.c:61:16: error: comparison between two arrays [-Werror=array-compare]
+       61 |   if (on_stack < st2 || on_stack >= st2 + sizeof (st2))
+          |                ^
+    tst-setcontext.c:61:16: note: use '&on_stack[0] < &st2[0]' to compare the addresses
+    
+    The comparison in this case is deliberate, so adjust it as suggested
+    in that note.
+    
+    Tested with build-many-glibcs.py (GCC mainline) for aarch64-linux-gnu.
+    
+    (cherry picked from commit a0f0c08e4fe18e78866539b0571f8e4b57dba7a3)
+
+diff --git a/stdlib/tst-setcontext.c b/stdlib/tst-setcontext.c
+index 1b511708c1469444..1c2925bb760c9eb4 100644
+--- a/stdlib/tst-setcontext.c
++++ b/stdlib/tst-setcontext.c
+@@ -58,7 +58,7 @@ f2 (void)
+   puts ("start f2");
+ 
+   printf ("&on_stack=%p\n", on_stack);
+-  if (on_stack < st2 || on_stack >= st2 + sizeof (st2))
++  if (&on_stack[0] < &st2[0] || &on_stack[0] >= st2 + sizeof (st2))
+     {
+       printf ("%s: memory stack is not where it belongs!", __FUNCTION__);
+       exit (1);
diff --git a/SOURCES/glibc-upstream-2.34-378.patch b/SOURCES/glibc-upstream-2.34-378.patch
new file mode 100644
index 0000000..76de777
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-378.patch
@@ -0,0 +1,86 @@
+commit 6ff61a51459d141782fbcc32ae81c0ef1954dad6
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Mon Oct 4 19:10:43 2021 +0000
+
+    Fix stdio-common tests for GCC 12 -Waddress
+    
+    My glibc bot shows failures building the testsuite with GCC mainline
+    across all architectures:
+    
+    tst-vfprintf-width-prec.c: In function 'do_test':
+    tst-vfprintf-width-prec.c:90:16: error: the comparison will always evaluate as 'false' for the address of 'result' will never be NULL [-Werror=address]
+       90 |     if (result == NULL)
+          |                ^~
+    tst-vfprintf-width-prec.c:89:13: note: 'result' declared here
+       89 |     wchar_t result[100];
+          |             ^~~~~~
+    
+    This is clearly a correct warning; the comparison against NULL is
+    clearly a cut-and-paste mistake from an earlier case in the test that
+    does use calloc.  Thus, remove the unnecessary check for NULL shown up
+    by the warning.
+    
+    Similarly, two other tests have bogus comparisons against NULL; remove
+    those as well:
+    
+    scanf14a.c:95:13: error: the comparison will always evaluate as 'false' for the address of 'fname' will never be NULL [-Werror=address]
+       95 |   if (fname == NULL)
+          |             ^~
+    scanf14a.c:93:8: note: 'fname' declared here
+       93 |   char fname[strlen (tmpdir) + sizeof "/tst-scanf14.XXXXXX"];
+          |        ^~~~~
+    
+    scanf16a.c:125:13: error: the comparison will always evaluate as 'false' for the address of 'fname' will never be NULL [-Werror=address]
+      125 |   if (fname == NULL)
+          |             ^~
+    scanf16a.c:123:8: note: 'fname' declared here
+      123 |   char fname[strlen (tmpdir) + sizeof "/tst-scanf16.XXXXXX"];
+          |        ^~~~~
+    
+    Tested with build-many-glibcs.py (GCC mainline) for aarch64-linux-gnu.
+    
+    (cherry picked from commit a312e8fe6d89f5eae6a4583d5db577121e61c0b5)
+
+diff --git a/stdio-common/scanf14a.c b/stdio-common/scanf14a.c
+index 12adcff5a4970da1..b37712d1c673fa3a 100644
+--- a/stdio-common/scanf14a.c
++++ b/stdio-common/scanf14a.c
+@@ -92,8 +92,6 @@ main (void)
+ 
+   char fname[strlen (tmpdir) + sizeof "/tst-scanf14.XXXXXX"];
+   sprintf (fname, "%s/tst-scanf14.XXXXXX", tmpdir);
+-  if (fname == NULL)
+-    FAIL ();
+ 
+   /* Create a temporary file.   */
+   int fd = mkstemp (fname);
+diff --git a/stdio-common/scanf16a.c b/stdio-common/scanf16a.c
+index 400d85a54e81c3cb..74d0295c97f73b14 100644
+--- a/stdio-common/scanf16a.c
++++ b/stdio-common/scanf16a.c
+@@ -122,8 +122,6 @@ main (void)
+ 
+   char fname[strlen (tmpdir) + sizeof "/tst-scanf16.XXXXXX"];
+   sprintf (fname, "%s/tst-scanf16.XXXXXX", tmpdir);
+-  if (fname == NULL)
+-    FAIL ();
+ 
+   /* Create a temporary file.   */
+   int fd = mkstemp (fname);
+diff --git a/stdio-common/tst-vfprintf-width-prec.c b/stdio-common/tst-vfprintf-width-prec.c
+index 3192fd797ad4ea90..278d57f739f576e9 100644
+--- a/stdio-common/tst-vfprintf-width-prec.c
++++ b/stdio-common/tst-vfprintf-width-prec.c
+@@ -87,12 +87,6 @@ do_test (void)
+   }
+   {
+     wchar_t result[100];
+-    if (result == NULL)
+-      {
+-        printf ("error: calloc (%d, %zu): %m", ret + 1, sizeof (wchar_t));
+-        return 1;
+-      }
+-
+     ret = swprintf (result, 100, L"%133000.999999999x", 17);
+     if (ret >= 0)
+       {
diff --git a/SOURCES/glibc-upstream-2.34-379.patch b/SOURCES/glibc-upstream-2.34-379.patch
new file mode 100644
index 0000000..8ceaa45
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-379.patch
@@ -0,0 +1,33 @@
+commit 803c959745fd7c679e00f9bad58822616f0e51cb
+Author: Joseph Myers <joseph@codesourcery.com>
+Date:   Mon Aug 2 16:33:44 2021 +0000
+
+    Fix build of nptl/tst-thread_local1.cc with GCC 12
+    
+    The test nptl/tst-thread_local1.cc fails to build with GCC mainline
+    because of changes to what libstdc++ headers implicitly include what
+    other headers:
+    
+    tst-thread_local1.cc: In function 'int do_test()':
+    tst-thread_local1.cc:177:5: error: variable 'std::array<std::pair<const char*, std::function<void(void* (*)(void*))> >, 2> do_thread_X' has initializer but incomplete type
+      177 |     do_thread_X
+          |     ^~~~~~~~~~~
+    
+    Fix this by adding an explicit include of <array>.
+    
+    Tested with build-many-glibcs.py for aarch64-linux-gnu.
+    
+    (cherry picked from commit 2ee9b24f47db8d0a8d0ccadb999335a1d4cfc364)
+
+diff --git a/nptl/tst-thread_local1.cc b/nptl/tst-thread_local1.cc
+index 9608afa4b739e360..338aafea059e10b7 100644
+--- a/nptl/tst-thread_local1.cc
++++ b/nptl/tst-thread_local1.cc
+@@ -21,6 +21,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ 
++#include <array>
+ #include <functional>
+ #include <string>
+ #include <thread>
diff --git a/SOURCES/glibc-upstream-2.34-380.patch b/SOURCES/glibc-upstream-2.34-380.patch
new file mode 100644
index 0000000..509a9e8
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-380.patch
@@ -0,0 +1,176 @@
+commit 88b3228d9f6322b035fa89bb34f82d93b4190d48
+Author: Martin Sebor <msebor@redhat.com>
+Date:   Tue Jan 25 15:39:38 2022 -0700
+
+    Avoid -Wuse-after-free in tests [BZ #26779].
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit c094c232eb3246154265bb035182f92fe1b17ab8)
+
+diff --git a/malloc/tst-malloc-backtrace.c b/malloc/tst-malloc-backtrace.c
+index 4eb42e7f32f706e9..2ae3fb11efc245cb 100644
+--- a/malloc/tst-malloc-backtrace.c
++++ b/malloc/tst-malloc-backtrace.c
+@@ -20,6 +20,7 @@
+ #include <stdlib.h>
+ 
+ #include <support/support.h>
++#include <libc-diag.h>
+ 
+ #define SIZE 4096
+ 
+@@ -29,7 +30,15 @@ __attribute__((noinline))
+ call_free (void *ptr)
+ {
+   free (ptr);
++#if __GNUC_PREREQ (12, 0)
++  /* Ignore a valid warning about using a pointer made indeterminate
++     by a prior call to free().  */
++  DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free");
++#endif
+   *(size_t *)(ptr - sizeof (size_t)) = 1;
++#if __GNUC_PREREQ (12, 0)
++  DIAG_POP_NEEDS_COMMENT;
++#endif
+ }
+ 
+ int
+diff --git a/malloc/tst-malloc-check.c b/malloc/tst-malloc-check.c
+index 6650d09cf6cdde75..c5c9254a9e8936b0 100644
+--- a/malloc/tst-malloc-check.c
++++ b/malloc/tst-malloc-check.c
+@@ -87,7 +87,15 @@ do_test (void)
+     merror ("errno is not set correctly.");
+   DIAG_POP_NEEDS_COMMENT;
+ 
++#if __GNUC_PREREQ (12, 0)
++  /* Ignore a valid warning about using a pointer made indeterminate
++     by a prior call to realloc().  */
++  DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free");
++#endif
+   free (p);
++#if __GNUC_PREREQ (12, 0)
++  DIAG_POP_NEEDS_COMMENT;
++#endif
+ 
+   p = malloc (512);
+   if (p == NULL)
+@@ -105,7 +113,15 @@ do_test (void)
+     merror ("errno is not set correctly.");
+   DIAG_POP_NEEDS_COMMENT;
+ 
++#if __GNUC_PREREQ (12, 0)
++  /* Ignore a valid warning about using a pointer made indeterminate
++     by a prior call to realloc().  */
++  DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free");
++#endif
+   free (p);
++#if __GNUC_PREREQ (12, 0)
++  DIAG_POP_NEEDS_COMMENT;
++#endif
+   free (q);
+ 
+   return errors != 0;
+diff --git a/malloc/tst-malloc-too-large.c b/malloc/tst-malloc-too-large.c
+index a4349a9b4c506dfc..328b4a2a4fd72cf4 100644
+--- a/malloc/tst-malloc-too-large.c
++++ b/malloc/tst-malloc-too-large.c
+@@ -95,7 +95,15 @@ test_large_allocations (size_t size)
+   DIAG_POP_NEEDS_COMMENT;
+ #endif
+   TEST_VERIFY (errno == ENOMEM);
++#if __GNUC_PREREQ (12, 0)
++  /* Ignore a warning about using a pointer made indeterminate by
++     a prior call to realloc().  */
++  DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free");
++#endif
+   free (ptr_to_realloc);
++#if __GNUC_PREREQ (12, 0)
++  DIAG_POP_NEEDS_COMMENT;
++#endif
+ 
+   for (size_t nmemb = 1; nmemb <= 8; nmemb *= 2)
+     if ((size % nmemb) == 0)
+@@ -113,14 +121,30 @@ test_large_allocations (size_t size)
+         test_setup ();
+         TEST_VERIFY (reallocarray (ptr_to_realloc, nmemb, size / nmemb) == NULL);
+         TEST_VERIFY (errno == ENOMEM);
++#if __GNUC_PREREQ (12, 0)
++  /* Ignore a warning about using a pointer made indeterminate by
++     a prior call to realloc().  */
++  DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free");
++#endif
+         free (ptr_to_realloc);
++#if __GNUC_PREREQ (12, 0)
++  DIAG_POP_NEEDS_COMMENT;
++#endif
+ 
+         ptr_to_realloc = malloc (16);
+         TEST_VERIFY_EXIT (ptr_to_realloc != NULL);
+         test_setup ();
+         TEST_VERIFY (reallocarray (ptr_to_realloc, size / nmemb, nmemb) == NULL);
+         TEST_VERIFY (errno == ENOMEM);
++#if __GNUC_PREREQ (12, 0)
++  /* Ignore a warning about using a pointer made indeterminate by
++     a prior call to realloc().  */
++  DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free");
++#endif
+         free (ptr_to_realloc);
++#if __GNUC_PREREQ (12, 0)
++  DIAG_POP_NEEDS_COMMENT;
++#endif
+       }
+     else
+       break;
+diff --git a/malloc/tst-obstack.c b/malloc/tst-obstack.c
+index ee1385d0f764e368..7d700c4f9a86b676 100644
+--- a/malloc/tst-obstack.c
++++ b/malloc/tst-obstack.c
+@@ -21,8 +21,8 @@ verbose_malloc (size_t size)
+ static void
+ verbose_free (void *buf)
+ {
+-  free (buf);
+   printf ("free (%p)\n", buf);
++  free (buf);
+ }
+ 
+ static int
+diff --git a/malloc/tst-realloc.c b/malloc/tst-realloc.c
+index c89ac07e192d70eb..80711beab1257ed5 100644
+--- a/malloc/tst-realloc.c
++++ b/malloc/tst-realloc.c
+@@ -138,8 +138,16 @@ do_test (void)
+   if (ok == 0)
+     merror ("first 16 bytes were not correct after failed realloc");
+ 
++#if __GNUC_PREREQ (12, 0)
++  /* Ignore a valid warning about using a pointer made indeterminate
++     by a prior call to realloc().  */
++  DIAG_IGNORE_NEEDS_COMMENT (12, "-Wuse-after-free");
++#endif
+   /* realloc (p, 0) frees p (C89) and returns NULL (glibc).  */
+   p = realloc (p, 0);
++#if __GNUC_PREREQ (12, 0)
++  DIAG_POP_NEEDS_COMMENT;
++#endif
+   if (p != NULL)
+     merror ("realloc (p, 0) returned non-NULL.");
+ 
+diff --git a/support/tst-support-open-dev-null-range.c b/support/tst-support-open-dev-null-range.c
+index 8e29def1ce780629..80c97e51586bf6ce 100644
+--- a/support/tst-support-open-dev-null-range.c
++++ b/support/tst-support-open-dev-null-range.c
+@@ -39,10 +39,11 @@ check_path (int fd)
+   char file_path[PATH_MAX];
+   ssize_t file_path_length
+     = readlink (proc_fd_path, file_path, sizeof (file_path));
+-  free (proc_fd_path);
+   if (file_path_length < 0)
+     FAIL_EXIT1 ("readlink (%s, %p, %zu)", proc_fd_path, file_path,
+ 		sizeof (file_path));
++
++  free (proc_fd_path);
+   file_path[file_path_length] = '\0';
+   TEST_COMPARE_STRING (file_path, "/dev/null");
+ }
diff --git a/SOURCES/glibc-upstream-2.34-381.patch b/SOURCES/glibc-upstream-2.34-381.patch
new file mode 100644
index 0000000..f123f25
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-381.patch
@@ -0,0 +1,28 @@
+commit dd0c72fb461a8879164588cd870702efae0c7237
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Mon Dec 20 15:15:12 2021 -0800
+
+    Regenerate ulps on x86_64 with GCC 12
+    
+    Fix
+    
+    FAIL: math/test-float-clog10
+    FAIL: math/test-float32-clog10
+    
+    on Intel Core i7-1165G7 with GCC 12.
+    
+    (cherry picked from commit de8a0897e3c084dc93676e331b610f146000a0ab)
+
+diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
+index 312575f93397c4b0..1c75f0ead46819a7 100644
+--- a/sysdeps/x86_64/fpu/libm-test-ulps
++++ b/sysdeps/x86_64/fpu/libm-test-ulps
+@@ -705,7 +705,7 @@ ldouble: 3
+ 
+ Function: Real part of "clog10_towardzero":
+ double: 5
+-float: 5
++float: 6
+ float128: 4
+ ldouble: 8
+ 
diff --git a/SOURCES/glibc-upstream-2.34-382.patch b/SOURCES/glibc-upstream-2.34-382.patch
new file mode 100644
index 0000000..e82998c
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-382.patch
@@ -0,0 +1,111 @@
+commit 80b24b86548eee3d96130a48e760d1d6c2e0c587
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Mon Dec 20 15:00:24 2021 -0800
+
+    math: Properly cast X_TLOSS to float [BZ #28713]
+    
+    Add
+    
+     #define AS_FLOAT_CONSTANT_1(x) x##f
+     #define AS_FLOAT_CONSTANT(x) AS_FLOAT_CONSTANT_1(x)
+    
+    to cast X_TLOSS to float at compile-time to fix:
+    
+    FAIL: math/test-float-j0
+    FAIL: math/test-float-jn
+    FAIL: math/test-float-y0
+    FAIL: math/test-float-y1
+    FAIL: math/test-float-yn
+    FAIL: math/test-float32-j0
+    FAIL: math/test-float32-jn
+    FAIL: math/test-float32-y0
+    FAIL: math/test-float32-y1
+    FAIL: math/test-float32-yn
+    
+    when compiling with GCC 12.
+    
+    Reviewed-by: Paul Zimmermann <Paul.Zimmermann@inria.fr>
+    (cherry picked from commit 6e30181b4a3ab6c56da0378b65f4d60504982300)
+
+diff --git a/math/math-svid-compat.h b/math/math-svid-compat.h
+index 5c18cb1b039cb3be..876cadde4084dab0 100644
+--- a/math/math-svid-compat.h
++++ b/math/math-svid-compat.h
+@@ -49,6 +49,8 @@ extern int matherr (struct exception *__exc);
+ extern int __matherr (struct exception *__exc);
+ 
+ #define X_TLOSS	1.41484755040568800000e+16
++#define AS_FLOAT_CONSTANT_1(x) x##f
++#define AS_FLOAT_CONSTANT(x) AS_FLOAT_CONSTANT_1(x)
+ 
+ /* Types of exceptions in the `type' field.  */
+ #define DOMAIN		1
+diff --git a/math/w_j0f_compat.c b/math/w_j0f_compat.c
+index a4882eadb33853b2..f35a55219f7baa78 100644
+--- a/math/w_j0f_compat.c
++++ b/math/w_j0f_compat.c
+@@ -28,7 +28,8 @@
+ float
+ __j0f (float x)
+ {
+-  if (__builtin_expect (isgreater (fabsf (x), (float) X_TLOSS), 0)
++  if (__builtin_expect (isgreater (fabsf (x),
++				   AS_FLOAT_CONSTANT (X_TLOSS)), 0)
+       && _LIB_VERSION != _IEEE_ && _LIB_VERSION != _POSIX_)
+     /* j0(|x|>X_TLOSS) */
+     return __kernel_standard_f (x, x, 134);
+@@ -43,7 +44,7 @@ float
+ __y0f (float x)
+ {
+   if (__builtin_expect (islessequal (x, 0.0f)
+-                        || isgreater (x, (float) X_TLOSS), 0)
++                        || isgreater (x, AS_FLOAT_CONSTANT (X_TLOSS)), 0)
+       && _LIB_VERSION != _IEEE_)
+     {
+       if (x < 0.0f)
+diff --git a/math/w_j1f_compat.c b/math/w_j1f_compat.c
+index f2ec7b327d2bc90a..c5e3ccd035031799 100644
+--- a/math/w_j1f_compat.c
++++ b/math/w_j1f_compat.c
+@@ -28,7 +28,8 @@
+ float
+ __j1f (float x)
+ {
+-  if (__builtin_expect (isgreater (fabsf (x), X_TLOSS), 0)
++  if (__builtin_expect (isgreater (fabsf (x),
++				   AS_FLOAT_CONSTANT (X_TLOSS)), 0)
+       && _LIB_VERSION != _IEEE_ && _LIB_VERSION != _POSIX_)
+     /* j1(|x|>X_TLOSS) */
+     return __kernel_standard_f (x, x, 136);
+@@ -43,7 +44,7 @@ float
+ __y1f (float x)
+ {
+   if (__builtin_expect (islessequal (x, 0.0f)
+-			|| isgreater (x, (float) X_TLOSS), 0)
++			|| isgreater (x, AS_FLOAT_CONSTANT (X_TLOSS)), 0)
+       && _LIB_VERSION != _IEEE_)
+     {
+       if (x < 0.0f)
+diff --git a/math/w_jnf_compat.c b/math/w_jnf_compat.c
+index fb6e5060096fb070..925ccc4cd0988a8f 100644
+--- a/math/w_jnf_compat.c
++++ b/math/w_jnf_compat.c
+@@ -28,7 +28,8 @@
+ float
+ __jnf (int n, float x)
+ {
+-  if (__builtin_expect (isgreater (fabsf (x), (float) X_TLOSS), 0)
++  if (__builtin_expect (isgreater (fabsf (x),
++				   AS_FLOAT_CONSTANT (X_TLOSS)), 0)
+       && _LIB_VERSION != _IEEE_ && _LIB_VERSION != _POSIX_)
+     /* jn(n,|x|>X_TLOSS) */
+     return __kernel_standard_f (n, x, 138);
+@@ -43,7 +44,7 @@ float
+ __ynf (int n, float x)
+ {
+   if (__builtin_expect (islessequal (x, 0.0f)
+-			|| isgreater (x, (float) X_TLOSS), 0)
++			|| isgreater (x, AS_FLOAT_CONSTANT (X_TLOSS)), 0)
+       && _LIB_VERSION != _IEEE_)
+     {
+       if (x < 0.0f)
diff --git a/SOURCES/glibc-upstream-2.34-383.patch b/SOURCES/glibc-upstream-2.34-383.patch
new file mode 100644
index 0000000..25a4892
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-383.patch
@@ -0,0 +1,43 @@
+commit c5c666f34939d4bbf73aac8b753ab39621ebf33c
+Author: H.J. Lu <hjl.tools@gmail.com>
+Date:   Mon Dec 20 14:37:26 2021 -0800
+
+    s_sincosf.h: Change pio4 type to float [BZ #28713]
+    
+    s_cosf.c and s_sinf.c have
+    
+      if (abstop12 (y) < abstop12 (pio4))
+    
+    where abstop12 takes a float argument, but pio4 is static const double.
+    pio4 is used only in calls to abstop12 and never in arithmetic.  Apply
+    
+    -static const double pio4 = 0x1.921FB54442D18p-1;
+    +static const float pio4 = 0x1.921FB6p-1f;
+    
+    to fix:
+    
+    FAIL: math/test-float-cos
+    FAIL: math/test-float-sin
+    FAIL: math/test-float-sincos
+    FAIL: math/test-float32-cos
+    FAIL: math/test-float32-sin
+    FAIL: math/test-float32-sincos
+    
+    when compiling with GCC 12.
+    
+    Reviewed-by: Paul Zimmermann <Paul.Zimmermann@inria.fr>
+    (cherry picked from commit d3e4f5a1014db09ff1c62c6506f92cba469e193d)
+
+diff --git a/sysdeps/ieee754/flt-32/s_sincosf.h b/sysdeps/ieee754/flt-32/s_sincosf.h
+index 125ab7f846c463c6..372d8542c2c9a9c7 100644
+--- a/sysdeps/ieee754/flt-32/s_sincosf.h
++++ b/sysdeps/ieee754/flt-32/s_sincosf.h
+@@ -24,7 +24,7 @@
+ /* 2PI * 2^-64.  */
+ static const double pi63 = 0x1.921FB54442D18p-62;
+ /* PI / 4.  */
+-static const double pio4 = 0x1.921FB54442D18p-1;
++static const float pio4 = 0x1.921FB6p-1f;
+ 
+ /* Polynomial data (the cosine polynomial is negated in the 2nd entry).  */
+ extern const sincos_t __sincosf_table[2] attribute_hidden;
diff --git a/SOURCES/glibc-upstream-2.34-384.patch b/SOURCES/glibc-upstream-2.34-384.patch
new file mode 100644
index 0000000..1dfffbe
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-384.patch
@@ -0,0 +1,83 @@
+commit 6484ae5b8c4d4314f748e4d3c9a9baa5385e57c5
+Author: Carlos O'Donell <carlos@redhat.com>
+Date:   Fri Jan 28 15:14:29 2022 -0500
+
+    malloc: Fix -Wuse-after-free warning in tst-mallocalign1 [BZ #26779]
+    
+    The test leaks bits from the freed pointer via the return value
+    in ret, and the compiler correctly identifies this issue.
+    We switch the test to use TEST_VERIFY and terminate the test
+    if any of the pointers return an unexpected alignment.
+    
+    This fixes another -Wuse-after-free error when compiling glibc
+    with gcc 12.
+    
+    Tested on x86_64 and i686 without regression.
+    
+    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    (cherry picked from commit 3a7bed5f5a527dbd87412551f41e42e63aeef07a)
+
+diff --git a/malloc/tst-mallocalign1.c b/malloc/tst-mallocalign1.c
+index 294e821afebd25ac..3e09ff30c4aa9f91 100644
+--- a/malloc/tst-mallocalign1.c
++++ b/malloc/tst-mallocalign1.c
+@@ -20,6 +20,7 @@
+ #include <stdlib.h>
+ #include <inttypes.h>
+ #include <malloc-size.h>
++#include <support/check.h>
+ 
+ static void *
+ test (size_t s)
+@@ -31,41 +32,42 @@ test (size_t s)
+   return p;
+ }
+ 
++#define ALIGNED(p) (((uintptr_t )p & MALLOC_ALIGN_MASK) == 0)
++
+ static int
+ do_test (void)
+ {
+   void *p;
+-  int ret = 0;
+ 
+   p = test (2);
+-  ret |= (uintptr_t) p & MALLOC_ALIGN_MASK;
++  TEST_VERIFY (ALIGNED (p));
+   free (p);
+ 
+   p = test (8);
+-  ret |= (uintptr_t) p & MALLOC_ALIGN_MASK;
++  TEST_VERIFY (ALIGNED (p));
+   free (p);
+ 
+   p = test (13);
+-  ret |= (uintptr_t) p & MALLOC_ALIGN_MASK;
++  TEST_VERIFY (ALIGNED (p));
+   free (p);
+ 
+   p = test (16);
+-  ret |= (uintptr_t) p & MALLOC_ALIGN_MASK;
++  TEST_VERIFY (ALIGNED (p));
+   free (p);
+ 
+   p = test (23);
+-  ret |= (uintptr_t) p & MALLOC_ALIGN_MASK;
++  TEST_VERIFY (ALIGNED (p));
+   free (p);
+ 
+   p = test (43);
+-  ret |= (uintptr_t) p & MALLOC_ALIGN_MASK;
++  TEST_VERIFY (ALIGNED (p));
+   free (p);
+ 
+   p = test (123);
+-  ret |= (uintptr_t) p & MALLOC_ALIGN_MASK;
++  TEST_VERIFY (ALIGNED (p));
+   free (p);
+ 
+-  return ret;
++  return 0;
+ }
+ 
+ #include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-385.patch b/SOURCES/glibc-upstream-2.34-385.patch
new file mode 100644
index 0000000..d952d48
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-385.patch
@@ -0,0 +1,48 @@
+commit c5c792092b57687ae3ebecbe8645fa71ddb19f8c
+Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date:   Thu Feb 2 07:49:02 2023 -0500
+
+    cdefs: Limit definition of fortification macros
+    
+    Define the __glibc_fortify and other macros only when __FORTIFY_LEVEL >
+    0.  This has the effect of not defining these macros on older C90
+    compilers that do not have support for variable length argument lists.
+    
+    Also trim off the trailing backslashes from the definition of
+    __glibc_fortify and __glibc_fortify_n macros.
+    
+    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+    Reviewed-by: Florian Weimer <fweimer@redhat.com>
+    (cherry picked from commit 2337e04e21ba6040926ec871e403533f77043c40)
+
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index b166f3d209fe361f..92dbd3e1fc68dae7 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -151,6 +151,7 @@
+ # define __glibc_objsize(__o) __bos (__o)
+ #endif
+ 
++#if __USE_FORTIFY_LEVEL > 0
+ /* Compile time conditions to choose between the regular, _chk and _chk_warn
+    variants.  These conditions should get evaluated to constant and optimized
+    away.  */
+@@ -186,7 +187,7 @@
+    ? __ ## f ## _alias (__VA_ARGS__)					      \
+    : (__glibc_unsafe_len (__l, __s, __osz)				      \
+       ? __ ## f ## _chk_warn (__VA_ARGS__, __osz)			      \
+-      : __ ## f ## _chk (__VA_ARGS__, __osz)))			      \
++      : __ ## f ## _chk (__VA_ARGS__, __osz)))
+ 
+ /* Fortify function f, where object size argument passed to f is the number of
+    elements and not total size.  */
+@@ -196,7 +197,8 @@
+    ? __ ## f ## _alias (__VA_ARGS__)					      \
+    : (__glibc_unsafe_len (__l, __s, __osz)				      \
+       ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s))		      \
+-      : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))		      \
++      : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))
++#endif
+ 
+ #if __GNUC_PREREQ (4,3)
+ # define __warnattr(msg) __attribute__((__warning__ (msg)))
diff --git a/SOURCES/glibc-upstream-2.34-386.patch b/SOURCES/glibc-upstream-2.34-386.patch
new file mode 100644
index 0000000..fc111d4
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-386.patch
@@ -0,0 +1,127 @@
+commit 0b962177ee3b45cf775176eb454fcf6aa1b0f6e3
+Author: Andreas Schwab <schwab@suse.de>
+Date:   Thu Jan 26 14:25:05 2023 +0100
+
+    Use 64-bit time_t interfaces in strftime and strptime (bug 30053)
+    
+    Both functions use time_t only internally, so the ABI is not affected.
+    
+    (cherry picked from commit 41349f6f67c83e7bafe49f985b56493d2c4c9c77)
+
+diff --git a/time/Makefile b/time/Makefile
+index 38e3a7f4c77ea27f..ef3bb767b825f76a 100644
+--- a/time/Makefile
++++ b/time/Makefile
+@@ -50,7 +50,7 @@ tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
+ 	   tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 \
+ 	   tst-adjtime tst-ctime tst-difftime tst-mktime4 tst-clock_settime \
+ 	   tst-settimeofday tst-itimer tst-gmtime tst-timegm \
+-	   tst-timespec_get tst-timespec_getres
++	   tst-timespec_get tst-timespec_getres tst-strftime4
+ 
+ tests-time64 := \
+   tst-adjtime-time64 \
+@@ -65,6 +65,7 @@ tests-time64 := \
+   tst-itimer-time64 \
+   tst-mktime4-time64 \
+   tst-settimeofday-time64 \
++  tst-strftime4-time64 \
+   tst-timegm-time64 \
+   tst-timespec_get-time64 \
+   tst-timespec_getres-time64 \
+diff --git a/time/strftime_l.c b/time/strftime_l.c
+index d8cde9c5a3af87c7..57abbaa571694505 100644
+--- a/time/strftime_l.c
++++ b/time/strftime_l.c
+@@ -159,6 +159,10 @@ extern char *tzname[];
+ #ifdef _LIBC
+ # define tzname __tzname
+ # define tzset __tzset
++
++# define time_t __time64_t
++# define __gmtime_r(t, tp) __gmtime64_r (t, tp)
++# define mktime(tp) __mktime64 (tp)
+ #endif
+ 
+ #if !HAVE_TM_GMTOFF
+diff --git a/time/strptime_l.c b/time/strptime_l.c
+index 02c5d63c798f9c13..39d1e59b0871f4b4 100644
+--- a/time/strptime_l.c
++++ b/time/strptime_l.c
+@@ -30,8 +30,10 @@
+ #ifdef _LIBC
+ # define HAVE_LOCALTIME_R 0
+ # include "../locale/localeinfo.h"
+-#endif
+ 
++# define time_t __time64_t
++# define __localtime_r(t, tp) __localtime64_r (t, tp)
++#endif
+ 
+ #if ! HAVE_LOCALTIME_R && ! defined localtime_r
+ # ifdef _LIBC
+diff --git a/time/tst-strftime4-time64.c b/time/tst-strftime4-time64.c
+new file mode 100644
+index 0000000000000000..4d47ee7d79f9e648
+--- /dev/null
++++ b/time/tst-strftime4-time64.c
+@@ -0,0 +1 @@
++#include "tst-strftime4.c"
+diff --git a/time/tst-strftime4.c b/time/tst-strftime4.c
+new file mode 100644
+index 0000000000000000..659716d0fa4534ae
+--- /dev/null
++++ b/time/tst-strftime4.c
+@@ -0,0 +1,52 @@
++/* Test strftime and strptime after 2038-01-19 03:14:07 UTC (bug 30053).
++   Copyright (C) 2023 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 <time.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  TEST_VERIFY_EXIT (setenv ("TZ", "UTC0", 1) == 0);
++  tzset ();
++  if (sizeof (time_t) > 4)
++    {
++      time_t wrap = (time_t) 2147483648LL;
++      char buf[80];
++      struct tm *tm = gmtime (&wrap);
++      TEST_VERIFY_EXIT (tm != NULL);
++      TEST_VERIFY_EXIT (strftime (buf, sizeof buf, "%s", tm) > 0);
++      puts (buf);
++      TEST_VERIFY (strcmp (buf, "2147483648") == 0);
++
++      struct tm tm2;
++      char *p = strptime (buf, "%s", &tm2);
++      TEST_VERIFY_EXIT (p != NULL && *p == '\0');
++      time_t t = mktime (&tm2);
++      printf ("%lld\n", (long long) t);
++      TEST_VERIFY (t == wrap);
++    }
++  else
++    FAIL_UNSUPPORTED ("32-bit time_t");
++  return 0;
++}
++
++#include <support/test-driver.c>
diff --git a/SOURCES/glibc-upstream-2.34-388.patch b/SOURCES/glibc-upstream-2.34-388.patch
new file mode 100644
index 0000000..f749370
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-388.patch
@@ -0,0 +1,328 @@
+commit 11ad405fd4c4c9f320d461d9ae1dd2e087cc8c32
+Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date:   Wed Dec 29 10:20:46 2021 -0300
+
+    elf: Fix 64 time_t support for installed statically binaries
+    
+    The usage of internal static symbol for statically linked binaries
+    does not work correctly for objects built with -D_TIME_BITS=64,
+    since the internal definition does not provide the expected aliases.
+    
+    This patch makes it to use the default stat functions instead (which
+    uses the default 64 time_t alias and types).
+    
+    Checked on i686-linux-gnu.
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    Tested-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 9fe6f6363886aae6b2b210cae3ed1f5921299083)
+
+diff --git a/elf/cache.c b/elf/cache.c
+index 8a3404923c625d18..062ec7fb0c9c300f 100644
+--- a/elf/cache.c
++++ b/elf/cache.c
+@@ -319,8 +319,8 @@ print_cache (const char *cache_name)
+   if (fd < 0)
+     error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name);
+ 
+-  struct stat64 st;
+-  if (__fstat64 (fd, &st) < 0
++  struct stat st;
++  if (fstat (fd, &st) < 0
+       /* No need to map the file if it is empty.  */
+       || st.st_size == 0)
+     {
+@@ -933,7 +933,7 @@ init_aux_cache (void)
+ }
+ 
+ int
+-search_aux_cache (struct stat64 *stat_buf, int *flags,
++search_aux_cache (struct stat *stat_buf, int *flags,
+ 		  unsigned int *osversion, unsigned int *isa_level,
+ 		  char **soname)
+ {
+@@ -995,7 +995,7 @@ insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
+ }
+ 
+ void
+-add_to_aux_cache (struct stat64 *stat_buf, int flags,
++add_to_aux_cache (struct stat *stat_buf, int flags,
+ 		  unsigned int osversion, unsigned int isa_level,
+ 		  const char *soname)
+ {
+@@ -1018,8 +1018,8 @@ load_aux_cache (const char *aux_cache_name)
+       return;
+     }
+ 
+-  struct stat64 st;
+-  if (__fstat64 (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file))
++  struct stat st;
++  if (fstat (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file))
+     {
+       close (fd);
+       init_aux_cache ();
+@@ -1135,8 +1135,8 @@ save_aux_cache (const char *aux_cache_name)
+   char *dir = strdupa (aux_cache_name);
+   dir = dirname (dir);
+ 
+-  struct stat64 st;
+-  if (stat64 (dir, &st) < 0)
++  struct stat st;
++  if (stat (dir, &st) < 0)
+     {
+       if (mkdir (dir, 0700) < 0)
+ 	goto out_fail;
+diff --git a/elf/chroot_canon.c b/elf/chroot_canon.c
+index 045611e730be9e41..a70fd25046112290 100644
+--- a/elf/chroot_canon.c
++++ b/elf/chroot_canon.c
+@@ -67,7 +67,7 @@ chroot_canon (const char *chroot, const char *name)
+ 
+   for (start = end = name; *start; start = end)
+     {
+-      struct stat64 st;
++      struct stat st;
+ 
+       /* Skip sequence of multiple path-separators.  */
+       while (*start == '/')
+@@ -114,7 +114,7 @@ chroot_canon (const char *chroot, const char *name)
+ 	  dest = mempcpy (dest, start, end - start);
+ 	  *dest = '\0';
+ 
+-	  if (lstat64 (rpath, &st) < 0)
++	  if (lstat (rpath, &st) < 0)
+ 	    {
+ 	      if (*end == '\0')
+ 		goto done;
+diff --git a/elf/ldconfig.c b/elf/ldconfig.c
+index b8893637f8aaea8d..be47ad8c2d7f89f3 100644
+--- a/elf/ldconfig.c
++++ b/elf/ldconfig.c
+@@ -338,7 +338,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+    inode data from *ST.  */
+ static struct dir_entry *
+ new_sub_entry (const struct dir_entry *entry, const char *path,
+-	       const struct stat64 *st)
++	       const struct stat *st)
+ {
+   struct dir_entry *new_entry = xmalloc (sizeof (struct dir_entry));
+   new_entry->from_file = entry->from_file;
+@@ -428,8 +428,8 @@ add_glibc_hwcaps_subdirectories (struct dir_entry *entry, const char *path)
+ 	    continue;
+ 
+ 	  /* See if this entry eventually resolves to a directory.  */
+-	  struct stat64 st;
+-	  if (fstatat64 (dirfd (dir), e->d_name, &st, 0) < 0)
++	  struct stat st;
++	  if (fstatat (dirfd (dir), e->d_name, &st, 0) < 0)
+ 	    /* Ignore unreadable entries.  */
+ 	    continue;
+ 
+@@ -513,8 +513,8 @@ add_dir_1 (const char *line, const char *from_file, int from_line)
+   if (opt_chroot != NULL)
+     path = chroot_canon (opt_chroot, path);
+ 
+-  struct stat64 stat_buf;
+-  if (path == NULL || stat64 (path, &stat_buf))
++  struct stat stat_buf;
++  if (path == NULL || stat (path, &stat_buf))
+     {
+       if (opt_verbose)
+ 	error (0, errno, _("Can't stat %s"), entry->path);
+@@ -542,15 +542,15 @@ add_dir (const char *line)
+ }
+ 
+ static int
+-chroot_stat (const char *real_path, const char *path, struct stat64 *st)
++chroot_stat (const char *real_path, const char *path, struct stat *st)
+ {
+   int ret;
+   char *canon_path;
+ 
+   if (!opt_chroot)
+-    return stat64 (real_path, st);
++    return stat (real_path, st);
+ 
+-  ret = lstat64 (real_path, st);
++  ret = lstat (real_path, st);
+   if (ret || !S_ISLNK (st->st_mode))
+     return ret;
+ 
+@@ -558,7 +558,7 @@ chroot_stat (const char *real_path, const char *path, struct stat64 *st)
+   if (canon_path == NULL)
+     return -1;
+ 
+-  ret = stat64 (canon_path, st);
++  ret = stat (canon_path, st);
+   free (canon_path);
+   return ret;
+ }
+@@ -570,7 +570,7 @@ create_links (const char *real_path, const char *path, const char *libname,
+ {
+   char *full_libname, *full_soname;
+   char *real_full_libname, *real_full_soname;
+-  struct stat64 stat_lib, stat_so, lstat_so;
++  struct stat stat_lib, stat_so, lstat_so;
+   int do_link = 1;
+   int do_remove = 1;
+   /* XXX: The logics in this function should be simplified.  */
+@@ -605,7 +605,7 @@ create_links (const char *real_path, const char *path, const char *libname,
+ 	  && stat_lib.st_ino == stat_so.st_ino)
+ 	/* Link is already correct.  */
+ 	do_link = 0;
+-      else if (lstat64 (full_soname, &lstat_so) == 0
++      else if (lstat (full_soname, &lstat_so) == 0
+ 	       && !S_ISLNK (lstat_so.st_mode))
+ 	{
+ 	  error (0, 0, _("%s is not a symbolic link\n"), full_soname);
+@@ -613,7 +613,7 @@ create_links (const char *real_path, const char *path, const char *libname,
+ 	  do_remove = 0;
+ 	}
+     }
+-  else if (lstat64 (real_full_soname, &lstat_so) != 0
++  else if (lstat (real_full_soname, &lstat_so) != 0
+ 	   || !S_ISLNK (lstat_so.st_mode))
+     /* Unless it is a stale symlink, there is no need to remove.  */
+     do_remove = 0;
+@@ -657,7 +657,7 @@ manual_link (char *library)
+   char *real_library;
+   char *libname;
+   char *soname;
+-  struct stat64 stat_buf;
++  struct stat stat_buf;
+   int flag;
+   unsigned int osversion;
+   unsigned int isa_level;
+@@ -711,7 +711,7 @@ manual_link (char *library)
+     }
+ 
+   /* Do some sanity checks first.  */
+-  if (lstat64 (real_library, &stat_buf))
++  if (lstat (real_library, &stat_buf))
+     {
+       error (0, errno, _("Cannot lstat %s"), library);
+       goto out;
+@@ -886,18 +886,18 @@ search_dir (const struct dir_entry *entry)
+ 	  sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
+ 	}
+ 
+-      struct stat64 lstat_buf;
++      struct stat lstat_buf;
+       /* We optimize and try to do the lstat call only if needed.  */
+       if (direntry->d_type != DT_UNKNOWN)
+ 	lstat_buf.st_mode = DTTOIF (direntry->d_type);
+       else
+-	if (__glibc_unlikely (lstat64 (real_file_name, &lstat_buf)))
++	if (__glibc_unlikely (lstat (real_file_name, &lstat_buf)))
+ 	  {
+ 	    error (0, errno, _("Cannot lstat %s"), file_name);
+ 	    continue;
+ 	  }
+ 
+-      struct stat64 stat_buf;
++      struct stat stat_buf;
+       bool is_dir;
+       int is_link = S_ISLNK (lstat_buf.st_mode);
+       if (is_link)
+@@ -915,7 +915,7 @@ search_dir (const struct dir_entry *entry)
+ 		  continue;
+ 		}
+ 	    }
+-	  if (__glibc_unlikely (stat64 (target_name, &stat_buf)))
++	  if (__glibc_unlikely (stat (target_name, &stat_buf)))
+ 	    {
+ 	      if (opt_verbose)
+ 		error (0, errno, _("Cannot stat %s"), file_name);
+@@ -951,7 +951,7 @@ search_dir (const struct dir_entry *entry)
+ 	{
+ 	  if (!is_link
+ 	      && direntry->d_type != DT_UNKNOWN
+-	      && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
++	      && __builtin_expect (lstat (real_file_name, &lstat_buf), 0))
+ 	    {
+ 	      error (0, errno, _("Cannot lstat %s"), file_name);
+ 	      continue;
+@@ -980,10 +980,10 @@ search_dir (const struct dir_entry *entry)
+       else
+ 	real_name = real_file_name;
+ 
+-      /* Call lstat64 if not done yet.  */
++      /* Call lstat if not done yet.  */
+       if (!is_link
+ 	  && direntry->d_type != DT_UNKNOWN
+-	  && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
++	  && __builtin_expect (lstat (real_file_name, &lstat_buf), 0))
+ 	{
+ 	  error (0, errno, _("Cannot lstat %s"), file_name);
+ 	  continue;
+diff --git a/elf/readlib.c b/elf/readlib.c
+index 7383c23249426c44..8901de2684835653 100644
+--- a/elf/readlib.c
++++ b/elf/readlib.c
+@@ -76,10 +76,10 @@ int
+ process_file (const char *real_file_name, const char *file_name,
+ 	      const char *lib, int *flag, unsigned int *osversion,
+ 	      unsigned int *isa_level, char **soname, int is_link,
+-	      struct stat64 *stat_buf)
++	      struct stat *stat_buf)
+ {
+   FILE *file;
+-  struct stat64 statbuf;
++  struct stat statbuf;
+   void *file_contents;
+   int ret;
+   ElfW(Ehdr) *elf_header;
+@@ -99,7 +99,7 @@ process_file (const char *real_file_name, const char *file_name,
+       return 1;
+     }
+ 
+-  if (fstat64 (fileno (file), &statbuf) < 0)
++  if (fstat (fileno (file), &statbuf) < 0)
+     {
+       error (0, 0, _("Cannot fstat file %s.\n"), file_name);
+       fclose (file);
+diff --git a/elf/sln.c b/elf/sln.c
+index 26f371a4932cf475..f71321d565803f06 100644
+--- a/elf/sln.c
++++ b/elf/sln.c
+@@ -153,11 +153,11 @@ makesymlinks (const char *file)
+ static int
+ makesymlink (const char *src, const char *dest)
+ {
+-  struct stat64 stats;
++  struct stat stats;
+   const char *error;
+ 
+   /* Destination must not be a directory. */
+-  if (lstat64 (dest, &stats) == 0)
++  if (lstat (dest, &stats) == 0)
+     {
+       if (S_ISDIR (stats.st_mode))
+ 	{
+diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h
+index 3ab757077d160520..c0eb95bcf989dddc 100644
+--- a/sysdeps/generic/ldconfig.h
++++ b/sysdeps/generic/ldconfig.h
+@@ -79,11 +79,11 @@ extern void init_aux_cache (void);
+ 
+ extern void load_aux_cache (const char *aux_cache_name);
+ 
+-extern int search_aux_cache (struct stat64 *stat_buf, int *flags,
++extern int search_aux_cache (struct stat *stat_buf, int *flags,
+ 			     unsigned int *osversion,
+ 			     unsigned int *isa_level, char **soname);
+ 
+-extern void add_to_aux_cache (struct stat64 *stat_buf, int flags,
++extern void add_to_aux_cache (struct stat *stat_buf, int flags,
+ 			      unsigned int osversion,
+ 			      unsigned int isa_level, const char *soname);
+ 
+@@ -94,7 +94,7 @@ extern int process_file (const char *real_file_name, const char *file_name,
+ 			 const char *lib, int *flag,
+ 			 unsigned int *osversion, unsigned int *isa_level,
+ 			 char **soname, int is_link,
+-			 struct stat64 *stat_buf);
++			 struct stat *stat_buf);
+ 
+ extern char *implicit_soname (const char *lib, int flag);
+ 
diff --git a/SOURCES/glibc-upstream-2.34-389.patch b/SOURCES/glibc-upstream-2.34-389.patch
new file mode 100644
index 0000000..83170ad
--- /dev/null
+++ b/SOURCES/glibc-upstream-2.34-389.patch
@@ -0,0 +1,120 @@
+commit 2d7550e6cfff541380d3a1f2ac33e76aaf1273de
+Author: Florian Weimer <fweimer@redhat.com>
+Date:   Wed Feb 8 18:11:04 2023 +0100
+
+    elf: Smoke-test ldconfig -p against system /etc/ld.so.cache
+    
+    The test is sufficient to detect the ldconfig bug fixed in
+    commit 9fe6f6363886aae6b2b210cae3ed1f5921299083 ("elf: Fix 64 time_t
+    support for installed statically binaries").
+    
+    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+    (cherry picked from commit 9fd63e35371b9939e9153907c6a753e6960b68ad)
+
+diff --git a/elf/Makefile b/elf/Makefile
+index 3a8590e0d3cc33ab..0daa8a85ec1a1bc5 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -553,6 +553,7 @@ ifeq ($(run-built-tests),yes)
+ tests-special += \
+   $(objpfx)noload-mem.out \
+   $(objpfx)tst-ldconfig-X.out \
++  $(objpfx)tst-ldconfig-p.out \
+   $(objpfx)tst-leaks1-mem.out \
+   $(objpfx)tst-rtld-help.out \
+   # tests-special
+@@ -2259,6 +2260,11 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig
+ 		 '$(run-program-env)' > $@; \
+ 	$(evaluate-test)
+ 
++$(objpfx)tst-ldconfig-p.out : tst-ldconfig-p.sh $(objpfx)ldconfig
++	$(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \
++		 '$(run-program-env)' > $@; \
++	$(evaluate-test)
++
+ # Test static linking of all the libraries we can possibly link
+ # together.  Note that in some configurations this may be less than the
+ # complete list of libraries we build but we try to maxmimize this list.
+diff --git a/elf/tst-ldconfig-p.sh b/elf/tst-ldconfig-p.sh
+new file mode 100644
+index 0000000000000000..ec937bf4ec04e8c0
+--- /dev/null
++++ b/elf/tst-ldconfig-p.sh
+@@ -0,0 +1,77 @@
++#!/bin/sh
++# Test that ldconfig -p prints something useful.
++# Copyright (C) 2023 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/>.
++
++# Check that the newly built ldconfig -p can dump the system
++# /etc/ld.so.cache file.  This should always work even if the ABIs are
++# not compatible, except in a cross-endian build (that presumably
++# involves emulation when running ldconfig).
++
++common_objpfx=$1
++test_wrapper_env=$2
++run_program_env=$3
++
++if ! test -r /etc/ld.so.cache; then
++    echo "warning: /etc/ld.so.cache does not exist, test skipped"
++    exit 77
++fi
++
++testout="${common_objpfx}elf/tst-ldconfig-p.out"
++# Truncate file.
++: > "$testout"
++
++${test_wrapper_env} \
++${run_program_env} \
++${common_objpfx}elf/ldconfig -p \
++  $testroot/lib >>"$testout" 2>>"$testout"
++status=$?
++echo "info: ldconfig exit status: $status" >>"$testout"
++
++errors=0
++case $status in
++    (0)
++	if head -n 1 "$testout" | \
++		grep -q "libs found in cache \`/etc/ld.so.cache'\$" ; then
++	    echo "info: initial string found" >>"$testout"
++	else
++	    echo "error: initial string not found" >>"$testout"
++	    errors=1
++	fi
++	if grep -q "^	libc\.so\..* => " "$testout"; then
++	    echo "info: libc.so.* string found" >>"$testout"
++	else
++	    echo "error: libc.so.* string not found" >>"$testout"
++	    errors=1
++	fi
++	;;
++    (1)
++	if head -n 1 "$testout" | \
++		grep -q ": Cache file has wrong endianness\.$" ; then
++	    echo "info: cache file has wrong endianess" >> "$testout"
++	else
++	    echo "error: unexpected ldconfig error message" >> "$testout"
++	    errors=1
++	fi
++	;;
++    (*)
++	echo "error: unexpected exit status" >> "$testout"
++	errors=1
++	;;
++esac
++
++exit $errors
diff --git a/SOURCES/wrap-find-debuginfo.sh b/SOURCES/wrap-find-debuginfo.sh
index 6a558df..4cbb01b 100644
--- a/SOURCES/wrap-find-debuginfo.sh
+++ b/SOURCES/wrap-find-debuginfo.sh
@@ -15,8 +15,16 @@
 
 set -ex
 
-ldso_tmp="$(mktemp)"
-libc_tmp="$(mktemp)"
+workdir="$(mktemp -d -t find_debuginfo.XXXXXX)"
+
+ldso_tmp="$workdir/ld.so"
+libc_tmp_dir="$workdir/"
+
+# Return the path where a libc should be saved temporarily. This path is
+# based on its original path received in $1.
+libc_tmp_path() {
+    echo "$libc_tmp_dir"`dirname "$1"`"/libc.so"
+}
 
 # Prefer a separately installed debugedit over the RPM-integrated one.
 if command -v debugedit >/dev/null ; then
@@ -26,7 +34,7 @@ else
 fi
 
 cleanup () {
-    rm -f "$ldso_tmp" "$libc_tmp"
+    rm -rf "$workdir"
 }
 trap cleanup 0
 
@@ -37,8 +45,8 @@ shift
 
 # See ldso_path setting in glibc.spec.
 ldso_path=
-for ldso_candidate in `find "$sysroot_path" -regextype posix-extended \
-  -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do
+for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \
+  -regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do
     if test -z "$ldso_path" ; then
 	ldso_path="$ldso_candidate"
     else
@@ -48,47 +56,71 @@ for ldso_candidate in `find "$sysroot_path" -regextype posix-extended \
 done
 
 # libc.so.6 always uses this name, so it is simpler to locate.
-libc_path=
-for libc_candidate in `find "$sysroot_path" -name libc.so.6`; do
-    if test -z "$libc_path" ; then
-	libc_path="$libc_candidate"
-    else
-	echo "error: multiple libc.so.6 candidates: $libc_path, $libc_candidate"
-	exit 1
-    fi
-done
+libc_path=`find "$sysroot_path" -name libc.so.6`
 
 
 # Preserve the original files.
 cp "$ldso_path" "$ldso_tmp"
-cp "$libc_path" "$libc_tmp"
+for lib in $libc_path ; do
+    libtmp=`libc_tmp_path $lib`
+    mkdir -p `dirname "$libtmp"`
+    cp "$lib" "$libtmp"
+done
 
 # Run the debuginfo extraction.
 "$script_path" "$@"
 
-# Restore the original files.
+for lib in $libc_path ; do
+    libtmp=`libc_tmp_path "$lib"`
+    # libc.so.6: Extract the .gnu_debuglink section
+    objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
+        -O binary "$lib" "$libtmp.debuglink"
+    # Restore the original files.
+    cp "$libtmp" "$lib"
+
+    # Reduce the size of libc notes.  Primarily for annobin.
+    objcopy --merge-notes "$lib"
+
+    # libc.so.6: Restore the .gnu_debuglink section
+    objcopy --add-section .gnu_debuglink="$libtmp.debuglink" "$lib"
+
+    # libc.so.6: Reduce to valuable symbols.  Eliminate file symbols,
+    # annobin symbols, and symbols used by the glibc build to implement
+    # hidden aliases (__EI_*).  We would also like to remove __GI_*
+    # symbols, but even listing them explicitly (as in -K __GI_strlen)
+    # still causes strip to remove them, so there is no filtering of
+    # __GI_* here.  (Debuginfo is gone after this, so no need to optimize
+    # it.)
+    strip -w \
+          -K '*' \
+          -K '!*.c' \
+          -K '!*.os' \
+          -K '!.annobin_*' \
+          -K '!__EI_*' \
+          -K '!__PRETTY_FUNCTION__*' \
+          "$lib"
+done
+
+# Restore the original ld.so.
 cp "$ldso_tmp" "$ldso_path"
-cp "$libc_tmp" "$libc_path"
 
 # Reduce the size of notes.  Primarily for annobin.
 objcopy --merge-notes "$ldso_path"
-objcopy --merge-notes "$libc_path"
-
-# libc.so.6: Reduce to valuable symbols.  Eliminate file symbols,
-# annobin symbols, and symbols used by the glibc build to implement
-# hidden aliases (__EI_*).  We would also like to remove __GI_*
-# symbols, but even listing them explicitly (as in -K __GI_strlen)
-# still causes strip to remove them, so there is no filtering of
-# __GI_* here.  (Debuginfo is gone after this, so no need to optimize
-# it.)
-strip -w \
-    -K '*' \
-    -K '!*.c' \
-    -K '!*.os' \
-    -K '!.annobin_*' \
-    -K '!__EI_*' \
-    -K '!__PRETTY_FUNCTION__*' \
-    "$libc_path"
+
+# ld.so does not have separated debuginfo and so the debuginfo file
+# generated by find-debuginfo is redundant.  Therefore, remove it.
+ldso_debug=
+for ldso_debug_candidate in `find "$sysroot_path" -maxdepth 2 \
+    -regextype posix-extended \
+  -regex '.*/ld(-.*|64|)\.so\.[0-9]+.*debug$' -type f` ; do
+    if test -z "$ldso_debug" ; then
+	ldso_debug="$ldso_debug_candidate"
+    else
+	echo "error: multiple ld.so debug candidates: $ldso_debug, $ldso_debug_candidate"
+	exit 1
+    fi
+done
+rm -f "$ldso_debug"
 
 # ld.so: Rewrite the source file paths to match the extracted
 # locations.  First compute the arguments for invoking debugedit.
@@ -112,6 +144,11 @@ while true ; do
 done
 debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
 $debugedit -b "$debug_base_name" -d "$debug_dest_name" -n $ldso_path
+# Remove the .annobin* symbols (and only them).
+if nm --format=posix "$ldso_path" | cut -d' ' -f1 \
+	| grep '^\.annobin' > "$ldso_tmp.annobin-symbols"; then
+    objcopy --strip-symbols="$ldso_tmp.annobin-symbols" "$ldso_path"
+fi
 
 # Apply single-file DWARF optimization.
 dwz $ldso_path
diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec
index 9384d1c..ddb8035 100644
--- a/SPECS/glibc.spec
+++ b/SPECS/glibc.spec
@@ -69,6 +69,13 @@
 %undefine with_valgrind
 %endif
 
+# Build the POWER10 runtime on POWER, but only for downstream.
+%ifarch ppc64le
+%define buildpower10 0%{?rhel} > 0
+%else
+%define buildpower10 0
+%endif
+
 # The annobin annotations cause binutils to produce broken ARM EABI
 # unwinding information.  Symptom is a hang/test failure for
 # malloc/tst-malloc-stats-cancellation.  See
@@ -148,7 +155,7 @@ end \
 Summary: The GNU libc libraries
 Name: glibc
 Version: %{glibcversion}
-Release: 40%{?dist}.1
+Release: 60%{?dist}
 
 # In general, GPLv2+ is used by programs, LGPLv2+ is used for
 # libraries.
@@ -203,6 +210,19 @@ rpm.define("__debug_install_post bash " .. wrapper
   .. " " .. sysroot .. " " .. original)
 }
 
+# sysroot package support.  These contain arch-specific packages, so
+# turn off the rpmbuild check.
+%global _binaries_in_noarch_packages_terminate_build 0
+# Variant of %%dist that contains just the distribution release, no affixes.
+%{?fedora:%global sysroot_dist fc%{fedora}}
+%{?rhel:%global sysroot_dist el%{rhel}}
+%{?!sysroot_dist:%global sysroot_dist root}
+# The name of the sysroot package.
+%global sysroot_package_arch sysroot-%{_arch}-%{sysroot_dist}-%{name}
+# Installed path for the sysroot tree.  Must contain /sys-root/, which
+# triggers filtering.
+%global sysroot_prefix /usr/%{_arch}-redhat-linux/sys-root/%{sysroot_dist}
+
 # The wrapper script relies on the fact that debugedit does not change
 # build IDs.
 %define _no_recompute_build_ids 1
@@ -579,7 +599,107 @@ Patch371: glibc-upstream-2.34-299.patch
 Patch372: glibc-upstream-2.34-300.patch
 Patch373: glibc-upstream-2.34-301.patch
 Patch374: glibc-upstream-2.34-302.patch
-Patch375: glibc-rh2142111.patch
+Patch375: glibc-upstream-2.34-303.patch
+Patch376: glibc-upstream-2.34-304.patch
+Patch377: glibc-upstream-2.34-305.patch
+Patch378: glibc-upstream-2.34-306.patch
+Patch379: glibc-upstream-2.34-307.patch
+Patch380: glibc-upstream-2.34-308.patch
+Patch381: glibc-rh2118666.patch
+Patch382: glibc-rh2128615-1.patch
+Patch383: glibc-rh2128615-2.patch
+Patch384: glibc-rh2128615-3.patch
+Patch385: glibc-rh2117712-1.patch
+Patch386: glibc-rh2117712-2.patch
+Patch387: glibc-rh2117712-3.patch
+Patch388: glibc-rh2117712-4.patch
+Patch389: glibc-rh2117712-5.patch
+Patch390: glibc-rh2117712-6.patch
+Patch391: glibc-upstream-2.34-309.patch
+Patch392: glibc-upstream-2.34-310.patch
+Patch393: glibc-upstream-2.34-311.patch
+Patch394: glibc-upstream-2.34-312.patch
+# glibc-2.34-313-gbc5cb538e5 backported above as glibc-rh2118666.patch.
+Patch395: glibc-upstream-2.34-314.patch
+Patch396: glibc-upstream-2.34-315.patch
+Patch397: glibc-upstream-2.34-316.patch
+Patch398: glibc-upstream-2.34-317.patch
+Patch399: glibc-upstream-2.34-318.patch
+Patch400: glibc-upstream-2.34-319.patch
+Patch401: glibc-upstream-2.34-320.patch
+Patch402: glibc-upstream-2.34-321.patch
+Patch403: glibc-upstream-2.34-322.patch
+Patch404: glibc-upstream-2.34-323.patch
+Patch405: glibc-upstream-2.34-324.patch
+Patch406: glibc-upstream-2.34-325.patch
+Patch407: glibc-upstream-2.34-326.patch
+Patch408: glibc-upstream-2.34-327.patch
+# glibc-2.34-328-g2def56a349 conflicts with glibc-rh2096191-2.patch;
+# glibc-rh2129005.patch contains the original master branch commit instead.
+Patch409: glibc-rh2129005.patch
+Patch410: glibc-upstream-2.34-329.patch
+Patch411: glibc-upstream-2.34-330.patch
+Patch412: glibc-upstream-2.34-331.patch
+Patch413: glibc-upstream-2.34-332.patch
+Patch414: glibc-upstream-2.34-333.patch
+Patch415: glibc-upstream-2.34-334.patch
+Patch416: glibc-upstream-2.34-335.patch
+Patch417: glibc-upstream-2.34-336.patch
+Patch418: glibc-upstream-2.34-337.patch
+Patch419: glibc-upstream-2.34-338.patch
+Patch420: glibc-upstream-2.34-339.patch
+Patch421: glibc-upstream-2.34-340.patch
+Patch422: glibc-upstream-2.34-341.patch
+Patch423: glibc-upstream-2.34-342.patch
+Patch424: glibc-upstream-2.34-343.patch
+Patch425: glibc-upstream-2.34-344.patch
+Patch426: glibc-upstream-2.34-345.patch
+Patch427: glibc-upstream-2.34-346.patch
+Patch428: glibc-upstream-2.34-347.patch
+Patch429: glibc-upstream-2.34-348.patch
+Patch430: glibc-upstream-2.34-349.patch
+Patch431: glibc-upstream-2.34-350.patch
+Patch432: glibc-upstream-2.34-351.patch
+Patch433: glibc-upstream-2.34-352.patch
+Patch434: glibc-upstream-2.34-353.patch
+Patch435: glibc-upstream-2.34-354.patch
+Patch436: glibc-upstream-2.34-355.patch
+Patch437: glibc-upstream-2.34-356.patch
+Patch438: glibc-upstream-2.34-357.patch
+Patch439: glibc-upstream-2.34-358.patch
+Patch440: glibc-upstream-2.34-359.patch
+# glibc-2.34-360-g75b0edb7ef only changes NEWS.
+Patch441: glibc-upstream-2.34-361.patch
+Patch442: glibc-upstream-2.34-362.patch
+Patch443: glibc-upstream-2.34-363.patch
+Patch444: glibc-upstream-2.34-364.patch
+Patch445: glibc-upstream-2.34-365.patch
+Patch446: glibc-rh2149102.patch
+Patch447: glibc-upstream-2.34-366.patch
+Patch448: glibc-upstream-2.34-367.patch
+Patch449: glibc-upstream-2.34-368.patch
+Patch450: glibc-upstream-2.34-369.patch
+Patch451: glibc-upstream-2.34-370.patch
+Patch452: glibc-upstream-2.34-371.patch
+Patch453: glibc-upstream-2.34-372.patch
+Patch454: glibc-upstream-2.34-373.patch
+Patch455: glibc-upstream-2.34-374.patch
+Patch456: glibc-upstream-2.34-375.patch
+Patch457: glibc-upstream-2.34-376.patch
+Patch458: glibc-upstream-2.34-377.patch
+Patch459: glibc-upstream-2.34-378.patch
+Patch460: glibc-upstream-2.34-379.patch
+Patch461: glibc-upstream-2.34-380.patch
+Patch462: glibc-upstream-2.34-381.patch
+Patch463: glibc-upstream-2.34-382.patch
+Patch464: glibc-upstream-2.34-383.patch
+Patch465: glibc-upstream-2.34-384.patch
+Patch466: glibc-rh2162962.patch
+Patch467: glibc-upstream-2.34-385.patch
+Patch468: glibc-upstream-2.34-386.patch
+# glibc-upstream-2.34-387.patch is a NEWS-only update.  Skipped downstream.
+Patch469: glibc-upstream-2.34-388.patch
+Patch470: glibc-upstream-2.34-389.patch
 
 ##############################################################################
 # Continued list of core "glibc" package information:
@@ -1381,6 +1501,21 @@ libpthread_nonshared.a which is no longer used. The static library
 libpthread_nonshared.a is an internal implementation detail of the C
 runtime and should not be expected to exist.
 
+%if %{without bootstrap}
+%package -n %sysroot_package_arch
+Summary: Sysroot package for glibc, %{_arch} architecture
+BuildArch: noarch
+Provides: sysroot-%{_arch}-%{name}
+# The files are not usable for execution, so do not provide nor
+# require anything.
+AutoReqProv: no
+
+%description -n %sysroot_package_arch
+This package contains development files for the glibc package
+that can be installed across architectures.
+%dnl %%{without bootstrap}
+%endif
+
 ##############################################################################
 # Prepare for the build.
 ##############################################################################
@@ -1583,6 +1718,15 @@ build()
 # Default set of compiler options.
 build
 
+%if %{buildpower10}
+(
+  GCC="$GCC -mcpu=power10 -mtune=power10"
+  GXX="$GXX -mcpu=power10 -mtune=power10"
+  core_with_options="--with-cpu=power10"
+  build power10
+)
+%endif
+
 ##############################################################################
 # Install glibc...
 ##############################################################################
@@ -1650,23 +1794,27 @@ install_different()
 	mkdir -p "$destdir"
 	mkdir -p "$libdestdir"
 	# Walk all of the libraries we installed...
-	for lib in libc math/libm nptl/libpthread rt/librt nptl_db/libthread_db
+	for lib in libc math/libm
 	do
 		libbase=${lib#*/}
 		# Take care that `libbaseso' has a * that needs expanding so
 		# take care with quoting.
-		libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}-*.so)
+		libbaseso=$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*)
 		# Only install if different from default build library.
 		if cmp -s ${lib}.so ../build-%{target}/${lib}.so; then
 			ln -sf "$subdir_up"/$libbaseso $libdestdir/$libbaseso
 		else
 			cp -a ${lib}.so $libdestdir/$libbaseso
 		fi
-		dlib=$libdestdir/$(basename %{glibc_sysroot}/%{_lib}/${libbase}.so.*)
-		ln -sf $libbaseso $dlib
 	done
 }
 
+%if %{buildpower10}
+pushd build-%{target}-power10
+install_different "$RPM_BUILD_ROOT/%{_libdir}/glibc-hwcaps" power10 ..
+popd
+%endif
+
 ##############################################################################
 # Remove the files we don't want to distribute
 ##############################################################################
@@ -1886,6 +2034,61 @@ done
 ##############################################################################
 ar cr %{glibc_sysroot}%{_prefix}/%{_lib}/libpthread_nonshared.a
 
+###############################################################################
+# Sysroot package creation.
+###############################################################################
+
+%if %{without bootstrap}
+mkdir -p %{glibc_sysroot}/%{sysroot_prefix}
+pushd %{glibc_sysroot}/%{sysroot_prefix}
+mkdir -p usr/lib usr/lib64
+
+cp -a %{glibc_sysroot}/%{_prefix}/include usr/.
+for lib in lib lib64;  do
+    for pfx in "" %{_prefix}/; do
+	if test -d %{glibc_sysroot}/$pfx$lib ; then
+	    # Implement UsrMove: everything goes into usr/$lib.  Only
+	    # copy files directly in $lib.
+	    find %{glibc_sysroot}/$pfx$lib -maxdepth 1 -type f \
+		| xargs -I '{}' cp  '{}' usr/$lib/.
+	    # Symbolic links need to be adjusted for UsrMove: They
+	    # need to stay within the same directory.
+	    for sl in `find %{glibc_sysroot}/$pfx$lib -maxdepth 1 -type l`; do
+		set +x
+		slbase=$(basename $sl)
+		sltarget=$(basename $(readlink $sl))
+		if ! test -r usr/$lib/$sltarget; then
+		    echo "$sl: inferred $sltarget ($(readlink $sl)) missing"
+		    exit 1
+		fi
+		set -x
+		ln -s $sltarget usr/$lib/$slbase
+	    done
+	fi
+    done
+done
+
+# Workaround for the lack of a kernel sysroot package.  Copy the
+# kernel headers into the sysroot.
+rpm -ql kernel-headers | grep "^/usr/include" | while read f ; do
+    if test -f "$f" ; then
+        install -D "$f" "./$f"
+    fi
+done
+
+# Remove the executable bit from files in the sysroot.  This prevents
+# debuginfo extraction.
+find -type f | xargs chmod a-x
+
+# Use sysroot-relative paths in linker script.  Ignore symbolic links.
+sed -e 's,\([^0-9a-zA-Z=*]/lib\),=/usr/lib,g' \
+    -e 's,\([^0-9a-zA-Z=*]\)/,\1=/,g' \
+    -i $(find -type f -name 'lib[cm].so')
+
+popd
+%dnl %%{without bootstrap}
+%endif
+
 ##############################################################################
 # Beyond this point in the install process we no longer modify the set of
 # installed files.
@@ -1974,13 +2177,14 @@ touch compat-libpthread-nonshared.filelist
   # language specific sub-packages.
   # libnss_ files go into subpackages related to NSS modules.
   # and .*/share/i18n/charmaps/.*), they go into the sub-package
-  # "locale-source":
+  # "locale-source".  /sys-root/ files are put into the sysroot package.
   sed -e '\,.*/share/locale/\([^/_]\+\).*/LC_MESSAGES/.*\.mo,d' \
       -e '\,.*/share/i18n/locales/.*,d' \
       -e '\,.*/share/i18n/charmaps/.*,d' \
       -e '\,.*/etc/\(localtime\|nsswitch.conf\|ld\.so\.conf\|ld\.so\.cache\|default\|rpc\|gai\.conf\),d' \
       -e '\,.*/%{_libdir}/lib\(pcprofile\|memusage\)\.so,d' \
-      -e '\,.*/bin/\(memusage\|mtrace\|xtrace\|pcprofiledump\),d'
+      -e '\,.*/bin/\(memusage\|mtrace\|xtrace\|pcprofiledump\),d' \
+      -e '\,.*/sys-root,d'
 } | sort > master.filelist
 
 # The master file list is now used by each subpackage to list their own
@@ -2305,6 +2509,16 @@ pushd build-%{target}
 run_tests
 popd
 
+%if %{buildpower10}
+# Run this test only if the server supports Power10 instructions.
+if LD_SHOW_AUXV=1 /bin/true | grep -E "AT_HWCAP2:[^$]*arch_3_1" > /dev/null; then
+  echo ====================TESTING -mcpu=power10=============
+  pushd build-%{target}-power10
+  run_tests
+  popd
+fi
+%endif
+
 echo ====================TESTING END=====================
 PLTCMD='/^Relocation section .*\(\.rela\?\.plt\|\.rela\.IA_64\.pltoff\)/,/^$/p'
 echo ====================PLT RELOCS LD.SO================
@@ -2315,8 +2529,9 @@ echo ====================PLT RELOCS END==================
 
 # Obtain a way to run the dynamic loader.  Avoid matching the symbolic
 # link and then pick the first loader (although there should be only
-# one).  See wrap-find-debuginfo.sh.
-ldso_path="$(find %{glibc_sysroot}/ -regextype posix-extended \
+# one).  Use -maxdepth 2 to avoid descending into the /sys-root/
+# sub-tree.  See wrap-find-debuginfo.sh.
+ldso_path="$(find %{glibc_sysroot}/ -maxdepth 2 -regextype posix-extended \
   -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f | LC_ALL=C sort | head -n1)"
 run_ldso="$ldso_path --library-path %{glibc_sysroot}/%{_lib}"
 
@@ -2349,13 +2564,11 @@ if rpm.vercmp(rel, required) < 0 then
   error("FATAL: kernel too old", 0)
 end
 
-%post -p <lua>
-%glibc_post_funcs
 -- (1) Remove multilib libraries from previous installs.
 -- In order to support in-place upgrades, we must immediately remove
--- obsolete platform directories after installing a new glibc
+-- all platform directories before installing a new glibc
 -- version.  RPM only deletes files removed by updates near the end
--- of the transaction.  If we did not remove the obsolete platform
+-- of the transaction.  If we did not remove all platform
 -- directories here, they may be preferred by the dynamic linker
 -- during the execution of subsequent RPM scriptlets, likely
 -- resulting in process startup failures.
@@ -2428,7 +2641,9 @@ for _, rdir in ipairs (remove_dirs) do
   end
 end
 
--- (2) Update /etc/ld.so.conf
+%post -p <lua>
+%glibc_post_funcs
+-- (1) Update /etc/ld.so.conf
 -- Next we update /etc/ld.so.conf to ensure that it starts with
 -- a literal "include ld.so.conf.d/*.conf".
 
@@ -2467,7 +2682,7 @@ if posix.access (ldsoconf) then
   end
 end
 
--- (3) Rebuild ld.so.cache early.
+-- (2) Rebuild ld.so.cache early.
 -- If the format of the cache changes then we need to rebuild
 -- the cache early to avoid any problems running binaries with
 -- the new glibc.
@@ -2475,7 +2690,7 @@ end
 -- Note: We use _prefix because Fedora's UsrMove says so.
 post_exec ("%{_prefix}/sbin/ldconfig")
 
--- (4) Update gconv modules cache.
+-- (3) Update gconv modules cache.
 -- If the /usr/lib/gconv/gconv-modules.cache exists, then update it
 -- with the latest set of modules that were just installed.
 -- We assume that the cache is in _libdir/gconv and called
@@ -2483,7 +2698,7 @@ post_exec ("%{_prefix}/sbin/ldconfig")
 
 update_gconv_modules_cache()
 
--- (5) On upgrades, restart systemd if installed.  "systemctl -q" does
+-- (4) On upgrades, restart systemd if installed.  "systemctl -q" does
 -- not suppress the error message (which is common in chroots), so
 -- open-code post_exec with standard error suppressed.
 if tonumber(arg[2]) >= 2
@@ -2550,6 +2765,9 @@ fi
 
 %files -f glibc.filelist
 %dir %{_prefix}/%{_lib}/audit
+%if %{buildpower10}
+%dir /%{_libdir}/glibc-hwcaps/power10
+%endif
 %verify(not md5 size mtime) %config(noreplace) /etc/nsswitch.conf
 %verify(not md5 size mtime) %config(noreplace) /etc/ld.so.conf
 %verify(not md5 size mtime) %config(noreplace) /etc/rpc
@@ -2635,9 +2853,162 @@ fi
 
 %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
 
+%if %{without bootstrap}
+%files -n sysroot-%{_arch}-%{sysroot_dist}-glibc
+%{sysroot_prefix}
+%endif
+
 %changelog
-* Tue Nov 22 2022 Florian Weimer <fweimer@redhat.com> - 2.34-40.1
-- Restore IPC_64 support in sysvipc *ctl functions (#2142111)
+* Wed Feb  8 2023 Florian Weimer <fweimer@redhat.com> - 2.34-60
+- Upstream test for ldconfig -p (#2167811)
+
+* Wed Feb  8 2023 Florian Weimer <fweimer@redhat.com> - 2.34-59
+- Fix ldconfig -p on i686 (#2167811)
+
+* Wed Jan 25 2023 Florian Weimer <fweimer@redhat.com> - 2.34-58
+- Enhance internal tunables ABI stability (awk iteration order) (#2162962)
+
+* Tue Jan 17 2023 Florian Weimer <fweimer@redhat.com> - 2.34-57
+- Sync with upstream branch release/2.34/master,
+  commit 6484ae5b8c4d4314f748e4d3c9a9baa5385e57c5
+- malloc: Fix -Wuse-after-free warning in tst-mallocalign1 [BZ #26779]
+- s_sincosf.h: Change pio4 type to float [BZ #28713]
+- math: Properly cast X_TLOSS to float [BZ #28713]
+- Regenerate ulps on x86_64 with GCC 12
+- Avoid -Wuse-after-free in tests [BZ #26779].
+- Fix build of nptl/tst-thread_local1.cc with GCC 12
+- Fix stdio-common tests for GCC 12 -Waddress
+- Fix stdlib/tst-setcontext.c for GCC 12 -Warray-compare
+- resolv: Avoid GCC 12 false positive warning [BZ #28439].
+- intl: Avoid -Wuse-after-free [BZ #26779]
+- elf: Drop elf/tls-macros.h in favor of __thread and tls_model attributes [BZ #28152] [BZ #28205]
+- time: Set daylight to 1 for matching DST/offset change (RHBZ#2155352)
+- elf/tst-tlsopt-powerpc fails when compiled with -mcpu=power10 (BZ# 29776)
+- time: Use 64 bit time on tzfile
+- nscd: Use 64 bit time_t on libc nscd routines (BZ# 29402)
+- nis: Build libnsl with 64 bit time_t
+- Use LFS and 64 bit time for installed programs (BZ #15333)
+
+* Mon Dec 12 2022 Tulio Magno Quites Machado Filho <tuliom@redhat.com> - 2.34-56
+- Earlier removal of alternative multilibs (#2149994)
+
+* Mon Dec 12 2022 Tulio Magno Quites Machado Filho <tuliom@redhat.com> - 2.34-55
+- Earlier removal of alternative multilibs (#2149994)
+
+* Mon Dec 12 2022 Florian Weimer <fweimer@redhat.com> - 2.34-54
+- Install kernel header files into the sysroot subpackage (#2149644)
+
+* Wed Dec 07 2022 Arjun Shankar <arjun@redhat.com> - 2.34-53
+- Sync with upstream branch release/2.34/master,
+  commit a4217408a3d6050a7f42ac23adb6ac7218dca85f:
+- Apply asm redirections in syslog.h before first use [BZ #27087]
+- _Static_assert needs two arguments for compatibility with GCC before 9
+
+* Wed Nov 30 2022 Florian Weimer <fweimer@redhat.com> - 2.34-52
+- Add noarch sysroot subpackages (#2149644)
+
+* Tue Nov 29 2022 Florian Weimer <fweimer@redhat.com> - 2.34-51
+- Prepare for integration of GCC 8 compatible _Static_assert (#2149102)
+
+* Fri Nov 25 2022 Arjun Shankar <arjun@redhat.com> - 2.34-50
+- Sync with upstream branch release/2.34/master,
+  commit 405b8ae13540e9fd614df614e3361ebf9abd14cf:
+- elf: Fix wrong fscanf usage on tst-pldd
+- Allow for unpriviledged nested containers
+- elf: Fix wrong fscanf usage on tst-pldd
+- x86: Fix wcsnlen-avx2 page cross length comparison [BZ #29591]
+- elf: Fix rtld-audit trampoline for aarch64
+
+* Mon Nov 14 2022 Arjun Shankar <arjun@redhat.com> - 2.34-49
+- Sync with upstream branch release/2.34/master,
+  commit: 75b0edb7ef338084e53925139ae81fb0dfc07dd4:
+- Update NEWS file in the right place
+- Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771)
+- io: Fix use-after-free in ftw [BZ #26779]
+- io: Fix ftw internal realloc buffer (BZ #28126)
+- regex: fix buffer read overrun in search [BZ#28470]
+- regex: copy back from Gnulib
+- Allow #pragma GCC in headers in conformtest
+- Fix memmove call in vfprintf-internal.c:group_number
+- mktime: improve heuristic for ca-1986 Indiana DST
+- Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564]
+- linux: Fix generic struct_stat for 64 bit time (BZ# 29657)
+- elf: Do not completely clear reused namespace in dlmopen (bug 29600)
+- nss: Use shared prefix in IPv4 address in tst-reload1
+- nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816)
+- nss: Implement --no-addrconfig option for getent
+
+* Thu Oct 13 2022 Arjun Shankar <arjun@redhat.com> - 2.34-48
+- Handle non-hostname CNAME aliases during name resolution (#2129005)
+- Sync with upstream branch release/2.34/master,
+  commit e3976287b22422787f3cc6fc9adda58304b55bd9:
+- nscd: Drop local address tuple variable [BZ #29607]
+- x86-64: Require BMI1/BMI2 for AVX2 strrchr and wcsrchr implementations
+- x86-64: Require BMI2 and LZCNT for AVX2 memrchr implementation
+- x86-64: Require BMI2 for AVX2 (raw|w)memchr implementations
+- x86-64: Require BMI2 for AVX2 wcs(n)cmp implementations
+- x86-64: Require BMI2 for AVX2 strncmp implementation
+- x86-64: Require BMI2 for AVX2 strcmp implementation
+- x86-64: Require BMI2 for AVX2 str(n)casecmp implementations
+- x86: include BMI1 and BMI2 in x86-64-v3 level
+- nptl: Add backoff mechanism to spinlock loop
+- sysdeps: Add 'get_fast_jitter' interace in fast-jitter.h
+- nptl: Effectively skip CAS in spinlock loop
+- Move assignment out of the CAS condition
+- Add LLL_MUTEX_READ_LOCK [BZ #28537]
+- Avoid extra load with CAS in __pthread_mutex_clocklock_common [BZ #28537]
+- Avoid extra load with CAS in __pthread_mutex_lock_full [BZ #28537]
+- resolv: Fix building tst-resolv-invalid-cname for earlier C standards
+- nss_dns: Rewrite _nss_dns_gethostbyname4_r using current interfaces
+- resolv: Add new tst-resolv-invalid-cname
+- nss_dns: In gaih_getanswer_slice, skip strange aliases (bug 12154)
+  (#2129005)
+- nss_dns: Rewrite getanswer_r to match getanswer_ptr (bug 12154, bug 29305)
+- nss_dns: Remove remnants of IPv6 address mapping
+- nss_dns: Rewrite _nss_dns_gethostbyaddr2_r and getanswer_ptr
+- nss_dns: Split getanswer_ptr from getanswer_r
+- resolv: Add DNS packet parsing helpers geared towards wire format
+- resolv: Add internal __ns_name_length_uncompressed function
+- resolv: Add the __ns_samebinaryname function
+- resolv: Add internal __res_binary_hnok function
+- resolv: Add tst-resolv-aliases
+- resolv: Add tst-resolv-byaddr for testing reverse lookup
+- gconv: Use 64-bit interfaces in gconv_parseconfdir (bug 29583)
+- elf: Fix hwcaps string size overestimation
+- nscd: Fix netlink cache invalidation if epoll is used [BZ #29415]
+- Apply asm redirections in wchar.h before first use
+- Apply asm redirections in stdio.h before first use [BZ #27087]
+- elf: Call __libc_early_init for reused namespaces (bug 29528)
+
+* Tue Oct 11 2022 Florian Weimer <fweimer@redhat.com> - 2.34-47
+- Simplify the glibc system call profile (#2117712)
+
+* Tue Oct 11 2022 Florian Weimer <fweimer@redhat.com> - 2.34-46
+- DSO dependency sort must put new map first even if in cycle (#2128615)
+
+* Tue Oct 11 2022 Florian Weimer <fweimer@redhat.com> - 2.34-45
+- Run tst-audit-tlsdesc{,-dlopen} on all architectures (#2118666)
+
+* Thu Oct 06 2022 Arjun Shankar <arjun@redhat.com> - 2.34-44
+- wrap-find-debuginfo.sh: Use nm --format=posix instead of --format=just-symbols
+
+* Mon Oct 03 2022 Arjun Shankar <arjun@redhat.com> - 2.34-43
+- Remove .annobin* symbols from ld.so (#2126477)
+
+* Tue Sep 06 2022 Arjun Shankar <arjun@redhat.com> - 2.34-42
+- Co-Authored-By: Benjamin Herrenschmidt <benh@amazon.com>
+- Retain .gnu_debuglink section in libc.so.6 (#2090744)
+- Remove redundant ld.so debuginfo file (#2090744)
+
+* Tue Aug 23 2022 Arjun Shankar <arjun@redhat.com> - 2.34-41
+- Sync with upstream branch release/2.34/master,
+  commit 68507377f249d165f1f35502d96e9365edb07d9a:
+- socket: Check lengths before advancing pointer in CMSG_NXTHDR
+- alpha: Fix generic brk system call emulation in __brk_call (bug 29490)
+- stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279]
+- stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265]
+- Update syscall lists for Linux 5.19
+- dlfcn: Pass caller pointer to static dlopen implementation (bug 29446)
 
 * Fri Jul 22 2022 Arjun Shankar <arjun@redhat.com> - 2.34-40
 - Sync with upstream branch release/2.34/master,
-- 
GitLab