Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: debian-gl...@lists.debian.org, debian-boot@lists.debian.org

Please unblock package glibc

[ Reason ]
This new version fixes testsuite failures when run on a kernel which has
kernel.unprivileged_userns_clone set to 1. This is the case of the
Bullseye kernel. This problem manifests itself as an FTBFS when building
the package or a failed autopkgtests.

In addition this version also fixes the display of non-ascii characters
in German debconf template. It also includes fixes from the upstream
stable branch fixing:
- a wrong assumption of available instructions on s390x in the memmove
  code which might be triggered by a kernel parameter or some older
  versions of zVM
- a fix in the way of AT_SECURE binaries are handled, which might be
  used to facilitate the exploitation of security issues in those
  binaries

[ Impact ]
If the unblock is not granted, users won't be able to build the package
from sources on a Bullseye system without using the nocheck build option
or disabling kernel.unprivileged_userns_clone. In addition users with
a German locale will have to understand the displayed text without the
non-ASCII letters.

[ Tests ]
The changes related to the testsuite actually improves the testsuite
coverage. This allowed to find an issue in the debian/rules makefile
causing the value of the --build= parameter to be wrongly empty.

The debconf changes have been tested manually on a system set to German
locale.

The upstream changes related to the AT_SECURE binaries come with
additional tests. Note that those tests actually represent the bigger
part of the debdiff.

[ Risks ]
The fixes related to the testsuite involves many changes to our build
system, by letting the upstream makefiles to install the ld.so symlink
instead of doing it in the Debian makefiles, in an architecture specific
way for bi/tri-arch packages. While the changes might look risky at a
first glance, they do not change the code in the binaries, but only the
ld.so symlinks and the libc.so linker scripts. Those have been verified
manually on the packages built by glibc and cross-toolchain-base.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]
The decision to install the ld.so symlink using the Debian specific
makefiles instead of the upstream ones seems to have been taken many
years ago to avoid changing dpkg-cross. dpkg-cross has been fixed
recently in version 2.6.18+nmu1 (already in Bullseye), so this is not
an issue anymore. No conflicts or breaks against dpkg-cross have been
added as dpkg-cross is basically a .deb mangler which takes any .deb
file from the command line.

unblock glibc/2.31-12
diff -Nru glibc-2.31/debian/changelog glibc-2.31/debian/changelog
--- glibc-2.31/debian/changelog 2021-03-31 22:09:32.000000000 +0200
+++ glibc-2.31/debian/changelog 2021-05-01 22:56:06.000000000 +0200
@@ -1,3 +1,29 @@
+glibc (2.31-12) unstable; urgency=medium
+
+  * debian/po/de.po: fix encoding declaration.  Closes: #986450.
+  * debian/patches/git-updates.diff: update from upstream stable branch:
+    - On s390x, check for vector support in memmove ifunc-selector in
+      addition to Miscellaneous-Instruction-Extensions.
+  * debian/patches/any/local-rtlddir-cross.diff: drop patch, letting upstream
+    makefiles to install the dynamic linker symlink directly in the right
+    location. This fixes the temporary installation done by upstream makefiles
+    to run some tests in a container.  Closes: #973278, #985617.
+  * debian/rules.d/build.mk: do not create the dynamic linker manually.
+  * debian/sysdeps/*.mk: do not create the dynamic linker manually for
+    bi/tri-arch packages.
+  * debian/rules.d/build.mk: create the soname symlink for ld-2.xx.so, to
+    avoid its creation later by ldconfig.
+  * debian/debhelper.in/libc.install, debhelper.in/libc-alt.install,
+    debhelper.in/libc-udeb.install, debhelper.in/libc-udeb.install.hurd-i386:
+    adjust given that the dynamic linker symlink is now already at the correct
+    location.
+  * debian/patches/git-updates.diff: update from upstream stable branch:
+    - Fix GLIBC_TUNABLES parsing for AT_SECURE binaries.
+  * debian/rules.d/build.mk: escape EOL so that $configure_build is correctly
+    passed to the configure script.
+
+ -- Aurelien Jarno <aure...@debian.org>  Sat, 01 May 2021 22:56:06 +0200
+
 glibc (2.31-11) unstable; urgency=medium
 
   * debian/debhelper.in/libc.preinst: handle the case where debconf
diff -Nru glibc-2.31/debian/debhelper.in/libc-alt.install 
glibc-2.31/debian/debhelper.in/libc-alt.install
--- glibc-2.31/debian/debhelper.in/libc-alt.install     2019-07-29 
11:56:57.000000000 +0200
+++ glibc-2.31/debian/debhelper.in/libc-alt.install     2021-04-25 
18:11:42.000000000 +0200
@@ -1,4 +1,5 @@
 # This file is used for biarch libraries.
+TMPDIR/RTLDDIR/*.so* RTLDDIR
 TMPDIR/SLIBDIR/*.so* SLIBDIR
 TMPDIR/LIBDIR/gconv/* LIBDIR/gconv/
 
diff -Nru glibc-2.31/debian/debhelper.in/libc.install 
glibc-2.31/debian/debhelper.in/libc.install
--- glibc-2.31/debian/debhelper.in/libc.install 2019-07-29 11:56:57.000000000 
+0200
+++ glibc-2.31/debian/debhelper.in/libc.install 2021-04-25 18:11:42.000000000 
+0200
@@ -1,4 +1,4 @@
-TMPDIR/lib/*.so* RTLDDIR
+TMPDIR/RTLDDIR/*.so* RTLDDIR
 TMPDIR/SLIBDIR/*.so* SLIBDIR
 TMPDIR/LIBDIR/gconv/* LIBDIR/gconv
 TMPDIR/LIBDIR/audit/* LIBDIR/audit
diff -Nru glibc-2.31/debian/debhelper.in/libc-udeb.install 
glibc-2.31/debian/debhelper.in/libc-udeb.install
--- glibc-2.31/debian/debhelper.in/libc-udeb.install    2020-07-13 
21:26:16.000000000 +0200
+++ glibc-2.31/debian/debhelper.in/libc-udeb.install    2021-04-25 
18:11:42.000000000 +0200
@@ -1,4 +1,4 @@
-TMPDIR/lib/*.so* RTLDDIR
+TMPDIR/RTLDDIR/*.so* RTLDDIR
 TMPDIR/SLIBDIR/ld*.so* SLIBDIR
 TMPDIR/SLIBDIR/libm-*.so* SLIBDIR
 TMPDIR/SLIBDIR/libm.so* SLIBDIR
diff -Nru glibc-2.31/debian/debhelper.in/libc-udeb.install.hurd-i386 
glibc-2.31/debian/debhelper.in/libc-udeb.install.hurd-i386
--- glibc-2.31/debian/debhelper.in/libc-udeb.install.hurd-i386  2021-03-20 
23:52:37.000000000 +0100
+++ glibc-2.31/debian/debhelper.in/libc-udeb.install.hurd-i386  2021-04-25 
18:11:42.000000000 +0200
@@ -1,4 +1,4 @@
-TMPDIR/lib/*.so* RTLDDIR
+TMPDIR/RTLDDIR/*.so* RTLDDIR
 TMPDIR/SLIBDIR/ld*.so* SLIBDIR
 TMPDIR/SLIBDIR/libm-*.so* SLIBDIR
 TMPDIR/SLIBDIR/libm.so* SLIBDIR
diff -Nru glibc-2.31/debian/patches/any/local-rtlddir-cross.diff 
glibc-2.31/debian/patches/any/local-rtlddir-cross.diff
--- glibc-2.31/debian/patches/any/local-rtlddir-cross.diff      2019-08-16 
12:57:32.000000000 +0200
+++ glibc-2.31/debian/patches/any/local-rtlddir-cross.diff      1970-01-01 
01:00:00.000000000 +0100
@@ -1,29 +0,0 @@
-Description: Install ld.so to slibdir instead of rtlddir to fix cross builds
- When installing a cross-libc purely for linking purposes but not
- runtime use, the linker shouldn't be installed in rtlddir, since
- we won't actually be USING it, and thus referencing the rtlddir
- path in libc.so ends up blowing up cross-compilers for no reason.
-Author: Adam Conrad <adcon...@ubuntu.com>
-
---- a/Makeconfig
-+++ b/Makeconfig
-@@ -161,7 +161,7 @@
- ifndef rtlddir
- rtlddir = $(slibdir)
- endif
--inst_rtlddir = $(install_root)$(rtlddir)
-+inst_rtlddir = $(install_root)$(slibdir)
- 
- # Prefix to put on files installed in $(libdir).  For libraries `libNAME.a',
- # the prefix is spliced between `lib' and the name, so the linker switch
---- a/Makerules
-+++ b/Makerules
-@@ -1168,7 +1168,7 @@
-        cat $<; \
-        echo 'GROUP ( $(slibdir)/libc.so$(libc.so-version)' \
-             '$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)$(libc-name))'\
--            ' AS_NEEDED (' $(rtlddir)/$(rtld-installed-name) ') )' \
-+            ' AS_NEEDED (' $(slibdir)/$(rtld-installed-name) ') )' \
-       ) > $@.new
- ifeq ($(patsubst gnu%,,$(config-os)),)
-       echo 'INPUT ( AS_NEEDED ( -lmachuser -lhurduser ) )' >> $@.new
diff -Nru glibc-2.31/debian/patches/git-updates.diff 
glibc-2.31/debian/patches/git-updates.diff
--- glibc-2.31/debian/patches/git-updates.diff  2021-03-20 23:52:40.000000000 
+0100
+++ glibc-2.31/debian/patches/git-updates.diff  2021-04-26 12:29:50.000000000 
+0200
@@ -188,7 +188,7 @@
        /* Check whether we make any progress.  */
        _Unwind_Word cfa = unwind_getcfa (ctx);
 diff --git a/elf/Makefile b/elf/Makefile
-index 632a4d8b0f..e8384d1754 100644
+index 632a4d8b0f..f9646f9c8c 100644
 --- a/elf/Makefile
 +++ b/elf/Makefile
 @@ -1348,6 +1348,8 @@ CFLAGS-ifuncmain7pie.c += $(pie-ccflag)
@@ -200,6 +200,106 @@
  $(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so
  $(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o
  $(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so
+@@ -1581,8 +1583,6 @@ $(objpfx)tst-nodelete-dlclose.out: 
$(objpfx)tst-nodelete-dlclose-dso.so \
+ 
+ tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \
+                    LD_HWCAP_MASK=0x1
+-tst-env-setuid-tunables-ENV = \
+-      GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096
+ 
+ $(objpfx)tst-debug1: $(libdl)
+ $(objpfx)tst-debug1.out: $(objpfx)tst-debug1mod1.so
+diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
+index 44d06665b4..2296ad3870 100644
+--- a/elf/dl-tunables.c
++++ b/elf/dl-tunables.c
+@@ -177,6 +177,7 @@ parse_tunables (char *tunestr, char *valstring)
+     return;
+ 
+   char *p = tunestr;
++  size_t off = 0;
+ 
+   while (true)
+     {
+@@ -190,7 +191,11 @@ parse_tunables (char *tunestr, char *valstring)
+       /* If we reach the end of the string before getting a valid name-value
+        pair, bail out.  */
+       if (p[len] == '\0')
+-      return;
++      {
++        if (__libc_enable_secure)
++          tunestr[off] = '\0';
++        return;
++      }
+ 
+       /* We did not find a valid name-value pair before encountering the
+        colon.  */
+@@ -216,35 +221,28 @@ parse_tunables (char *tunestr, char *valstring)
+ 
+         if (tunable_is_name (cur->name, name))
+           {
+-            /* If we are in a secure context (AT_SECURE) then ignore the 
tunable
+-               unless it is explicitly marked as secure.  Tunable values take
+-               precendence over their envvar aliases.  */
++            /* If we are in a secure context (AT_SECURE) then ignore the
++               tunable unless it is explicitly marked as secure.  Tunable
++               values take precedence over their envvar aliases.  We write
++               the tunables that are not SXID_ERASE back to TUNESTR, thus
++               dropping all SXID_ERASE tunables and any invalid or
++               unrecognized tunables.  */
+             if (__libc_enable_secure)
+               {
+-                if (cur->security_level == TUNABLE_SECLEVEL_SXID_ERASE)
++                if (cur->security_level != TUNABLE_SECLEVEL_SXID_ERASE)
+                   {
+-                    if (p[len] == '\0')
+-                      {
+-                        /* Last tunable in the valstring.  Null-terminate and
+-                           return.  */
+-                        *name = '\0';
+-                        return;
+-                      }
+-                    else
+-                      {
+-                        /* Remove the current tunable from the string.  We do
+-                           this by overwriting the string starting from NAME
+-                           (which is where the current tunable begins) with
+-                           the remainder of the string.  We then have P point
+-                           to NAME so that we continue in the correct
+-                           position in the valstring.  */
+-                        char *q = &p[len + 1];
+-                        p = name;
+-                        while (*q != '\0')
+-                          *name++ = *q++;
+-                        name[0] = '\0';
+-                        len = 0;
+-                      }
++                    if (off > 0)
++                      tunestr[off++] = ':';
++
++                    const char *n = cur->name;
++
++                    while (*n != '\0')
++                      tunestr[off++] = *n++;
++
++                    tunestr[off++] = '=';
++
++                    for (size_t j = 0; j < len; j++)
++                      tunestr[off++] = value[j];
+                   }
+ 
+                 if (cur->security_level != TUNABLE_SECLEVEL_NONE)
+@@ -257,9 +255,7 @@ parse_tunables (char *tunestr, char *valstring)
+           }
+       }
+ 
+-      if (p[len] == '\0')
+-      return;
+-      else
++      if (p[len] != '\0')
+       p += len + 1;
+     }
+ }
 diff --git a/elf/ifuncmain6pie.c b/elf/ifuncmain6pie.c
 index 04faeb86ef..4a01906836 100644
 --- a/elf/ifuncmain6pie.c
@@ -274,6 +374,391 @@
 -  return foo;
 +  return foo ();
  }
+diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
+index 971d5892b1..ca0c8c245c 100644
+--- a/elf/tst-env-setuid-tunables.c
++++ b/elf/tst-env-setuid-tunables.c
+@@ -25,35 +25,76 @@
+ #include "config.h"
+ #undef _LIBC
+ 
+-#define test_parent test_parent_tunables
+-#define test_child test_child_tunables
+-
+-static int test_child_tunables (void);
+-static int test_parent_tunables (void);
+-
+-#include "tst-env-setuid.c"
+-
+-#define CHILD_VALSTRING_VALUE "glibc.malloc.mmap_threshold=4096"
+-#define PARENT_VALSTRING_VALUE \
+-  "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096"
++#include <errno.h>
++#include <fcntl.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <sys/wait.h>
++#include <unistd.h>
++#include <intprops.h>
++#include <array_length.h>
++
++#include <support/check.h>
++#include <support/support.h>
++#include <support/test-driver.h>
++#include <support/capture_subprocess.h>
++
++const char *teststrings[] =
++{
++  "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
++  
"glibc.malloc.check=2:glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
++  
"glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096:glibc.malloc.check=2",
++  "glibc.malloc.perturb=0x800",
++  "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
++  
"glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
++  "glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096",
++  "not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
++  
"glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2",
++  
"glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096",
++  ":glibc.malloc.garbage=2:glibc.malloc.check=1",
++  "glibc.malloc.check=1:glibc.malloc.check=2",
++  "not_valid.malloc.check=2",
++  "glibc.not_valid.check=2",
++};
++
++const char *resultstrings[] =
++{
++  "glibc.malloc.mmap_threshold=4096",
++  "glibc.malloc.mmap_threshold=4096",
++  "glibc.malloc.mmap_threshold=4096",
++  "glibc.malloc.perturb=0x800",
++  "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
++  "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
++  "glibc.malloc.mmap_threshold=4096",
++  "glibc.malloc.mmap_threshold=4096",
++  "",
++  "",
++  "",
++  "",
++  "",
++  "",
++};
+ 
+ static int
+-test_child_tunables (void)
++test_child (int off)
+ {
+   const char *val = getenv ("GLIBC_TUNABLES");
+ 
+ #if HAVE_TUNABLES
+-  if (val != NULL && strcmp (val, CHILD_VALSTRING_VALUE) == 0)
++  if (val != NULL && strcmp (val, resultstrings[off]) == 0)
+     return 0;
+ 
+   if (val != NULL)
+-    printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val);
++    printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
+ 
+   return 1;
+ #else
+   if (val != NULL)
+     {
+-      printf ("GLIBC_TUNABLES not cleared\n");
++      printf ("[%d] GLIBC_TUNABLES not cleared\n", off);
+       return 1;
+     }
+   return 0;
+@@ -61,15 +102,48 @@ test_child_tunables (void)
+ }
+ 
+ static int
+-test_parent_tunables (void)
++do_test (int argc, char **argv)
+ {
+-  const char *val = getenv ("GLIBC_TUNABLES");
++  /* Setgid child process.  */
++  if (argc == 2)
++    {
++      if (getgid () == getegid ())
++      /* This can happen if the file system is mounted nosuid.  */
++      FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
++                        (intmax_t) getgid ());
+ 
+-  if (val != NULL && strcmp (val, PARENT_VALSTRING_VALUE) == 0)
+-    return 0;
++      int ret = test_child (atoi (argv[1]));
+ 
+-  if (val != NULL)
+-    printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val);
++      if (ret != 0)
++      exit (1);
+ 
+-  return 1;
++      exit (EXIT_SUCCESS);
++    }
++  else
++    {
++      int ret = 0;
++
++      /* Spawn tests.  */
++      for (int i = 0; i < array_length (teststrings); i++)
++      {
++        char buf[INT_BUFSIZE_BOUND (int)];
++
++        printf ("Spawned test for %s (%d)\n", teststrings[i], i);
++        snprintf (buf, sizeof (buf), "%d\n", i);
++        if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
++          exit (1);
++
++        int status = support_capture_subprogram_self_sgid (buf);
++
++        /* Bail out early if unsupported.  */
++        if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
++          return EXIT_UNSUPPORTED;
++
++        ret |= status;
++      }
++      return ret;
++    }
+ }
++
++#define TEST_FUNCTION_ARGV do_test
++#include <support/test-driver.c>
+diff --git a/elf/tst-env-setuid.c b/elf/tst-env-setuid.c
+index 41dc79e83a..2dbccdb69e 100644
+--- a/elf/tst-env-setuid.c
++++ b/elf/tst-env-setuid.c
+@@ -29,173 +29,12 @@
+ #include <sys/wait.h>
+ #include <unistd.h>
+ 
++#include <support/check.h>
+ #include <support/support.h>
+ #include <support/test-driver.h>
++#include <support/capture_subprocess.h>
+ 
+ static char SETGID_CHILD[] = "setgid-child";
+-#define CHILD_STATUS 42
+-
+-/* Return a GID which is not our current GID, but is present in the
+-   supplementary group list.  */
+-static gid_t
+-choose_gid (void)
+-{
+-  const int count = 64;
+-  gid_t groups[count];
+-  int ret = getgroups (count, groups);
+-  if (ret < 0)
+-    {
+-      printf ("getgroups: %m\n");
+-      exit (1);
+-    }
+-  gid_t current = getgid ();
+-  for (int i = 0; i < ret; ++i)
+-    {
+-      if (groups[i] != current)
+-      return groups[i];
+-    }
+-  return 0;
+-}
+-
+-/* Spawn and execute a program and verify that it returns the CHILD_STATUS.  
*/
+-static pid_t
+-do_execve (char **args)
+-{
+-  pid_t kid = vfork ();
+-
+-  if (kid < 0)
+-    {
+-      printf ("vfork: %m\n");
+-      return -1;
+-    }
+-
+-  if (kid == 0)
+-    {
+-      /* Child process.  */
+-      execve (args[0], args, environ);
+-      _exit (-errno);
+-    }
+-
+-  if (kid < 0)
+-    return 1;
+-
+-  int status;
+-
+-  if (waitpid (kid, &status, 0) < 0)
+-    {
+-      printf ("waitpid: %m\n");
+-      return 1;
+-    }
+-
+-  if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+-    return EXIT_UNSUPPORTED;
+-
+-  if (!WIFEXITED (status) || WEXITSTATUS (status) != CHILD_STATUS)
+-    {
+-      printf ("Unexpected exit status %d from child process\n",
+-            WEXITSTATUS (status));
+-      return 1;
+-    }
+-  return 0;
+-}
+-
+-/* Copies the executable into a restricted directory, so that we can
+-   safely make it SGID with the TARGET group ID.  Then runs the
+-   executable.  */
+-static int
+-run_executable_sgid (gid_t target)
+-{
+-  char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd",
+-                           test_dir, (intmax_t) getpid ());
+-  char *execname = xasprintf ("%s/bin", dirname);
+-  int infd = -1;
+-  int outfd = -1;
+-  int ret = 0;
+-  if (mkdir (dirname, 0700) < 0)
+-    {
+-      printf ("mkdir: %m\n");
+-      goto err;
+-    }
+-  infd = open ("/proc/self/exe", O_RDONLY);
+-  if (infd < 0)
+-    {
+-      printf ("open (/proc/self/exe): %m\n");
+-      goto err;
+-    }
+-  outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700);
+-  if (outfd < 0)
+-    {
+-      printf ("open (%s): %m\n", execname);
+-      goto err;
+-    }
+-  char buf[4096];
+-  for (;;)
+-    {
+-      ssize_t rdcount = read (infd, buf, sizeof (buf));
+-      if (rdcount < 0)
+-      {
+-        printf ("read: %m\n");
+-        goto err;
+-      }
+-      if (rdcount == 0)
+-      break;
+-      char *p = buf;
+-      char *end = buf + rdcount;
+-      while (p != end)
+-      {
+-        ssize_t wrcount = write (outfd, buf, end - p);
+-        if (wrcount == 0)
+-          errno = ENOSPC;
+-        if (wrcount <= 0)
+-          {
+-            printf ("write: %m\n");
+-            goto err;
+-          }
+-        p += wrcount;
+-      }
+-    }
+-  if (fchown (outfd, getuid (), target) < 0)
+-    {
+-      printf ("fchown (%s): %m\n", execname);
+-      goto err;
+-    }
+-  if (fchmod (outfd, 02750) < 0)
+-    {
+-      printf ("fchmod (%s): %m\n", execname);
+-      goto err;
+-    }
+-  if (close (outfd) < 0)
+-    {
+-      printf ("close (outfd): %m\n");
+-      goto err;
+-    }
+-  if (close (infd) < 0)
+-    {
+-      printf ("close (infd): %m\n");
+-      goto err;
+-    }
+-
+-  char *args[] = {execname, SETGID_CHILD, NULL};
+-
+-  ret = do_execve (args);
+-
+-err:
+-  if (outfd >= 0)
+-    close (outfd);
+-  if (infd >= 0)
+-    close (infd);
+-  if (execname)
+-    {
+-      unlink (execname);
+-      free (execname);
+-    }
+-  if (dirname)
+-    {
+-      rmdir (dirname);
+-      free (dirname);
+-    }
+-  return ret;
+-}
+ 
+ #ifndef test_child
+ static int
+@@ -256,40 +95,32 @@ do_test (int argc, char **argv)
+   if (argc == 2 && strcmp (argv[1], SETGID_CHILD) == 0)
+     {
+       if (getgid () == getegid ())
+-      {
+-        /* This can happen if the file system is mounted nosuid.  */
+-        fprintf (stderr, "SGID failed: GID and EGID match (%jd)\n",
+-                 (intmax_t) getgid ());
+-        exit (EXIT_UNSUPPORTED);
+-      }
++      /* This can happen if the file system is mounted nosuid.  */
++      FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
++                        (intmax_t) getgid ());
+ 
+       int ret = test_child ();
+ 
+       if (ret != 0)
+       exit (1);
+ 
+-      exit (CHILD_STATUS);
++      exit (EXIT_SUCCESS);
+     }
+   else
+     {
+       if (test_parent () != 0)
+       exit (1);
+ 
+-      /* Try running a setgid program.  */
+-      gid_t target = choose_gid ();
+-      if (target == 0)
+-      {
+-        fprintf (stderr,
+-                 "Could not find a suitable GID for user %jd, skipping 
test\n",
+-                 (intmax_t) getuid ());
+-        exit (0);
+-      }
++      int status = support_capture_subprogram_self_sgid (SETGID_CHILD);
+ 
+-      return run_executable_sgid (target);
+-    }
++      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
++      return EXIT_UNSUPPORTED;
++
++      if (!WIFEXITED (status))
++      FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
+ 
+-  /* Something went wrong and our argv was corrupted.  */
+-  _exit (1);
++      return 0;
++    }
+ }
+ 
+ #define TEST_FUNCTION_ARGV do_test
 diff --git a/iconv/Makefile b/iconv/Makefile
 index b8fe8c47df..f9b51e23ec 100644
 --- a/iconv/Makefile
@@ -3183,6 +3668,236 @@
  
  ifeq ($(build-hardcoded-path-in-tests),yes)
  tests += tst-empty-env
+diff --git a/stdlib/tst-secure-getenv.c b/stdlib/tst-secure-getenv.c
+index 3cfe9a05c3..d4b1139c5e 100644
+--- a/stdlib/tst-secure-getenv.c
++++ b/stdlib/tst-secure-getenv.c
+@@ -30,167 +30,12 @@
+ #include <sys/wait.h>
+ #include <unistd.h>
+ 
++#include <support/check.h>
+ #include <support/support.h>
++#include <support/capture_subprocess.h>
+ #include <support/test-driver.h>
+ 
+ static char MAGIC_ARGUMENT[] = "run-actual-test";
+-#define MAGIC_STATUS 19
+-
+-/* Return a GID which is not our current GID, but is present in the
+-   supplementary group list.  */
+-static gid_t
+-choose_gid (void)
+-{
+-  int count = getgroups (0, NULL);
+-  if (count < 0)
+-    {
+-      printf ("getgroups: %m\n");
+-      exit (1);
+-    }
+-  gid_t *groups;
+-  groups = xcalloc (count, sizeof (*groups));
+-  int ret = getgroups (count, groups);
+-  if (ret < 0)
+-    {
+-      printf ("getgroups: %m\n");
+-      exit (1);
+-    }
+-  gid_t current = getgid ();
+-  gid_t not_current = 0;
+-  for (int i = 0; i < ret; ++i)
+-    {
+-      if (groups[i] != current)
+-        {
+-          not_current = groups[i];
+-          break;
+-        }
+-    }
+-  free (groups);
+-  return not_current;
+-}
+-
+-
+-/* Copies the executable into a restricted directory, so that we can
+-   safely make it SGID with the TARGET group ID.  Then runs the
+-   executable.  */
+-static int
+-run_executable_sgid (gid_t target)
+-{
+-  char *dirname = xasprintf ("%s/secure-getenv.%jd",
+-                           test_dir, (intmax_t) getpid ());
+-  char *execname = xasprintf ("%s/bin", dirname);
+-  int infd = -1;
+-  int outfd = -1;
+-  int ret = -1;
+-  if (mkdir (dirname, 0700) < 0)
+-    {
+-      printf ("mkdir: %m\n");
+-      goto err;
+-    }
+-  infd = open ("/proc/self/exe", O_RDONLY);
+-  if (infd < 0)
+-    {
+-      printf ("open (/proc/self/exe): %m\n");
+-      goto err;
+-    }
+-  outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700);
+-  if (outfd < 0)
+-    {
+-      printf ("open (%s): %m\n", execname);
+-      goto err;
+-    }
+-  char buf[4096];
+-  for (;;)
+-    {
+-      ssize_t rdcount = read (infd, buf, sizeof (buf));
+-      if (rdcount < 0)
+-      {
+-        printf ("read: %m\n");
+-        goto err;
+-      }
+-      if (rdcount == 0)
+-      break;
+-      char *p = buf;
+-      char *end = buf + rdcount;
+-      while (p != end)
+-      {
+-        ssize_t wrcount = write (outfd, buf, end - p);
+-        if (wrcount == 0)
+-          errno = ENOSPC;
+-        if (wrcount <= 0)
+-          {
+-            printf ("write: %m\n");
+-            goto err;
+-          }
+-        p += wrcount;
+-      }
+-    }
+-  if (fchown (outfd, getuid (), target) < 0)
+-    {
+-      printf ("fchown (%s): %m\n", execname);
+-      goto err;
+-    }
+-  if (fchmod (outfd, 02750) < 0)
+-    {
+-      printf ("fchmod (%s): %m\n", execname);
+-      goto err;
+-    }
+-  if (close (outfd) < 0)
+-    {
+-      printf ("close (outfd): %m\n");
+-      goto err;
+-    }
+-  if (close (infd) < 0)
+-    {
+-      printf ("close (infd): %m\n");
+-      goto err;
+-    }
+-
+-  int kid = fork ();
+-  if (kid < 0)
+-    {
+-      printf ("fork: %m\n");
+-      goto err;
+-    }
+-  if (kid == 0)
+-    {
+-      /* Child process.  */
+-      char *args[] = { execname, MAGIC_ARGUMENT, NULL };
+-      execve (execname, args, environ);
+-      printf ("execve (%s): %m\n", execname);
+-      _exit (1);
+-    }
+-  int status;
+-  if (waitpid (kid, &status, 0) < 0)
+-    {
+-      printf ("waitpid: %m\n");
+-      goto err;
+-    }
+-  if (!WIFEXITED (status) || WEXITSTATUS (status) != MAGIC_STATUS)
+-    {
+-      printf ("Unexpected exit status %d from child process\n",
+-            status);
+-      goto err;
+-    }
+-  ret = 0;
+-
+-err:
+-  if (outfd >= 0)
+-    close (outfd);
+-  if (infd >= 0)
+-    close (infd);
+-  if (execname)
+-    {
+-      unlink (execname);
+-      free (execname);
+-    }
+-  if (dirname)
+-    {
+-      rmdir (dirname);
+-      free (dirname);
+-    }
+-  return ret;
+-}
+ 
+ static int
+ do_test (void)
+@@ -212,15 +57,15 @@ do_test (void)
+       exit (1);
+     }
+ 
+-  gid_t target = choose_gid ();
+-  if (target == 0)
+-    {
+-      fprintf (stderr,
+-             "Could not find a suitable GID for user %jd, skipping test\n",
+-             (intmax_t) getuid ());
+-      exit (0);
+-    }
+-  return run_executable_sgid (target);
++  int status = support_capture_subprogram_self_sgid (MAGIC_ARGUMENT);
++
++  if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
++    return EXIT_UNSUPPORTED;
++
++  if (!WIFEXITED (status))
++    FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
++
++  return 0;
+ }
+ 
+ static void
+@@ -229,23 +74,15 @@ alternative_main (int argc, char **argv)
+   if (argc == 2 && strcmp (argv[1], MAGIC_ARGUMENT) == 0)
+     {
+       if (getgid () == getegid ())
+-      {
+-        /* This can happen if the file system is mounted nosuid.  */
+-        fprintf (stderr, "SGID failed: GID and EGID match (%jd)\n",
+-                (intmax_t) getgid ());
+-        exit (MAGIC_STATUS);
+-      }
++      /* This can happen if the file system is mounted nosuid.  */
++      FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
++                 (intmax_t) getgid ());
+       if (getenv ("PATH") == NULL)
+-      {
+-        printf ("PATH variable not present\n");
+-        exit (3);
+-      }
++      FAIL_EXIT (3, "PATH variable not present\n");
+       if (secure_getenv ("PATH") != NULL)
+-      {
+-        printf ("PATH variable not filtered out\n");
+-        exit (4);
+-      }
+-      exit (MAGIC_STATUS);
++      FAIL_EXIT (4, "PATH variable not filtered out\n");
++
++      exit (EXIT_SUCCESS);
+     }
+ }
+ 
 diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
 index b6c5aea08f..eddea33f4c 100644
 --- a/stdlib/tst-system.c
@@ -3322,6 +4037,23 @@
 -#define TEST_FUNCTION do_test ()
 -#include "../test-skeleton.c"
 +#include <support/test-driver.c>
+diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
+index 9808750f80..421f657678 100644
+--- a/support/capture_subprocess.h
++++ b/support/capture_subprocess.h
+@@ -41,6 +41,12 @@ struct support_capture_subprocess support_capture_subprocess
+ struct support_capture_subprocess support_capture_subprogram
+   (const char *file, char *const argv[]);
+ 
++/* Copy the running program into a setgid binary and run it with CHILD_ID
++   argument.  If execution is successful, return the exit status of the child
++   program, otherwise return a non-zero failure exit code.  */
++int support_capture_subprogram_self_sgid
++  (char *child_id);
++
+ /* Deallocate the subprocess data captured by
+    support_capture_subprocess.  */
+ void support_capture_subprocess_free (struct support_capture_subprocess *);
 diff --git a/support/shell-container.c b/support/shell-container.c
 index 509e0d69b1..201536d24e 100644
 --- a/support/shell-container.c
@@ -3394,6 +4126,240 @@
    else
      exit (1);
  }
+diff --git a/support/subprocess.h b/support/subprocess.h
+index 8b442fd5c0..34ffd02e8e 100644
+--- a/support/subprocess.h
++++ b/support/subprocess.h
+@@ -38,6 +38,11 @@ struct support_subprocess support_subprocess
+ struct support_subprocess support_subprogram
+   (const char *file, char *const argv[]);
+ 
++/* Invoke program FILE with ARGV arguments by using posix_spawn and wait for 
it
++   to complete.  Return program exit status.  */
++int support_subprogram_wait
++  (const char *file, char *const argv[]);
++
+ /* Wait for the subprocess indicated by PROC::PID.  Return the status
+    indicate by waitpid call.  */
+ int support_process_wait (struct support_subprocess *proc);
+diff --git a/support/support_capture_subprocess.c 
b/support/support_capture_subprocess.c
+index eeed676e3d..28a37df67f 100644
+--- a/support/support_capture_subprocess.c
++++ b/support/support_capture_subprocess.c
+@@ -20,11 +20,14 @@
+ #include <support/capture_subprocess.h>
+ 
+ #include <errno.h>
++#include <fcntl.h>
+ #include <stdlib.h>
+ #include <support/check.h>
+ #include <support/xunistd.h>
+ #include <support/xsocket.h>
+ #include <support/xspawn.h>
++#include <support/support.h>
++#include <support/test-driver.h>
+ 
+ static void
+ transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream)
+@@ -36,7 +39,7 @@ transfer (const char *what, struct pollfd *pfd, struct 
xmemstream *stream)
+       if (ret < 0)
+         {
+           support_record_failure ();
+-          printf ("error: reading from subprocess %s: %m", what);
++          printf ("error: reading from subprocess %s: %m\n", what);
+           pfd->events = 0;
+           pfd->revents = 0;
+         }
+@@ -102,6 +105,129 @@ support_capture_subprogram (const char *file, char 
*const argv[])
+   return result;
+ }
+ 
++/* Copies the executable into a restricted directory, so that we can
++   safely make it SGID with the TARGET group ID.  Then runs the
++   executable.  */
++static int
++copy_and_spawn_sgid (char *child_id, gid_t gid)
++{
++  char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd",
++                           test_dir, (intmax_t) getpid ());
++  char *execname = xasprintf ("%s/bin", dirname);
++  int infd = -1;
++  int outfd = -1;
++  int ret = 1, status = 1;
++
++  TEST_VERIFY (mkdir (dirname, 0700) == 0);
++  if (support_record_failure_is_failed ())
++    goto err;
++
++  infd = open ("/proc/self/exe", O_RDONLY);
++  if (infd < 0)
++    FAIL_UNSUPPORTED ("unsupported: Cannot read binary from procfs\n");
++
++  outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700);
++  TEST_VERIFY (outfd >= 0);
++  if (support_record_failure_is_failed ())
++    goto err;
++
++  char buf[4096];
++  for (;;)
++    {
++      ssize_t rdcount = read (infd, buf, sizeof (buf));
++      TEST_VERIFY (rdcount >= 0);
++      if (support_record_failure_is_failed ())
++      goto err;
++      if (rdcount == 0)
++      break;
++      char *p = buf;
++      char *end = buf + rdcount;
++      while (p != end)
++      {
++        ssize_t wrcount = write (outfd, buf, end - p);
++        if (wrcount == 0)
++          errno = ENOSPC;
++        TEST_VERIFY (wrcount > 0);
++        if (support_record_failure_is_failed ())
++          goto err;
++        p += wrcount;
++      }
++    }
++  TEST_VERIFY (fchown (outfd, getuid (), gid) == 0);
++  if (support_record_failure_is_failed ())
++    goto err;
++  TEST_VERIFY (fchmod (outfd, 02750) == 0);
++  if (support_record_failure_is_failed ())
++    goto err;
++  TEST_VERIFY (close (outfd) == 0);
++  if (support_record_failure_is_failed ())
++    goto err;
++  TEST_VERIFY (close (infd) == 0);
++  if (support_record_failure_is_failed ())
++    goto err;
++
++  /* We have the binary, now spawn the subprocess.  Avoid using
++     support_subprogram because we only want the program exit status, not the
++     contents.  */
++  ret = 0;
++
++  char * const args[] = {execname, child_id, NULL};
++
++  status = support_subprogram_wait (args[0], args);
++
++err:
++  if (outfd >= 0)
++    close (outfd);
++  if (infd >= 0)
++    close (infd);
++  if (execname != NULL)
++    {
++      unlink (execname);
++      free (execname);
++    }
++  if (dirname != NULL)
++    {
++      rmdir (dirname);
++      free (dirname);
++    }
++
++  if (ret != 0)
++    FAIL_EXIT1("Failed to make sgid executable for test\n");
++
++  return status;
++}
++
++int
++support_capture_subprogram_self_sgid (char *child_id)
++{
++  gid_t target = 0;
++  const int count = 64;
++  gid_t groups[count];
++
++  /* Get a GID which is not our current GID, but is present in the
++     supplementary group list.  */
++  int ret = getgroups (count, groups);
++  if (ret < 0)
++    FAIL_UNSUPPORTED("Could not get group list for user %jd\n",
++                   (intmax_t) getuid ());
++
++  gid_t current = getgid ();
++  for (int i = 0; i < ret; ++i)
++    {
++      if (groups[i] != current)
++      {
++        target = groups[i];
++        break;
++      }
++    }
++
++  if (target == 0)
++    FAIL_UNSUPPORTED("Could not find a suitable GID for user %jd\n",
++                   (intmax_t) getuid ());
++
++  return copy_and_spawn_sgid (child_id, target);
++}
++
+ void
+ support_capture_subprocess_free (struct support_capture_subprocess *p)
+ {
+diff --git a/support/support_subprocess.c b/support/support_subprocess.c
+index 36e3a77af2..4a25828111 100644
+--- a/support/support_subprocess.c
++++ b/support/support_subprocess.c
+@@ -27,7 +27,7 @@
+ #include <support/subprocess.h>
+ 
+ static struct support_subprocess
+-support_suprocess_init (void)
++support_subprocess_init (void)
+ {
+   struct support_subprocess result;
+ 
+@@ -48,7 +48,7 @@ support_suprocess_init (void)
+ struct support_subprocess
+ support_subprocess (void (*callback) (void *), void *closure)
+ {
+-  struct support_subprocess result = support_suprocess_init ();
++  struct support_subprocess result = support_subprocess_init ();
+ 
+   result.pid = xfork ();
+   if (result.pid == 0)
+@@ -71,7 +71,7 @@ support_subprocess (void (*callback) (void *), void *closure)
+ struct support_subprocess
+ support_subprogram (const char *file, char *const argv[])
+ {
+-  struct support_subprocess result = support_suprocess_init ();
++  struct support_subprocess result = support_subprocess_init ();
+ 
+   posix_spawn_file_actions_t fa;
+   /* posix_spawn_file_actions_init does not fail.  */
+@@ -84,7 +84,7 @@ support_subprogram (const char *file, char *const argv[])
+   xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[1]);
+   xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[1]);
+ 
+-  result.pid = xposix_spawn (file, &fa, NULL, argv, NULL);
++  result.pid = xposix_spawn (file, &fa, NULL, argv, environ);
+ 
+   xclose (result.stdout_pipe[1]);
+   xclose (result.stderr_pipe[1]);
+@@ -92,6 +92,19 @@ support_subprogram (const char *file, char *const argv[])
+   return result;
+ }
+ 
++int
++support_subprogram_wait (const char *file, char *const argv[])
++{
++  posix_spawn_file_actions_t fa;
++
++  posix_spawn_file_actions_init (&fa);
++  struct support_subprocess res = support_subprocess_init ();
++
++  res.pid = xposix_spawn (file, &fa, NULL, argv, environ);
++
++  return support_process_wait (&res);
++}
++
+ int
+ support_process_wait (struct support_subprocess *proc)
+ {
 diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
 index db3335e5ad..8ffa0d1c51 100644
 --- a/sysdeps/aarch64/dl-machine.h
@@ -5023,6 +5989,85 @@
      return true;
  #endif
    return false;
+diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
+index fa46e9e351..e7f576338d 100644
+--- a/sysdeps/s390/configure
++++ b/sysdeps/s390/configure
+@@ -123,7 +123,9 @@ void testinsn (char *buf)
+     __asm__ (".machine \"arch13\" \n\t"
+            ".machinemode \"zarch_nohighgprs\" \n\t"
+            "lghi %%r0,16 \n\t"
+-           "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++           "mvcrl 0(%0),32(%0) \n\t"
++           "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
++           : : "a" (buf) : "memory", "r0");
+ }
+ EOF
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
+@@ -271,7 +273,9 @@ else
+ void testinsn (char *buf)
+ {
+     __asm__ ("lghi %%r0,16 \n\t"
+-           "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++           "mvcrl 0(%0),32(%0) \n\t"
++           "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
++           : : "a" (buf) : "memory", "r0");
+ }
+ EOF
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
+diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
+index 3ed5a8ef87..5c3479e8cf 100644
+--- a/sysdeps/s390/configure.ac
++++ b/sysdeps/s390/configure.ac
+@@ -88,7 +88,9 @@ void testinsn (char *buf)
+     __asm__ (".machine \"arch13\" \n\t"
+            ".machinemode \"zarch_nohighgprs\" \n\t"
+            "lghi %%r0,16 \n\t"
+-           "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++           "mvcrl 0(%0),32(%0) \n\t"
++           "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
++           : : "a" (buf) : "memory", "r0");
+ }
+ EOF
+ dnl test, if assembler supports S390 arch13 instructions
+@@ -195,7 +197,9 @@ cat > conftest.c <<\EOF
+ void testinsn (char *buf)
+ {
+     __asm__ ("lghi %%r0,16 \n\t"
+-           "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
++           "mvcrl 0(%0),32(%0) \n\t"
++           "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
++           : : "a" (buf) : "memory", "r0");
+ }
+ EOF
+ dnl test, if assembler supports S390 arch13 zarch instructions as default
+diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c
+index 5fc85e129f..ee59b5de14 100644
+--- a/sysdeps/s390/memmove.c
++++ b/sysdeps/s390/memmove.c
+@@ -43,7 +43,7 @@ extern __typeof (__redirect_memmove) MEMMOVE_ARCH13 
attribute_hidden;
+ s390_libc_ifunc_expr (__redirect_memmove, memmove,
+                     ({
+                       s390_libc_ifunc_expr_stfle_init ();
+-                      (HAVE_MEMMOVE_ARCH13
++                      (HAVE_MEMMOVE_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)
+                        && S390_IS_ARCH13_MIE3 (stfle_bits))
+                         ? MEMMOVE_ARCH13
+                         : (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX))
+diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c 
b/sysdeps/s390/multiarch/ifunc-impl-list.c
+index e6195c6e26..17c0cc3952 100644
+--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
+@@ -171,7 +171,8 @@ __libc_ifunc_impl_list (const char *name, struct 
libc_ifunc_impl *array,
+     IFUNC_IMPL (i, name, memmove,
+ # if HAVE_MEMMOVE_ARCH13
+               IFUNC_IMPL_ADD (array, i, memmove,
+-                              S390_IS_ARCH13_MIE3 (stfle_bits),
++                              ((dl_hwcap & HWCAP_S390_VXRS_EXT2)
++                               && S390_IS_ARCH13_MIE3 (stfle_bits)),
+                               MEMMOVE_ARCH13)
+ # endif
+ # if HAVE_MEMMOVE_Z13
 diff --git a/sysdeps/sh/be/sh4/fpu/Implies b/sysdeps/sh/be/sh4/fpu/Implies
 new file mode 100644
 index 0000000000..71b28ee1a4
diff -Nru glibc-2.31/debian/patches/series glibc-2.31/debian/patches/series
--- glibc-2.31/debian/patches/series    2021-03-27 11:04:42.000000000 +0100
+++ glibc-2.31/debian/patches/series    2021-04-25 18:19:34.000000000 +0200
@@ -143,7 +143,6 @@
 all/local-nis-shadow.diff
 all/submitted-po-fr-fixes.diff
 
-any/local-rtlddir-cross.diff
 any/local-asserth-decls.diff
 any/local-bindresvport_blacklist.diff
 any/local-fhs-linux-paths.diff
diff -Nru glibc-2.31/debian/po/de.po glibc-2.31/debian/po/de.po
--- glibc-2.31/debian/po/de.po  2020-10-11 14:21:23.000000000 +0200
+++ glibc-2.31/debian/po/de.po  2021-04-12 00:31:42.000000000 +0200
@@ -12,7 +12,7 @@
 "Language-Team: de <debian-l10n-ger...@lists.debian.org>\n"
 "Language: German\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #. Type: multiselect
diff -Nru glibc-2.31/debian/rules.d/build.mk glibc-2.31/debian/rules.d/build.mk
--- glibc-2.31/debian/rules.d/build.mk  2021-01-03 17:11:31.000000000 +0100
+++ glibc-2.31/debian/rules.d/build.mk  2021-05-01 19:29:17.000000000 +0200
@@ -94,8 +94,8 @@
            echo "No.  Forcing cross-compile by setting build to 
$$configure_build."; \
          fi; \
        fi; \
-       echo -n "Build started: " ; date --rfc-2822
-       echo "---------------"
+       echo -n "Build started: " ; date --rfc-2822; \
+       echo "---------------"; \
        cd $(DEB_BUILDDIR) && \
                CC="$(call xx,CC)" \
                CXX=$(if $(filter nocheck,$(DEB_BUILD_OPTIONS)),:,"$(call 
xx,CXX)") \
@@ -317,14 +317,14 @@
          esac; \
        fi
 
-       # Create the ld.so symlink to the multiarch directory
-       if [ $(curpass) = libc ]; then \
-         rtld_so="$$(LANG=C LC_ALL=C readelf -l 
debian/tmp-$(curpass)/usr/bin/iconv | grep 'interpreter' | sed -e 
's/.*interpreter: \(.*\)]/\1/g')" ; \
-         rtld_so="$$(basename $$rtld_so)" ; \
-         link_name="debian/tmp-$(curpass)/lib/$$rtld_so" ; \
-         target="$(call xx,slibdir)/$$(readlink debian/tmp-$(curpass)/$(call 
xx,slibdir)/$$rtld_so)" ; \
-         ln -s $$target $$link_name ;  \
-       fi
+       # Create the ld.so symlink in the slibdir directory, otherwise it will 
get
+       # created later by ldconfig, leading to a dangling symlink when the 
package
+       # is removed
+       ld_so="$$(ls debian/tmp-$(curpass)/$(call xx,slibdir)/ld-*.so)" ; \
+       soname="$$(LANG=C LC_ALL=C readelf -d $$ld_so | grep 'Library soname:' 
| sed -e 's/.*Library soname: \[\(.*\)\]/\1/g')" ; \
+       target="$$(basename $$ld_so)" ; \
+       link_name="debian/tmp-$(curpass)/$(call xx,slibdir)/$$soname" ; \
+       ln -sf $$target $$link_name
        
        $(call xx,extra_install)
 endif
diff -Nru glibc-2.31/debian/sysdeps/amd64.mk glibc-2.31/debian/sysdeps/amd64.mk
--- glibc-2.31/debian/sysdeps/amd64.mk  2020-05-11 11:19:49.000000000 +0200
+++ glibc-2.31/debian/sysdeps/amd64.mk  2021-04-25 18:11:42.000000000 +0200
@@ -29,11 +29,6 @@
 
 endef
 
-define libc6-i386_extra_pkg_install
-mkdir -p debian/libc6-i386/lib
-ln -sf /lib32/ld-linux.so.2 debian/libc6-i386/lib
-endef
-
 # build x32 ABI alternative library
 GLIBC_PASSES += x32
 DEB_ARCH_MULTILIB_PACKAGES += libc6-x32 libc6-dev-x32
diff -Nru glibc-2.31/debian/sysdeps/armel.mk glibc-2.31/debian/sysdeps/armel.mk
--- glibc-2.31/debian/sysdeps/armel.mk  2020-05-11 11:19:49.000000000 +0200
+++ glibc-2.31/debian/sysdeps/armel.mk  2021-04-25 18:27:39.000000000 +0200
@@ -26,7 +26,6 @@
 #
 #define libc6-armhf_extra_pkg_install
 #mkdir -p debian/libc6-armhf$(armhf_slibdir)
-#ln -sf $(armhf_slibdir)/ld-linux-armhf.so.3 debian/libc6-armhf/lib
 #ln -sf ld-linux-armhf.so.3 debian/libc6-armhf$(armhf_slibdir)/ld-linux.so.3 
 #endef
 
diff -Nru glibc-2.31/debian/sysdeps/armhf.mk glibc-2.31/debian/sysdeps/armhf.mk
--- glibc-2.31/debian/sysdeps/armhf.mk  2020-05-11 11:19:49.000000000 +0200
+++ glibc-2.31/debian/sysdeps/armhf.mk  2021-04-25 18:27:10.000000000 +0200
@@ -34,10 +34,5 @@
 #      debian/libc6-dev-armel/usr/include/arm-linux-gnueabihf/gnu
 #
 #endef
-#
-#define libc6-armel_extra_pkg_install
-#mkdir -p debian/libc6-armel/lib
-#ln -sf $(armel_slibdir)/ld-linux.so.3 debian/libc6-armel/lib
-#endef
 
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/kfreebsd-amd64.mk 
glibc-2.31/debian/sysdeps/kfreebsd-amd64.mk
--- glibc-2.31/debian/sysdeps/kfreebsd-amd64.mk 2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/kfreebsd-amd64.mk 2021-04-25 18:11:42.000000000 
+0200
@@ -28,9 +28,4 @@
 
 endef
 
-define libc0.1-i386_extra_pkg_install
-mkdir -p debian/libc0.1-i386/lib
-ln -sf /lib32/ld.so.1 debian/libc0.1-i386/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mips64el.mk 
glibc-2.31/debian/sysdeps/mips64el.mk
--- glibc-2.31/debian/sysdeps/mips64el.mk       2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/mips64el.mk       2021-04-25 18:11:42.000000000 
+0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mips64.mk 
glibc-2.31/debian/sysdeps/mips64.mk
--- glibc-2.31/debian/sysdeps/mips64.mk 2020-05-11 11:19:49.000000000 +0200
+++ glibc-2.31/debian/sysdeps/mips64.mk 2021-04-25 18:11:42.000000000 +0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mips64r6el.mk 
glibc-2.31/debian/sysdeps/mips64r6el.mk
--- glibc-2.31/debian/sysdeps/mips64r6el.mk     2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/mips64r6el.mk     2021-04-25 18:11:42.000000000 
+0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld-linux-mipsn8.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mips64r6.mk 
glibc-2.31/debian/sysdeps/mips64r6.mk
--- glibc-2.31/debian/sysdeps/mips64r6.mk       2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/mips64r6.mk       2021-04-25 18:11:42.000000000 
+0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld-linux-mipsn8.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mipsn32el.mk 
glibc-2.31/debian/sysdeps/mipsn32el.mk
--- glibc-2.31/debian/sysdeps/mipsn32el.mk      2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/mipsn32el.mk      2021-04-25 18:11:42.000000000 
+0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mipsn32.mk 
glibc-2.31/debian/sysdeps/mipsn32.mk
--- glibc-2.31/debian/sysdeps/mipsn32.mk        2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/mipsn32.mk        2021-04-25 18:11:42.000000000 
+0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mipsn32r6el.mk 
glibc-2.31/debian/sysdeps/mipsn32r6el.mk
--- glibc-2.31/debian/sysdeps/mipsn32r6el.mk    2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/mipsn32r6el.mk    2021-04-25 18:11:42.000000000 
+0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld-linux-mipsn8.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/mipsn32r6.mk 
glibc-2.31/debian/sysdeps/mipsn32r6.mk
--- glibc-2.31/debian/sysdeps/mipsn32r6.mk      2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/mipsn32r6.mk      2021-04-25 18:11:42.000000000 
+0200
@@ -46,10 +46,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-mips32_extra_pkg_install
-mkdir -p debian/libc6-mips32/lib
-ln -sf /libo32/ld-linux-mipsn8.so.1 debian/libc6-mips32/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/ppc64.mk glibc-2.31/debian/sysdeps/ppc64.mk
--- glibc-2.31/debian/sysdeps/ppc64.mk  2020-05-11 11:19:49.000000000 +0200
+++ glibc-2.31/debian/sysdeps/ppc64.mk  2021-04-25 18:11:42.000000000 +0200
@@ -28,10 +28,4 @@
 
 endef
 
-# create a symlink for the 32 bit dynamic linker in /lib
-define libc6-powerpc_extra_pkg_install
-mkdir -p debian/$(curpass)/lib
-ln -s /lib32/ld.so.1 debian/$(curpass)/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/s390x.mk glibc-2.31/debian/sysdeps/s390x.mk
--- glibc-2.31/debian/sysdeps/s390x.mk  2020-05-11 11:19:49.000000000 +0200
+++ glibc-2.31/debian/sysdeps/s390x.mk  2021-04-25 18:11:42.000000000 +0200
@@ -25,9 +25,4 @@
 
 endef
 
-define libc6-s390_extra_pkg_install
-mkdir -p debian/$(curpass)/lib
-ln -s /lib32/ld.so.1 debian/$(curpass)/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/sparc64.mk 
glibc-2.31/debian/sysdeps/sparc64.mk
--- glibc-2.31/debian/sysdeps/sparc64.mk        2020-05-11 11:19:49.000000000 
+0200
+++ glibc-2.31/debian/sysdeps/sparc64.mk        2021-04-25 18:11:42.000000000 
+0200
@@ -31,9 +31,4 @@
 
 endef
 
-define libc6-sparc_extra_pkg_install
-mkdir -p debian/$(curpass)/lib
-ln -s /lib32/ld-linux.so.2 debian/$(curpass)/lib
-endef
-
 endif # multilib
diff -Nru glibc-2.31/debian/sysdeps/x32.mk glibc-2.31/debian/sysdeps/x32.mk
--- glibc-2.31/debian/sysdeps/x32.mk    2020-05-11 11:19:49.000000000 +0200
+++ glibc-2.31/debian/sysdeps/x32.mk    2021-04-25 18:11:42.000000000 +0200
@@ -51,9 +51,4 @@
 
 endef
 
-define libc6-i386_extra_pkg_install
-mkdir -p debian/libc6-i386/lib
-ln -sf /lib32/ld-linux.so.2 debian/libc6-i386/lib
-endef
-
 endif # multilib

Reply via email to