commit c3fda489cfdb2260f9fec706e6fd7259858c4467
Author: Tom Honermann <tom@honermann.net>
Date:   Sun Jul 24 01:11:43 2022 -0400

    stdlib: Suppress gcc diagnostic that char8_t is a keyword in C++20 in uchar.h.
    
    gcc 13 issues the following diagnostic for the uchar.h header when the
    -Wc++20-compat option is enabled in C++ modes that do not enable char8_t
    as a builtin type (C++17 and earlier by default; subject to _GNU_SOURCE
    and the gcc -f[no-]char8_t option).
      warning: identifier ‘char8_t’ is a keyword in C++20 [-Wc++20-compat]
    This change modifies the uchar.h header to suppress the diagnostic through
    the use of '#pragma GCC diagnostic' directives for gcc 10 and later (the
    -Wc++20-compat option was added in gcc version 10).  Unfortunately, a bug
    in gcc currently prevents those directives from having the intended effect
    as reported at https://gcc.gnu.org/PR106423.  A patch for that issue has
    been submitted and is available in the email thread archive linked below.
      https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598736.html
    
    (cherry picked from commit 825f84f133bd840347dc49229b6d831f07d04775)

diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index c37e8619a0..5f7139f279 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -34,8 +34,16 @@
 /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
   __cpp_char8_t feature test macro is not defined.  */
 #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
+#if __GNUC_PREREQ (10, 0) && defined __cplusplus
+/* Suppress the diagnostic regarding char8_t being a keyword in C++20.  */
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wc++20-compat"
+#endif
 /* Define the 8-bit character type.  */
 typedef unsigned char char8_t;
+#if __GNUC_PREREQ (10, 0) && defined __cplusplus
+# pragma GCC diagnostic pop
+#endif
 #endif
 
 #ifndef __USE_ISOCXX11

commit 33f1b4c1452b33991e670f636ebe98b90a405e10
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Jul 29 10:50:56 2022 -0700

    wcsmbs: Add missing test-c8rtomb/test-mbrtoc8 dependency
    
    Make test-c8rtomb.out and test-mbrtoc8.out depend on $(gen-locales) for
    
      xsetlocale (LC_ALL, "de_DE.UTF-8");
      xsetlocale (LC_ALL, "zh_HK.BIG5-HKSCS");
    
    Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit e03f5ccd6cc8f829416156eac75acee501626c1f)

diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index e6b9e8743a..3d19d5556f 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -73,6 +73,8 @@ $(objpfx)tst-wcstol-locale.out: $(gen-locales)
 $(objpfx)tst-wcstod-nan-locale.out: $(gen-locales)
 $(objpfx)tst-c16-surrogate.out: $(gen-locales)
 $(objpfx)tst-c32-state.out: $(gen-locales)
+$(objpfx)test-c8rtomb.out: $(gen-locales)
+$(objpfx)test-mbrtoc8.out: $(gen-locales)
 endif
 
 $(objpfx)tst-wcstod-round: $(libm)

commit c74bb93cfdb04d49155b0e30983a3c866167bbca
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/NEWS b/NEWS
index f61e521fc8..15f3dd2cdb 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,13 @@ See the end for copying conditions.
 
 Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
 using `glibc' in the "product" field.
+
+Version 2.36.1
+
+The following bugs are resolved with this release:
+
+  [29446] _dlopen now ignores dl_caller argument in static mode
+
 
 Version 2.36
 
diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
index 2696dde4b1..9b07b4e132 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 *

commit ac47d8f6cf9744139adb12f540fb9cc610cac579
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 bf4be80f8d..202520ee25 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 d656aedcc2..4e65f337d4 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 6c7b2f7011..028ad3107a 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

commit 302bc33bc53c787da6e74162a7092e9c0fb964a8
Author: Noah Goldstein <goldstein.w.n@gmail.com>
Date:   Mon Aug 8 11:26:22 2022 +0800

    elf: Replace `strcpy` call with `memcpy` [BZ #29454]
    
    GCC normally does this optimization for us in
    strlen_pass::handle_builtin_strcpy but only for optimized
    build. To avoid needing to include strcpy.S in the rtld build to
    support the debug build, just do the optimization by hand.
    
    (cherry picked from commit 483cfe1a6a33d6335b1901581b41040d2d412511)

diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index 8bbf110d02..b97c17b3a9 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -509,8 +509,9 @@ _dl_load_cache_lookup (const char *name)
      we are accessing. Therefore we must make the copy of the
      mapping data without using malloc.  */
   char *temp;
-  temp = alloca (strlen (best) + 1);
-  strcpy (temp, best);
+  size_t best_len = strlen (best) + 1;
+  temp = alloca (best_len);
+  memcpy (temp, best, best_len);
   return __strdup (temp);
 }
 

commit e982657073c4db21459ffd9e17bc505b1d64b876
Author: Florian Weimer <fweimer@redhat.com>
Date:   Mon Aug 15 16:43:59 2022 +0200

    Linux: Terminate subprocess on late failure in tst-pidfd (bug 29485)
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>
    (cherry picked from commit f82e05ebb295cadd35f7372f652c72264da810ad)

diff --git a/NEWS b/NEWS
index 15f3dd2cdb..f8fb8db510 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.36.1
 The following bugs are resolved with this release:
 
   [29446] _dlopen now ignores dl_caller argument in static mode
+  [29485] Linux: Terminate subprocess on late failure in tst-pidfd
 
 
 Version 2.36
diff --git a/sysdeps/unix/sysv/linux/tst-pidfd.c b/sysdeps/unix/sysv/linux/tst-pidfd.c
index 037af22290..5711d1c312 100644
--- a/sysdeps/unix/sysv/linux/tst-pidfd.c
+++ b/sysdeps/unix/sysv/linux/tst-pidfd.c
@@ -147,8 +147,11 @@ do_test (void)
        may be denied if the process doesn't have CAP_SYS_PTRACE or
        if a LSM security_ptrace_access_check denies access.  */
     if (fd == -1 && errno == EPERM)
-      FAIL_UNSUPPORTED ("don't have permission to use pidfd_getfd on pidfd, "
-			"skipping test");
+      {
+	TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), 0);
+	FAIL_UNSUPPORTED ("don't have permission to use pidfd_getfd on pidfd, "
+			  "skipping test");
+      }
     TEST_VERIFY (fd > 0);
 
     char *path = xasprintf ("/proc/%d/fd/%d", pid, remote_fd);

commit 8b139cd4f1074ae0d95d9bff60db283a1ed72734
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/NEWS b/NEWS
index f8fb8db510..becab3ade9 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ The following bugs are resolved with this release:
 
   [29446] _dlopen now ignores dl_caller argument in static mode
   [29485] Linux: Terminate subprocess on late failure in tst-pidfd
+  [29490] alpha: New __brk_call implementation is broken
 
 
 Version 2.36
diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h
index b8088cf13f..0b851b6c86 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;
 }

commit d13a7a6f100576b1e30dc044b2e0c4cbcb6196f6
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 2b99dea33b..aac8c49b00 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 156eec6c85..2bde78387f 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 0000000000..4c6898569b
--- /dev/null
+++ b/socket/tst-cmsghdr-skeleton.c
@@ -0,0 +1,92 @@
+/* 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>
+
+#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 0000000000..68c96d3c9d
--- /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 5b35ea81ec..70fce4fb27 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 4f1f810ea1..539b8d7716 100644
--- a/sysdeps/unix/sysv/linux/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/bits/socket.h
@@ -307,6 +307,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
@@ -316,18 +322,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 15b7a3a925..24f72b797a 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)

commit 5c62874f423af93e97b51bc9a57af228a546156f
Author: Arjun Shankar <arjun@redhat.com>
Date:   Mon Aug 22 18:21:14 2022 +0200

    NEWS: Add entry for bug 28846

diff --git a/NEWS b/NEWS
index becab3ade9..ae30900bbc 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Version 2.36.1
 
 The following bugs are resolved with this release:
 
+  [28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
   [29446] _dlopen now ignores dl_caller argument in static mode
   [29485] Linux: Terminate subprocess on late failure in tst-pidfd
   [29490] alpha: New __brk_call implementation is broken

commit 0062e7dd1c3674ece2daca53a898badd28b60421
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Aug 10 16:24:06 2022 -0300

    glibcextract.py: Add compile_c_snippet
    
    It might be used on tests to check if a snippet build with the provided
    compiler and flags.
    
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
    (cherry picked from commit 841afa116e32b3c7195475769c26bf46fd870d32)

diff --git a/scripts/glibcextract.py b/scripts/glibcextract.py
index 43ab58ffe2..36d204c9b0 100644
--- a/scripts/glibcextract.py
+++ b/scripts/glibcextract.py
@@ -17,6 +17,7 @@
 # License along with the GNU C Library; if not, see
 # <https://www.gnu.org/licenses/>.
 
+import collections
 import os.path
 import re
 import subprocess
@@ -173,3 +174,21 @@ def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None,
             if not allow_extra_2:
                 ret = 1
     return ret
+
+CompileResult = collections.namedtuple("CompileResult", "returncode output")
+
+def compile_c_snippet(snippet, cc, extra_cc_args=''):
+    """Compile and return whether the SNIPPET can be build with CC along
+       EXTRA_CC_ARGS compiler flags.  Return a CompileResult with RETURNCODE
+       being 0 for success, or the failure value and the compiler output.
+    """
+    with tempfile.TemporaryDirectory() as temp_dir:
+        c_file_name = os.path.join(temp_dir, 'test.c')
+        obj_file_name = os.path.join(temp_dir, 'test.o')
+        with open(c_file_name, 'w') as c_file:
+            c_file.write(snippet + '\n')
+        cmd = cc.split() + extra_cc_args.split() + ['-c', '-o', obj_file_name,
+                c_file_name]
+        r = subprocess.run(cmd, check=False, stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT)
+        return CompileResult(r.returncode, r.stdout)

commit 1cc5513114e76083669cba1b11252aad35525e69
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Aug 10 14:24:44 2022 -0300

    linux: Use compile_c_snippet to check linux/pidfd.h availability
    
    Instead of tying to a specific kernel version.
    
    Checked on x86_64-linux-gnu.
    
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
    (cherry picked from commit 1542019b69b7ec7b2cd34357af035e406d153631)

diff --git a/sysdeps/unix/sysv/linux/tst-pidfd-consts.py b/sysdeps/unix/sysv/linux/tst-pidfd-consts.py
index 90cbb9be64..d732173abd 100644
--- a/sysdeps/unix/sysv/linux/tst-pidfd-consts.py
+++ b/sysdeps/unix/sysv/linux/tst-pidfd-consts.py
@@ -33,11 +33,13 @@ def main():
                         help='C compiler (including options) to use')
     args = parser.parse_args()
 
-    linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
-    # Linux started to provide pidfd.h with 5.10.
-    if linux_version_headers < (5, 10):
+    if glibcextract.compile_c_snippet(
+            '#include <linux/pidfd.h>',
+            args.cc).returncode != 0:
         sys.exit (77)
-    linux_version_glibc = (5, 18)
+
+    linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
+    linux_version_glibc = (5, 19)
     sys.exit(glibcextract.compare_macro_consts(
                 '#include <sys/pidfd.h>\n',
                 '#include <asm/fcntl.h>\n'

commit 4dad97e2a2e510c6b53a0add29a2188714fcf4ab
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Aug 10 14:24:45 2022 -0300

    linux: Mimic kernel defition for BLOCK_SIZE
    
    To avoid possible warnings if the kernel header is included before
    sys/mount.h.
    
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
    (cherry picked from commit c68b6044bc7945716431f1adc091b17c39b80a06)

diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
index f965986ba8..df6b0dbb42 100644
--- a/sysdeps/unix/sysv/linux/sys/mount.h
+++ b/sysdeps/unix/sysv/linux/sys/mount.h
@@ -27,8 +27,8 @@
 #include <stddef.h>
 #include <sys/ioctl.h>
 
-#define BLOCK_SIZE	1024
 #define BLOCK_SIZE_BITS	10
+#define BLOCK_SIZE	(1<<BLOCK_SIZE_BITS)
 
 
 /* These are the fs-independent mount-flags: up to 16 flags are

commit d48813227b63a0d92ea357ea0733229ed74e31ab
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Aug 10 14:24:46 2022 -0300

    linux: Use compile_c_snippet to check linux/mount.h availability
    
    Checked on x86_64-linux-gnu.
    
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
    (cherry picked from commit e1226cdc6b209539a92d32d5b620ba53fd35abf3)

diff --git a/sysdeps/unix/sysv/linux/tst-mount-consts.py b/sysdeps/unix/sysv/linux/tst-mount-consts.py
index a62f803123..be2ef2daf1 100755
--- a/sysdeps/unix/sysv/linux/tst-mount-consts.py
+++ b/sysdeps/unix/sysv/linux/tst-mount-consts.py
@@ -33,6 +33,11 @@ def main():
                         help='C compiler (including options) to use')
     args = parser.parse_args()
 
+    if glibcextract.compile_c_snippet(
+            '#include <linux/mount.h>',
+            args.cc).returncode != 0:
+        sys.exit (77)
+
     linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
     # Constants in glibc were updated to match Linux v5.16.  When glibc
     # constants are updated this value should be updated to match the

commit bb1e8b0ca99b5cbedfae3e6245528a87d95ff3e2
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Aug 10 14:24:47 2022 -0300

    linux: Fix sys/mount.h usage with kernel headers
    
    Now that kernel exports linux/mount.h and includes it on linux/fs.h,
    its definitions might clash with glibc exports sys/mount.h.  To avoid
    the need to rearrange the Linux header to be always after glibc one,
    the glibc sys/mount.h is changed to:
    
      1. Undefine the macros also used as enum constants.  This covers prior
         inclusion of <linux/mount.h> (for instance MS_RDONLY).
    
      2. Include <linux/mount.h> based on the usual __has_include check
         (needs to use __has_include ("linux/mount.h") to paper over GCC
         bugs.
    
      3. Define enum fsconfig_command only if FSOPEN_CLOEXEC is not defined.
         (FSOPEN_CLOEXEC should be a very close proxy.)
    
      4. Define struct mount_attr if MOUNT_ATTR_SIZE_VER0 is not defined.
         (Added in the same commit on the Linux side.)
    
    This patch also adds some tests to check if including linux/fs.h and
    linux/mount.h after and before sys/mount.h does work.
    
    Checked on x86_64-linux-gnu.
    
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
    (cherry picked from commit 774058d72942249f71d74e7f2b639f77184160a6)

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index a139a16532..3ceda9fdbf 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -265,6 +265,14 @@ $(objpfx)tst-mount-consts.out: ../sysdeps/unix/sysv/linux/tst-mount-consts.py
 	  < /dev/null > $@ 2>&1; $(evaluate-test)
 $(objpfx)tst-mount-consts.out: $(sysdeps-linux-python-deps)
 
+tests-special += $(objpfx)tst-mount-compile.out
+$(objpfx)tst-mount-compile.out: ../sysdeps/unix/sysv/linux/tst-mount-compile.py
+	$(sysdeps-linux-python) \
+	  ../sysdeps/unix/sysv/linux/tst-mount-compile.py \
+	    $(sysdeps-linux-python-cc) \
+	  < /dev/null > $@ 2>&1; $(evaluate-test)
+$(objpfx)tst-mount-compile.out: $(sysdeps-linux-python-deps)
+
 tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
 
 endif # $(subdir) == misc
diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
index df6b0dbb42..2e3fd6a7fe 100644
--- a/sysdeps/unix/sysv/linux/sys/mount.h
+++ b/sysdeps/unix/sysv/linux/sys/mount.h
@@ -27,6 +27,13 @@
 #include <stddef.h>
 #include <sys/ioctl.h>
 
+#ifdef __has_include
+# if __has_include ("linux/mount.h")
+#  include "linux/mount.h"
+# endif
+#endif
+
+
 #define BLOCK_SIZE_BITS	10
 #define BLOCK_SIZE	(1<<BLOCK_SIZE_BITS)
 
@@ -35,69 +42,98 @@
    supported  */
 enum
 {
+#undef MS_RDONLY
   MS_RDONLY = 1,		/* Mount read-only.  */
 #define MS_RDONLY	MS_RDONLY
+#undef MS_NOSUID
   MS_NOSUID = 2,		/* Ignore suid and sgid bits.  */
 #define MS_NOSUID	MS_NOSUID
+#undef MS_NODEV
   MS_NODEV = 4,			/* Disallow access to device special files.  */
 #define MS_NODEV	MS_NODEV
+#undef MS_NOEXEC
   MS_NOEXEC = 8,		/* Disallow program execution.  */
 #define MS_NOEXEC	MS_NOEXEC
+#undef MS_SYNCHRONOUS
   MS_SYNCHRONOUS = 16,		/* Writes are synced at once.  */
 #define MS_SYNCHRONOUS	MS_SYNCHRONOUS
+#undef MS_REMOUNT
   MS_REMOUNT = 32,		/* Alter flags of a mounted FS.  */
 #define MS_REMOUNT	MS_REMOUNT
+#undef MS_MANDLOCK
   MS_MANDLOCK = 64,		/* Allow mandatory locks on an FS.  */
 #define MS_MANDLOCK	MS_MANDLOCK
+#undef MS_DIRSYNC
   MS_DIRSYNC = 128,		/* Directory modifications are synchronous.  */
 #define MS_DIRSYNC	MS_DIRSYNC
+#undef MS_NOSYMFOLLOW
   MS_NOSYMFOLLOW = 256,		/* Do not follow symlinks.  */
 #define MS_NOSYMFOLLOW	MS_NOSYMFOLLOW
+#undef MS_NOATIME
   MS_NOATIME = 1024,		/* Do not update access times.  */
 #define MS_NOATIME	MS_NOATIME
+#undef MS_NODIRATIME
   MS_NODIRATIME = 2048,		/* Do not update directory access times.  */
 #define MS_NODIRATIME	MS_NODIRATIME
+#undef MS_BIND
   MS_BIND = 4096,		/* Bind directory at different place.  */
 #define MS_BIND		MS_BIND
+#undef MS_MOVE
   MS_MOVE = 8192,
 #define MS_MOVE		MS_MOVE
+#undef MS_REC
   MS_REC = 16384,
 #define MS_REC		MS_REC
+#undef MS_SILENT
   MS_SILENT = 32768,
 #define MS_SILENT	MS_SILENT
+#undef MS_POSIXACL
   MS_POSIXACL = 1 << 16,	/* VFS does not apply the umask.  */
 #define MS_POSIXACL	MS_POSIXACL
+#undef MS_UNBINDABLE
   MS_UNBINDABLE = 1 << 17,	/* Change to unbindable.  */
 #define MS_UNBINDABLE	MS_UNBINDABLE
+#undef MS_PRIVATE
   MS_PRIVATE = 1 << 18,		/* Change to private.  */
 #define MS_PRIVATE	MS_PRIVATE
+#undef MS_SLAVE
   MS_SLAVE = 1 << 19,		/* Change to slave.  */
 #define MS_SLAVE	MS_SLAVE
+#undef MS_SHARED
   MS_SHARED = 1 << 20,		/* Change to shared.  */
 #define MS_SHARED	MS_SHARED
+#undef MS_RELATIME
   MS_RELATIME = 1 << 21,	/* Update atime relative to mtime/ctime.  */
 #define MS_RELATIME	MS_RELATIME
+#undef MS_KERNMOUNT
   MS_KERNMOUNT = 1 << 22,	/* This is a kern_mount call.  */
 #define MS_KERNMOUNT	MS_KERNMOUNT
+#undef MS_I_VERSION
   MS_I_VERSION =  1 << 23,	/* Update inode I_version field.  */
 #define MS_I_VERSION	MS_I_VERSION
+#undef MS_STRICTATIME
   MS_STRICTATIME = 1 << 24,	/* Always perform atime updates.  */
 #define MS_STRICTATIME	MS_STRICTATIME
+#undef MS_LAZYTIME
   MS_LAZYTIME = 1 << 25,	/* Update the on-disk [acm]times lazily.  */
 #define MS_LAZYTIME	MS_LAZYTIME
+#undef MS_ACTIVE
   MS_ACTIVE = 1 << 30,
 #define MS_ACTIVE	MS_ACTIVE
+#undef MS_NOUSER
   MS_NOUSER = 1 << 31
 #define MS_NOUSER	MS_NOUSER
 };
 
 /* Flags that can be altered by MS_REMOUNT  */
+#undef MS_RMT_MASK
 #define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION \
 		     |MS_LAZYTIME)
 
 
 /* Magic mount flag number. Has to be or-ed to the flag values.  */
 
+#undef MS_MGC_VAL
 #define MS_MGC_VAL 0xc0ed0000	/* Magic flag number to indicate "new" flags */
 #define MS_MGC_MSK 0xffff0000	/* Magic flag number mask */
 
@@ -106,20 +142,35 @@ enum
    is probably as bad and I don't want to create yet another include
    file.  */
 
+#undef BLKROSET
 #define BLKROSET   _IO(0x12, 93) /* Set device read-only (0 = read-write).  */
+#undef BLKROGET
 #define BLKROGET   _IO(0x12, 94) /* Get read-only status (0 = read_write).  */
+#undef BLKRRPART
 #define BLKRRPART  _IO(0x12, 95) /* Re-read partition table.  */
+#undef BLKGETSIZE
 #define BLKGETSIZE _IO(0x12, 96) /* Return device size.  */
+#undef BLKFLSBUF
 #define BLKFLSBUF  _IO(0x12, 97) /* Flush buffer cache.  */
+#undef BLKRASET
 #define BLKRASET   _IO(0x12, 98) /* Set read ahead for block device.  */
+#undef BLKRAGET
 #define BLKRAGET   _IO(0x12, 99) /* Get current read ahead setting.  */
+#undef BLKFRASET
 #define BLKFRASET  _IO(0x12,100) /* Set filesystem read-ahead.  */
+#undef BLKFRAGET
 #define BLKFRAGET  _IO(0x12,101) /* Get filesystem read-ahead.  */
+#undef BLKSECTSET
 #define BLKSECTSET _IO(0x12,102) /* Set max sectors per request.  */
+#undef BLKSECTGET
 #define BLKSECTGET _IO(0x12,103) /* Get max sectors per request.  */
+#undef BLKSSZGET
 #define BLKSSZGET  _IO(0x12,104) /* Get block device sector size.  */
+#undef BLKBSZGET
 #define BLKBSZGET  _IOR(0x12,112,size_t)
+#undef BLKBSZSET
 #define BLKBSZSET  _IOW(0x12,113,size_t)
+#undef BLKGETSIZE64
 #define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size.  */
 
 
@@ -157,6 +208,7 @@ enum
 #define MOUNT_ATTR_NOSYMFOLLOW  0x00200000 /* Do not follow symlinks.  */
 
 
+#ifndef MOUNT_ATTR_SIZE_VER0
 /* For mount_setattr.  */
 struct mount_attr
 {
@@ -165,6 +217,7 @@ struct mount_attr
   uint64_t propagation;
   uint64_t userns_fd;
 };
+#endif
 
 #define MOUNT_ATTR_SIZE_VER0    32 /* sizeof first published struct */
 
@@ -185,26 +238,28 @@ struct mount_attr
 #define FSPICK_EMPTY_PATH       0x00000008
 
 
+#ifndef FSOPEN_CLOEXEC
 /* The type of fsconfig call made.   */
 enum fsconfig_command
 {
   FSCONFIG_SET_FLAG       = 0,    /* Set parameter, supplying no value */
-#define FSCONFIG_SET_FLAG FSCONFIG_SET_FLAG
+# define FSCONFIG_SET_FLAG FSCONFIG_SET_FLAG
   FSCONFIG_SET_STRING     = 1,    /* Set parameter, supplying a string value */
-#define FSCONFIG_SET_STRING FSCONFIG_SET_STRING
+# define FSCONFIG_SET_STRING FSCONFIG_SET_STRING
   FSCONFIG_SET_BINARY     = 2,    /* Set parameter, supplying a binary blob value */
-#define FSCONFIG_SET_BINARY FSCONFIG_SET_BINARY
+# define FSCONFIG_SET_BINARY FSCONFIG_SET_BINARY
   FSCONFIG_SET_PATH       = 3,    /* Set parameter, supplying an object by path */
-#define FSCONFIG_SET_PATH FSCONFIG_SET_PATH
+# define FSCONFIG_SET_PATH FSCONFIG_SET_PATH
   FSCONFIG_SET_PATH_EMPTY = 4,    /* Set parameter, supplying an object by (empty) path */
-#define FSCONFIG_SET_PATH_EMPTY FSCONFIG_SET_PATH_EMPTY
+# define FSCONFIG_SET_PATH_EMPTY FSCONFIG_SET_PATH_EMPTY
   FSCONFIG_SET_FD         = 5,    /* Set parameter, supplying an object by fd */
-#define FSCONFIG_SET_FD FSCONFIG_SET_FD
+# define FSCONFIG_SET_FD FSCONFIG_SET_FD
   FSCONFIG_CMD_CREATE     = 6,    /* Invoke superblock creation */
-#define FSCONFIG_CMD_CREATE FSCONFIG_CMD_CREATE
+# define FSCONFIG_CMD_CREATE FSCONFIG_CMD_CREATE
   FSCONFIG_CMD_RECONFIGURE = 7,   /* Invoke superblock reconfiguration */
-#define FSCONFIG_CMD_RECONFIGURE FSCONFIG_CMD_RECONFIGURE
+# define FSCONFIG_CMD_RECONFIGURE FSCONFIG_CMD_RECONFIGURE
 };
+#endif
 
 /* open_tree flags.  */
 #define OPEN_TREE_CLONE    1         /* Clone the target tree and attach the clone */
diff --git a/sysdeps/unix/sysv/linux/tst-mount-compile.py b/sysdeps/unix/sysv/linux/tst-mount-compile.py
new file mode 100755
index 0000000000..0ec74d4e0b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-mount-compile.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python3
+# Check if glibc provided sys/mount.h can be used along related kernel
+# headers.
+# 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/>.
+
+import argparse
+import sys
+
+import glibcextract
+
+
+def main():
+    """The main entry point."""
+    parser = argparse.ArgumentParser(
+        description='Check if glibc provided sys/mount.h can be '
+                    ' used along related kernel headers.')
+    parser.add_argument('--cc', metavar='CC',
+                        help='C compiler (including options) to use')
+    args = parser.parse_args()
+
+    if glibcextract.compile_c_snippet(
+            '#include <linux/mount.h>',
+            args.cc).returncode != 0:
+        sys.exit (77)
+
+    def check(testname, snippet):
+        # Add -Werror to catch macro redefinitions and _ISOMAC to avoid
+        # internal glibc definitions.
+        r = glibcextract.compile_c_snippet(snippet, args.cc,
+                '-Werror -D_ISOMAC')
+        if r.returncode != 0:
+            print('error: test {}:\n{}'.format(testname, r.output.decode()))
+        return r.returncode
+
+    status = max(
+        check("sys/mount.h + linux/mount.h",
+              "#include <sys/mount.h>\n"
+              "#include <linux/mount.h>"),
+        check("sys/mount.h + linux/fs.h",
+              "#include <sys/mount.h>\n"
+              "#include <linux/fs.h>"),
+        check("linux/mount.h + sys/mount.h",
+              "#include <linux/mount.h>\n"
+              "#include <sys/mount.h>"),
+        check("linux/fs.h + sys/mount.h",
+              "#include <linux/fs.h>\n"
+              "#include <sys/mount.h>"))
+    sys.exit(status)
+
+if __name__ == '__main__':
+    main()

commit 3bd3c612e98a53ce60ed972f5cd2b90628b3cba5
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 16 09:25:23 2022 +0200

    Linux: Fix enum fsconfig_command detection in <sys/mount.h>
    
    The #ifdef FSOPEN_CLOEXEC check did not work because the macro
    was always defined in this header prior to the check, so that
    the <linux/mount.h> contents did not matter.
    
    Fixes commit 774058d72942249f71d74e7f2b639f77184160a6
    ("linux: Fix sys/mount.h usage with kernel headers").
    
    (cherry picked from commit 2955ef4b7c9b56fcd7abfeddef7ee83c60abff98)

diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
index 2e3fd6a7fe..19841d0738 100644
--- a/sysdeps/unix/sysv/linux/sys/mount.h
+++ b/sysdeps/unix/sysv/linux/sys/mount.h
@@ -188,9 +188,6 @@ enum
 };
 
 
-/* fsopen flags.  */
-#define FSOPEN_CLOEXEC          0x00000001
-
 /* fsmount flags.  */
 #define FSMOUNT_CLOEXEC         0x00000001
 
@@ -261,6 +258,9 @@ enum fsconfig_command
 };
 #endif
 
+/* fsopen flags.  */
+#define FSOPEN_CLOEXEC          0x00000001
+
 /* open_tree flags.  */
 #define OPEN_TREE_CLONE    1         /* Clone the target tree and attach the clone */
 #define OPEN_TREE_CLOEXEC  O_CLOEXEC /* Close the file on execve() */

commit b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Sun Aug 28 16:52:53 2022 -0300

    syslog: Fix large messages (BZ#29536)
    
    The a583b6add407c17cd change did not handle large messages that
    would require a heap allocation correctly, where the message itself
    is not take in consideration.
    
    This patch fixes it and extend the tst-syslog to check for large
    messages as well.
    
    Checked on x86_64-linux-gnu.
    
    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
    (cherry picked from commit 52a5be0df411ef3ff45c10c7c308cb92993d15b1)

diff --git a/misc/syslog.c b/misc/syslog.c
index 554089bfc4..b88f66c835 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -193,28 +193,32 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
       int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
                                      mode_flags);
       if (0 <= vl && vl < sizeof bufs - l)
-        {
-          buf = bufs;
-          bufsize = l + vl;
-        }
+        buf = bufs;
+      bufsize = l + vl;
 
       va_end (apc);
     }
 
   if (buf == NULL)
     {
-      buf = malloc (l * sizeof (char));
+      buf = malloc ((bufsize + 1) * sizeof (char));
       if (buf != NULL)
 	{
 	  /* Tell the cancellation handler to free this buffer.  */
 	  clarg.buf = buf;
 
 	  if (has_ts)
-	    __snprintf (bufs, sizeof bufs,
+	    __snprintf (buf, l + 1,
 			SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
 	  else
-	    __snprintf (bufs, sizeof bufs,
+	    __snprintf (buf, l + 1,
 			SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
+
+	  va_list apc;
+	  va_copy (apc, ap);
+	  __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
+				mode_flags);
+	  va_end (apc);
 	}
       else
         {
diff --git a/misc/tst-syslog.c b/misc/tst-syslog.c
index e550d15796..1d332ece53 100644
--- a/misc/tst-syslog.c
+++ b/misc/tst-syslog.c
@@ -68,21 +68,19 @@ static const int priorities[] =
     LOG_DEBUG
   };
 
-enum
-  {
-    ident_length = 64,
-    msg_length = 64
-  };
+#define IDENT_LENGTH 64
+#define MSG_LENGTH   1024
 
 #define SYSLOG_MSG_BASE "syslog_message"
 #define OPENLOG_IDENT   "openlog_ident"
+static char large_message[MSG_LENGTH];
 
 struct msg_t
   {
     int priority;
     int facility;
-    char ident[ident_length];
-    char msg[msg_length];
+    char ident[IDENT_LENGTH];
+    char msg[MSG_LENGTH];
     pid_t pid;
   };
 
@@ -147,6 +145,37 @@ check_syslog_message (const struct msg_t *msg, int msgnum, int options,
   return true;
 }
 
+static void
+send_syslog_large (int options)
+{
+  int facility = LOG_USER;
+  int priority = LOG_INFO;
+
+  syslog (facility | priority, "%s %d %d", large_message, facility,
+	  priority);
+}
+
+static void
+send_vsyslog_large (int options)
+{
+  int facility = LOG_USER;
+  int priority = LOG_INFO;
+
+  call_vsyslog (facility | priority, "%s %d %d", large_message, facility,
+		priority);
+}
+
+static bool
+check_syslog_message_large (const struct msg_t *msg, int msgnum, int options,
+			    pid_t pid)
+{
+  TEST_COMPARE (msg->facility, LOG_USER);
+  TEST_COMPARE (msg->priority, LOG_INFO);
+  TEST_COMPARE_STRING (msg->msg, large_message);
+
+  return false;
+}
+
 static void
 send_openlog (int options)
 {
@@ -179,6 +208,17 @@ send_openlog (int options)
   closelog ();
 }
 
+static void
+send_openlog_large (int options)
+{
+  /* Define a non-default IDENT and a not default facility.  */
+  openlog (OPENLOG_IDENT, options, LOG_LOCAL0);
+
+  syslog (LOG_INFO, "%s %d %d", large_message, LOG_LOCAL0, LOG_INFO);
+
+  closelog ();
+}
+
 static bool
 check_openlog_message (const struct msg_t *msg, int msgnum,
                        int options, pid_t pid)
@@ -189,7 +229,7 @@ check_openlog_message (const struct msg_t *msg, int msgnum,
   int expected_priority = priorities[msgnum % array_length (priorities)];
   TEST_COMPARE (msg->priority, expected_priority);
 
-  char expected_ident[ident_length];
+  char expected_ident[IDENT_LENGTH];
   snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:",
             OPENLOG_IDENT,
             options & LOG_PID ? "[" : "",
@@ -211,15 +251,38 @@ check_openlog_message (const struct msg_t *msg, int msgnum,
   return true;
 }
 
+static bool
+check_openlog_message_large (const struct msg_t *msg, int msgnum,
+			     int options, pid_t pid)
+{
+  char expected_ident[IDENT_LENGTH];
+  snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:",
+            OPENLOG_IDENT,
+            options & LOG_PID ? "[" : "",
+            options & LOG_PID ? pid : 0,
+            options & LOG_PID ? "]" : "");
+
+  TEST_COMPARE_STRING (msg->ident, expected_ident);
+  TEST_COMPARE_STRING (msg->msg, large_message);
+  TEST_COMPARE (msg->priority, LOG_INFO);
+  TEST_COMPARE (msg->facility, LOG_LOCAL0);
+
+  return false;
+}
+
 static struct msg_t
 parse_syslog_msg (const char *msg)
 {
   struct msg_t r = { .pid = -1 };
   int number;
 
+#define STRINPUT(size)  XSTRINPUT(size)
+#define XSTRINPUT(size) "%" # size "s"
+
   /* The message in the form:
-     <179>Apr  8 14:51:19 tst-syslog: syslog message 176 3  */
-  int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d %32s %64s %*d %*d",
+     <179>Apr  8 14:51:19  tst-syslog: message 176 3  */
+  int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d " STRINPUT(IDENT_LENGTH)
+		       " " STRINPUT(MSG_LENGTH) " %*d %*d",
                   &number, r.ident, r.msg);
   TEST_COMPARE (n, 3);
 
@@ -246,7 +309,7 @@ parse_syslog_console (const char *msg)
 
   /* The message in the form:
      openlog_ident: syslog_message 128 0  */
-  int n = sscanf (msg, "%32s %64s %d %d",
+  int n = sscanf (msg, STRINPUT(IDENT_LENGTH) " " STRINPUT(MSG_LENGTH) " %d %d",
       r.ident, r.msg, &facility, &priority);
   TEST_COMPARE (n, 4);
 
@@ -281,7 +344,7 @@ check_syslog_udp (void (*syslog_send)(int), int options,
   int msgnum = 0;
   while (1)
     {
-      char buf[512];
+      char buf[2048];
       size_t l = xrecvfrom (server_udp, buf, sizeof (buf), 0,
                             (struct sockaddr *) &addr, &addrlen);
       buf[l] = '\0';
@@ -325,7 +388,7 @@ check_syslog_tcp (void (*syslog_send)(int), int options,
 
   int client_tcp = xaccept (server_tcp, NULL, NULL);
 
-  char buf[512], *rb = buf;
+  char buf[2048], *rb = buf;
   size_t rbl = sizeof (buf);
   size_t prl = 0;  /* Track the size of the partial record.  */
   int msgnum = 0;
@@ -393,20 +456,34 @@ check_syslog_console_read (FILE *fp)
 }
 
 static void
-check_syslog_console (void)
+check_syslog_console_read_large (FILE *fp)
+{
+  char buf[2048];
+  TEST_VERIFY (fgets (buf, sizeof (buf), fp) != NULL);
+  struct msg_t msg = parse_syslog_console (buf);
+
+  TEST_COMPARE_STRING (msg.ident, OPENLOG_IDENT ":");
+  TEST_COMPARE_STRING (msg.msg, large_message);
+  TEST_COMPARE (msg.priority, LOG_INFO);
+  TEST_COMPARE (msg.facility, LOG_LOCAL0);
+}
+
+static void
+check_syslog_console (void (*syslog_send)(int),
+		      void (*syslog_check)(FILE *fp))
 {
   xmkfifo (_PATH_CONSOLE, 0666);
 
   pid_t sender_pid = xfork ();
   if (sender_pid == 0)
     {
-      send_openlog (LOG_CONS);
+      syslog_send (LOG_CONS);
       _exit (0);
     }
 
   {
     FILE *fp = xfopen (_PATH_CONSOLE, "r+");
-    check_syslog_console_read (fp);
+    syslog_check (fp);
     xfclose (fp);
   }
 
@@ -425,16 +502,28 @@ send_openlog_callback (void *clousure)
 }
 
 static void
-check_syslog_perror (void)
+send_openlog_callback_large (void *clousure)
+{
+  int options = *(int *) clousure;
+  send_openlog_large (options);
+}
+
+static void
+check_syslog_perror (bool large)
 {
   struct support_capture_subprocess result;
-  result = support_capture_subprocess (send_openlog_callback,
+  result = support_capture_subprocess (large
+				       ? send_openlog_callback_large
+				       : send_openlog_callback,
                                        &(int){LOG_PERROR});
 
   FILE *mfp = fmemopen (result.err.buffer, result.err.length, "r");
   if (mfp == NULL)
     FAIL_EXIT1 ("fmemopen: %m");
-  check_syslog_console_read (mfp);
+  if (large)
+    check_syslog_console_read_large (mfp);
+  else
+    check_syslog_console_read (mfp);
   xfclose (mfp);
 
   support_capture_subprocess_check (&result, "tst-openlog-child", 0,
@@ -462,10 +551,31 @@ do_test (void)
   check_syslog_tcp (send_openlog, LOG_PID, check_openlog_message);
 
   /* Check the LOG_CONS option.  */
-  check_syslog_console ();
+  check_syslog_console (send_openlog, check_syslog_console_read);
 
   /* Check the LOG_PERROR option.  */
-  check_syslog_perror ();
+  check_syslog_perror (false);
+
+  /* Similar tests as before, but with a large message to trigger the
+     syslog path that uses dynamically allocated memory.  */
+  memset (large_message, 'a', sizeof large_message - 1);
+  large_message[sizeof large_message - 1] = '\0';
+
+  check_syslog_udp (send_syslog_large, 0, check_syslog_message_large);
+  check_syslog_tcp (send_syslog_large, 0, check_syslog_message_large);
+
+  check_syslog_udp (send_vsyslog_large, 0, check_syslog_message_large);
+  check_syslog_tcp (send_vsyslog_large, 0, check_syslog_message_large);
+
+  check_syslog_udp (send_openlog_large, 0, check_openlog_message_large);
+  check_syslog_tcp (send_openlog_large, 0, check_openlog_message_large);
+
+  check_syslog_udp (send_openlog_large, LOG_PID, check_openlog_message_large);
+  check_syslog_tcp (send_openlog_large, LOG_PID, check_openlog_message_large);
+
+  check_syslog_console (send_openlog_large, check_syslog_console_read_large);
+
+  check_syslog_perror (true);
 
   return 0;
 }

commit 924e4f3eaa502ce82fccf8537f021a796d158771
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)

diff --git a/NEWS b/NEWS
index ae30900bbc..6d31e5abba 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
   [29446] _dlopen now ignores dl_caller argument in static mode
   [29485] Linux: Terminate subprocess on late failure in tst-pidfd
   [29490] alpha: New __brk_call implementation is broken
+  [29528] elf: Call __libc_early_init for reused namespaces
 
 
 Version 2.36
diff --git a/elf/Makefile b/elf/Makefile
index fd77d0c7c8..43353a4b08 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -408,6 +408,7 @@ tests += \
   tst-dlmopen4 \
   tst-dlmopen-dlerror \
   tst-dlmopen-gethostbyname \
+  tst-dlmopen-twice \
   tst-dlopenfail \
   tst-dlopenfail-2 \
   tst-dlopenrpath \
@@ -834,6 +835,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 \
@@ -2967,3 +2970,25 @@ $(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
+
+$(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 a23e65926b..46e8066fd8 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -844,11 +844,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_update (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 0000000000..0eaf04948c
--- /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 0000000000..40c6c01f96
--- /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 0000000000..449f3c8fa9
--- /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>

commit 3c791f2031ca8f6b99e96b774ed1c505ceb93595
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 0000000000..00b1b93342
--- /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 3d19d5556f..4af102a3f6 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 0000000000..8e1735c33b
--- /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 0e017f458b..3f110efe57 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 5d6a40853d..c1321c7518 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  */

commit b3736d1a3c60a3ec9959bf3b38794958546bf6a2
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 30 13:35:52 2022 -0300

    elf: Restore how vDSO dependency is printed with LD_TRACE_LOADED_OBJECTS (BZ #29539)
    
    The d7703d3176d225d5743b21811d888619eba39e82 changed how vDSO like
    dependencies are printed, instead of just the name and address it
    follows other libraries mode and prints 'name => path'.
    
    Unfortunately, this broke some ldd consumer that uses the output to
    filter out the program's dependencies.  For instance CMake
    bundleutilities module [1], where GetPrequirite uses the regex to filter
    out 'name => path' [2].
    
    This patch restore the previous way to print just the name and the
    mapping address.
    
    Checked on x86_64-linux-gnu.
    
    [1] https://github.com/Kitware/CMake/tree/master/Tests/BundleUtilities
    [2] https://github.com/Kitware/CMake/blob/master/Modules/GetPrerequisites.cmake#L733
    
    Reviewed-by: Florian Weimer <fweimer@redhat.com>
    (cherry picked from commit 1e903124cec4492463d075c6c061a2a772db77bf)

diff --git a/NEWS b/NEWS
index 6d31e5abba..757ded85e0 100644
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ The following bugs are resolved with this release:
   [29485] Linux: Terminate subprocess on late failure in tst-pidfd
   [29490] alpha: New __brk_call implementation is broken
   [29528] elf: Call __libc_early_init for reused namespaces
-
+  [29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
 
 Version 2.36
 
diff --git a/elf/rtld.c b/elf/rtld.c
index cbbaf4a331..3e771a93d8 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2122,6 +2122,12 @@ dl_main (const ElfW(Phdr) *phdr,
 	    if (l->l_faked)
 	      /* The library was not found.  */
 	      _dl_printf ("\t%s => not found\n",  l->l_libname->name);
+	    else if (strcmp (l->l_libname->name, l->l_name) == 0)
+	      /* Print vDSO like libraries without duplicate name.  Some
+		 consumers depend of this format.  */
+	      _dl_printf ("\t%s (0x%0*Zx)\n", l->l_libname->name,
+			  (int) sizeof l->l_map_start * 2,
+			  (size_t) l->l_map_start);
 	    else
 	      _dl_printf ("\t%s => %s (0x%0*Zx)\n",
 			  DSO_FILENAME (l->l_libname->name),
