core/glibc/glibc-2.32-5.patch

6166 lines
211 KiB
Diff
Raw Normal View History

diff -pruN glibc-2.32.orig/debug/Makefile glibc-2.32/debug/Makefile
--- glibc-2.32.orig/debug/Makefile 2021-09-18 21:02:32.642182626 +1000
+++ glibc-2.32/debug/Makefile 2021-09-18 21:03:05.310302219 +1000
@@ -51,7 +51,7 @@ routines = backtrace backtracesyms back
2021-03-22 16:38:00 +01:00
explicit_bzero_chk \
stack_chk_fail fortify_fail \
$(static-only-routines)
-static-only-routines := warning-nop stack_chk_fail_local
+static-only-routines := stack_chk_fail_local
# Don't add stack_chk_fail_local.o to libc.a since __stack_chk_fail_local
# is an alias of __stack_chk_fail in stack_chk_fail.o.
diff -pruN glibc-2.32.orig/debug/warning-nop.c glibc-2.32/debug/warning-nop.c
--- glibc-2.32.orig/debug/warning-nop.c 2021-09-18 21:02:32.642182626 +1000
+++ glibc-2.32/debug/warning-nop.c 1970-01-01 10:00:00.000000000 +1000
2021-03-22 16:38:00 +01:00
@@ -1,70 +0,0 @@
-/* Dummy nop functions to elicit link-time warnings.
- Copyright (C) 2005-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- In addition to the permissions in the GNU Lesser General Public
- License, the Free Software Foundation gives you unlimited
- permission to link the compiled version of this file with other
- programs, and to distribute those programs without any restriction
- coming from the use of this file. (The GNU Lesser General Public
- License restrictions do apply in other respects; for example, they
- cover modification of the file, and distribution when not linked
- into another program.)
-
- Note that people who make modified versions of this file are not
- obligated to grant this special exception for their modified
- versions; it is their choice whether to do so. The GNU Lesser
- General Public License gives permission to release a modified
- version without this exception; this exception also makes it
- possible to release a modified version which carries forward this
- exception.
-
- 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/cdefs.h>
-
-static void
-__attribute__ ((used))
-nop (void)
-{
-}
-
-/* Don't insert any other #include's before this #undef! */
-
-#undef __warndecl
-#define __warndecl(name, msg) \
- extern void name (void) __attribute__ ((alias ("nop"))) attribute_hidden; \
- link_warning (name, msg)
-
-#undef __USE_FORTIFY_LEVEL
-#define __USE_FORTIFY_LEVEL 99
-
-/* Following here we need an #include for each public header file
- that uses __warndecl. */
-
-/* Define away to avoid warnings with compilers that do not have these
- builtins. */
-#define __builtin___memcpy_chk(dest, src, len, bos) NULL
-#define __builtin___memmove_chk(dest, src, len, bos) NULL
-#define __builtin___mempcpy_chk(dest, src, len, bos) NULL
-#define __builtin___memset_chk(dest, ch, len, bos) NULL
-#define __builtin___stpcpy_chk(dest, src, bos) NULL
-#define __builtin___strcat_chk(dest, src, bos) NULL
-#define __builtin___strcpy_chk(dest, src, bos) NULL
-#define __builtin___strncat_chk(dest, src, len, bos) NULL
-#define __builtin___strncpy_chk(dest, src, len, bos) NULL
-#define __builtin_object_size(bos, level) 0
-
-#include <string.h>
diff -pruN glibc-2.32.orig/elf/dl-load.c glibc-2.32/elf/dl-load.c
--- glibc-2.32.orig/elf/dl-load.c 2021-09-18 21:02:32.643182660 +1000
+++ glibc-2.32/elf/dl-load.c 2021-09-18 21:03:05.311302253 +1000
@@ -855,10 +855,12 @@ lose (int code, int fd, const char *name
2021-03-22 16:38:00 +01:00
/* Process PT_GNU_PROPERTY program header PH in module L after
PT_LOAD segments are mapped. Only one NT_GNU_PROPERTY_TYPE_0
- note is handled which contains processor specific properties. */
+ note is handled which contains processor specific properties.
+ FD is -1 for the kernel mapped main executable otherwise it is
+ the fd used for loading module L. */
void
-_dl_process_pt_gnu_property (struct link_map *l, const ElfW(Phdr) *ph)
+_dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
{
const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
const ElfW(Addr) size = ph->p_memsz;
@@ -905,7 +907,7 @@ _dl_process_pt_gnu_property (struct link
2021-03-22 16:38:00 +01:00
last_type = type;
/* Target specific property processing. */
- if (_dl_process_gnu_property (l, type, datasz, ptr) == 0)
+ if (_dl_process_gnu_property (l, fd, type, datasz, ptr) == 0)
return;
/* Check the next property item. */
@@ -1251,21 +1253,6 @@ _dl_map_object_from_fd (const char *name
2021-03-22 16:38:00 +01:00
maplength, has_holes, loader);
if (__glibc_unlikely (errstring != NULL))
goto call_lose;
-
- /* Process program headers again after load segments are mapped in
- case processing requires accessing those segments. Scan program
- headers backward so that PT_NOTE can be skipped if PT_GNU_PROPERTY
- exits. */
- for (ph = &phdr[l->l_phnum]; ph != phdr; --ph)
- switch (ph[-1].p_type)
- {
- case PT_NOTE:
- _dl_process_pt_note (l, &ph[-1]);
- break;
- case PT_GNU_PROPERTY:
- _dl_process_pt_gnu_property (l, &ph[-1]);
- break;
- }
}
if (l->l_ld == 0)
@@ -1377,6 +1364,21 @@ cannot enable executable stack as shared
2021-03-22 16:38:00 +01:00
if (l->l_tls_initimage != NULL)
l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr;
+ /* Process program headers again after load segments are mapped in
+ case processing requires accessing those segments. Scan program
+ headers backward so that PT_NOTE can be skipped if PT_GNU_PROPERTY
+ exits. */
+ for (ph = &l->l_phdr[l->l_phnum]; ph != l->l_phdr; --ph)
+ switch (ph[-1].p_type)
+ {
+ case PT_NOTE:
+ _dl_process_pt_note (l, fd, &ph[-1]);
+ break;
+ case PT_GNU_PROPERTY:
+ _dl_process_pt_gnu_property (l, fd, &ph[-1]);
+ break;
+ }
+
/* We are done mapping in the file. We no longer need the descriptor. */
if (__glibc_unlikely (__close_nocancel (fd) != 0))
{
diff -pruN glibc-2.32.orig/elf/dl-tunables.c glibc-2.32/elf/dl-tunables.c
--- glibc-2.32.orig/elf/dl-tunables.c 2021-09-18 21:02:32.643182660 +1000
+++ glibc-2.32/elf/dl-tunables.c 2021-09-18 21:03:05.311302253 +1000
@@ -177,6 +177,7 @@ parse_tunables (char *tunestr, char *val
2021-08-06 12:41:15 +02:00
return;
char *p = tunestr;
+ size_t off = 0;
while (true)
{
@@ -190,7 +191,11 @@ parse_tunables (char *tunestr, char *val
2021-08-06 12:41:15 +02:00
/* 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 *val
2021-08-06 12:41:15 +02:00
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
- precedence 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 *val
2021-08-06 12:41:15 +02:00
}
}
- if (p[len] == '\0')
- return;
- else
+ if (p[len] != '\0')
p += len + 1;
}
}
diff -pruN glibc-2.32.orig/elf/ifuncmain6pie.c glibc-2.32/elf/ifuncmain6pie.c
--- glibc-2.32.orig/elf/ifuncmain6pie.c 2021-09-18 21:02:32.643182660 +1000
+++ glibc-2.32/elf/ifuncmain6pie.c 2021-09-18 21:03:05.311302253 +1000
2021-03-22 16:38:00 +01:00
@@ -9,7 +9,6 @@
#include "ifunc-sel.h"
typedef int (*foo_p) (void);
-extern foo_p foo_ptr;
static int
one (void)
@@ -28,20 +27,17 @@ foo_ifunc (void)
}
extern int foo (void);
-extern foo_p get_foo (void);
+extern int call_foo (void);
extern foo_p get_foo_p (void);
-foo_p my_foo_ptr = foo;
+foo_p foo_ptr = foo;
int
main (void)
{
foo_p p;
- p = get_foo ();
- if (p != foo)
- abort ();
- if ((*p) () != -30)
+ if (call_foo () != -30)
abort ();
p = get_foo_p ();
@@ -52,12 +48,8 @@ main (void)
if (foo_ptr != foo)
abort ();
- if (my_foo_ptr != foo)
- abort ();
if ((*foo_ptr) () != -30)
abort ();
- if ((*my_foo_ptr) () != -30)
- abort ();
if (foo () != -30)
abort ();
diff -pruN glibc-2.32.orig/elf/ifuncmod6.c glibc-2.32/elf/ifuncmod6.c
--- glibc-2.32.orig/elf/ifuncmod6.c 2021-09-18 21:02:32.643182660 +1000
+++ glibc-2.32/elf/ifuncmod6.c 2021-09-18 21:03:05.311302253 +1000
2021-03-22 16:38:00 +01:00
@@ -4,7 +4,7 @@ extern int foo (void);
typedef int (*foo_p) (void);
-foo_p foo_ptr = foo;
+extern foo_p foo_ptr;
foo_p
get_foo_p (void)
@@ -12,8 +12,8 @@ get_foo_p (void)
return foo_ptr;
}
-foo_p
-get_foo (void)
+int
+call_foo (void)
{
- return foo;
+ return foo ();
}
diff -pruN glibc-2.32.orig/elf/Makefile glibc-2.32/elf/Makefile
--- glibc-2.32.orig/elf/Makefile 2021-09-18 21:02:32.643182660 +1000
+++ glibc-2.32/elf/Makefile 2021-09-18 21:03:05.311302253 +1000
@@ -1381,6 +1381,8 @@ CFLAGS-ifuncmain7pie.c += $(pie-ccflag)
CFLAGS-ifuncmain9pie.c += $(pie-ccflag)
CFLAGS-tst-ifunc-textrel.c += $(pic-ccflag)
2021-08-06 12:41:15 +02:00
+LDFLAGS-ifuncmain6pie = -Wl,-z,lazy
2021-08-06 12:41:15 +02:00
+
$(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so
$(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o
$(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so
@@ -1630,8 +1632,6 @@ $(objpfx)tst-nodelete-dlclose.out: $(obj
2021-08-06 12:41:15 +02:00
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 -pruN glibc-2.32.orig/elf/rtld.c glibc-2.32/elf/rtld.c
--- glibc-2.32.orig/elf/rtld.c 2021-09-18 21:02:32.644182694 +1000
+++ glibc-2.32/elf/rtld.c 2021-09-18 21:03:05.311302253 +1000
@@ -1534,10 +1534,10 @@ of this helper program; chances are you
switch (ph[-1].p_type)
{
case PT_NOTE:
- _dl_process_pt_note (main_map, &ph[-1]);
+ _dl_process_pt_note (main_map, -1, &ph[-1]);
break;
case PT_GNU_PROPERTY:
- _dl_process_pt_gnu_property (main_map, &ph[-1]);
+ _dl_process_pt_gnu_property (main_map, -1, &ph[-1]);
break;
}
diff -pruN glibc-2.32.orig/elf/tst-env-setuid.c glibc-2.32/elf/tst-env-setuid.c
--- glibc-2.32.orig/elf/tst-env-setuid.c 2021-09-18 21:02:32.644182694 +1000
+++ glibc-2.32/elf/tst-env-setuid.c 2021-09-18 21:03:05.311302253 +1000
2021-08-06 12:41:15 +02:00
@@ -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 -pruN glibc-2.32.orig/elf/tst-env-setuid-tunables.c glibc-2.32/elf/tst-env-setuid-tunables.c
--- glibc-2.32.orig/elf/tst-env-setuid-tunables.c 2021-09-18 21:02:32.644182694 +1000
+++ glibc-2.32/elf/tst-env-setuid-tunables.c 2021-09-18 21:03:05.311302253 +1000
@@ -25,35 +25,76 @@
#include "config.h"
#undef _LIBC
-#define test_parent test_parent_tunables
-#define test_child test_child_tunables
+#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>
-static int test_child_tunables (void);
-static int test_parent_tunables (void);
-
-#include "tst-env-setuid.c"
+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",
+};
-#define CHILD_VALSTRING_VALUE "glibc.malloc.mmap_threshold=4096"
-#define PARENT_VALSTRING_VALUE \
- "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096"
+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 -pruN glibc-2.32.orig/iconv/gconv_charset.c glibc-2.32/iconv/gconv_charset.c
--- glibc-2.32.orig/iconv/gconv_charset.c 2021-09-18 21:02:32.646182763 +1000
+++ glibc-2.32/iconv/gconv_charset.c 2021-09-18 21:03:05.311302253 +1000
@@ -216,3 +216,13 @@ out:
return ret;
}
libc_hidden_def (__gconv_create_spec)
+
+
+void
+__gconv_destroy_spec (struct gconv_spec *conv_spec)
+{
+ free (conv_spec->fromcode);
+ free (conv_spec->tocode);
+ return;
+}
+libc_hidden_def (__gconv_destroy_spec)
diff -pruN glibc-2.32.orig/iconv/gconv_charset.h glibc-2.32/iconv/gconv_charset.h
--- glibc-2.32.orig/iconv/gconv_charset.h 2021-09-18 21:02:32.646182763 +1000
+++ glibc-2.32/iconv/gconv_charset.h 2021-09-18 21:03:05.311302253 +1000
@@ -48,33 +48,6 @@
#define GCONV_IGNORE_ERRORS_SUFFIX "IGNORE"
-/* This function accepts the charset names of the source and destination of the
- conversion and populates *conv_spec with an equivalent conversion
- specification that may later be used by __gconv_open. The charset names
- might contain options in the form of suffixes that alter the conversion,
- e.g. "ISO-10646/UTF-8/TRANSLIT". It processes the charset names, ignoring
- and truncating any suffix options in fromcode, and processing and truncating
- any suffix options in tocode. Supported suffix options ("TRANSLIT" or
- "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
- to be set to true. Unrecognized suffix options are silently discarded. If
- the function succeeds, it returns conv_spec back to the caller. It returns
- NULL upon failure. */
-struct gconv_spec *
-__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
- const char *tocode);
-libc_hidden_proto (__gconv_create_spec)
-
-
-/* This function frees all heap memory allocated by __gconv_create_spec. */
-static void __attribute__ ((unused))
-gconv_destroy_spec (struct gconv_spec *conv_spec)
-{
- free (conv_spec->fromcode);
- free (conv_spec->tocode);
- return;
-}
-
-
/* This function copies in-order, characters from the source 's' that are
either alpha-numeric or one in one of these: "_-.,:/" - into the destination
'wp' while dropping all other characters. In the process, it converts all
diff -pruN glibc-2.32.orig/iconv/gconv_int.h glibc-2.32/iconv/gconv_int.h
--- glibc-2.32.orig/iconv/gconv_int.h 2021-09-18 21:02:32.646182763 +1000
+++ glibc-2.32/iconv/gconv_int.h 2021-09-18 21:03:05.311302253 +1000
@@ -152,6 +152,27 @@ extern int __gconv_open (struct gconv_sp
__gconv_t *handle, int flags);
libc_hidden_proto (__gconv_open)
+/* This function accepts the charset names of the source and destination of the
+ conversion and populates *conv_spec with an equivalent conversion
+ specification that may later be used by __gconv_open. The charset names
+ might contain options in the form of suffixes that alter the conversion,
+ e.g. "ISO-10646/UTF-8/TRANSLIT". It processes the charset names, ignoring
+ and truncating any suffix options in fromcode, and processing and truncating
+ any suffix options in tocode. Supported suffix options ("TRANSLIT" or
+ "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
+ to be set to true. Unrecognized suffix options are silently discarded. If
+ the function succeeds, it returns conv_spec back to the caller. It returns
+ NULL upon failure. */
+extern struct gconv_spec *
+__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
+ const char *tocode);
+libc_hidden_proto (__gconv_create_spec)
+
+/* This function frees all heap memory allocated by __gconv_create_spec. */
+extern void
+__gconv_destroy_spec (struct gconv_spec *conv_spec);
+libc_hidden_proto (__gconv_destroy_spec)
+
/* Free resources associated with transformation descriptor CD. */
extern int __gconv_close (__gconv_t cd)
attribute_hidden;
diff -pruN glibc-2.32.orig/iconv/iconv_open.c glibc-2.32/iconv/iconv_open.c
--- glibc-2.32.orig/iconv/iconv_open.c 2021-09-18 21:02:32.646182763 +1000
+++ glibc-2.32/iconv/iconv_open.c 2021-09-18 21:03:05.311302253 +1000
@@ -39,7 +39,7 @@ iconv_open (const char *tocode, const ch
int res = __gconv_open (&conv_spec, &cd, 0);
- gconv_destroy_spec (&conv_spec);
+ __gconv_destroy_spec (&conv_spec);
if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK)
{
diff -pruN glibc-2.32.orig/iconv/iconv_prog.c glibc-2.32/iconv/iconv_prog.c
--- glibc-2.32.orig/iconv/iconv_prog.c 2021-09-18 21:02:32.646182763 +1000
+++ glibc-2.32/iconv/iconv_prog.c 2021-09-18 21:03:05.311302253 +1000
@@ -184,7 +184,7 @@ main (int argc, char *argv[])
/* Let's see whether we have these coded character sets. */
res = __gconv_open (&conv_spec, &cd, 0);
- gconv_destroy_spec (&conv_spec);
+ __gconv_destroy_spec (&conv_spec);
if (res != __GCONV_OK)
{
diff -pruN glibc-2.32.orig/iconv/tst-iconv_prog.sh glibc-2.32/iconv/tst-iconv_prog.sh
--- glibc-2.32.orig/iconv/tst-iconv_prog.sh 2021-09-18 21:02:32.646182763 +1000
+++ glibc-2.32/iconv/tst-iconv_prog.sh 2021-09-18 21:03:05.311302253 +1000
2021-03-22 16:38:00 +01:00
@@ -102,12 +102,16 @@ hangarray=(
"\x00\x80;-c;IBM1161;UTF-8//TRANSLIT//IGNORE"
"\x00\xdb;-c;IBM1162;UTF-8//TRANSLIT//IGNORE"
"\x00\x70;-c;IBM12712;UTF-8//TRANSLIT//IGNORE"
-# These are known hangs that are yet to be fixed:
-# "\x00\x0f;-c;IBM1364;UTF-8"
-# "\x00\x0f;-c;IBM1371;UTF-8"
-# "\x00\x0f;-c;IBM1388;UTF-8"
-# "\x00\x0f;-c;IBM1390;UTF-8"
-# "\x00\x0f;-c;IBM1399;UTF-8"
+"\x00\x0f;-c;IBM1364;UTF-8"
+"\x0e\x0e;-c;IBM1364;UTF-8"
+"\x00\x0f;-c;IBM1371;UTF-8"
+"\x0e\x0e;-c;IBM1371;UTF-8"
+"\x00\x0f;-c;IBM1388;UTF-8"
+"\x0e\x0e;-c;IBM1388;UTF-8"
+"\x00\x0f;-c;IBM1390;UTF-8"
+"\x0e\x0e;-c;IBM1390;UTF-8"
+"\x00\x0f;-c;IBM1399;UTF-8"
+"\x0e\x0e;-c;IBM1399;UTF-8"
"\x00\x53;-c;IBM16804;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM274;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM275;UTF-8//TRANSLIT//IGNORE"
diff -pruN glibc-2.32.orig/iconv/Versions glibc-2.32/iconv/Versions
--- glibc-2.32.orig/iconv/Versions 2021-09-18 21:02:32.646182763 +1000
+++ glibc-2.32/iconv/Versions 2021-09-18 21:03:05.311302253 +1000
@@ -6,7 +6,9 @@ libc {
GLIBC_PRIVATE {
# functions shared with iconv program
__gconv_get_alias_db; __gconv_get_cache; __gconv_get_modules_db;
- __gconv_open; __gconv_create_spec;
+
+ # functions used elsewhere in glibc
+ __gconv_open; __gconv_create_spec; __gconv_destroy_spec;
2021-03-22 16:38:00 +01:00
# function used by the gconv modules
__gconv_transliterate;
diff -pruN glibc-2.32.orig/iconvdata/bug-iconv13.c glibc-2.32/iconvdata/bug-iconv13.c
--- glibc-2.32.orig/iconvdata/bug-iconv13.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/iconvdata/bug-iconv13.c 2021-09-18 21:03:05.311302253 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1,53 @@
+/* bug 24973: Test EUC-KR module
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <iconv.h>
+#include <stdio.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ iconv_t cd = iconv_open ("UTF-8//IGNORE", "EUC-KR");
+ TEST_VERIFY_EXIT (cd != (iconv_t) -1);
+
+ /* 0xfe (->0x7e : row 94) and 0xc9 (->0x49 : row 41) are user-defined
+ areas, which are not allowed and should be skipped over due to
+ //IGNORE. The trailing 0xfe also is an incomplete sequence, which
+ should be checked first. */
+ char input[4] = { '\xc9', '\xa1', '\0', '\xfe' };
+ char *inptr = input;
+ size_t insize = sizeof (input);
+ char output[4];
+ char *outptr = output;
+ size_t outsize = sizeof (output);
+
+ /* This used to crash due to buffer overrun. */
+ TEST_VERIFY (iconv (cd, &inptr, &insize, &outptr, &outsize) == (size_t) -1);
+ TEST_VERIFY (errno == EINVAL);
+ /* The conversion should produce one character, the converted null
+ character. */
+ TEST_VERIFY (sizeof (output) - outsize == 1);
+
+ TEST_VERIFY_EXIT (iconv_close (cd) != -1);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff -pruN glibc-2.32.orig/iconvdata/bug-iconv14.c glibc-2.32/iconvdata/bug-iconv14.c
--- glibc-2.32.orig/iconvdata/bug-iconv14.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/iconvdata/bug-iconv14.c 2021-09-18 21:03:05.311302253 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1,127 @@
+/* Assertion in ISO-2022-JP-3 due to two-character sequence (bug 27256).
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <iconv.h>
+#include <string.h>
+#include <errno.h>
+#include <support/check.h>
+
+/* Use an escape sequence to return to the initial state. */
+static void
+with_escape_sequence (void)
+{
+ iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
+ TEST_VERIFY_EXIT (c != (iconv_t) -1);
+
+ char in[] = "\e$(O+D\e(B";
+ char *inbuf = in;
+ size_t inleft = strlen (in);
+ char out[3]; /* Space for one output character. */
+ char *outbuf;
+ size_t outleft;
+
+ outbuf = out;
+ outleft = sizeof (out);
+ TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
+ TEST_COMPARE (errno, E2BIG);
+ TEST_COMPARE (inleft, 3);
+ TEST_COMPARE (inbuf - in, strlen (in) - 3);
+ TEST_COMPARE (outleft, sizeof (out) - 2);
+ TEST_COMPARE (outbuf - out, 2);
+ TEST_COMPARE (out[0] & 0xff, 0xc3);
+ TEST_COMPARE (out[1] & 0xff, 0xa6);
+
+ /* Return to the initial shift state, producing the pending
+ character. */
+ outbuf = out;
+ outleft = sizeof (out);
+ TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), 0);
+ TEST_COMPARE (inleft, 0);
+ TEST_COMPARE (inbuf - in, strlen (in));
+ TEST_COMPARE (outleft, sizeof (out) - 2);
+ TEST_COMPARE (outbuf - out, 2);
+ TEST_COMPARE (out[0] & 0xff, 0xcc);
+ TEST_COMPARE (out[1] & 0xff, 0x80);
+
+ /* Nothing should be flushed the second time. */
+ outbuf = out;
+ outleft = sizeof (out);
+ TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
+ TEST_COMPARE (outleft, sizeof (out));
+ TEST_COMPARE (outbuf - out, 0);
+ TEST_COMPARE (out[0] & 0xff, 0xcc);
+ TEST_COMPARE (out[1] & 0xff, 0x80);
+
+ TEST_COMPARE (iconv_close (c), 0);
+}
+
+/* Use an explicit flush to return to the initial state. */
+static void
+with_flush (void)
+{
+ iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
+ TEST_VERIFY_EXIT (c != (iconv_t) -1);
+
+ char in[] = "\e$(O+D";
+ char *inbuf = in;
+ size_t inleft = strlen (in);
+ char out[3]; /* Space for one output character. */
+ char *outbuf;
+ size_t outleft;
+
+ outbuf = out;
+ outleft = sizeof (out);
+ TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
+ TEST_COMPARE (errno, E2BIG);
+ TEST_COMPARE (inleft, 0);
+ TEST_COMPARE (inbuf - in, strlen (in));
+ TEST_COMPARE (outleft, sizeof (out) - 2);
+ TEST_COMPARE (outbuf - out, 2);
+ TEST_COMPARE (out[0] & 0xff, 0xc3);
+ TEST_COMPARE (out[1] & 0xff, 0xa6);
+
+ /* Flush the pending character. */
+ outbuf = out;
+ outleft = sizeof (out);
+ TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
+ TEST_COMPARE (outleft, sizeof (out) - 2);
+ TEST_COMPARE (outbuf - out, 2);
+ TEST_COMPARE (out[0] & 0xff, 0xcc);
+ TEST_COMPARE (out[1] & 0xff, 0x80);
+
+ /* Nothing should be flushed the second time. */
+ outbuf = out;
+ outleft = sizeof (out);
+ TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
+ TEST_COMPARE (outleft, sizeof (out));
+ TEST_COMPARE (outbuf - out, 0);
+ TEST_COMPARE (out[0] & 0xff, 0xcc);
+ TEST_COMPARE (out[1] & 0xff, 0x80);
+
+ TEST_COMPARE (iconv_close (c), 0);
+}
+
+static int
+do_test (void)
+{
+ with_escape_sequence ();
+ with_flush ();
+ return 0;
+}
+
+#include <support/test-driver.c>
diff -pruN glibc-2.32.orig/iconvdata/euc-kr.c glibc-2.32/iconvdata/euc-kr.c
--- glibc-2.32.orig/iconvdata/euc-kr.c 2021-09-18 21:02:32.648182831 +1000
+++ glibc-2.32/iconvdata/euc-kr.c 2021-09-18 21:03:05.311302253 +1000
@@ -80,11 +80,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned c
2021-03-22 16:38:00 +01:00
\
if (ch <= 0x9f) \
++inptr; \
- /* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are \
- user-defined areas. */ \
- else if (__builtin_expect (ch == 0xa0, 0) \
- || __builtin_expect (ch > 0xfe, 0) \
- || __builtin_expect (ch == 0xc9, 0)) \
+ else if (__glibc_unlikely (ch == 0xa0)) \
{ \
/* This is illegal. */ \
STANDARD_FROM_LOOP_ERR_HANDLER (1); \
diff -pruN glibc-2.32.orig/iconvdata/ibm1364.c glibc-2.32/iconvdata/ibm1364.c
--- glibc-2.32.orig/iconvdata/ibm1364.c 2021-09-18 21:02:32.649182866 +1000
+++ glibc-2.32/iconvdata/ibm1364.c 2021-09-18 21:03:05.311302253 +1000
2021-03-22 16:38:00 +01:00
@@ -158,24 +158,14 @@ enum
\
if (__builtin_expect (ch, 0) == SO) \
{ \
- /* Shift OUT, change to DBCS converter. */ \
- if (curcs == db) \
- { \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
+ /* Shift OUT, change to DBCS converter (redundant escape okay). */ \
curcs = db; \
++inptr; \
continue; \
} \
if (__builtin_expect (ch, 0) == SI) \
{ \
- /* Shift IN, change to SBCS converter. */ \
- if (curcs == sb) \
- { \
- result = __GCONV_ILLEGAL_INPUT; \
- break; \
- } \
+ /* Shift IN, change to SBCS converter (redundant escape okay). */ \
curcs = sb; \
++inptr; \
continue; \
diff -pruN glibc-2.32.orig/iconvdata/iso-2022-jp-3.c glibc-2.32/iconvdata/iso-2022-jp-3.c
--- glibc-2.32.orig/iconvdata/iso-2022-jp-3.c 2021-09-18 21:02:32.651182934 +1000
+++ glibc-2.32/iconvdata/iso-2022-jp-3.c 2021-09-18 21:03:05.311302253 +1000
2021-03-22 16:38:00 +01:00
@@ -67,23 +67,34 @@ enum
CURRENT_SEL_MASK = 7 << 3
};
-/* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the state
- also contains the last two bytes to be output, shifted by 6 bits, and a
- one-bit indicator whether they must be preceded by the shift sequence,
- in bit 22. */
+/* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the
+ state also contains the last two bytes to be output, shifted by 6
+ bits, and a one-bit indicator whether they must be preceded by the
+ shift sequence, in bit 22. During ISO-2022-JP-3 to UCS-4
+ conversion, COUNT may also contain a non-zero pending wide
+ character, shifted by six bits. This happens for certain inputs in
+ JISX0213_1_2004_set and JISX0213_2_set if the second wide character
+ in a combining sequence cannot be written because the buffer is
+ full. */
/* Since this is a stateful encoding we have to provide code which resets
the output state to the initial state. This has to be done during the
flushing. */
#define EMIT_SHIFT_TO_INIT \
- if ((data->__statep->__count & ~7) != ASCII_set) \
+ if (data->__statep->__count != ASCII_set) \
{ \
if (FROM_DIRECTION) \
{ \
- /* It's easy, we don't have to emit anything, we just reset the \
- state for the input. */ \
- data->__statep->__count &= 7; \
- data->__statep->__count |= ASCII_set; \
+ if (__glibc_likely (outbuf + 4 <= outend)) \
+ { \
+ /* Write out the last character. */ \
+ *((uint32_t *) outbuf) = data->__statep->__count >> 6; \
+ outbuf += sizeof (uint32_t); \
+ data->__statep->__count = ASCII_set; \
+ } \
+ else \
+ /* We don't have enough room in the output buffer. */ \
+ status = __GCONV_FULL_OUTPUT; \
} \
else \
{ \
@@ -151,7 +162,21 @@ enum
#define LOOPFCT FROM_LOOP
#define BODY \
{ \
- uint32_t ch = *inptr; \
+ uint32_t ch; \
+ \
+ /* Output any pending character. */ \
+ ch = set >> 6; \
+ if (__glibc_unlikely (ch != 0)) \
+ { \
+ put32 (outptr, ch); \
+ outptr += 4; \
+ /* Remove the pending character, but preserve state bits. */ \
+ set &= (1 << 6) - 1; \
+ continue; \
+ } \
+ \
+ /* Otherwise read the next input byte. */ \
+ ch = *inptr; \
\
/* Recognize escape sequences. */ \
if (__glibc_unlikely (ch == ESC)) \
@@ -297,21 +322,25 @@ enum
uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0]; \
uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1]; \
\
+ inptr += 2; \
+ \
+ put32 (outptr, u1); \
+ outptr += 4; \
+ \
/* See whether we have room for two characters. */ \
- if (outptr + 8 <= outend) \
+ if (outptr + 4 <= outend) \
{ \
- inptr += 2; \
- put32 (outptr, u1); \
- outptr += 4; \
put32 (outptr, u2); \
outptr += 4; \
continue; \
} \
- else \
- { \
- result = __GCONV_FULL_OUTPUT; \
- break; \
- } \
+ \
+ /* Otherwise store only the first character now, and \
+ put the second one into the queue. */ \
+ set |= u2 << 6; \
+ /* Tell the caller why we terminate the loop. */ \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
} \
\
inptr += 2; \
diff -pruN glibc-2.32.orig/iconvdata/ksc5601.h glibc-2.32/iconvdata/ksc5601.h
--- glibc-2.32.orig/iconvdata/ksc5601.h 2021-09-18 21:02:32.652182968 +1000
+++ glibc-2.32/iconvdata/ksc5601.h 2021-09-18 21:03:05.311302253 +1000
@@ -50,15 +50,15 @@ ksc5601_to_ucs4 (const unsigned char **s
2021-03-22 16:38:00 +01:00
unsigned char ch2;
int idx;
+ if (avail < 2)
+ return 0;
+
/* row 94(0x7e) and row 41(0x49) are user-defined area in KS C 5601 */
if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) >= 0x7e
|| (ch - offset) == 0x49)
return __UNKNOWN_10646_CHAR;
- if (avail < 2)
- return 0;
-
ch2 = (*s)[1];
if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f)
return __UNKNOWN_10646_CHAR;
diff -pruN glibc-2.32.orig/iconvdata/Makefile glibc-2.32/iconvdata/Makefile
--- glibc-2.32.orig/iconvdata/Makefile 2021-09-18 21:02:32.647182797 +1000
+++ glibc-2.32/iconvdata/Makefile 2021-09-18 21:03:05.311302253 +1000
@@ -73,7 +73,8 @@ modules.so := $(addsuffix .so, $(modules
ifeq (yes,$(build-shared))
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
- bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4
+ bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \
+ bug-iconv13 bug-iconv14
ifeq ($(have-thread-library),yes)
tests += bug-iconv3
endif
@@ -321,6 +322,8 @@ $(objpfx)bug-iconv10.out: $(objpfx)gconv
$(addprefix $(objpfx),$(modules.so))
$(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so))
+$(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \
+ $(addprefix $(objpfx),$(modules.so))
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \
diff -pruN glibc-2.32.orig/intl/dcigettext.c glibc-2.32/intl/dcigettext.c
--- glibc-2.32.orig/intl/dcigettext.c 2021-09-18 21:02:32.656183106 +1000
+++ glibc-2.32/intl/dcigettext.c 2021-09-18 21:03:05.311302253 +1000
@@ -1120,15 +1120,18 @@ _nl_find_msg (struct loaded_l10nfile *do
# ifdef _LIBC
- struct gconv_spec conv_spec
- = { .fromcode = norm_add_slashes (charset, ""),
- .tocode = norm_add_slashes (outcharset, ""),
- /* We always want to use transliteration. */
- .translit = true,
- .ignore = false
- };
+ struct gconv_spec conv_spec;
+
+ __gconv_create_spec (&conv_spec, charset, outcharset);
+
+ /* We always want to use transliteration. */
+ conv_spec.translit = true;
+
int r = __gconv_open (&conv_spec, &convd->conv,
GCONV_AVOID_NOCONV);
+
+ __gconv_destroy_spec (&conv_spec);
+
if (__builtin_expect (r != __GCONV_OK, 0))
{
/* If the output encoding is the same there is
diff -pruN glibc-2.32.orig/intl/tst-codeset.c glibc-2.32/intl/tst-codeset.c
--- glibc-2.32.orig/intl/tst-codeset.c 2021-09-18 21:02:32.656183106 +1000
+++ glibc-2.32/intl/tst-codeset.c 2021-09-18 21:03:05.311302253 +1000
@@ -22,13 +22,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <support/check.h>
static int
do_test (void)
{
- char *s;
- int result = 0;
-
unsetenv ("LANGUAGE");
unsetenv ("OUTPUT_CHARSET");
setlocale (LC_ALL, "de_DE.ISO-8859-1");
@@ -36,25 +34,21 @@ do_test (void)
bindtextdomain ("codeset", OBJPFX "domaindir");
/* Here we expect output in ISO-8859-1. */
- s = gettext ("cheese");
- if (strcmp (s, "K\344se"))
- {
- printf ("call 1 returned: %s\n", s);
- result = 1;
- }
+ TEST_COMPARE_STRING (gettext ("cheese"), "K\344se");
+ /* Here we expect output in UTF-8. */
bind_textdomain_codeset ("codeset", "UTF-8");
+ TEST_COMPARE_STRING (gettext ("cheese"), "K\303\244se");
- /* Here we expect output in UTF-8. */
- s = gettext ("cheese");
- if (strcmp (s, "K\303\244se"))
- {
- printf ("call 2 returned: %s\n", s);
- result = 1;
- }
+ /* `a with umlaut' is transliterated to `ae'. */
+ bind_textdomain_codeset ("codeset", "ASCII//TRANSLIT");
+ TEST_COMPARE_STRING (gettext ("cheese"), "Kaese");
+
+ /* Transliteration also works by default even if not set. */
+ bind_textdomain_codeset ("codeset", "ASCII");
+ TEST_COMPARE_STRING (gettext ("cheese"), "Kaese");
- return result;
+ return 0;
}
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff -pruN glibc-2.32.orig/malloc/Makefile glibc-2.32/malloc/Makefile
--- glibc-2.32.orig/malloc/Makefile 2021-09-18 21:02:32.670183585 +1000
+++ glibc-2.32/malloc/Makefile 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -62,6 +62,16 @@ endif
tests += $(tests-static)
test-srcs = tst-mtrace
+# These tests either are run with MALLOC_CHECK_=3 by default or do not work
+# with MALLOC_CHECK_=3 because they expect a specific failure.
+tests-exclude-mcheck = tst-mcheck tst-malloc-usable \
+ tst-interpose-nothread tst-interpose-static-nothread \
+ tst-interpose-static-thread tst-malloc-too-large \
+ tst-mxfast tst-safe-linking
+
+# Run all tests with MALLOC_CHECK_=3
+tests-mcheck = $(filter-out $(tests-exclude-mcheck),$(tests))
+
routines = malloc morecore mcheck mtrace obstack reallocarray \
scratch_buffer_grow scratch_buffer_grow_preserve \
scratch_buffer_set_array_size \
@@ -100,6 +110,11 @@ $(objpfx)tst-malloc-thread-exit: $(share
2021-03-22 16:38:00 +01:00
$(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
$(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library)
$(objpfx)tst-malloc-stats-cancellation: $(shared-thread-library)
+$(objpfx)tst-malloc-backtrace-mcheck: $(shared-thread-library)
+$(objpfx)tst-malloc-thread-exit-mcheck: $(shared-thread-library)
+$(objpfx)tst-malloc-thread-fail-mcheck: $(shared-thread-library)
+$(objpfx)tst-malloc-fork-deadlock-mcheck: $(shared-thread-library)
+$(objpfx)tst-malloc-stats-cancellation-mcheck: $(shared-thread-library)
# Export the __malloc_initialize_hook variable to libc.so.
LDFLAGS-tst-mallocstate = -rdynamic
@@ -239,6 +254,8 @@ $(tests:%=$(objpfx)%.o): CPPFLAGS += -DT
2021-03-22 16:38:00 +01:00
$(objpfx)tst-interpose-nothread: $(objpfx)tst-interpose-aux-nothread.o
$(objpfx)tst-interpose-thread: \
$(objpfx)tst-interpose-aux-thread.o $(shared-thread-library)
+$(objpfx)tst-interpose-thread-mcheck: \
+ $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library)
$(objpfx)tst-interpose-static-nothread: $(objpfx)tst-interpose-aux-nothread.o
$(objpfx)tst-interpose-static-thread: \
$(objpfx)tst-interpose-aux-thread.o $(static-thread-library)
@@ -256,3 +273,6 @@ $(objpfx)tst-dynarray-fail-mem.out: $(ob
2021-03-22 16:38:00 +01:00
$(objpfx)tst-malloc-tcache-leak: $(shared-thread-library)
$(objpfx)tst-malloc_info: $(shared-thread-library)
$(objpfx)tst-mallocfork2: $(shared-thread-library)
+$(objpfx)tst-malloc-tcache-leak-mcheck: $(shared-thread-library)
+$(objpfx)tst-malloc_info-mcheck: $(shared-thread-library)
+$(objpfx)tst-mallocfork2-mcheck: $(shared-thread-library)
diff -pruN glibc-2.32.orig/manual/tunables.texi glibc-2.32/manual/tunables.texi
--- glibc-2.32.orig/manual/tunables.texi 2021-09-18 21:02:32.672183654 +1000
+++ glibc-2.32/manual/tunables.texi 2021-09-18 21:03:05.312302287 +1000
@@ -432,7 +432,11 @@ set shared cache size in bytes for use i
2021-03-22 16:38:00 +01:00
@deftp Tunable glibc.cpu.x86_non_temporal_threshold
The @code{glibc.cpu.x86_non_temporal_threshold} tunable allows the user
-to set threshold in bytes for non temporal store.
+to set threshold in bytes for non temporal store. Non temporal stores
+give a hint to the hardware to move data directly to memory without
+displacing other data from the cache. This tunable is used by some
+platforms to determine when to use non temporal stores in operations
+like memmove and memcpy.
This tunable is specific to i386 and x86-64.
@end deftp
diff -pruN glibc-2.32.orig/misc/sys/cdefs.h glibc-2.32/misc/sys/cdefs.h
--- glibc-2.32.orig/misc/sys/cdefs.h 2021-09-18 21:02:32.690184271 +1000
+++ glibc-2.32/misc/sys/cdefs.h 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -124,13 +124,10 @@
#define __bos0(ptr) __builtin_object_size (ptr, 0)
#if __GNUC_PREREQ (4,3)
-# define __warndecl(name, msg) \
- extern void name (void) __attribute__((__warning__ (msg)))
# define __warnattr(msg) __attribute__((__warning__ (msg)))
# define __errordecl(name, msg) \
extern void name (void) __attribute__((__error__ (msg)))
#else
-# define __warndecl(name, msg) extern void name (void)
# define __warnattr(msg)
# define __errordecl(name, msg) extern void name (void)
#endif
diff -pruN glibc-2.32.orig/NEWS glibc-2.32/NEWS
--- glibc-2.32.orig/NEWS 2021-09-18 21:02:32.639182523 +1000
+++ glibc-2.32/NEWS 2021-09-18 21:30:11.284117111 +1000
@@ -5,6 +5,33 @@ See the end for copying conditions.
Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
+The following bugs are resolved with this release:
+
+ [20019] NULL pointer dereference in libc.so.6 IFUNC due to uninitialized GOT
+ [25399] Remove __warn_memset_zero_len
+ [26224] iconv hangs when converting some invalid inputs from several IBM
+ character sets (CVE-2020-27618)
+ [26534] libm.so 2.32 SIGILL in pow() due to FMA4 instruction on non-FMA4
+ system
+ [26555] string: strerrorname_np does not return the documented value
+ [26600] Transaction ID collisions cause slow DNS lookups in getaddrinfo
+ [26636] libc: 32-bit shmctl(IPC_INFO) crashes when shminfo struct is
+ at the end of a memory mapping
+ [26637] libc: semctl SEM_STAT_ANY fails to pass the buffer specified
+ by the caller to the kernel
+ [26639] libc: msgctl IPC_INFO and MSG_INFO return garbage
+ [26690] __vfscanf_internal: fix aliasing violation
+ [26853] aarch64: Missing unwind information in statically linked startup code
+ [26932] libc: sh: Multiple floating point functions defined as stubs only
+ [27024] posix: Correct attribute access mode on readlinkat
+ [27130] "rep movsb" performance issue
+ [27177] GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on doesn't work
+ [27256] gconv: Fix assertion failure in ISO-2022-JP-3 module
+ [27462] nscd: Fix double free in netgroupcache
+ [27471] Fix SXID_ERASE behavior in setuid programs
+ [27896] Use __pthread_attr_copy in mq_notify (CVE-2021-33574)
+ [28213] librt: fix NULL pointer dereference
+
Version 2.32
Major new features:
@@ -185,6 +212,14 @@ Security related changes:
Dytrych of the Cisco Security Assessment and Penetration Team (See
TALOS-2020-1019).
+ CVE-2020-27618: An infinite loop has been fixed in the iconv program when
+ invoked with input containing redundant shift sequences in the IBM1364,
+ IBM1371, IBM1388, IBM1390, or IBM1399 character sets.
+
+ CVE-2021-33574: The mq_notify function has a potential use-after-free
+ issue when using a notification type of SIGEV_THREAD and a thread
+ attribute with a non-default affinity mask.
+
The following bugs are resolved with this release:
[9809] localedata: ckb_IQ: new Kurdish Sorani locale
diff -pruN glibc-2.32.orig/nscd/netgroupcache.c glibc-2.32/nscd/netgroupcache.c
--- glibc-2.32.orig/nscd/netgroupcache.c 2021-09-18 21:02:32.692184339 +1000
+++ glibc-2.32/nscd/netgroupcache.c 2021-09-18 21:03:05.312302287 +1000
@@ -248,7 +248,7 @@ addgetnetgrentX (struct database_dyn *db
2021-03-22 16:38:00 +01:00
: NULL);
ndomain = (ndomain ? newbuf + ndomaindiff
: NULL);
- buffer = newbuf;
+ *tofreep = buffer = newbuf;
}
nhost = memcpy (buffer + bufused,
@@ -319,7 +319,7 @@ addgetnetgrentX (struct database_dyn *db
2021-03-22 16:38:00 +01:00
else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
{
buflen *= 2;
- buffer = xrealloc (buffer, buflen);
+ *tofreep = buffer = xrealloc (buffer, buflen);
}
else if (status == NSS_STATUS_RETURN
|| status == NSS_STATUS_NOTFOUND
diff -pruN glibc-2.32.orig/posix/unistd.h glibc-2.32/posix/unistd.h
--- glibc-2.32.orig/posix/unistd.h 2021-09-18 21:02:32.696184476 +1000
+++ glibc-2.32/posix/unistd.h 2021-09-18 21:04:13.411636170 +1000
@@ -831,7 +831,7 @@ extern int symlinkat (const char *__from
/* Like readlink but a relative PATH is interpreted relative to FD. */
extern ssize_t readlinkat (int __fd, const char *__restrict __path,
char *__restrict __buf, size_t __len)
- __THROW __nonnull ((2, 3)) __wur __attr_access ((__read_only__, 3, 4));
+ __THROW __nonnull ((2, 3)) __wur __attr_access ((__write_only__, 3, 4));
#endif
/* Remove the link NAME. */
diff -pruN glibc-2.32.orig/posix/wordexp.c glibc-2.32/posix/wordexp.c
--- glibc-2.32.orig/posix/wordexp.c 2021-09-18 21:02:32.696184476 +1000
+++ glibc-2.32/posix/wordexp.c 2021-09-18 21:03:05.312302287 +1000
2021-08-06 12:41:15 +02:00
@@ -1399,7 +1399,7 @@ envsubst:
/* Is it a numeric parameter? */
else if (isdigit (env[0]))
{
- int n = atoi (env);
+ unsigned long n = strtoul (env, NULL, 10);
if (n >= __libc_argc)
/* Substitute NULL. */
diff -pruN glibc-2.32.orig/posix/wordexp-test.c glibc-2.32/posix/wordexp-test.c
--- glibc-2.32.orig/posix/wordexp-test.c 2021-09-18 21:02:32.696184476 +1000
+++ glibc-2.32/posix/wordexp-test.c 2021-09-18 21:03:05.312302287 +1000
@@ -183,6 +183,7 @@ struct test_case_struct
{ 0, NULL, "$var", 0, 0, { NULL, }, IFS },
{ 0, NULL, "\"\\n\"", 0, 1, { "\\n", }, IFS },
{ 0, NULL, "", 0, 0, { NULL, }, IFS },
+ { 0, NULL, "${1234567890123456789012}", 0, 0, { NULL, }, IFS },
/* Flags not already covered (testit() has special handling for these) */
{ 0, NULL, "one two", WRDE_DOOFFS, 2, { "one", "two", }, IFS },
diff -pruN glibc-2.32.orig/resolv/Makefile glibc-2.32/resolv/Makefile
--- glibc-2.32.orig/resolv/Makefile 2021-09-18 21:02:32.696184476 +1000
+++ glibc-2.32/resolv/Makefile 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -61,6 +61,11 @@ tests += \
tst-resolv-search \
tst-resolv-trailing \
+# This test calls __res_context_send directly, which is not exported
+# from libresolv.
+tests-internal += tst-resolv-txnid-collision
+tests-static += tst-resolv-txnid-collision
+
# These tests need libdl.
ifeq (yes,$(build-shared))
tests += \
@@ -191,6 +196,8 @@ $(objpfx)tst-resolv-search: $(objpfx)lib
2021-03-22 16:38:00 +01:00
$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-threads: \
$(libdl) $(objpfx)libresolv.so $(shared-thread-library)
+$(objpfx)tst-resolv-txnid-collision: $(objpfx)libresolv.a \
+ $(static-thread-library)
$(objpfx)tst-resolv-canonname: \
$(libdl) $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-trustad: $(objpfx)libresolv.so $(shared-thread-library)
diff -pruN glibc-2.32.orig/resolv/res_send.c glibc-2.32/resolv/res_send.c
--- glibc-2.32.orig/resolv/res_send.c 2021-09-18 21:02:32.696184476 +1000
+++ glibc-2.32/resolv/res_send.c 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -1342,15 +1342,6 @@ send_dg(res_state statp,
*terrno = EMSGSIZE;
return close_and_return_error (statp, resplen2);
}
- if ((recvresp1 || hp->id != anhp->id)
- && (recvresp2 || hp2->id != anhp->id)) {
- /*
- * response from old query, ignore it.
- * XXX - potential security hazard could
- * be detected here.
- */
- goto wait;
- }
/* Paranoia check. Due to the connected UDP socket,
the kernel has already filtered invalid addresses
@@ -1360,15 +1351,24 @@ send_dg(res_state statp,
/* Check for the correct header layout and a matching
question. */
- if ((recvresp1 || !res_queriesmatch(buf, buf + buflen,
- *thisansp,
- *thisansp
- + *thisanssizp))
- && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2,
- *thisansp,
- *thisansp
- + *thisanssizp)))
- goto wait;
+ int matching_query = 0; /* Default to no matching query. */
+ if (!recvresp1
+ && anhp->id == hp->id
+ && res_queriesmatch (buf, buf + buflen,
+ *thisansp, *thisansp + *thisanssizp))
+ matching_query = 1;
+ if (!recvresp2
+ && anhp->id == hp2->id
+ && res_queriesmatch (buf2, buf2 + buflen2,
+ *thisansp, *thisansp + *thisanssizp))
+ matching_query = 2;
+ if (matching_query == 0)
+ /* Spurious UDP packet. Drop it and continue
+ waiting. */
+ {
+ need_recompute = 1;
+ goto wait;
+ }
if (anhp->rcode == SERVFAIL ||
anhp->rcode == NOTIMP ||
@@ -1383,7 +1383,7 @@ send_dg(res_state statp,
/* No data from the first reply. */
resplen = 0;
/* We are waiting for a possible second reply. */
- if (hp->id == anhp->id)
+ if (matching_query == 1)
recvresp1 = 1;
else
recvresp2 = 1;
@@ -1414,7 +1414,7 @@ send_dg(res_state statp,
return (1);
}
/* Mark which reply we received. */
- if (recvresp1 == 0 && hp->id == anhp->id)
+ if (matching_query == 1)
recvresp1 = 1;
else
recvresp2 = 1;
diff -pruN glibc-2.32.orig/resolv/tst-resolv-txnid-collision.c glibc-2.32/resolv/tst-resolv-txnid-collision.c
--- glibc-2.32.orig/resolv/tst-resolv-txnid-collision.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/resolv/tst-resolv-txnid-collision.c 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1,334 @@
+/* Test parallel queries with transaction ID collisions.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <array_length.h>
+#include <resolv-internal.h>
+#include <resolv_context.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+
+/* Result of parsing a DNS question name.
+
+ A question name has the form reorder-N-M-rcode-C.example.net, where
+ N and M are either 0 and 1, corresponding to the reorder member,
+ and C is a number that will be stored in the rcode field.
+
+ Also see parse_qname below. */
+struct parsed_qname
+{
+ /* The DNS response code requested from the first server. The
+ second server always responds with RCODE zero. */
+ int rcode;
+
+ /* Indicates whether to perform reordering in the responses from the
+ respective server. */
+ bool reorder[2];
+};
+
+/* Fills *PARSED based on QNAME. */
+static void
+parse_qname (struct parsed_qname *parsed, const char *qname)
+{
+ int reorder0;
+ int reorder1;
+ int rcode;
+ char *suffix;
+ if (sscanf (qname, "reorder-%d-%d.rcode-%d.%ms",
+ &reorder0, &reorder1, &rcode, &suffix) == 4)
+ {
+ if (reorder0 != 0)
+ TEST_COMPARE (reorder0, 1);
+ if (reorder1 != 0)
+ TEST_COMPARE (reorder1, 1);
+ TEST_VERIFY (rcode >= 0 && rcode <= 15);
+ TEST_COMPARE_STRING (suffix, "example.net");
+ free (suffix);
+
+ parsed->rcode = rcode;
+ parsed->reorder[0] = reorder0;
+ parsed->reorder[1] = reorder1;
+ }
+ else
+ FAIL_EXIT1 ("unexpected query: %s", qname);
+}
+
+/* Used to construct a response. The first server responds with an
+ error, the second server succeeds. */
+static void
+build_response (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+ struct parsed_qname parsed;
+ parse_qname (&parsed, qname);
+
+ switch (ctx->server_index)
+ {
+ case 0:
+ {
+ struct resolv_response_flags flags = { 0 };
+ if (parsed.rcode == 0)
+ /* Simulate a delegation in case a NODATA (RCODE zero)
+ response is requested. */
+ flags.clear_ra = true;
+ else
+ flags.rcode = parsed.rcode;
+
+ resolv_response_init (b, flags);
+ resolv_response_add_question (b, qname, qclass, qtype);
+ }
+ break;
+
+ case 1:
+ {
+ struct resolv_response_flags flags = { 0, };
+ resolv_response_init (b, flags);
+ resolv_response_add_question (b, qname, qclass, qtype);
+
+ resolv_response_section (b, ns_s_an);
+ resolv_response_open_record (b, qname, qclass, qtype, 0);
+ if (qtype == T_A)
+ {
+ char ipv4[4] = { 192, 0, 2, 1 };
+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
+ }
+ else
+ {
+ char ipv6[16]
+ = { 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
+ }
+ resolv_response_close_record (b);
+ }
+ break;
+ }
+}
+
+/* Used to reorder responses. */
+struct resolv_response_context *previous_query;
+
+/* Used to keep track of the queries received. */
+static int previous_server_index = -1;
+static uint16_t previous_qtype;
+
+/* For each server, buffer the first query and then send both answers
+ to the second query, reordered if requested. */
+static void
+response (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+ TEST_VERIFY (qtype == T_A || qtype == T_AAAA);
+ if (ctx->server_index != 0)
+ TEST_COMPARE (ctx->server_index, 1);
+
+ struct parsed_qname parsed;
+ parse_qname (&parsed, qname);
+
+ if (previous_query == NULL)
+ {
+ /* No buffered query. Record this query and do not send a
+ response. */
+ TEST_COMPARE (previous_qtype, 0);
+ previous_query = resolv_response_context_duplicate (ctx);
+ previous_qtype = qtype;
+ resolv_response_drop (b);
+ previous_server_index = ctx->server_index;
+
+ if (test_verbose)
+ printf ("info: buffering first query for: %s\n", qname);
+ }
+ else
+ {
+ TEST_VERIFY (previous_query != 0);
+ TEST_COMPARE (ctx->server_index, previous_server_index);
+ TEST_VERIFY (previous_qtype != qtype); /* Not a duplicate. */
+
+ /* If reordering, send a response for this query explicitly, and
+ then skip the implicit send. */
+ if (parsed.reorder[ctx->server_index])
+ {
+ if (test_verbose)
+ printf ("info: sending reordered second response for: %s\n",
+ qname);
+ build_response (ctx, b, qname, qclass, qtype);
+ resolv_response_send_udp (ctx, b);
+ resolv_response_drop (b);
+ }
+
+ /* Build a response for the previous query and send it, thus
+ reordering the two responses. */
+ {
+ if (test_verbose)
+ printf ("info: sending first response for: %s\n", qname);
+ struct resolv_response_builder *btmp
+ = resolv_response_builder_allocate (previous_query->query_buffer,
+ previous_query->query_length);
+ build_response (ctx, btmp, qname, qclass, previous_qtype);
+ resolv_response_send_udp (ctx, btmp);
+ resolv_response_builder_free (btmp);
+ }
+
+ /* If not reordering, send the reply as usual. */
+ if (!parsed.reorder[ctx->server_index])
+ {
+ if (test_verbose)
+ printf ("info: sending non-reordered second response for: %s\n",
+ qname);
+ build_response (ctx, b, qname, qclass, qtype);
+ }
+
+ /* Unbuffer the response and prepare for the next query. */
+ resolv_response_context_free (previous_query);
+ previous_query = NULL;
+ previous_qtype = 0;
+ previous_server_index = -1;
+ }
+}
+
+/* Runs a query for QNAME and checks for the expected reply. See
+ struct parsed_qname for the expected format for QNAME. */
+static void
+test_qname (const char *qname, int rcode)
+{
+ struct resolv_context *ctx = __resolv_context_get ();
+ TEST_VERIFY_EXIT (ctx != NULL);
+
+ unsigned char q1[512];
+ int q1len = res_mkquery (QUERY, qname, C_IN, T_A, NULL, 0, NULL,
+ q1, sizeof (q1));
+ TEST_VERIFY_EXIT (q1len > 12);
+
+ unsigned char q2[512];
+ int q2len = res_mkquery (QUERY, qname, C_IN, T_AAAA, NULL, 0, NULL,
+ q2, sizeof (q2));
+ TEST_VERIFY_EXIT (q2len > 12);
+
+ /* Produce a transaction ID collision. */
+ memcpy (q2, q1, 2);
+
+ unsigned char ans1[512];
+ unsigned char *ans1p = ans1;
+ unsigned char *ans2p = NULL;
+ int nans2p = 0;
+ int resplen2 = 0;
+ int ans2p_malloced = 0;
+
+ /* Perform a parallel A/AAAA query. */
+ int resplen1 = __res_context_send (ctx, q1, q1len, q2, q2len,
+ ans1, sizeof (ans1), &ans1p,
+ &ans2p, &nans2p,
+ &resplen2, &ans2p_malloced);
+
+ TEST_VERIFY (resplen1 > 12);
+ TEST_VERIFY (resplen2 > 12);
+ if (resplen1 <= 12 || resplen2 <= 12)
+ return;
+
+ if (rcode == 1 || rcode == 3)
+ {
+ /* Format Error and Name Error responses does not trigger
+ switching to the next server. */
+ TEST_COMPARE (ans1p[3] & 0x0f, rcode);
+ TEST_COMPARE (ans2p[3] & 0x0f, rcode);
+ return;
+ }
+
+ /* The response should be successful. */
+ TEST_COMPARE (ans1p[3] & 0x0f, 0);
+ TEST_COMPARE (ans2p[3] & 0x0f, 0);
+
+ /* Due to bug 19691, the answer may not be in the slot matching the
+ query. Assume that the AAAA response is the longer one. */
+ unsigned char *a_answer;
+ int a_answer_length;
+ unsigned char *aaaa_answer;
+ int aaaa_answer_length;
+ if (resplen2 > resplen1)
+ {
+ a_answer = ans1p;
+ a_answer_length = resplen1;
+ aaaa_answer = ans2p;
+ aaaa_answer_length = resplen2;
+ }
+ else
+ {
+ a_answer = ans2p;
+ a_answer_length = resplen2;
+ aaaa_answer = ans1p;
+ aaaa_answer_length = resplen1;
+ }
+
+ {
+ char *expected = xasprintf ("name: %s\n"
+ "address: 192.0.2.1\n",
+ qname);
+ check_dns_packet (qname, a_answer, a_answer_length, expected);
+ free (expected);
+ }
+ {
+ char *expected = xasprintf ("name: %s\n"
+ "address: 2001:db8::1\n",
+ qname);
+ check_dns_packet (qname, aaaa_answer, aaaa_answer_length, expected);
+ free (expected);
+ }
+
+ if (ans2p_malloced)
+ free (ans2p);
+
+ __resolv_context_put (ctx);
+}
+
+static int
+do_test (void)
+{
+ struct resolv_test *aux = resolv_test_start
+ ((struct resolv_redirect_config)
+ {
+ .response_callback = response,
+
+ /* The response callback use global state (the previous_*
+ variables), and query processing must therefore be
+ serialized. */
+ .single_thread_udp = true,
+ });
+
+ for (int rcode = 0; rcode <= 5; ++rcode)
+ for (int do_reorder_0 = 0; do_reorder_0 < 2; ++do_reorder_0)
+ for (int do_reorder_1 = 0; do_reorder_1 < 2; ++do_reorder_1)
+ {
+ char *qname = xasprintf ("reorder-%d-%d.rcode-%d.example.net",
+ do_reorder_0, do_reorder_1, rcode);
+ test_qname (qname, rcode);
+ free (qname);
+ }
+
+ resolv_test_end (aux);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff -pruN glibc-2.32.orig/Rules glibc-2.32/Rules
--- glibc-2.32.orig/Rules 2021-09-18 21:02:32.639182523 +1000
+++ glibc-2.32/Rules 2021-09-18 21:03:05.310302219 +1000
@@ -155,6 +155,7 @@ xtests: tests $(xtests-special)
else
tests: $(tests:%=$(objpfx)%.out) $(tests-internal:%=$(objpfx)%.out) \
$(tests-container:%=$(objpfx)%.out) \
+ $(tests-mcheck:%=$(objpfx)%-mcheck.out) \
$(tests-special) $(tests-printers-out)
xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-special)
endif
@@ -165,7 +166,7 @@ ifeq ($(run-built-tests),no)
tests-expected =
else
tests-expected = $(tests) $(tests-internal) $(tests-printers) \
- $(tests-container)
+ $(tests-container) $(tests-mcheck:%=%-mcheck)
endif
tests:
$(..)scripts/merge-test-results.sh -s $(objpfx) $(subdir) \
@@ -191,6 +192,7 @@ else
binaries-pie-tests =
binaries-pie-notests =
endif
+binaries-mcheck-tests = $(tests-mcheck:%=%-mcheck)
else
binaries-all-notests =
binaries-all-tests = $(tests) $(tests-internal) $(xtests) $(test-srcs)
@@ -200,6 +202,7 @@ binaries-static-tests =
binaries-static =
binaries-pie-tests =
binaries-pie-notests =
+binaries-mcheck-tests =
endif
binaries-pie = $(binaries-pie-tests) $(binaries-pie-notests)
@@ -223,6 +226,14 @@ $(addprefix $(objpfx),$(binaries-shared-
$(+link-tests)
endif
+ifneq "$(strip $(binaries-mcheck-tests))" ""
+$(addprefix $(objpfx),$(binaries-mcheck-tests)): %-mcheck: %.o \
+ $(link-extra-libs-tests) \
+ $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
+ $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
+ $(+link-tests)
+endif
+
ifneq "$(strip $(binaries-pie-tests))" ""
$(addprefix $(objpfx),$(binaries-pie-tests)): %: %.o \
$(link-extra-libs-tests) \
@@ -253,6 +264,12 @@ $(addprefix $(objpfx),$(binaries-static-
$(+link-static-tests)
endif
+# All mcheck tests will be run with MALLOC_CHECK_=3
+define mcheck-ENVS
+$(1)-mcheck-ENV = MALLOC_CHECK_=3
+endef
+$(foreach t,$(tests-mcheck),$(eval $(call mcheck-ENVS,$(t))))
+
ifneq "$(strip $(tests) $(tests-internal) $(xtests) $(test-srcs))" ""
# These are the implicit rules for making test outputs
# from the test programs and whatever input files are present.
diff -pruN glibc-2.32.orig/stdio-common/errlist.c glibc-2.32/stdio-common/errlist.c
--- glibc-2.32.orig/stdio-common/errlist.c 2021-09-18 21:02:32.698184545 +1000
+++ glibc-2.32/stdio-common/errlist.c 2021-09-18 21:03:05.312302287 +1000
@@ -20,9 +20,13 @@
#include <libintl.h>
#include <array_length.h>
+#ifndef ERR_MAP
+# define ERR_MAP(n) n
+#endif
+
const char *const _sys_errlist_internal[] =
{
-#define _S(n, str) [n] = str,
+#define _S(n, str) [ERR_MAP(n)] = str,
#include <errlist.h>
#undef _S
};
@@ -41,20 +45,21 @@ static const union sys_errname_t
{
#define MSGSTRFIELD1(line) str##line
#define MSGSTRFIELD(line) MSGSTRFIELD1(line)
-#define _S(n, str) char MSGSTRFIELD(__LINE__)[sizeof(str)];
+#define _S(n, str) char MSGSTRFIELD(__LINE__)[sizeof(#n)];
#include <errlist.h>
#undef _S
};
char str[0];
} _sys_errname = { {
-#define _S(n, s) s,
+#define _S(n, s) #n,
#include <errlist.h>
#undef _S
} };
static const unsigned short _sys_errnameidx[] =
{
-#define _S(n, s) [n] = offsetof(union sys_errname_t, MSGSTRFIELD(__LINE__)),
+#define _S(n, s) \
+ [ERR_MAP(n)] = offsetof(union sys_errname_t, MSGSTRFIELD(__LINE__)),
#include <errlist.h>
#undef _S
};
diff -pruN glibc-2.32.orig/stdio-common/Makefile glibc-2.32/stdio-common/Makefile
--- glibc-2.32.orig/stdio-common/Makefile 2021-09-18 21:02:32.698184545 +1000
+++ glibc-2.32/stdio-common/Makefile 2021-09-18 21:03:05.312302287 +1000
@@ -69,7 +69,8 @@ tests := tstscanf test_rdwr test-popen t
tst-printf-bz25691 \
tst-vfprintf-width-prec-alloc \
tst-printf-fp-free \
- tst-printf-fp-leak
+ tst-printf-fp-leak \
+ test-strerr
test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble
diff -pruN glibc-2.32.orig/stdio-common/test-strerr.c glibc-2.32/stdio-common/test-strerr.c
--- glibc-2.32.orig/stdio-common/test-strerr.c 2021-09-18 21:02:32.698184545 +1000
+++ glibc-2.32/stdio-common/test-strerr.c 2021-09-18 21:03:05.312302287 +1000
@@ -18,46 +18,672 @@
#include <string.h>
#include <errno.h>
-#include <array_length.h>
#include <support/support.h>
#include <support/check.h>
-#define N_(name) name
-
-static const char *const errlist[] =
- {
-/* This file is auto-generated from errlist.def. */
-#include <errlist.h>
- };
-
-#define MSGSTR_T errname_t
-#define MSGSTR errname
-#define MSGIDX errnameidx
-#include <errlist-name.h>
-#undef MSGSTR
-#undef MSGIDX
-
static int
do_test (void)
{
- TEST_VERIFY (strerrordesc_np (-1) == NULL);
- TEST_VERIFY (strerrordesc_np (array_length (errlist)) == NULL);
- for (size_t i = 0; i < array_length (errlist); i++)
- {
- if (errlist[i] == NULL)
- continue;
- TEST_COMPARE_STRING (strerrordesc_np (i), errlist[i]);
- }
+ TEST_COMPARE_STRING (strerrordesc_np (0), "Success");
+ TEST_COMPARE_STRING (strerrorname_np (0), "0");
- TEST_VERIFY (strerrorname_np (-1) == NULL);
- TEST_VERIFY (strerrorname_np (array_length (errlist)) == NULL);
- for (size_t i = 0; i < array_length (errlist); i++)
- {
- if (errlist[i] == NULL)
- continue;
- TEST_COMPARE_STRING (strerrorname_np (i), errname.str + errnameidx[i]);
- }
+#ifdef EPERM
+ TEST_COMPARE_STRING (strerrordesc_np (EPERM), "Operation not permitted");
+ TEST_COMPARE_STRING (strerrorname_np (EPERM), "EPERM");
+#endif
+#ifdef ENOENT
+ TEST_COMPARE_STRING (strerrordesc_np (ENOENT),
+ "No such file or directory");
+ TEST_COMPARE_STRING (strerrorname_np (ENOENT), "ENOENT");
+#endif
+#ifdef ESRCH
+ TEST_COMPARE_STRING (strerrordesc_np (ESRCH), "No such process");
+ TEST_COMPARE_STRING (strerrorname_np (ESRCH), "ESRCH");
+#endif
+#ifdef EINTR
+ TEST_COMPARE_STRING (strerrordesc_np (EINTR), "Interrupted system call");
+ TEST_COMPARE_STRING (strerrorname_np (EINTR), "EINTR");
+#endif
+#ifdef EIO
+ TEST_COMPARE_STRING (strerrordesc_np (EIO), "Input/output error");
+ TEST_COMPARE_STRING (strerrorname_np (EIO), "EIO");
+#endif
+#ifdef ENXIO
+ TEST_COMPARE_STRING (strerrordesc_np (ENXIO), "No such device or address");
+ TEST_COMPARE_STRING (strerrorname_np (ENXIO), "ENXIO");
+#endif
+#ifdef E2BIG
+ TEST_COMPARE_STRING (strerrordesc_np (E2BIG), "Argument list too long");
+ TEST_COMPARE_STRING (strerrorname_np (E2BIG), "E2BIG");
+#endif
+#ifdef ENOEXEC
+ TEST_COMPARE_STRING (strerrordesc_np (ENOEXEC), "Exec format error");
+ TEST_COMPARE_STRING (strerrorname_np (ENOEXEC), "ENOEXEC");
+#endif
+#ifdef EBADF
+ TEST_COMPARE_STRING (strerrordesc_np (EBADF), "Bad file descriptor");
+ TEST_COMPARE_STRING (strerrorname_np (EBADF), "EBADF");
+#endif
+#ifdef ECHILD
+ TEST_COMPARE_STRING (strerrordesc_np (ECHILD), "No child processes");
+ TEST_COMPARE_STRING (strerrorname_np (ECHILD), "ECHILD");
+#endif
+#ifdef EDEADLK
+ TEST_COMPARE_STRING (strerrordesc_np (EDEADLK),
+ "Resource deadlock avoided");
+ TEST_COMPARE_STRING (strerrorname_np (EDEADLK), "EDEADLK");
+#endif
+#ifdef ENOMEM
+ TEST_COMPARE_STRING (strerrordesc_np (ENOMEM), "Cannot allocate memory");
+ TEST_COMPARE_STRING (strerrorname_np (ENOMEM), "ENOMEM");
+#endif
+#ifdef EACCES
+ TEST_COMPARE_STRING (strerrordesc_np (EACCES), "Permission denied");
+ TEST_COMPARE_STRING (strerrorname_np (EACCES), "EACCES");
+#endif
+#ifdef EFAULT
+ TEST_COMPARE_STRING (strerrordesc_np (EFAULT), "Bad address");
+ TEST_COMPARE_STRING (strerrorname_np (EFAULT), "EFAULT");
+#endif
+#ifdef ENOTBLK
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTBLK), "Block device required");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTBLK), "ENOTBLK");
+#endif
+#ifdef EBUSY
+ TEST_COMPARE_STRING (strerrordesc_np (EBUSY), "Device or resource busy");
+ TEST_COMPARE_STRING (strerrorname_np (EBUSY), "EBUSY");
+#endif
+#ifdef EEXIST
+ TEST_COMPARE_STRING (strerrordesc_np (EEXIST), "File exists");
+ TEST_COMPARE_STRING (strerrorname_np (EEXIST), "EEXIST");
+#endif
+#ifdef EXDEV
+ TEST_COMPARE_STRING (strerrordesc_np (EXDEV), "Invalid cross-device link");
+ TEST_COMPARE_STRING (strerrorname_np (EXDEV), "EXDEV");
+#endif
+#ifdef ENODEV
+ TEST_COMPARE_STRING (strerrordesc_np (ENODEV), "No such device");
+ TEST_COMPARE_STRING (strerrorname_np (ENODEV), "ENODEV");
+#endif
+#ifdef ENOTDIR
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTDIR), "Not a directory");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTDIR), "ENOTDIR");
+#endif
+#ifdef EISDIR
+ TEST_COMPARE_STRING (strerrordesc_np (EISDIR), "Is a directory");
+ TEST_COMPARE_STRING (strerrorname_np (EISDIR), "EISDIR");
+#endif
+#ifdef EINVAL
+ TEST_COMPARE_STRING (strerrordesc_np (EINVAL), "Invalid argument");
+ TEST_COMPARE_STRING (strerrorname_np (EINVAL), "EINVAL");
+#endif
+#ifdef EMFILE
+ TEST_COMPARE_STRING (strerrordesc_np (EMFILE), "Too many open files");
+ TEST_COMPARE_STRING (strerrorname_np (EMFILE), "EMFILE");
+#endif
+#ifdef ENFILE
+ TEST_COMPARE_STRING (strerrordesc_np (ENFILE),
+ "Too many open files in system");
+ TEST_COMPARE_STRING (strerrorname_np (ENFILE), "ENFILE");
+#endif
+#ifdef ENOTTY
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTTY),
+ "Inappropriate ioctl for device");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTTY), "ENOTTY");
+#endif
+#ifdef ETXTBSY
+ TEST_COMPARE_STRING (strerrordesc_np (ETXTBSY), "Text file busy");
+ TEST_COMPARE_STRING (strerrorname_np (ETXTBSY), "ETXTBSY");
+#endif
+#ifdef EFBIG
+ TEST_COMPARE_STRING (strerrordesc_np (EFBIG), "File too large");
+ TEST_COMPARE_STRING (strerrorname_np (EFBIG), "EFBIG");
+#endif
+#ifdef ENOSPC
+ TEST_COMPARE_STRING (strerrordesc_np (ENOSPC), "No space left on device");
+ TEST_COMPARE_STRING (strerrorname_np (ENOSPC), "ENOSPC");
+#endif
+#ifdef ESPIPE
+ TEST_COMPARE_STRING (strerrordesc_np (ESPIPE), "Illegal seek");
+ TEST_COMPARE_STRING (strerrorname_np (ESPIPE), "ESPIPE");
+#endif
+#ifdef EROFS
+ TEST_COMPARE_STRING (strerrordesc_np (EROFS), "Read-only file system");
+ TEST_COMPARE_STRING (strerrorname_np (EROFS), "EROFS");
+#endif
+#ifdef EMLINK
+ TEST_COMPARE_STRING (strerrordesc_np (EMLINK), "Too many links");
+ TEST_COMPARE_STRING (strerrorname_np (EMLINK), "EMLINK");
+#endif
+#ifdef EPIPE
+ TEST_COMPARE_STRING (strerrordesc_np (EPIPE), "Broken pipe");
+ TEST_COMPARE_STRING (strerrorname_np (EPIPE), "EPIPE");
+#endif
+#ifdef EDOM
+ TEST_COMPARE_STRING (strerrordesc_np (EDOM),
+ "Numerical argument out of domain");
+ TEST_COMPARE_STRING (strerrorname_np (EDOM), "EDOM");
+#endif
+#ifdef ERANGE
+ TEST_COMPARE_STRING (strerrordesc_np (ERANGE),
+ "Numerical result out of range");
+ TEST_COMPARE_STRING (strerrorname_np (ERANGE), "ERANGE");
+#endif
+#ifdef EAGAIN
+ TEST_COMPARE_STRING (strerrordesc_np (EAGAIN),
+ "Resource temporarily unavailable");
+ TEST_COMPARE_STRING (strerrorname_np (EAGAIN), "EAGAIN");
+#endif
+#ifdef EINPROGRESS
+ TEST_COMPARE_STRING (strerrordesc_np (EINPROGRESS),
+ "Operation now in progress");
+ TEST_COMPARE_STRING (strerrorname_np (EINPROGRESS), "EINPROGRESS");
+#endif
+#ifdef EALREADY
+ TEST_COMPARE_STRING (strerrordesc_np (EALREADY),
+ "Operation already in progress");
+ TEST_COMPARE_STRING (strerrorname_np (EALREADY), "EALREADY");
+#endif
+#ifdef ENOTSOCK
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTSOCK),
+ "Socket operation on non-socket");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTSOCK), "ENOTSOCK");
+#endif
+#ifdef EMSGSIZE
+ TEST_COMPARE_STRING (strerrordesc_np (EMSGSIZE), "Message too long");
+ TEST_COMPARE_STRING (strerrorname_np (EMSGSIZE), "EMSGSIZE");
+#endif
+#ifdef EPROTOTYPE
+ TEST_COMPARE_STRING (strerrordesc_np (EPROTOTYPE),
+ "Protocol wrong type for socket");
+ TEST_COMPARE_STRING (strerrorname_np (EPROTOTYPE), "EPROTOTYPE");
+#endif
+#ifdef ENOPROTOOPT
+ TEST_COMPARE_STRING (strerrordesc_np (ENOPROTOOPT),
+ "Protocol not available");
+ TEST_COMPARE_STRING (strerrorname_np (ENOPROTOOPT), "ENOPROTOOPT");
+#endif
+#ifdef EPROTONOSUPPORT
+ TEST_COMPARE_STRING (strerrordesc_np (EPROTONOSUPPORT),
+ "Protocol not supported");
+ TEST_COMPARE_STRING (strerrorname_np (EPROTONOSUPPORT), "EPROTONOSUPPORT");
+#endif
+#ifdef ESOCKTNOSUPPORT
+ TEST_COMPARE_STRING (strerrordesc_np (ESOCKTNOSUPPORT),
+ "Socket type not supported");
+ TEST_COMPARE_STRING (strerrorname_np (ESOCKTNOSUPPORT), "ESOCKTNOSUPPORT");
+#endif
+#ifdef EOPNOTSUPP
+ TEST_COMPARE_STRING (strerrordesc_np (EOPNOTSUPP),
+ "Operation not supported");
+ TEST_COMPARE_STRING (strerrorname_np (EOPNOTSUPP), "EOPNOTSUPP");
+#endif
+#ifdef EPFNOSUPPORT
+ TEST_COMPARE_STRING (strerrordesc_np (EPFNOSUPPORT),
+ "Protocol family not supported");
+ TEST_COMPARE_STRING (strerrorname_np (EPFNOSUPPORT), "EPFNOSUPPORT");
+#endif
+#ifdef EAFNOSUPPORT
+ TEST_COMPARE_STRING (strerrordesc_np (EAFNOSUPPORT),
+ "Address family not supported by protocol");
+ TEST_COMPARE_STRING (strerrorname_np (EAFNOSUPPORT), "EAFNOSUPPORT");
+#endif
+#ifdef EADDRINUSE
+ TEST_COMPARE_STRING (strerrordesc_np (EADDRINUSE),
+ "Address already in use");
+ TEST_COMPARE_STRING (strerrorname_np (EADDRINUSE), "EADDRINUSE");
+#endif
+#ifdef EADDRNOTAVAIL
+ TEST_COMPARE_STRING (strerrordesc_np (EADDRNOTAVAIL),
+ "Cannot assign requested address");
+ TEST_COMPARE_STRING (strerrorname_np (EADDRNOTAVAIL), "EADDRNOTAVAIL");
+#endif
+#ifdef ENETDOWN
+ TEST_COMPARE_STRING (strerrordesc_np (ENETDOWN), "Network is down");
+ TEST_COMPARE_STRING (strerrorname_np (ENETDOWN), "ENETDOWN");
+#endif
+#ifdef ENETUNREACH
+ TEST_COMPARE_STRING (strerrordesc_np (ENETUNREACH),
+ "Network is unreachable");
+ TEST_COMPARE_STRING (strerrorname_np (ENETUNREACH), "ENETUNREACH");
+#endif
+#ifdef ENETRESET
+ TEST_COMPARE_STRING (strerrordesc_np (ENETRESET),
+ "Network dropped connection on reset");
+ TEST_COMPARE_STRING (strerrorname_np (ENETRESET), "ENETRESET");
+#endif
+#ifdef ECONNABORTED
+ TEST_COMPARE_STRING (strerrordesc_np (ECONNABORTED),
+ "Software caused connection abort");
+ TEST_COMPARE_STRING (strerrorname_np (ECONNABORTED), "ECONNABORTED");
+#endif
+#ifdef ECONNRESET
+ TEST_COMPARE_STRING (strerrordesc_np (ECONNRESET),
+ "Connection reset by peer");
+ TEST_COMPARE_STRING (strerrorname_np (ECONNRESET), "ECONNRESET");
+#endif
+#ifdef ENOBUFS
+ TEST_COMPARE_STRING (strerrordesc_np (ENOBUFS),
+ "No buffer space available");
+ TEST_COMPARE_STRING (strerrorname_np (ENOBUFS), "ENOBUFS");
+#endif
+#ifdef EISCONN
+ TEST_COMPARE_STRING (strerrordesc_np (EISCONN),
+ "Transport endpoint is already connected");
+ TEST_COMPARE_STRING (strerrorname_np (EISCONN), "EISCONN");
+#endif
+#ifdef ENOTCONN
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTCONN),
+ "Transport endpoint is not connected");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTCONN), "ENOTCONN");
+#endif
+#ifdef EDESTADDRREQ
+ TEST_COMPARE_STRING (strerrordesc_np (EDESTADDRREQ),
+ "Destination address required");
+ TEST_COMPARE_STRING (strerrorname_np (EDESTADDRREQ), "EDESTADDRREQ");
+#endif
+#ifdef ESHUTDOWN
+ TEST_COMPARE_STRING (strerrordesc_np (ESHUTDOWN),
+ "Cannot send after transport endpoint shutdown");
+ TEST_COMPARE_STRING (strerrorname_np (ESHUTDOWN), "ESHUTDOWN");
+#endif
+#ifdef ETOOMANYREFS
+ TEST_COMPARE_STRING (strerrordesc_np (ETOOMANYREFS),
+ "Too many references: cannot splice");
+ TEST_COMPARE_STRING (strerrorname_np (ETOOMANYREFS), "ETOOMANYREFS");
+#endif
+#ifdef ETIMEDOUT
+ TEST_COMPARE_STRING (strerrordesc_np (ETIMEDOUT), "Connection timed out");
+ TEST_COMPARE_STRING (strerrorname_np (ETIMEDOUT), "ETIMEDOUT");
+#endif
+#ifdef ECONNREFUSED
+ TEST_COMPARE_STRING (strerrordesc_np (ECONNREFUSED), "Connection refused");
+ TEST_COMPARE_STRING (strerrorname_np (ECONNREFUSED), "ECONNREFUSED");
+#endif
+#ifdef ELOOP
+ TEST_COMPARE_STRING (strerrordesc_np (ELOOP),
+ "Too many levels of symbolic links");
+ TEST_COMPARE_STRING (strerrorname_np (ELOOP), "ELOOP");
+#endif
+#ifdef ENAMETOOLONG
+ TEST_COMPARE_STRING (strerrordesc_np (ENAMETOOLONG), "File name too long");
+ TEST_COMPARE_STRING (strerrorname_np (ENAMETOOLONG), "ENAMETOOLONG");
+#endif
+#ifdef EHOSTDOWN
+ TEST_COMPARE_STRING (strerrordesc_np (EHOSTDOWN), "Host is down");
+ TEST_COMPARE_STRING (strerrorname_np (EHOSTDOWN), "EHOSTDOWN");
+#endif
+#ifdef EHOSTUNREACH
+ TEST_COMPARE_STRING (strerrordesc_np (EHOSTUNREACH), "No route to host");
+ TEST_COMPARE_STRING (strerrorname_np (EHOSTUNREACH), "EHOSTUNREACH");
+#endif
+#ifdef ENOTEMPTY
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTEMPTY), "Directory not empty");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTEMPTY), "ENOTEMPTY");
+#endif
+#ifdef EUSERS
+ TEST_COMPARE_STRING (strerrordesc_np (EUSERS), "Too many users");
+ TEST_COMPARE_STRING (strerrorname_np (EUSERS), "EUSERS");
+#endif
+#ifdef EDQUOT
+ TEST_COMPARE_STRING (strerrordesc_np (EDQUOT), "Disk quota exceeded");
+ TEST_COMPARE_STRING (strerrorname_np (EDQUOT), "EDQUOT");
+#endif
+#ifdef ESTALE
+ TEST_COMPARE_STRING (strerrordesc_np (ESTALE), "Stale file handle");
+ TEST_COMPARE_STRING (strerrorname_np (ESTALE), "ESTALE");
+#endif
+#ifdef EREMOTE
+ TEST_COMPARE_STRING (strerrordesc_np (EREMOTE), "Object is remote");
+ TEST_COMPARE_STRING (strerrorname_np (EREMOTE), "EREMOTE");
+#endif
+#ifdef ENOLCK
+ TEST_COMPARE_STRING (strerrordesc_np (ENOLCK), "No locks available");
+ TEST_COMPARE_STRING (strerrorname_np (ENOLCK), "ENOLCK");
+#endif
+#ifdef ENOSYS
+ TEST_COMPARE_STRING (strerrordesc_np (ENOSYS), "Function not implemented");
+ TEST_COMPARE_STRING (strerrorname_np (ENOSYS), "ENOSYS");
+#endif
+#ifdef EILSEQ
+ TEST_COMPARE_STRING (strerrordesc_np (EILSEQ),
+ "Invalid or incomplete multibyte or wide character");
+ TEST_COMPARE_STRING (strerrorname_np (EILSEQ), "EILSEQ");
+#endif
+#ifdef EBADMSG
+ TEST_COMPARE_STRING (strerrordesc_np (EBADMSG), "Bad message");
+ TEST_COMPARE_STRING (strerrorname_np (EBADMSG), "EBADMSG");
+#endif
+#ifdef EIDRM
+ TEST_COMPARE_STRING (strerrordesc_np (EIDRM), "Identifier removed");
+ TEST_COMPARE_STRING (strerrorname_np (EIDRM), "EIDRM");
+#endif
+#ifdef EMULTIHOP
+ TEST_COMPARE_STRING (strerrordesc_np (EMULTIHOP), "Multihop attempted");
+ TEST_COMPARE_STRING (strerrorname_np (EMULTIHOP), "EMULTIHOP");
+#endif
+#ifdef ENODATA
+ TEST_COMPARE_STRING (strerrordesc_np (ENODATA), "No data available");
+ TEST_COMPARE_STRING (strerrorname_np (ENODATA), "ENODATA");
+#endif
+#ifdef ENOLINK
+ TEST_COMPARE_STRING (strerrordesc_np (ENOLINK), "Link has been severed");
+ TEST_COMPARE_STRING (strerrorname_np (ENOLINK), "ENOLINK");
+#endif
+#ifdef ENOMSG
+ TEST_COMPARE_STRING (strerrordesc_np (ENOMSG),
+ "No message of desired type");
+ TEST_COMPARE_STRING (strerrorname_np (ENOMSG), "ENOMSG");
+#endif
+#ifdef ENOSR
+ TEST_COMPARE_STRING (strerrordesc_np (ENOSR), "Out of streams resources");
+ TEST_COMPARE_STRING (strerrorname_np (ENOSR), "ENOSR");
+#endif
+#ifdef ENOSTR
+ TEST_COMPARE_STRING (strerrordesc_np (ENOSTR), "Device not a stream");
+ TEST_COMPARE_STRING (strerrorname_np (ENOSTR), "ENOSTR");
+#endif
+#ifdef EOVERFLOW
+ TEST_COMPARE_STRING (strerrordesc_np (EOVERFLOW),
+ "Value too large for defined data type");
+ TEST_COMPARE_STRING (strerrorname_np (EOVERFLOW), "EOVERFLOW");
+#endif
+#ifdef EPROTO
+ TEST_COMPARE_STRING (strerrordesc_np (EPROTO), "Protocol error");
+ TEST_COMPARE_STRING (strerrorname_np (EPROTO), "EPROTO");
+#endif
+#ifdef ETIME
+ TEST_COMPARE_STRING (strerrordesc_np (ETIME), "Timer expired");
+ TEST_COMPARE_STRING (strerrorname_np (ETIME), "ETIME");
+#endif
+#ifdef ECANCELED
+ TEST_COMPARE_STRING (strerrordesc_np (ECANCELED), "Operation canceled");
+ TEST_COMPARE_STRING (strerrorname_np (ECANCELED), "ECANCELED");
+#endif
+#ifdef EOWNERDEAD
+ TEST_COMPARE_STRING (strerrordesc_np (EOWNERDEAD), "Owner died");
+ TEST_COMPARE_STRING (strerrorname_np (EOWNERDEAD), "EOWNERDEAD");
+#endif
+#ifdef ENOTRECOVERABLE
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTRECOVERABLE),
+ "State not recoverable");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTRECOVERABLE), "ENOTRECOVERABLE");
+#endif
+#ifdef ERESTART
+ TEST_COMPARE_STRING (strerrordesc_np (ERESTART),
+ "Interrupted system call should be restarted");
+ TEST_COMPARE_STRING (strerrorname_np (ERESTART), "ERESTART");
+#endif
+#ifdef ECHRNG
+ TEST_COMPARE_STRING (strerrordesc_np (ECHRNG),
+ "Channel number out of range");
+ TEST_COMPARE_STRING (strerrorname_np (ECHRNG), "ECHRNG");
+#endif
+#ifdef EL2NSYNC
+ TEST_COMPARE_STRING (strerrordesc_np (EL2NSYNC),
+ "Level 2 not synchronized");
+ TEST_COMPARE_STRING (strerrorname_np (EL2NSYNC), "EL2NSYNC");
+#endif
+#ifdef EL3HLT
+ TEST_COMPARE_STRING (strerrordesc_np (EL3HLT), "Level 3 halted");
+ TEST_COMPARE_STRING (strerrorname_np (EL3HLT), "EL3HLT");
+#endif
+#ifdef EL3RST
+ TEST_COMPARE_STRING (strerrordesc_np (EL3RST), "Level 3 reset");
+ TEST_COMPARE_STRING (strerrorname_np (EL3RST), "EL3RST");
+#endif
+#ifdef ELNRNG
+ TEST_COMPARE_STRING (strerrordesc_np (ELNRNG), "Link number out of range");
+ TEST_COMPARE_STRING (strerrorname_np (ELNRNG), "ELNRNG");
+#endif
+#ifdef EUNATCH
+ TEST_COMPARE_STRING (strerrordesc_np (EUNATCH),
+ "Protocol driver not attached");
+ TEST_COMPARE_STRING (strerrorname_np (EUNATCH), "EUNATCH");
+#endif
+#ifdef ENOCSI
+ TEST_COMPARE_STRING (strerrordesc_np (ENOCSI),
+ "No CSI structure available");
+ TEST_COMPARE_STRING (strerrorname_np (ENOCSI), "ENOCSI");
+#endif
+#ifdef EL2HLT
+ TEST_COMPARE_STRING (strerrordesc_np (EL2HLT), "Level 2 halted");
+ TEST_COMPARE_STRING (strerrorname_np (EL2HLT), "EL2HLT");
+#endif
+#ifdef EBADE
+ TEST_COMPARE_STRING (strerrordesc_np (EBADE), "Invalid exchange");
+ TEST_COMPARE_STRING (strerrorname_np (EBADE), "EBADE");
+#endif
+#ifdef EBADR
+ TEST_COMPARE_STRING (strerrordesc_np (EBADR),
+ "Invalid request descriptor");
+ TEST_COMPARE_STRING (strerrorname_np (EBADR), "EBADR");
+#endif
+#ifdef EXFULL
+ TEST_COMPARE_STRING (strerrordesc_np (EXFULL), "Exchange full");
+ TEST_COMPARE_STRING (strerrorname_np (EXFULL), "EXFULL");
+#endif
+#ifdef ENOANO
+ TEST_COMPARE_STRING (strerrordesc_np (ENOANO), "No anode");
+ TEST_COMPARE_STRING (strerrorname_np (ENOANO), "ENOANO");
+#endif
+#ifdef EBADRQC
+ TEST_COMPARE_STRING (strerrordesc_np (EBADRQC), "Invalid request code");
+ TEST_COMPARE_STRING (strerrorname_np (EBADRQC), "EBADRQC");
+#endif
+#ifdef EBADSLT
+ TEST_COMPARE_STRING (strerrordesc_np (EBADSLT), "Invalid slot");
+ TEST_COMPARE_STRING (strerrorname_np (EBADSLT), "EBADSLT");
+#endif
+#ifdef EBFONT
+ TEST_COMPARE_STRING (strerrordesc_np (EBFONT), "Bad font file format");
+ TEST_COMPARE_STRING (strerrorname_np (EBFONT), "EBFONT");
+#endif
+#ifdef ENONET
+ TEST_COMPARE_STRING (strerrordesc_np (ENONET),
+ "Machine is not on the network");
+ TEST_COMPARE_STRING (strerrorname_np (ENONET), "ENONET");
+#endif
+#ifdef ENOPKG
+ TEST_COMPARE_STRING (strerrordesc_np (ENOPKG), "Package not installed");
+ TEST_COMPARE_STRING (strerrorname_np (ENOPKG), "ENOPKG");
+#endif
+#ifdef EADV
+ TEST_COMPARE_STRING (strerrordesc_np (EADV), "Advertise error");
+ TEST_COMPARE_STRING (strerrorname_np (EADV), "EADV");
+#endif
+#ifdef ESRMNT
+ TEST_COMPARE_STRING (strerrordesc_np (ESRMNT), "Srmount error");
+ TEST_COMPARE_STRING (strerrorname_np (ESRMNT), "ESRMNT");
+#endif
+#ifdef ECOMM
+ TEST_COMPARE_STRING (strerrordesc_np (ECOMM),
+ "Communication error on send");
+ TEST_COMPARE_STRING (strerrorname_np (ECOMM), "ECOMM");
+#endif
+#ifdef EDOTDOT
+ TEST_COMPARE_STRING (strerrordesc_np (EDOTDOT), "RFS specific error");
+ TEST_COMPARE_STRING (strerrorname_np (EDOTDOT), "EDOTDOT");
+#endif
+#ifdef ENOTUNIQ
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTUNIQ),
+ "Name not unique on network");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTUNIQ), "ENOTUNIQ");
+#endif
+#ifdef EBADFD
+ TEST_COMPARE_STRING (strerrordesc_np (EBADFD),
+ "File descriptor in bad state");
+ TEST_COMPARE_STRING (strerrorname_np (EBADFD), "EBADFD");
+#endif
+#ifdef EREMCHG
+ TEST_COMPARE_STRING (strerrordesc_np (EREMCHG), "Remote address changed");
+ TEST_COMPARE_STRING (strerrorname_np (EREMCHG), "EREMCHG");
+#endif
+#ifdef ELIBACC
+ TEST_COMPARE_STRING (strerrordesc_np (ELIBACC),
+ "Can not access a needed shared library");
+ TEST_COMPARE_STRING (strerrorname_np (ELIBACC), "ELIBACC");
+#endif
+#ifdef ELIBBAD
+ TEST_COMPARE_STRING (strerrordesc_np (ELIBBAD),
+ "Accessing a corrupted shared library");
+ TEST_COMPARE_STRING (strerrorname_np (ELIBBAD), "ELIBBAD");
+#endif
+#ifdef ELIBSCN
+ TEST_COMPARE_STRING (strerrordesc_np (ELIBSCN),
+ ".lib section in a.out corrupted");
+ TEST_COMPARE_STRING (strerrorname_np (ELIBSCN), "ELIBSCN");
+#endif
+#ifdef ELIBMAX
+ TEST_COMPARE_STRING (strerrordesc_np (ELIBMAX),
+ "Attempting to link in too many shared libraries");
+ TEST_COMPARE_STRING (strerrorname_np (ELIBMAX), "ELIBMAX");
+#endif
+#ifdef ELIBEXEC
+ TEST_COMPARE_STRING (strerrordesc_np (ELIBEXEC),
+ "Cannot exec a shared library directly");
+ TEST_COMPARE_STRING (strerrorname_np (ELIBEXEC), "ELIBEXEC");
+#endif
+#ifdef ESTRPIPE
+ TEST_COMPARE_STRING (strerrordesc_np (ESTRPIPE), "Streams pipe error");
+ TEST_COMPARE_STRING (strerrorname_np (ESTRPIPE), "ESTRPIPE");
+#endif
+#ifdef EUCLEAN
+ TEST_COMPARE_STRING (strerrordesc_np (EUCLEAN),
+ "Structure needs cleaning");
+ TEST_COMPARE_STRING (strerrorname_np (EUCLEAN), "EUCLEAN");
+#endif
+#ifdef ENOTNAM
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTNAM),
+ "Not a XENIX named type file");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTNAM), "ENOTNAM");
+#endif
+#ifdef ENAVAIL
+ TEST_COMPARE_STRING (strerrordesc_np (ENAVAIL),
+ "No XENIX semaphores available");
+ TEST_COMPARE_STRING (strerrorname_np (ENAVAIL), "ENAVAIL");
+#endif
+#ifdef EISNAM
+ TEST_COMPARE_STRING (strerrordesc_np (EISNAM), "Is a named type file");
+ TEST_COMPARE_STRING (strerrorname_np (EISNAM), "EISNAM");
+#endif
+#ifdef EREMOTEIO
+ TEST_COMPARE_STRING (strerrordesc_np (EREMOTEIO), "Remote I/O error");
+ TEST_COMPARE_STRING (strerrorname_np (EREMOTEIO), "EREMOTEIO");
+#endif
+#ifdef ENOMEDIUM
+ TEST_COMPARE_STRING (strerrordesc_np (ENOMEDIUM), "No medium found");
+ TEST_COMPARE_STRING (strerrorname_np (ENOMEDIUM), "ENOMEDIUM");
+#endif
+#ifdef EMEDIUMTYPE
+ TEST_COMPARE_STRING (strerrordesc_np (EMEDIUMTYPE), "Wrong medium type");
+ TEST_COMPARE_STRING (strerrorname_np (EMEDIUMTYPE), "EMEDIUMTYPE");
+#endif
+#ifdef ENOKEY
+ TEST_COMPARE_STRING (strerrordesc_np (ENOKEY),
+ "Required key not available");
+ TEST_COMPARE_STRING (strerrorname_np (ENOKEY), "ENOKEY");
+#endif
+#ifdef EKEYEXPIRED
+ TEST_COMPARE_STRING (strerrordesc_np (EKEYEXPIRED), "Key has expired");
+ TEST_COMPARE_STRING (strerrorname_np (EKEYEXPIRED), "EKEYEXPIRED");
+#endif
+#ifdef EKEYREVOKED
+ TEST_COMPARE_STRING (strerrordesc_np (EKEYREVOKED),
+ "Key has been revoked");
+ TEST_COMPARE_STRING (strerrorname_np (EKEYREVOKED), "EKEYREVOKED");
+#endif
+#ifdef EKEYREJECTED
+ TEST_COMPARE_STRING (strerrordesc_np (EKEYREJECTED),
+ "Key was rejected by service");
+ TEST_COMPARE_STRING (strerrorname_np (EKEYREJECTED), "EKEYREJECTED");
+#endif
+#ifdef ERFKILL
+ TEST_COMPARE_STRING (strerrordesc_np (ERFKILL),
+ "Operation not possible due to RF-kill");
+ TEST_COMPARE_STRING (strerrorname_np (ERFKILL), "ERFKILL");
+#endif
+#ifdef EHWPOISON
+ TEST_COMPARE_STRING (strerrordesc_np (EHWPOISON),
+ "Memory page has hardware error");
+ TEST_COMPARE_STRING (strerrorname_np (EHWPOISON), "EHWPOISON");
+#endif
+#ifdef EBADRPC
+ TEST_COMPARE_STRING (strerrordesc_np (EBADRPC), "RPC struct is bad");
+ TEST_COMPARE_STRING (strerrorname_np (EBADRPC), "EBADRPC");
+#endif
+#ifdef EFTYPE
+ TEST_COMPARE_STRING (strerrordesc_np (EFTYPE),
+ "Inappropriate file type or format");
+ TEST_COMPARE_STRING (strerrorname_np (EFTYPE), "EFTYPE");
+#endif
+#ifdef EPROCUNAVAIL
+ TEST_COMPARE_STRING (strerrordesc_np (EPROCUNAVAIL),
+ "RPC bad procedure for program");
+ TEST_COMPARE_STRING (strerrorname_np (EPROCUNAVAIL), "EPROCUNAVAIL");
+#endif
+#ifdef EAUTH
+ TEST_COMPARE_STRING (strerrordesc_np (EAUTH), "Authentication error");
+ TEST_COMPARE_STRING (strerrorname_np (EAUTH), "EAUTH");
+#endif
+#ifdef EDIED
+ TEST_COMPARE_STRING (strerrordesc_np (EDIED), "Translator died");
+ TEST_COMPARE_STRING (strerrorname_np (EDIED), "EDIED");
+#endif
+#ifdef ERPCMISMATCH
+ TEST_COMPARE_STRING (strerrordesc_np (ERPCMISMATCH), "RPC version wrong");
+ TEST_COMPARE_STRING (strerrorname_np (ERPCMISMATCH), "ERPCMISMATCH");
+#endif
+#ifdef EGREGIOUS
+ TEST_COMPARE_STRING (strerrordesc_np (EGREGIOUS),
+ "You really blew it this time");
+ TEST_COMPARE_STRING (strerrorname_np (EGREGIOUS), "EGREGIOUS");
+#endif
+#ifdef EPROCLIM
+ TEST_COMPARE_STRING (strerrordesc_np (EPROCLIM), "Too many processes");
+ TEST_COMPARE_STRING (strerrorname_np (EPROCLIM), "EPROCLIM");
+#endif
+#ifdef EGRATUITOUS
+ TEST_COMPARE_STRING (strerrordesc_np (EGRATUITOUS), "Gratuitous error");
+ TEST_COMPARE_STRING (strerrorname_np (EGRATUITOUS), "EGRATUITOUS");
+#endif
+#if defined (ENOTSUP) && ENOTSUP != EOPNOTSUPP
+ TEST_COMPARE_STRING (strerrordesc_np (ENOTSUP), "Not supported");
+ TEST_COMPARE_STRING (strerrorname_np (ENOTSUP), "ENOTSUP");
+#endif
+#ifdef EPROGMISMATCH
+ TEST_COMPARE_STRING (strerrordesc_np (EPROGMISMATCH),
+ "RPC program version wrong");
+ TEST_COMPARE_STRING (strerrorname_np (EPROGMISMATCH), "EPROGMISMATCH");
+#endif
+#ifdef EBACKGROUND
+ TEST_COMPARE_STRING (strerrordesc_np (EBACKGROUND),
+ "Inappropriate operation for background process");
+ TEST_COMPARE_STRING (strerrorname_np (EBACKGROUND), "EBACKGROUND");
+#endif
+#ifdef EIEIO
+ TEST_COMPARE_STRING (strerrordesc_np (EIEIO), "Computer bought the farm");
+ TEST_COMPARE_STRING (strerrorname_np (EIEIO), "EIEIO");
+#endif
+#if defined (EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ TEST_COMPARE_STRING (strerrordesc_np (EWOULDBLOCK),
+ "Operation would block");
+ TEST_COMPARE_STRING (strerrorname_np (EWOULDBLOCK), "EWOULDBLOCK");
+#endif
+#ifdef ENEEDAUTH
+ TEST_COMPARE_STRING (strerrordesc_np (ENEEDAUTH), "Need authenticator");
+ TEST_COMPARE_STRING (strerrorname_np (ENEEDAUTH), "ENEEDAUTH");
+#endif
+#ifdef ED
+ TEST_COMPARE_STRING (strerrordesc_np (ED), "?");
+ TEST_COMPARE_STRING (strerrorname_np (ED), "ED");
+#endif
+#ifdef EPROGUNAVAIL
+ TEST_COMPARE_STRING (strerrordesc_np (EPROGUNAVAIL),
+ "RPC program not available");
+ TEST_COMPARE_STRING (strerrorname_np (EPROGUNAVAIL), "EPROGUNAVAIL");
+#endif
2021-03-22 16:38:00 +01:00
return 0;
}
diff -pruN glibc-2.32.orig/stdio-common/vfscanf-internal.c glibc-2.32/stdio-common/vfscanf-internal.c
--- glibc-2.32.orig/stdio-common/vfscanf-internal.c 2021-09-18 21:02:32.699184579 +1000
+++ glibc-2.32/stdio-common/vfscanf-internal.c 2021-09-18 21:03:05.312302287 +1000
@@ -277,7 +277,7 @@ __vfscanf_internal (FILE *s, const char
2021-03-22 16:38:00 +01:00
#endif
{
va_list arg;
- const CHAR_T *f = format;
+ const UCHAR_T *f = (const UCHAR_T *) format;
UCHAR_T fc; /* Current character of the format. */
WINT_T done = 0; /* Assignments done. */
size_t read_in = 0; /* Chars read in. */
@@ -415,10 +415,11 @@ __vfscanf_internal (FILE *s, const char
2021-03-22 16:38:00 +01:00
#endif
#ifndef COMPILE_WSCANF
- if (!isascii ((unsigned char) *f))
+ if (!isascii (*f))
{
/* Non-ASCII, may be a multibyte. */
- int len = __mbrlen (f, strlen (f), &state);
+ int len = __mbrlen ((const char *) f, strlen ((const char *) f),
+ &state);
if (len > 0)
{
do
@@ -426,7 +427,7 @@ __vfscanf_internal (FILE *s, const char
2021-03-22 16:38:00 +01:00
c = inchar ();
if (__glibc_unlikely (c == EOF))
input_error ();
- else if (c != (unsigned char) *f++)
+ else if (c != *f++)
{
ungetc_not_eof (c, s);
conv_error ();
@@ -484,9 +485,9 @@ __vfscanf_internal (FILE *s, const char
2021-03-22 16:38:00 +01:00
char_buffer_rewind (&charbuf);
/* Check for a positional parameter specification. */
- if (ISDIGIT ((UCHAR_T) *f))
+ if (ISDIGIT (*f))
{
- argpos = read_int ((const UCHAR_T **) &f);
+ argpos = read_int (&f);
if (*f == L_('$'))
++f;
else
@@ -521,8 +522,8 @@ __vfscanf_internal (FILE *s, const char
2021-03-22 16:38:00 +01:00
/* Find the maximum field width. */
width = 0;
- if (ISDIGIT ((UCHAR_T) *f))
- width = read_int ((const UCHAR_T **) &f);
+ if (ISDIGIT (*f))
+ width = read_int (&f);
got_width:
if (width == 0)
width = -1;
@@ -2522,12 +2523,11 @@ __vfscanf_internal (FILE *s, const char
2021-03-22 16:38:00 +01:00
}
while ((fc = *f++) != '\0' && fc != ']')
- if (fc == '-' && *f != '\0' && *f != ']'
- && (unsigned char) f[-2] <= (unsigned char) *f)
+ if (fc == '-' && *f != '\0' && *f != ']' && f[-2] <= *f)
{
/* Add all characters from the one before the '-'
up to (but not including) the next format char. */
- for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
+ for (fc = f[-2]; fc < *f; ++fc)
((char *)charbuf.scratch.data)[fc] = 1;
}
else
diff -pruN glibc-2.32.orig/stdlib/tst-secure-getenv.c glibc-2.32/stdlib/tst-secure-getenv.c
--- glibc-2.32.orig/stdlib/tst-secure-getenv.c 2021-09-18 21:02:32.700184614 +1000
+++ glibc-2.32/stdlib/tst-secure-getenv.c 2021-09-18 21:03:05.312302287 +1000
2021-08-06 12:41:15 +02:00
@@ -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 -pruN glibc-2.32.orig/string/bits/string_fortified.h glibc-2.32/string/bits/string_fortified.h
--- glibc-2.32.orig/string/bits/string_fortified.h 2021-09-18 21:02:32.700184614 +1000
+++ glibc-2.32/string/bits/string_fortified.h 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -22,11 +22,6 @@
# error "Never use <bits/string_fortified.h> directly; include <string.h> instead."
#endif
-#if !__GNUC_PREREQ (5,0)
-__warndecl (__warn_memset_zero_len,
- "memset used with constant zero length parameter; this could be due to transposed parameters");
-#endif
-
__fortify_function void *
__NTH (memcpy (void *__restrict __dest, const void *__restrict __src,
size_t __len))
@@ -58,16 +53,6 @@ __NTH (mempcpy (void *__restrict __dest,
2021-03-22 16:38:00 +01:00
__fortify_function void *
__NTH (memset (void *__dest, int __ch, size_t __len))
{
- /* GCC-5.0 and newer implements these checks in the compiler, so we don't
- need them here. */
-#if !__GNUC_PREREQ (5,0)
- if (__builtin_constant_p (__len) && __len == 0
- && (!__builtin_constant_p (__ch) || __ch != 0))
- {
- __warn_memset_zero_len ();
- return __dest;
- }
-#endif
return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
}
diff -pruN glibc-2.32.orig/support/capture_subprocess.h glibc-2.32/support/capture_subprocess.h
--- glibc-2.32.orig/support/capture_subprocess.h 2021-09-18 21:02:32.701184648 +1000
+++ glibc-2.32/support/capture_subprocess.h 2021-09-18 21:03:05.312302287 +1000
@@ -41,6 +41,12 @@ struct support_capture_subprocess suppor
2021-08-06 12:41:15 +02:00
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 -pruN glibc-2.32.orig/support/Makefile glibc-2.32/support/Makefile
--- glibc-2.32.orig/support/Makefile 2021-09-18 21:02:32.701184648 +1000
+++ glibc-2.32/support/Makefile 2021-09-18 21:03:05.312302287 +1000
@@ -35,6 +35,8 @@ libsupport-routines = \
ignore_stderr \
next_to_fault \
oom_error \
+ resolv_response_context_duplicate \
+ resolv_response_context_free \
resolv_test \
set_fortify_handler \
support-xfstat \
diff -pruN glibc-2.32.orig/support/resolv_response_context_duplicate.c glibc-2.32/support/resolv_response_context_duplicate.c
--- glibc-2.32.orig/support/resolv_response_context_duplicate.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/support/resolv_response_context_duplicate.c 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1,37 @@
+/* Duplicate a response context used in DNS resolver tests.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+
+struct resolv_response_context *
+resolv_response_context_duplicate (const struct resolv_response_context *ctx)
+{
+ struct resolv_response_context *result = xmalloc (sizeof (*result));
+ memcpy (result, ctx, sizeof (*result));
+ if (result->client_address != NULL)
+ {
+ result->client_address = xmalloc (result->client_address_length);
+ memcpy (result->client_address, ctx->client_address,
+ result->client_address_length);
+ }
+ result->query_buffer = xmalloc (result->query_length);
+ memcpy (result->query_buffer, ctx->query_buffer, result->query_length);
+ return result;
+}
diff -pruN glibc-2.32.orig/support/resolv_response_context_free.c glibc-2.32/support/resolv_response_context_free.c
--- glibc-2.32.orig/support/resolv_response_context_free.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/support/resolv_response_context_free.c 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1,28 @@
+/* Free a response context used in DNS resolver tests.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <support/resolv_test.h>
+
+void
+resolv_response_context_free (struct resolv_response_context *ctx)
+{
+ free (ctx->query_buffer);
+ free (ctx->client_address);
+ free (ctx);
+}
diff -pruN glibc-2.32.orig/support/resolv_test.c glibc-2.32/support/resolv_test.c
--- glibc-2.32.orig/support/resolv_test.c 2021-09-18 21:02:32.701184648 +1000
+++ glibc-2.32/support/resolv_test.c 2021-09-18 21:03:05.312302287 +1000
@@ -181,7 +181,9 @@ resolv_response_init (struct resolv_resp
2021-03-22 16:38:00 +01:00
b->buffer[2] |= b->query_buffer[2] & 0x01; /* Copy the RD bit. */
if (flags.tc)
b->buffer[2] |= 0x02;
- b->buffer[3] = 0x80 | flags.rcode; /* Always set RA. */
+ b->buffer[3] = flags.rcode;
+ if (!flags.clear_ra)
+ b->buffer[3] |= 0x80;
if (flags.ad)
b->buffer[3] |= 0x20;
@@ -434,9 +436,9 @@ resolv_response_buffer (const struct res
2021-03-22 16:38:00 +01:00
return result;
}
-static struct resolv_response_builder *
-response_builder_allocate
- (const unsigned char *query_buffer, size_t query_length)
+struct resolv_response_builder *
+resolv_response_builder_allocate (const unsigned char *query_buffer,
+ size_t query_length)
{
struct resolv_response_builder *b = xmalloc (sizeof (*b));
memset (b, 0, offsetof (struct resolv_response_builder, buffer));
@@ -445,8 +447,8 @@ response_builder_allocate
return b;
}
-static void
-response_builder_free (struct resolv_response_builder *b)
+void
+resolv_response_builder_free (struct resolv_response_builder *b)
{
tdestroy (b->compression_offsets, free);
free (b);
@@ -661,13 +663,17 @@ server_thread_udp_process_one (struct re
2021-03-22 16:38:00 +01:00
struct resolv_response_context ctx =
{
+ .test = obj,
+ .client_address = &peer,
+ .client_address_length = peerlen,
.query_buffer = query,
.query_length = length,
.server_index = server_index,
.tcp = false,
.edns = qinfo.edns,
};
- struct resolv_response_builder *b = response_builder_allocate (query, length);
+ struct resolv_response_builder *b
+ = resolv_response_builder_allocate (query, length);
obj->config.response_callback
(&ctx, b, qinfo.qname, qinfo.qclass, qinfo.qtype);
@@ -684,7 +690,7 @@ server_thread_udp_process_one (struct re
2021-03-22 16:38:00 +01:00
if (b->offset >= 12)
printf ("info: UDP server %d: sending response:"
" %zu bytes, RCODE %d (for %s/%u/%u)\n",
- server_index, b->offset, b->buffer[3] & 0x0f,
+ ctx.server_index, b->offset, b->buffer[3] & 0x0f,
qinfo.qname, qinfo.qclass, qinfo.qtype);
else
printf ("info: UDP server %d: sending response: %zu bytes"
@@ -694,23 +700,31 @@ server_thread_udp_process_one (struct re
2021-03-22 16:38:00 +01:00
if (b->truncate_bytes > 0)
printf ("info: truncated by %u bytes\n", b->truncate_bytes);
}
- size_t to_send = b->offset;
- if (to_send < b->truncate_bytes)
- to_send = 0;
- else
- to_send -= b->truncate_bytes;
-
- /* Ignore most errors here because the other end may have closed
- the socket. */
- if (sendto (obj->servers[server_index].socket_udp,
- b->buffer, to_send, 0,
- (struct sockaddr *) &peer, peerlen) < 0)
- TEST_VERIFY_EXIT (errno != EBADF);
+ resolv_response_send_udp (&ctx, b);
}
- response_builder_free (b);
+ resolv_response_builder_free (b);
return true;
}
+void
+resolv_response_send_udp (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b)
+{
+ TEST_VERIFY_EXIT (!ctx->tcp);
+ size_t to_send = b->offset;
+ if (to_send < b->truncate_bytes)
+ to_send = 0;
+ else
+ to_send -= b->truncate_bytes;
+
+ /* Ignore most errors here because the other end may have closed
+ the socket. */
+ if (sendto (ctx->test->servers[ctx->server_index].socket_udp,
+ b->buffer, to_send, 0,
+ ctx->client_address, ctx->client_address_length) < 0)
+ TEST_VERIFY_EXIT (errno != EBADF);
+}
+
/* UDP thread_callback function. Variant for one thread per
server. */
static void
@@ -897,14 +911,15 @@ server_thread_tcp_client (void *arg)
struct resolv_response_context ctx =
{
+ .test = closure->obj,
.query_buffer = query_buffer,
.query_length = query_length,
.server_index = closure->server_index,
.tcp = true,
.edns = qinfo.edns,
};
- struct resolv_response_builder *b = response_builder_allocate
- (query_buffer, query_length);
+ struct resolv_response_builder *b
+ = resolv_response_builder_allocate (query_buffer, query_length);
closure->obj->config.response_callback
(&ctx, b, qinfo.qname, qinfo.qclass, qinfo.qtype);
@@ -936,7 +951,7 @@ server_thread_tcp_client (void *arg)
writev_fully (closure->client_socket, buffers, 2);
}
bool close_flag = b->close;
- response_builder_free (b);
+ resolv_response_builder_free (b);
free (query_buffer);
if (close_flag)
break;
diff -pruN glibc-2.32.orig/support/resolv_test.h glibc-2.32/support/resolv_test.h
--- glibc-2.32.orig/support/resolv_test.h 2021-09-18 21:02:32.701184648 +1000
+++ glibc-2.32/support/resolv_test.h 2021-09-18 21:03:05.312302287 +1000
2021-03-22 16:38:00 +01:00
@@ -35,25 +35,36 @@ struct resolv_edns_info
uint16_t payload_size;
};
+/* This opaque struct collects information about the resolver testing
+ currently in progress. */
+struct resolv_test;
+
/* This struct provides context information when the response callback
specified in struct resolv_redirect_config is invoked. */
struct resolv_response_context
{
- const unsigned char *query_buffer;
+ struct resolv_test *test;
+ void *client_address;
+ size_t client_address_length;
+ unsigned char *query_buffer;
size_t query_length;
int server_index;
bool tcp;
struct resolv_edns_info edns;
};
+/* Produces a deep copy of the context. */
+struct resolv_response_context *
+ resolv_response_context_duplicate (const struct resolv_response_context *);
+
+/* Frees the copy. For the context passed to the response function,
+ this happens implicitly. */
+void resolv_response_context_free (struct resolv_response_context *);
+
/* This opaque struct is used to construct responses from within the
response callback function. */
struct resolv_response_builder;
-/* This opaque struct collects information about the resolver testing
- currently in progress. */
-struct resolv_test;
-
enum
{
/* Maximum number of test servers supported by the framework. */
@@ -137,6 +148,10 @@ struct resolv_response_flags
/* If true, the AD (authenticated data) flag will be set. */
bool ad;
+ /* If true, do not set the RA (recursion available) flag in the
+ response. */
+ bool clear_ra;
+
/* Initial section count values. Can be used to artificially
increase the counts, for malformed packet testing.*/
unsigned short qdcount;
@@ -188,6 +203,22 @@ void resolv_response_close (struct resol
2021-03-22 16:38:00 +01:00
/* The size of the response packet built so far. */
size_t resolv_response_length (const struct resolv_response_builder *);
+/* Allocates a response builder tied to a specific query packet,
+ starting at QUERY_BUFFER, containing QUERY_LENGTH bytes. */
+struct resolv_response_builder *
+ resolv_response_builder_allocate (const unsigned char *query_buffer,
+ size_t query_length);
+
+/* Deallocates a response buffer. */
+void resolv_response_builder_free (struct resolv_response_builder *);
+
+/* Sends a UDP response using a specific context. This can be used to
+ reorder or duplicate responses, along with
+ resolv_response_context_duplicate and
+ response_builder_allocate. */
+void resolv_response_send_udp (const struct resolv_response_context *,
+ struct resolv_response_builder *);
+
__END_DECLS
#endif /* SUPPORT_RESOLV_TEST_H */
diff -pruN glibc-2.32.orig/support/subprocess.h glibc-2.32/support/subprocess.h
--- glibc-2.32.orig/support/subprocess.h 2021-09-18 21:02:32.701184648 +1000
+++ glibc-2.32/support/subprocess.h 2021-09-18 21:03:05.312302287 +1000
@@ -38,6 +38,11 @@ struct support_subprocess support_subpro
2021-08-06 12:41:15 +02:00
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 -pruN glibc-2.32.orig/support/support_capture_subprocess.c glibc-2.32/support/support_capture_subprocess.c
--- glibc-2.32.orig/support/support_capture_subprocess.c 2021-09-18 21:02:32.701184648 +1000
+++ glibc-2.32/support/support_capture_subprocess.c 2021-09-18 21:03:05.313302322 +1000
2021-08-06 12:41:15 +02:00
@@ -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 pollf
2021-08-06 12:41:15 +02:00
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 *
2021-08-06 12:41:15 +02:00
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 -pruN glibc-2.32.orig/support/support_subprocess.c glibc-2.32/support/support_subprocess.c
--- glibc-2.32.orig/support/support_subprocess.c 2021-09-18 21:02:32.701184648 +1000
+++ glibc-2.32/support/support_subprocess.c 2021-09-18 21:03:05.313302322 +1000
2021-08-06 12:41:15 +02:00
@@ -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) (vo
2021-08-06 12:41:15 +02:00
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, ch
2021-08-06 12:41:15 +02:00
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]);
@@ -93,6 +93,19 @@ support_subprogram (const char *file, ch
2021-08-06 12:41:15 +02:00
}
int
2021-08-06 12:41:15 +02:00
+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
2021-08-06 12:41:15 +02:00
support_process_wait (struct support_subprocess *proc)
{
xclose (proc->stdout_pipe[0]);
diff -pruN glibc-2.32.orig/sysdeps/aarch64/dl-bti.c glibc-2.32/sysdeps/aarch64/dl-bti.c
--- glibc-2.32.orig/sysdeps/aarch64/dl-bti.c 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/dl-bti.c 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -19,43 +19,76 @@
#include <errno.h>
#include <libintl.h>
#include <ldsodefs.h>
+#include <sys/mman.h>
-static int
-enable_bti (struct link_map *map, const char *program)
+/* See elf/dl-load.h. */
+#ifndef MAP_COPY
+# define MAP_COPY (MAP_PRIVATE | MAP_DENYWRITE)
+#endif
+
+/* Enable BTI protection for MAP. */
+
+void
+_dl_bti_protect (struct link_map *map, int fd)
{
+ const size_t pagesz = GLRO(dl_pagesize);
const ElfW(Phdr) *phdr;
- unsigned prot;
for (phdr = map->l_phdr; phdr < &map->l_phdr[map->l_phnum]; ++phdr)
if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
{
- void *start = (void *) (phdr->p_vaddr + map->l_addr);
- size_t len = phdr->p_memsz;
+ size_t vstart = ALIGN_DOWN (phdr->p_vaddr, pagesz);
+ size_t vend = ALIGN_UP (phdr->p_vaddr + phdr->p_filesz, pagesz);
+ off_t off = ALIGN_DOWN (phdr->p_offset, pagesz);
+ void *start = (void *) (vstart + map->l_addr);
+ size_t len = vend - vstart;
- prot = PROT_EXEC | PROT_BTI;
+ unsigned prot = PROT_EXEC | PROT_BTI;
if (phdr->p_flags & PF_R)
prot |= PROT_READ;
if (phdr->p_flags & PF_W)
prot |= PROT_WRITE;
- if (__mprotect (start, len, prot) < 0)
- {
- if (program)
- _dl_fatal_printf ("%s: mprotect failed to turn on BTI\n",
- map->l_name);
- else
- _dl_signal_error (errno, map->l_name, "dlopen",
- N_("mprotect failed to turn on BTI"));
- }
+ if (fd == -1)
+ /* Ignore failures for kernel mapped binaries. */
+ __mprotect (start, len, prot);
+ else
+ map->l_mach.bti_fail = __mmap (start, len, prot,
+ MAP_FIXED|MAP_COPY|MAP_FILE,
+ fd, off) == MAP_FAILED;
}
- return 0;
}
-/* Enable BTI for L if required. */
+
+static void
+bti_failed (struct link_map *l, const char *program)
+{
+ if (program)
+ _dl_fatal_printf ("%s: %s: failed to turn on BTI protection\n",
+ program, l->l_name);
+ else
+ /* Note: the errno value is not available any more. */
+ _dl_signal_error (0, l->l_name, "dlopen",
+ N_("failed to turn on BTI protection"));
+}
+
+
+/* Enable BTI for L and its dependencies. */
void
_dl_bti_check (struct link_map *l, const char *program)
{
- if (GLRO(dl_aarch64_cpu_features).bti && l->l_mach.bti)
- enable_bti (l, program);
+ if (!GLRO(dl_aarch64_cpu_features).bti)
+ return;
+
+ if (l->l_mach.bti_fail)
+ bti_failed (l, program);
+
+ unsigned int i = l->l_searchlist.r_nlist;
+ while (i-- > 0)
+ {
+ struct link_map *dep = l->l_initfini[i];
+ if (dep->l_mach.bti_fail)
+ bti_failed (dep, program);
+ }
}
diff -pruN glibc-2.32.orig/sysdeps/aarch64/dl-machine.h glibc-2.32/sysdeps/aarch64/dl-machine.h
--- glibc-2.32.orig/sysdeps/aarch64/dl-machine.h 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/dl-machine.h 2021-09-18 21:03:05.313302322 +1000
@@ -395,13 +395,6 @@ elf_machine_lazy_rel (struct link_map *m
2021-03-22 16:38:00 +01:00
/* Check for unexpected PLT reloc type. */
if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1))
{
- if (map->l_mach.plt == 0)
- {
- /* Prelinking. */
- *reloc_addr += l_addr;
- return;
- }
-
if (__glibc_unlikely (map->l_info[DT_AARCH64 (VARIANT_PCS)] != NULL))
{
/* Check the symbol table for variant PCS symbols. */
@@ -425,7 +418,10 @@ elf_machine_lazy_rel (struct link_map *m
2021-03-22 16:38:00 +01:00
}
}
- *reloc_addr = map->l_mach.plt;
+ if (map->l_mach.plt == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr = map->l_mach.plt;
}
else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1))
{
diff -pruN glibc-2.32.orig/sysdeps/aarch64/dl-prop.h glibc-2.32/sysdeps/aarch64/dl-prop.h
--- glibc-2.32.orig/sysdeps/aarch64/dl-prop.h 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/dl-prop.h 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -19,6 +19,8 @@
#ifndef _DL_PROP_H
#define _DL_PROP_H
+extern void _dl_bti_protect (struct link_map *, int) attribute_hidden;
+
extern void _dl_bti_check (struct link_map *, const char *)
attribute_hidden;
@@ -35,14 +37,18 @@ _dl_open_check (struct link_map *m)
}
static inline void __attribute__ ((always_inline))
-_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
+_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
{
}
2021-03-22 16:38:00 +01:00
static inline int
-_dl_process_gnu_property (struct link_map *l, uint32_t type, uint32_t datasz,
- void *data)
+_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
+ uint32_t datasz, void *data)
{
+ if (!GLRO(dl_aarch64_cpu_features).bti)
+ /* Skip note processing. */
+ return 0;
+
if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
{
/* Stop if the property note is ill-formed. */
@@ -51,7 +57,7 @@ _dl_process_gnu_property (struct link_ma
2021-03-22 16:38:00 +01:00
unsigned int feature_1 = *(unsigned int *) data;
if (feature_1 & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
- l->l_mach.bti = true;
+ _dl_bti_protect (l, fd);
/* Stop if we processed the property note. */
return 0;
diff -pruN glibc-2.32.orig/sysdeps/aarch64/linkmap.h glibc-2.32/sysdeps/aarch64/linkmap.h
--- glibc-2.32.orig/sysdeps/aarch64/linkmap.h 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/linkmap.h 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -22,5 +22,5 @@ struct link_map_machine
{
ElfW(Addr) plt; /* Address of .plt */
void *tlsdesc_table; /* Address of TLS descriptor hash table. */
- bool bti; /* Branch Target Identification is enabled. */
+ bool bti_fail; /* Failed to enable Branch Target Identification. */
};
diff -pruN glibc-2.32.orig/sysdeps/aarch64/multiarch/memcpy_advsimd.S glibc-2.32/sysdeps/aarch64/multiarch/memcpy_advsimd.S
--- glibc-2.32.orig/sysdeps/aarch64/multiarch/memcpy_advsimd.S 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/multiarch/memcpy_advsimd.S 2021-09-18 21:03:05.313302322 +1000
@@ -223,12 +223,13 @@ L(copy_long_backwards):
b.ls L(copy64_from_start)
L(loop64_backwards):
- stp A_q, B_q, [dstend, -32]
+ str B_q, [dstend, -16]
+ str A_q, [dstend, -32]
ldp A_q, B_q, [srcend, -96]
- stp C_q, D_q, [dstend, -64]
+ str D_q, [dstend, -48]
+ str C_q, [dstend, -64]!
ldp C_q, D_q, [srcend, -128]
sub srcend, srcend, 64
- sub dstend, dstend, 64
subs count, count, 64
b.hi L(loop64_backwards)
diff -pruN glibc-2.32.orig/sysdeps/aarch64/multiarch/memcpy.c glibc-2.32/sysdeps/aarch64/multiarch/memcpy.c
--- glibc-2.32.orig/sysdeps/aarch64/multiarch/memcpy.c 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/multiarch/memcpy.c 2021-09-18 21:03:05.313302322 +1000
@@ -41,7 +41,8 @@ libc_ifunc (__libc_memcpy,
? __memcpy_falkor
: (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr)
? __memcpy_thunderx2
- : (IS_NEOVERSE_N1 (midr)
+ : (IS_NEOVERSE_N1 (midr) || IS_NEOVERSE_N2 (midr)
+ || IS_NEOVERSE_V1 (midr)
? __memcpy_simd
: __memcpy_generic)))));
diff -pruN glibc-2.32.orig/sysdeps/aarch64/multiarch/memmove.c glibc-2.32/sysdeps/aarch64/multiarch/memmove.c
--- glibc-2.32.orig/sysdeps/aarch64/multiarch/memmove.c 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/multiarch/memmove.c 2021-09-18 21:03:05.313302322 +1000
@@ -41,7 +41,8 @@ libc_ifunc (__libc_memmove,
? __memmove_falkor
: (IS_THUNDERX2 (midr) || IS_THUNDERX2PA (midr)
? __memmove_thunderx2
- : (IS_NEOVERSE_N1 (midr)
+ : (IS_NEOVERSE_N1 (midr) || IS_NEOVERSE_N2 (midr)
+ || IS_NEOVERSE_V1 (midr)
? __memmove_simd
: __memmove_generic)))));
diff -pruN glibc-2.32.orig/sysdeps/aarch64/start.S glibc-2.32/sysdeps/aarch64/start.S
--- glibc-2.32.orig/sysdeps/aarch64/start.S 2021-09-18 21:02:32.702184682 +1000
+++ glibc-2.32/sysdeps/aarch64/start.S 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -43,11 +43,9 @@
*/
.text
- .globl _start
- .type _start,#function
-_start:
- BTI_C
+ENTRY(_start)
/* Create an initial frame with 0 LR and FP */
+ cfi_undefined (x30)
mov x29, #0
mov x30, #0
@@ -101,8 +99,10 @@ _start:
because crt1.o and rcrt1.o share code and the later must avoid the
use of GOT relocations before __libc_start_main is called. */
__wrap_main:
+ BTI_C
b main
#endif
+END(_start)
/* Define a symbol for the first piece of initialized data. */
.data
diff -pruN glibc-2.32.orig/sysdeps/generic/dl-prop.h glibc-2.32/sysdeps/generic/dl-prop.h
--- glibc-2.32.orig/sysdeps/generic/dl-prop.h 2021-09-18 21:02:32.705184785 +1000
+++ glibc-2.32/sysdeps/generic/dl-prop.h 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -37,15 +37,15 @@ _dl_open_check (struct link_map *m)
}
static inline void __attribute__ ((always_inline))
-_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
+_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
{
}
/* Called for each property in the NT_GNU_PROPERTY_TYPE_0 note of L,
processing of the properties continues until this returns 0. */
static inline int __attribute__ ((always_inline))
-_dl_process_gnu_property (struct link_map *l, uint32_t type, uint32_t datasz,
- void *data)
+_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
+ uint32_t datasz, void *data)
{
return 0;
}
diff -pruN glibc-2.32.orig/sysdeps/generic/ldsodefs.h glibc-2.32/sysdeps/generic/ldsodefs.h
--- glibc-2.32.orig/sysdeps/generic/ldsodefs.h 2021-09-18 21:02:32.705184785 +1000
+++ glibc-2.32/sysdeps/generic/ldsodefs.h 2021-09-18 21:03:05.313302322 +1000
@@ -919,8 +919,9 @@ extern void _dl_rtld_di_serinfo (struct
2021-03-22 16:38:00 +01:00
Dl_serinfo *si, bool counting);
/* Process PT_GNU_PROPERTY program header PH in module L after
- PT_LOAD segments are mapped. */
-void _dl_process_pt_gnu_property (struct link_map *l, const ElfW(Phdr) *ph);
+ PT_LOAD segments are mapped from file FD. */
+void _dl_process_pt_gnu_property (struct link_map *l, int fd,
+ const ElfW(Phdr) *ph);
/* Search loaded objects' symbol tables for a definition of the symbol
diff -pruN glibc-2.32.orig/sysdeps/generic/unwind.h glibc-2.32/sysdeps/generic/unwind.h
--- glibc-2.32.orig/sysdeps/generic/unwind.h 2021-09-18 21:02:32.706184819 +1000
+++ glibc-2.32/sysdeps/generic/unwind.h 2021-09-18 21:03:05.313302322 +1000
@@ -75,15 +75,21 @@ typedef void (*_Unwind_Exception_Cleanup
2021-03-22 16:38:00 +01:00
struct _Unwind_Exception
{
- _Unwind_Exception_Class exception_class;
- _Unwind_Exception_Cleanup_Fn exception_cleanup;
- _Unwind_Word private_1;
- _Unwind_Word private_2;
+ union
+ {
+ struct
+ {
+ _Unwind_Exception_Class exception_class;
+ _Unwind_Exception_Cleanup_Fn exception_cleanup;
+ _Unwind_Word private_1;
+ _Unwind_Word private_2;
+ };
- /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
- Taking that literally does not make much sense generically. Instead we
- provide the maximum alignment required by any type for the machine. */
-} __attribute__((__aligned__));
2021-03-22 16:38:00 +01:00
+ /* The IA-64 ABI says that this structure must be double-word aligned. */
+ _Unwind_Word unwind_exception_align[2]
+ __attribute__ ((__aligned__ (2 * sizeof (_Unwind_Word))));
+ };
+};
/* The ACTIONS argument to the personality routine is a bitwise OR of one
diff -pruN glibc-2.32.orig/sysdeps/gnu/errlist.h glibc-2.32/sysdeps/gnu/errlist.h
--- glibc-2.32.orig/sysdeps/gnu/errlist.h 2021-09-18 21:02:32.706184819 +1000
+++ glibc-2.32/sysdeps/gnu/errlist.h 2021-09-18 21:03:05.313302322 +1000
@@ -1,24 +1,21 @@
-#ifndef ERR_MAP
-#define ERR_MAP(value) value
-#endif
-_S(ERR_MAP(0), N_("Success"))
+_S(0, N_("Success"))
#ifdef EPERM
/*
TRANS Only the owner of the file (or other resource)
TRANS or processes with special privileges can perform the operation. */
-_S(ERR_MAP(EPERM), N_("Operation not permitted"))
+_S(EPERM, N_("Operation not permitted"))
#endif
#ifdef ENOENT
/*
TRANS This is a ``file doesn't exist'' error
TRANS for ordinary files that are referenced in contexts where they are
TRANS expected to already exist. */
-_S(ERR_MAP(ENOENT), N_("No such file or directory"))
+_S(ENOENT, N_("No such file or directory"))
#endif
#ifdef ESRCH
/*
TRANS No process matches the specified process ID. */
-_S(ERR_MAP(ESRCH), N_("No such process"))
+_S(ESRCH, N_("No such process"))
#endif
#ifdef EINTR
/*
@@ -29,12 +26,12 @@ TRANS
TRANS You can choose to have functions resume after a signal that is handled,
TRANS rather than failing with @code{EINTR}; see @ref{Interrupted
TRANS Primitives}. */
-_S(ERR_MAP(EINTR), N_("Interrupted system call"))
+_S(EINTR, N_("Interrupted system call"))
#endif
#ifdef EIO
/*
TRANS Usually used for physical read or write errors. */
-_S(ERR_MAP(EIO), N_("Input/output error"))
+_S(EIO, N_("Input/output error"))
#endif
#ifdef ENXIO
/*
@@ -43,7 +40,7 @@ TRANS represented by a file you specifie
TRANS This can mean that the device file was installed incorrectly, or that
TRANS the physical device is missing or not correctly attached to the
TRANS computer. */
-_S(ERR_MAP(ENXIO), N_("No such device or address"))
+_S(ENXIO, N_("No such device or address"))
#endif
#ifdef E2BIG
/*
@@ -51,27 +48,27 @@ TRANS Used when the arguments passed to
TRANS being executed with one of the @code{exec} functions (@pxref{Executing a
TRANS File}) occupy too much memory space. This condition never arises on
TRANS @gnuhurdsystems{}. */
-_S(ERR_MAP(E2BIG), N_("Argument list too long"))
+_S(E2BIG, N_("Argument list too long"))
#endif
#ifdef ENOEXEC
/*
TRANS Invalid executable file format. This condition is detected by the
TRANS @code{exec} functions; see @ref{Executing a File}. */
-_S(ERR_MAP(ENOEXEC), N_("Exec format error"))
+_S(ENOEXEC, N_("Exec format error"))
#endif
#ifdef EBADF
/*
TRANS For example, I/O on a descriptor that has been
TRANS closed or reading from a descriptor open only for writing (or vice
TRANS versa). */
-_S(ERR_MAP(EBADF), N_("Bad file descriptor"))
+_S(EBADF, N_("Bad file descriptor"))
#endif
#ifdef ECHILD
/*
TRANS This error happens on operations that are
TRANS supposed to manipulate child processes, when there aren't any processes
TRANS to manipulate. */
-_S(ERR_MAP(ECHILD), N_("No child processes"))
+_S(ECHILD, N_("No child processes"))
#endif
#ifdef EDEADLK
/*
@@ -79,74 +76,74 @@ TRANS Allocating a system resource would
TRANS deadlock situation. The system does not guarantee that it will notice
TRANS all such situations. This error means you got lucky and the system
TRANS noticed; it might just hang. @xref{File Locks}, for an example. */
-_S(ERR_MAP(EDEADLK), N_("Resource deadlock avoided"))
+_S(EDEADLK, N_("Resource deadlock avoided"))
#endif
#ifdef ENOMEM
/*
TRANS The system cannot allocate more virtual memory
TRANS because its capacity is full. */
-_S(ERR_MAP(ENOMEM), N_("Cannot allocate memory"))
+_S(ENOMEM, N_("Cannot allocate memory"))
#endif
#ifdef EACCES
/*
TRANS The file permissions do not allow the attempted operation. */
-_S(ERR_MAP(EACCES), N_("Permission denied"))
+_S(EACCES, N_("Permission denied"))
#endif
#ifdef EFAULT
/*
TRANS An invalid pointer was detected.
TRANS On @gnuhurdsystems{}, this error never happens; you get a signal instead. */
-_S(ERR_MAP(EFAULT), N_("Bad address"))
+_S(EFAULT, N_("Bad address"))
#endif
#ifdef ENOTBLK
/*
TRANS A file that isn't a block special file was given in a situation that
TRANS requires one. For example, trying to mount an ordinary file as a file
TRANS system in Unix gives this error. */
-_S(ERR_MAP(ENOTBLK), N_("Block device required"))
+_S(ENOTBLK, N_("Block device required"))
#endif
#ifdef EBUSY
/*
TRANS A system resource that can't be shared is already in use.
TRANS For example, if you try to delete a file that is the root of a currently
TRANS mounted filesystem, you get this error. */
-_S(ERR_MAP(EBUSY), N_("Device or resource busy"))
+_S(EBUSY, N_("Device or resource busy"))
#endif
#ifdef EEXIST
/*
TRANS An existing file was specified in a context where it only
TRANS makes sense to specify a new file. */
-_S(ERR_MAP(EEXIST), N_("File exists"))
+_S(EEXIST, N_("File exists"))
#endif
#ifdef EXDEV
/*
TRANS An attempt to make an improper link across file systems was detected.
TRANS This happens not only when you use @code{link} (@pxref{Hard Links}) but
TRANS also when you rename a file with @code{rename} (@pxref{Renaming Files}). */
-_S(ERR_MAP(EXDEV), N_("Invalid cross-device link"))
+_S(EXDEV, N_("Invalid cross-device link"))
#endif
#ifdef ENODEV
/*
TRANS The wrong type of device was given to a function that expects a
TRANS particular sort of device. */
-_S(ERR_MAP(ENODEV), N_("No such device"))
+_S(ENODEV, N_("No such device"))
#endif
#ifdef ENOTDIR
/*
TRANS A file that isn't a directory was specified when a directory is required. */
-_S(ERR_MAP(ENOTDIR), N_("Not a directory"))
+_S(ENOTDIR, N_("Not a directory"))
#endif
#ifdef EISDIR
/*
TRANS You cannot open a directory for writing,
TRANS or create or remove hard links to it. */
-_S(ERR_MAP(EISDIR), N_("Is a directory"))
+_S(EISDIR, N_("Is a directory"))
#endif
#ifdef EINVAL
/*
TRANS This is used to indicate various kinds of problems
TRANS with passing the wrong argument to a library function. */
-_S(ERR_MAP(EINVAL), N_("Invalid argument"))
+_S(EINVAL, N_("Invalid argument"))
#endif
#ifdef EMFILE
/*
@@ -157,20 +154,20 @@ TRANS In BSD and GNU, the number of open
TRANS limit that can usually be increased. If you get this error, you might
TRANS want to increase the @code{RLIMIT_NOFILE} limit or make it unlimited;
TRANS @pxref{Limits on Resources}. */
-_S(ERR_MAP(EMFILE), N_("Too many open files"))
+_S(EMFILE, N_("Too many open files"))
#endif
#ifdef ENFILE
/*
TRANS There are too many distinct file openings in the entire system. Note
TRANS that any number of linked channels count as just one file opening; see
TRANS @ref{Linked Channels}. This error never occurs on @gnuhurdsystems{}. */
-_S(ERR_MAP(ENFILE), N_("Too many open files in system"))
+_S(ENFILE, N_("Too many open files in system"))
#endif
#ifdef ENOTTY
/*
TRANS Inappropriate I/O control operation, such as trying to set terminal
TRANS modes on an ordinary file. */
-_S(ERR_MAP(ENOTTY), N_("Inappropriate ioctl for device"))
+_S(ENOTTY, N_("Inappropriate ioctl for device"))
#endif
#ifdef ETXTBSY
/*
@@ -179,35 +176,35 @@ TRANS write to a file that is currently
TRANS debugger to run a program is considered having it open for writing and
TRANS will cause this error. (The name stands for ``text file busy''.) This
TRANS is not an error on @gnuhurdsystems{}; the text is copied as necessary. */
-_S(ERR_MAP(ETXTBSY), N_("Text file busy"))
+_S(ETXTBSY, N_("Text file busy"))
#endif
#ifdef EFBIG
/*
TRANS The size of a file would be larger than allowed by the system. */
-_S(ERR_MAP(EFBIG), N_("File too large"))
+_S(EFBIG, N_("File too large"))
#endif
#ifdef ENOSPC
/*
TRANS Write operation on a file failed because the
TRANS disk is full. */
-_S(ERR_MAP(ENOSPC), N_("No space left on device"))
+_S(ENOSPC, N_("No space left on device"))
#endif
#ifdef ESPIPE
/*
TRANS Invalid seek operation (such as on a pipe). */
-_S(ERR_MAP(ESPIPE), N_("Illegal seek"))
+_S(ESPIPE, N_("Illegal seek"))
#endif
#ifdef EROFS
/*
TRANS An attempt was made to modify something on a read-only file system. */
-_S(ERR_MAP(EROFS), N_("Read-only file system"))
+_S(EROFS, N_("Read-only file system"))
#endif
#ifdef EMLINK
/*
TRANS The link count of a single file would become too large.
TRANS @code{rename} can cause this error if the file being renamed already has
TRANS as many links as it can take (@pxref{Renaming Files}). */
-_S(ERR_MAP(EMLINK), N_("Too many links"))
+_S(EMLINK, N_("Too many links"))
#endif
#ifdef EPIPE
/*
@@ -216,19 +213,19 @@ TRANS Every library function that return
TRANS @code{SIGPIPE} signal; this signal terminates the program if not handled
TRANS or blocked. Thus, your program will never actually see @code{EPIPE}
TRANS unless it has handled or blocked @code{SIGPIPE}. */
-_S(ERR_MAP(EPIPE), N_("Broken pipe"))
+_S(EPIPE, N_("Broken pipe"))
#endif
#ifdef EDOM
/*
TRANS Used by mathematical functions when an argument value does
TRANS not fall into the domain over which the function is defined. */
-_S(ERR_MAP(EDOM), N_("Numerical argument out of domain"))
+_S(EDOM, N_("Numerical argument out of domain"))
#endif
#ifdef ERANGE
/*
TRANS Used by mathematical functions when the result value is
TRANS not representable because of overflow or underflow. */
-_S(ERR_MAP(ERANGE), N_("Numerical result out of range"))
+_S(ERANGE, N_("Numerical result out of range"))
#endif
#ifdef EAGAIN
/*
@@ -261,7 +258,7 @@ TRANS Such shortages are usually fairly
TRANS so usually an interactive program should report the error to the user
TRANS and return to its command loop.
TRANS @end itemize */
-_S(ERR_MAP(EAGAIN), N_("Resource temporarily unavailable"))
+_S(EAGAIN, N_("Resource temporarily unavailable"))
#endif
#ifdef EINPROGRESS
/*
@@ -273,47 +270,47 @@ TRANS the operation has begun and will t
TRANS the object before the call completes return @code{EALREADY}. You can
TRANS use the @code{select} function to find out when the pending operation
TRANS has completed; @pxref{Waiting for I/O}. */
-_S(ERR_MAP(EINPROGRESS), N_("Operation now in progress"))
+_S(EINPROGRESS, N_("Operation now in progress"))
#endif
#ifdef EALREADY
/*
TRANS An operation is already in progress on an object that has non-blocking
TRANS mode selected. */
-_S(ERR_MAP(EALREADY), N_("Operation already in progress"))
+_S(EALREADY, N_("Operation already in progress"))
#endif
#ifdef ENOTSOCK
/*
TRANS A file that isn't a socket was specified when a socket is required. */
-_S(ERR_MAP(ENOTSOCK), N_("Socket operation on non-socket"))
+_S(ENOTSOCK, N_("Socket operation on non-socket"))
#endif
#ifdef EMSGSIZE
/*
TRANS The size of a message sent on a socket was larger than the supported
TRANS maximum size. */
-_S(ERR_MAP(EMSGSIZE), N_("Message too long"))
+_S(EMSGSIZE, N_("Message too long"))
#endif
#ifdef EPROTOTYPE
/*
TRANS The socket type does not support the requested communications protocol. */
-_S(ERR_MAP(EPROTOTYPE), N_("Protocol wrong type for socket"))
+_S(EPROTOTYPE, N_("Protocol wrong type for socket"))
#endif
#ifdef ENOPROTOOPT
/*
TRANS You specified a socket option that doesn't make sense for the
TRANS particular protocol being used by the socket. @xref{Socket Options}. */
-_S(ERR_MAP(ENOPROTOOPT), N_("Protocol not available"))
+_S(ENOPROTOOPT, N_("Protocol not available"))
#endif
#ifdef EPROTONOSUPPORT
/*
TRANS The socket domain does not support the requested communications protocol
TRANS (perhaps because the requested protocol is completely invalid).
TRANS @xref{Creating a Socket}. */
-_S(ERR_MAP(EPROTONOSUPPORT), N_("Protocol not supported"))
+_S(EPROTONOSUPPORT, N_("Protocol not supported"))
#endif
#ifdef ESOCKTNOSUPPORT
/*
TRANS The socket type is not supported. */
-_S(ERR_MAP(ESOCKTNOSUPPORT), N_("Socket type not supported"))
+_S(ESOCKTNOSUPPORT, N_("Socket type not supported"))
#endif
#ifdef EOPNOTSUPP
/*
@@ -323,71 +320,71 @@ TRANS implemented for all communications
TRANS error can happen for many calls when the object does not support the
TRANS particular operation; it is a generic indication that the server knows
TRANS nothing to do for that call. */
-_S(ERR_MAP(EOPNOTSUPP), N_("Operation not supported"))
+_S(EOPNOTSUPP, N_("Operation not supported"))
#endif
#ifdef EPFNOSUPPORT
/*
TRANS The socket communications protocol family you requested is not supported. */
-_S(ERR_MAP(EPFNOSUPPORT), N_("Protocol family not supported"))
+_S(EPFNOSUPPORT, N_("Protocol family not supported"))
#endif
#ifdef EAFNOSUPPORT
/*
TRANS The address family specified for a socket is not supported; it is
TRANS inconsistent with the protocol being used on the socket. @xref{Sockets}. */
-_S(ERR_MAP(EAFNOSUPPORT), N_("Address family not supported by protocol"))
+_S(EAFNOSUPPORT, N_("Address family not supported by protocol"))
#endif
#ifdef EADDRINUSE
/*
TRANS The requested socket address is already in use. @xref{Socket Addresses}. */
-_S(ERR_MAP(EADDRINUSE), N_("Address already in use"))
+_S(EADDRINUSE, N_("Address already in use"))
#endif
#ifdef EADDRNOTAVAIL
/*
TRANS The requested socket address is not available; for example, you tried
TRANS to give a socket a name that doesn't match the local host name.
TRANS @xref{Socket Addresses}. */
-_S(ERR_MAP(EADDRNOTAVAIL), N_("Cannot assign requested address"))
+_S(EADDRNOTAVAIL, N_("Cannot assign requested address"))
#endif
#ifdef ENETDOWN
/*
TRANS A socket operation failed because the network was down. */
-_S(ERR_MAP(ENETDOWN), N_("Network is down"))
+_S(ENETDOWN, N_("Network is down"))
#endif
#ifdef ENETUNREACH
/*
TRANS A socket operation failed because the subnet containing the remote host
TRANS was unreachable. */
-_S(ERR_MAP(ENETUNREACH), N_("Network is unreachable"))
+_S(ENETUNREACH, N_("Network is unreachable"))
#endif
#ifdef ENETRESET
/*
TRANS A network connection was reset because the remote host crashed. */
-_S(ERR_MAP(ENETRESET), N_("Network dropped connection on reset"))
+_S(ENETRESET, N_("Network dropped connection on reset"))
#endif
#ifdef ECONNABORTED
/*
TRANS A network connection was aborted locally. */
-_S(ERR_MAP(ECONNABORTED), N_("Software caused connection abort"))
+_S(ECONNABORTED, N_("Software caused connection abort"))
#endif
#ifdef ECONNRESET
/*
TRANS A network connection was closed for reasons outside the control of the
TRANS local host, such as by the remote machine rebooting or an unrecoverable
TRANS protocol violation. */
-_S(ERR_MAP(ECONNRESET), N_("Connection reset by peer"))
+_S(ECONNRESET, N_("Connection reset by peer"))
#endif
#ifdef ENOBUFS
/*
TRANS The kernel's buffers for I/O operations are all in use. In GNU, this
TRANS error is always synonymous with @code{ENOMEM}; you may get one or the
TRANS other from network operations. */
-_S(ERR_MAP(ENOBUFS), N_("No buffer space available"))
+_S(ENOBUFS, N_("No buffer space available"))
#endif
#ifdef EISCONN
/*
TRANS You tried to connect a socket that is already connected.
TRANS @xref{Connecting}. */
-_S(ERR_MAP(EISCONN), N_("Transport endpoint is already connected"))
+_S(EISCONN, N_("Transport endpoint is already connected"))
#endif
#ifdef ENOTCONN
/*
@@ -395,74 +392,74 @@ TRANS The socket is not connected to any
TRANS try to transmit data over a socket, without first specifying a
TRANS destination for the data. For a connectionless socket (for datagram
TRANS protocols, such as UDP), you get @code{EDESTADDRREQ} instead. */
-_S(ERR_MAP(ENOTCONN), N_("Transport endpoint is not connected"))
+_S(ENOTCONN, N_("Transport endpoint is not connected"))
#endif
#ifdef EDESTADDRREQ
/*
TRANS No default destination address was set for the socket. You get this
TRANS error when you try to transmit data over a connectionless socket,
TRANS without first specifying a destination for the data with @code{connect}. */
-_S(ERR_MAP(EDESTADDRREQ), N_("Destination address required"))
+_S(EDESTADDRREQ, N_("Destination address required"))
#endif
#ifdef ESHUTDOWN
/*
TRANS The socket has already been shut down. */
-_S(ERR_MAP(ESHUTDOWN), N_("Cannot send after transport endpoint shutdown"))
+_S(ESHUTDOWN, N_("Cannot send after transport endpoint shutdown"))
#endif
#ifdef ETOOMANYREFS
-_S(ERR_MAP(ETOOMANYREFS), N_("Too many references: cannot splice"))
+_S(ETOOMANYREFS, N_("Too many references: cannot splice"))
#endif
#ifdef ETIMEDOUT
/*
TRANS A socket operation with a specified timeout received no response during
TRANS the timeout period. */
-_S(ERR_MAP(ETIMEDOUT), N_("Connection timed out"))
+_S(ETIMEDOUT, N_("Connection timed out"))
#endif
#ifdef ECONNREFUSED
/*
TRANS A remote host refused to allow the network connection (typically because
TRANS it is not running the requested service). */
-_S(ERR_MAP(ECONNREFUSED), N_("Connection refused"))
+_S(ECONNREFUSED, N_("Connection refused"))
#endif
#ifdef ELOOP
/*
TRANS Too many levels of symbolic links were encountered in looking up a file name.
TRANS This often indicates a cycle of symbolic links. */
-_S(ERR_MAP(ELOOP), N_("Too many levels of symbolic links"))
+_S(ELOOP, N_("Too many levels of symbolic links"))
#endif
#ifdef ENAMETOOLONG
/*
TRANS Filename too long (longer than @code{PATH_MAX}; @pxref{Limits for
TRANS Files}) or host name too long (in @code{gethostname} or
TRANS @code{sethostname}; @pxref{Host Identification}). */
-_S(ERR_MAP(ENAMETOOLONG), N_("File name too long"))
+_S(ENAMETOOLONG, N_("File name too long"))
#endif
#ifdef EHOSTDOWN
/*
TRANS The remote host for a requested network connection is down. */
-_S(ERR_MAP(EHOSTDOWN), N_("Host is down"))
+_S(EHOSTDOWN, N_("Host is down"))
#endif
/*
TRANS The remote host for a requested network connection is not reachable. */
#ifdef EHOSTUNREACH
-_S(ERR_MAP(EHOSTUNREACH), N_("No route to host"))
+_S(EHOSTUNREACH, N_("No route to host"))
#endif
#ifdef ENOTEMPTY
/*
TRANS Directory not empty, where an empty directory was expected. Typically,
TRANS this error occurs when you are trying to delete a directory. */
-_S(ERR_MAP(ENOTEMPTY), N_("Directory not empty"))
+_S(ENOTEMPTY, N_("Directory not empty"))
#endif
#ifdef EUSERS
/*
TRANS The file quota system is confused because there are too many users.
TRANS @c This can probably happen in a GNU system when using NFS. */
-_S(ERR_MAP(EUSERS), N_("Too many users"))
+_S(EUSERS, N_("Too many users"))
#endif
#ifdef EDQUOT
/*
TRANS The user's disk quota was exceeded. */
-_S(ERR_MAP(EDQUOT), N_("Disk quota exceeded"))
+_S(EDQUOT, N_("Disk quota exceeded"))
#endif
#ifdef ESTALE
/*
@@ -471,7 +468,7 @@ TRANS file system which is due to file s
TRANS for NFS file systems or corruption in other file systems.
TRANS Repairing this condition usually requires unmounting, possibly repairing
TRANS and remounting the file system. */
-_S(ERR_MAP(ESTALE), N_("Stale file handle"))
+_S(ESTALE, N_("Stale file handle"))
#endif
#ifdef EREMOTE
/*
@@ -479,7 +476,7 @@ TRANS An attempt was made to NFS-mount a
TRANS already specifies an NFS-mounted file.
TRANS (This is an error on some operating systems, but we expect it to work
TRANS properly on @gnuhurdsystems{}, making this error code impossible.) */
-_S(ERR_MAP(EREMOTE), N_("Object is remote"))
+_S(EREMOTE, N_("Object is remote"))
#endif
#ifdef ENOLCK
/*
@@ -487,7 +484,7 @@ TRANS This is used by the file locking f
TRANS @ref{File Locks}. This error is never generated by @gnuhurdsystems{}, but
TRANS it can result from an operation to an NFS server running another
TRANS operating system. */
-_S(ERR_MAP(ENOLCK), N_("No locks available"))
+_S(ENOLCK, N_("No locks available"))
#endif
#ifdef ENOSYS
/*
@@ -496,46 +493,46 @@ TRANS not implemented at all, either in
TRANS operating system. When you get this error, you can be sure that this
TRANS particular function will always fail with @code{ENOSYS} unless you
TRANS install a new version of the C library or the operating system. */
-_S(ERR_MAP(ENOSYS), N_("Function not implemented"))
+_S(ENOSYS, N_("Function not implemented"))
#endif
#ifdef EILSEQ
/*
TRANS While decoding a multibyte character the function came along an invalid
TRANS or an incomplete sequence of bytes or the given wide character is invalid. */
-_S(ERR_MAP(EILSEQ), N_("Invalid or incomplete multibyte or wide character"))
+_S(EILSEQ, N_("Invalid or incomplete multibyte or wide character"))
#endif
#ifdef EBADMSG
-_S(ERR_MAP(EBADMSG), N_("Bad message"))
+_S(EBADMSG, N_("Bad message"))
#endif
#ifdef EIDRM
-_S(ERR_MAP(EIDRM), N_("Identifier removed"))
+_S(EIDRM, N_("Identifier removed"))
#endif
#ifdef EMULTIHOP
-_S(ERR_MAP(EMULTIHOP), N_("Multihop attempted"))
+_S(EMULTIHOP, N_("Multihop attempted"))
#endif
#ifdef ENODATA
-_S(ERR_MAP(ENODATA), N_("No data available"))
+_S(ENODATA, N_("No data available"))
#endif
#ifdef ENOLINK
-_S(ERR_MAP(ENOLINK), N_("Link has been severed"))
+_S(ENOLINK, N_("Link has been severed"))
#endif
#ifdef ENOMSG
-_S(ERR_MAP(ENOMSG), N_("No message of desired type"))
+_S(ENOMSG, N_("No message of desired type"))
#endif
#ifdef ENOSR
-_S(ERR_MAP(ENOSR), N_("Out of streams resources"))
+_S(ENOSR, N_("Out of streams resources"))
#endif
#ifdef ENOSTR
-_S(ERR_MAP(ENOSTR), N_("Device not a stream"))
+_S(ENOSTR, N_("Device not a stream"))
#endif
#ifdef EOVERFLOW
-_S(ERR_MAP(EOVERFLOW), N_("Value too large for defined data type"))
+_S(EOVERFLOW, N_("Value too large for defined data type"))
#endif
#ifdef EPROTO
-_S(ERR_MAP(EPROTO), N_("Protocol error"))
+_S(EPROTO, N_("Protocol error"))
#endif
#ifdef ETIME
-_S(ERR_MAP(ETIME), N_("Timer expired"))
+_S(ETIME, N_("Timer expired"))
#endif
#ifdef ECANCELED
/*
@@ -543,148 +540,148 @@ TRANS An asynchronous operation was canc
TRANS completed. @xref{Asynchronous I/O}. When you call @code{aio_cancel},
TRANS the normal result is for the operations affected to complete with this
TRANS error; @pxref{Cancel AIO Operations}. */
-_S(ERR_MAP(ECANCELED), N_("Operation canceled"))
+_S(ECANCELED, N_("Operation canceled"))
#endif
#ifdef EOWNERDEAD
-_S(ERR_MAP(EOWNERDEAD), N_("Owner died"))
+_S(EOWNERDEAD, N_("Owner died"))
#endif
#ifdef ENOTRECOVERABLE
-_S(ERR_MAP(ENOTRECOVERABLE), N_("State not recoverable"))
+_S(ENOTRECOVERABLE, N_("State not recoverable"))
#endif
#ifdef ERESTART
-_S(ERR_MAP(ERESTART), N_("Interrupted system call should be restarted"))
+_S(ERESTART, N_("Interrupted system call should be restarted"))
#endif
#ifdef ECHRNG
-_S(ERR_MAP(ECHRNG), N_("Channel number out of range"))
+_S(ECHRNG, N_("Channel number out of range"))
#endif
#ifdef EL2NSYNC
-_S(ERR_MAP(EL2NSYNC), N_("Level 2 not synchronized"))
+_S(EL2NSYNC, N_("Level 2 not synchronized"))
#endif
#ifdef EL3HLT
-_S(ERR_MAP(EL3HLT), N_("Level 3 halted"))
+_S(EL3HLT, N_("Level 3 halted"))
#endif
#ifdef EL3RST
-_S(ERR_MAP(EL3RST), N_("Level 3 reset"))
+_S(EL3RST, N_("Level 3 reset"))
#endif
#ifdef ELNRNG
-_S(ERR_MAP(ELNRNG), N_("Link number out of range"))
+_S(ELNRNG, N_("Link number out of range"))
#endif
#ifdef EUNATCH
-_S(ERR_MAP(EUNATCH), N_("Protocol driver not attached"))
+_S(EUNATCH, N_("Protocol driver not attached"))
#endif
#ifdef ENOCSI
-_S(ERR_MAP(ENOCSI), N_("No CSI structure available"))
+_S(ENOCSI, N_("No CSI structure available"))
#endif
#ifdef EL2HLT
-_S(ERR_MAP(EL2HLT), N_("Level 2 halted"))
+_S(EL2HLT, N_("Level 2 halted"))
#endif
#ifdef EBADE
-_S(ERR_MAP(EBADE), N_("Invalid exchange"))
+_S(EBADE, N_("Invalid exchange"))
#endif
#ifdef EBADR
-_S(ERR_MAP(EBADR), N_("Invalid request descriptor"))
+_S(EBADR, N_("Invalid request descriptor"))
#endif
#ifdef EXFULL
-_S(ERR_MAP(EXFULL), N_("Exchange full"))
+_S(EXFULL, N_("Exchange full"))
#endif
#ifdef ENOANO
-_S(ERR_MAP(ENOANO), N_("No anode"))
+_S(ENOANO, N_("No anode"))
#endif
#ifdef EBADRQC
-_S(ERR_MAP(EBADRQC), N_("Invalid request code"))
+_S(EBADRQC, N_("Invalid request code"))
#endif
#ifdef EBADSLT
-_S(ERR_MAP(EBADSLT), N_("Invalid slot"))
+_S(EBADSLT, N_("Invalid slot"))
#endif
#ifdef EBFONT
-_S(ERR_MAP(EBFONT), N_("Bad font file format"))
+_S(EBFONT, N_("Bad font file format"))
#endif
#ifdef ENONET
-_S(ERR_MAP(ENONET), N_("Machine is not on the network"))
+_S(ENONET, N_("Machine is not on the network"))
#endif
#ifdef ENOPKG
-_S(ERR_MAP(ENOPKG), N_("Package not installed"))
+_S(ENOPKG, N_("Package not installed"))
#endif
#ifdef EADV
-_S(ERR_MAP(EADV), N_("Advertise error"))
+_S(EADV, N_("Advertise error"))
#endif
#ifdef ESRMNT
-_S(ERR_MAP(ESRMNT), N_("Srmount error"))
+_S(ESRMNT, N_("Srmount error"))
#endif
#ifdef ECOMM
-_S(ERR_MAP(ECOMM), N_("Communication error on send"))
+_S(ECOMM, N_("Communication error on send"))
#endif
#ifdef EDOTDOT
-_S(ERR_MAP(EDOTDOT), N_("RFS specific error"))
+_S(EDOTDOT, N_("RFS specific error"))
#endif
#ifdef ENOTUNIQ
-_S(ERR_MAP(ENOTUNIQ), N_("Name not unique on network"))
+_S(ENOTUNIQ, N_("Name not unique on network"))
#endif
#ifdef EBADFD
-_S(ERR_MAP(EBADFD), N_("File descriptor in bad state"))
+_S(EBADFD, N_("File descriptor in bad state"))
#endif
#ifdef EREMCHG
-_S(ERR_MAP(EREMCHG), N_("Remote address changed"))
+_S(EREMCHG, N_("Remote address changed"))
#endif
#ifdef ELIBACC
-_S(ERR_MAP(ELIBACC), N_("Can not access a needed shared library"))
+_S(ELIBACC, N_("Can not access a needed shared library"))
#endif
#ifdef ELIBBAD
-_S(ERR_MAP(ELIBBAD), N_("Accessing a corrupted shared library"))
+_S(ELIBBAD, N_("Accessing a corrupted shared library"))
#endif
#ifdef ELIBSCN
-_S(ERR_MAP(ELIBSCN), N_(".lib section in a.out corrupted"))
+_S(ELIBSCN, N_(".lib section in a.out corrupted"))
#endif
#ifdef ELIBMAX
-_S(ERR_MAP(ELIBMAX), N_("Attempting to link in too many shared libraries"))
+_S(ELIBMAX, N_("Attempting to link in too many shared libraries"))
#endif
#ifdef ELIBEXEC
-_S(ERR_MAP(ELIBEXEC), N_("Cannot exec a shared library directly"))
+_S(ELIBEXEC, N_("Cannot exec a shared library directly"))
#endif
#ifdef ESTRPIPE
-_S(ERR_MAP(ESTRPIPE), N_("Streams pipe error"))
+_S(ESTRPIPE, N_("Streams pipe error"))
#endif
#ifdef EUCLEAN
-_S(ERR_MAP(EUCLEAN), N_("Structure needs cleaning"))
+_S(EUCLEAN, N_("Structure needs cleaning"))
#endif
#ifdef ENOTNAM
-_S(ERR_MAP(ENOTNAM), N_("Not a XENIX named type file"))
+_S(ENOTNAM, N_("Not a XENIX named type file"))
#endif
#ifdef ENAVAIL
-_S(ERR_MAP(ENAVAIL), N_("No XENIX semaphores available"))
+_S(ENAVAIL, N_("No XENIX semaphores available"))
#endif
#ifdef EISNAM
-_S(ERR_MAP(EISNAM), N_("Is a named type file"))
+_S(EISNAM, N_("Is a named type file"))
#endif
#ifdef EREMOTEIO
-_S(ERR_MAP(EREMOTEIO), N_("Remote I/O error"))
+_S(EREMOTEIO, N_("Remote I/O error"))
#endif
#ifdef ENOMEDIUM
-_S(ERR_MAP(ENOMEDIUM), N_("No medium found"))
+_S(ENOMEDIUM, N_("No medium found"))
#endif
#ifdef EMEDIUMTYPE
-_S(ERR_MAP(EMEDIUMTYPE), N_("Wrong medium type"))
+_S(EMEDIUMTYPE, N_("Wrong medium type"))
#endif
#ifdef ENOKEY
-_S(ERR_MAP(ENOKEY), N_("Required key not available"))
+_S(ENOKEY, N_("Required key not available"))
#endif
#ifdef EKEYEXPIRED
-_S(ERR_MAP(EKEYEXPIRED), N_("Key has expired"))
+_S(EKEYEXPIRED, N_("Key has expired"))
#endif
#ifdef EKEYREVOKED
-_S(ERR_MAP(EKEYREVOKED), N_("Key has been revoked"))
+_S(EKEYREVOKED, N_("Key has been revoked"))
#endif
#ifdef EKEYREJECTED
-_S(ERR_MAP(EKEYREJECTED), N_("Key was rejected by service"))
+_S(EKEYREJECTED, N_("Key was rejected by service"))
#endif
#ifdef ERFKILL
-_S(ERR_MAP(ERFKILL), N_("Operation not possible due to RF-kill"))
+_S(ERFKILL, N_("Operation not possible due to RF-kill"))
#endif
#ifdef EHWPOISON
-_S(ERR_MAP(EHWPOISON), N_("Memory page has hardware error"))
+_S(EHWPOISON, N_("Memory page has hardware error"))
#endif
#ifdef EBADRPC
-_S(ERR_MAP(EBADRPC), N_("RPC struct is bad"))
+_S(EBADRPC, N_("RPC struct is bad"))
#endif
#ifdef EFTYPE
/*
@@ -693,40 +690,40 @@ TRANS operation, or a data file had the
TRANS
TRANS On some systems @code{chmod} returns this error if you try to set the
TRANS sticky bit on a non-directory file; @pxref{Setting Permissions}. */
-_S(ERR_MAP(EFTYPE), N_("Inappropriate file type or format"))
+_S(EFTYPE, N_("Inappropriate file type or format"))
#endif
#ifdef EPROCUNAVAIL
-_S(ERR_MAP(EPROCUNAVAIL), N_("RPC bad procedure for program"))
+_S(EPROCUNAVAIL, N_("RPC bad procedure for program"))
#endif
#ifdef EAUTH
-_S(ERR_MAP(EAUTH), N_("Authentication error"))
+_S(EAUTH, N_("Authentication error"))
#endif
#ifdef EDIED
/*
TRANS On @gnuhurdsystems{}, opening a file returns this error when the file is
TRANS translated by a program and the translator program dies while starting
TRANS up, before it has connected to the file. */
-_S(ERR_MAP(EDIED), N_("Translator died"))
+_S(EDIED, N_("Translator died"))
#endif
#ifdef ERPCMISMATCH
-_S(ERR_MAP(ERPCMISMATCH), N_("RPC version wrong"))
+_S(ERPCMISMATCH, N_("RPC version wrong"))
#endif
#ifdef EGREGIOUS
/*
TRANS You did @strong{what}? */
-_S(ERR_MAP(EGREGIOUS), N_("You really blew it this time"))
+_S(EGREGIOUS, N_("You really blew it this time"))
#endif
#ifdef EPROCLIM
/*
TRANS This means that the per-user limit on new process would be exceeded by
TRANS an attempted @code{fork}. @xref{Limits on Resources}, for details on
TRANS the @code{RLIMIT_NPROC} limit. */
-_S(ERR_MAP(EPROCLIM), N_("Too many processes"))
+_S(EPROCLIM, N_("Too many processes"))
#endif
#ifdef EGRATUITOUS
/*
TRANS This error code has no purpose. */
-_S(ERR_MAP(EGRATUITOUS), N_("Gratuitous error"))
+_S(EGRATUITOUS, N_("Gratuitous error"))
#endif
#if defined (ENOTSUP) && ENOTSUP != EOPNOTSUPP
/*
@@ -742,10 +739,10 @@ TRANS values.
TRANS
TRANS If the entire function is not available at all in the implementation,
TRANS it returns @code{ENOSYS} instead. */
-_S(ERR_MAP(ENOTSUP), N_("Not supported"))
+_S(ENOTSUP, N_("Not supported"))
#endif
#ifdef EPROGMISMATCH
-_S(ERR_MAP(EPROGMISMATCH), N_("RPC program version wrong"))
+_S(EPROGMISMATCH, N_("RPC program version wrong"))
#endif
#ifdef EBACKGROUND
/*
@@ -755,7 +752,7 @@ TRANS foreground process group of the te
TRANS error because functions such as @code{read} and @code{write} translate
TRANS it into a @code{SIGTTIN} or @code{SIGTTOU} signal. @xref{Job Control},
TRANS for information on process groups and these signals. */
-_S(ERR_MAP(EBACKGROUND), N_("Inappropriate operation for background process"))
+_S(EBACKGROUND, N_("Inappropriate operation for background process"))
#endif
#ifdef EIEIO
/*
@@ -773,7 +770,7 @@ TRANS @c "bought the farm" means "died".
TRANS @c
TRANS @c Translators, please do not translate this litteraly, translate it into
TRANS @c an idiomatic funny way of saying that the computer died. */
-_S(ERR_MAP(EIEIO), N_("Computer bought the farm"))
+_S(EIEIO, N_("Computer bought the farm"))
#endif
#if defined (EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
/*
@@ -782,18 +779,18 @@ TRANS The values are always the same, on
TRANS
TRANS C libraries in many older Unix systems have @code{EWOULDBLOCK} as a
TRANS separate error code. */
-_S(ERR_MAP(EWOULDBLOCK), N_("Operation would block"))
+_S(EWOULDBLOCK, N_("Operation would block"))
#endif
#ifdef ENEEDAUTH
-_S(ERR_MAP(ENEEDAUTH), N_("Need authenticator"))
+_S(ENEEDAUTH, N_("Need authenticator"))
#endif
#ifdef ED
/*
TRANS The experienced user will know what is wrong.
TRANS @c This error code is a joke. Its perror text is part of the joke.
TRANS @c Don't change it. */
-_S(ERR_MAP(ED), N_("?"))
+_S(ED, N_("?"))
#endif
#ifdef EPROGUNAVAIL
-_S(ERR_MAP(EPROGUNAVAIL), N_("RPC program not available"))
+_S(EPROGUNAVAIL, N_("RPC program not available"))
#endif
diff -pruN glibc-2.32.orig/sysdeps/i386/dl-machine.h glibc-2.32/sysdeps/i386/dl-machine.h
--- glibc-2.32.orig/sysdeps/i386/dl-machine.h 2021-09-18 21:02:32.707184853 +1000
+++ glibc-2.32/sysdeps/i386/dl-machine.h 2021-09-18 21:03:05.313302322 +1000
@@ -338,16 +338,22 @@ elf_machine_rel (struct link_map *map, c
2021-03-22 16:38:00 +01:00
{
# ifndef RTLD_BOOTSTRAP
if (sym_map != map
- && sym_map->l_type != lt_executable
&& !sym_map->l_relocated)
{
const char *strtab
= (const char *) D_PTR (map, l_info[DT_STRTAB]);
- _dl_error_printf ("\
+ if (sym_map->l_type == lt_executable)
+ _dl_fatal_printf ("\
+%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
+and creates an unsatisfiable circular dependency.\n",
+ RTLD_PROGNAME, strtab + refsym->st_name,
+ map->l_name);
+ else
+ _dl_error_printf ("\
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
- RTLD_PROGNAME, map->l_name,
- sym_map->l_name,
- strtab + refsym->st_name);
+ RTLD_PROGNAME, map->l_name,
+ sym_map->l_name,
+ strtab + refsym->st_name);
}
# endif
value = ((Elf32_Addr (*) (void)) value) ();
diff -pruN glibc-2.32.orig/sysdeps/powerpc/powerpc64/backtrace.c glibc-2.32/sysdeps/powerpc/powerpc64/backtrace.c
--- glibc-2.32.orig/sysdeps/powerpc/powerpc64/backtrace.c 2021-09-18 21:02:32.723185402 +1000
+++ glibc-2.32/sysdeps/powerpc/powerpc64/backtrace.c 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -54,11 +54,22 @@ struct signal_frame_64 {
/* We don't care about the rest, since the IP value is at 'uc' field. */
};
+/* Test if the address match to the inside the trampoline code.
+ Up to and including kernel 5.8, returning from an interrupt or syscall to a
+ signal handler starts execution directly at the handler's entry point, with
+ LR set to address of the sigreturn trampoline (the vDSO symbol).
+ Newer kernels will branch to signal handler from the trampoline instead, so
+ checking the stacktrace against the vDSO entrypoint does not work in such
+ case.
+ The vDSO branches with a 'bctrl' instruction, so checking either the
+ vDSO address itself and the next instruction should cover all kernel
+ versions. */
static inline bool
is_sigtramp_address (void *nip)
{
#ifdef HAVE_SIGTRAMP_RT64
- if (nip == GLRO (dl_vdso_sigtramp_rt64))
+ if (nip == GLRO (dl_vdso_sigtramp_rt64) ||
+ nip == GLRO (dl_vdso_sigtramp_rt64) + 4)
return true;
#endif
return false;
diff -pruN glibc-2.32.orig/sysdeps/s390/configure glibc-2.32/sysdeps/s390/configure
--- glibc-2.32.orig/sysdeps/s390/configure 2021-09-18 21:02:32.727185539 +1000
+++ glibc-2.32/sysdeps/s390/configure 2021-09-18 21:03:05.313302322 +1000
2021-08-06 12:41:15 +02:00
@@ -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 -pruN glibc-2.32.orig/sysdeps/s390/configure.ac glibc-2.32/sysdeps/s390/configure.ac
--- glibc-2.32.orig/sysdeps/s390/configure.ac 2021-09-18 21:02:32.727185539 +1000
+++ glibc-2.32/sysdeps/s390/configure.ac 2021-09-18 21:03:05.313302322 +1000
2021-08-06 12:41:15 +02:00
@@ -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 -pruN glibc-2.32.orig/sysdeps/s390/memmove.c glibc-2.32/sysdeps/s390/memmove.c
--- glibc-2.32.orig/sysdeps/s390/memmove.c 2021-09-18 21:02:32.727185539 +1000
+++ glibc-2.32/sysdeps/s390/memmove.c 2021-09-18 21:03:05.313302322 +1000
@@ -43,7 +43,7 @@ extern __typeof (__redirect_memmove) MEM
2021-08-06 12:41:15 +02:00
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 -pruN glibc-2.32.orig/sysdeps/s390/multiarch/ifunc-impl-list.c glibc-2.32/sysdeps/s390/multiarch/ifunc-impl-list.c
--- glibc-2.32.orig/sysdeps/s390/multiarch/ifunc-impl-list.c 2021-09-18 21:02:32.727185539 +1000
+++ glibc-2.32/sysdeps/s390/multiarch/ifunc-impl-list.c 2021-09-18 21:03:05.313302322 +1000
@@ -171,7 +171,8 @@ __libc_ifunc_impl_list (const char *name
2021-08-06 12:41:15 +02:00
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 -pruN glibc-2.32.orig/sysdeps/sh/be/sh4/fpu/Implies glibc-2.32/sysdeps/sh/be/sh4/fpu/Implies
--- glibc-2.32.orig/sysdeps/sh/be/sh4/fpu/Implies 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/sh/be/sh4/fpu/Implies 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1 @@
+sh/sh4/fpu
diff -pruN glibc-2.32.orig/sysdeps/sh/le/sh4/fpu/Implies glibc-2.32/sysdeps/sh/le/sh4/fpu/Implies
--- glibc-2.32.orig/sysdeps/sh/le/sh4/fpu/Implies 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/sh/le/sh4/fpu/Implies 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1 @@
+sh/sh4/fpu
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/aarch64/cpu-features.h glibc-2.32/sysdeps/unix/sysv/linux/aarch64/cpu-features.h
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/aarch64/cpu-features.h 2021-09-18 21:02:32.731185676 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/aarch64/cpu-features.h 2021-09-18 21:03:05.313302322 +1000
@@ -54,6 +54,10 @@
&& MIDR_PARTNUM(midr) == 0x000)
#define IS_NEOVERSE_N1(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
&& MIDR_PARTNUM(midr) == 0xd0c)
+#define IS_NEOVERSE_N2(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
+ && MIDR_PARTNUM(midr) == 0xd49)
+#define IS_NEOVERSE_V1(midr) (MIDR_IMPLEMENTOR(midr) == 'A' \
+ && MIDR_PARTNUM(midr) == 0xd40)
#define IS_EMAG(midr) (MIDR_IMPLEMENTOR(midr) == 'P' \
&& MIDR_PARTNUM(midr) == 0x000)
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/Makefile glibc-2.32/sysdeps/unix/sysv/linux/Makefile
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/Makefile 2021-09-18 21:02:32.731185676 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/Makefile 2021-09-18 21:03:05.313302322 +1000
@@ -100,7 +100,7 @@ tests += tst-clone tst-clone2 tst-clone3
tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
- tst-tgkill
+ tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux tst-sysvshm-linux
tests-internal += tst-ofdlocks-compat tst-sigcontext-get_pc
CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/mq_notify.c glibc-2.32/sysdeps/unix/sysv/linux/mq_notify.c
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/mq_notify.c 2021-09-18 21:02:32.736185847 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/mq_notify.c 2021-09-18 21:09:50.680196980 +1000
@@ -132,9 +132,12 @@ helper_thread (void *arg)
to wait until it is done with it. */
2021-08-06 12:41:15 +02:00
(void) __pthread_barrier_wait (&notify_barrier);
}
- else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED)
2021-08-06 12:41:15 +02:00
- /* The only state we keep is the copy of the thread attributes. */
- free (data.attr);
+ else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED && data.attr != NULL)
2021-08-06 12:41:15 +02:00
+ {
+ /* The only state we keep is the copy of the thread attributes. */
+ pthread_attr_destroy (data.attr);
+ free (data.attr);
+ }
}
return NULL;
}
@@ -255,8 +258,14 @@ mq_notify (mqd_t mqdes, const struct sig
2021-08-06 12:41:15 +02:00
if (data.attr == NULL)
return -1;
- memcpy (data.attr, notification->sigev_notify_attributes,
- sizeof (pthread_attr_t));
+ int ret = __pthread_attr_copy (data.attr,
+ notification->sigev_notify_attributes);
+ if (ret != 0)
+ {
+ free (data.attr);
+ __set_errno (ret);
+ return -1;
+ }
}
/* Construct the new request. */
@@ -269,8 +278,11 @@ mq_notify (mqd_t mqdes, const struct sig
2021-08-06 12:41:15 +02:00
int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se);
/* If it failed, free the allocated memory. */
- if (__glibc_unlikely (retval != 0))
- free (data.attr);
+ if (retval != 0 && data.attr != NULL)
+ {
+ pthread_attr_destroy (data.attr);
+ free (data.attr);
+ }
return retval;
}
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/msgctl.c glibc-2.32/sysdeps/unix/sysv/linux/msgctl.c
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/msgctl.c 2021-09-18 21:02:32.736185847 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/msgctl.c 2021-09-18 21:03:05.313302322 +1000
@@ -90,8 +90,15 @@ __msgctl64 (int msqid, int cmd, struct _
struct kernel_msqid64_ds ksemid, *arg = NULL;
if (buf != NULL)
{
- msqid64_to_kmsqid64 (buf, &ksemid);
- arg = &ksemid;
+ /* This is a Linux extension where kernel returns a 'struct msginfo'
+ instead. */
+ if (cmd == IPC_INFO || cmd == MSG_INFO)
+ arg = (struct kernel_msqid64_ds *) buf;
+ else
+ {
+ msqid64_to_kmsqid64 (buf, &ksemid);
+ arg = &ksemid;
+ }
}
# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
if (cmd == IPC_SET)
@@ -169,8 +176,15 @@ __msgctl (int msqid, int cmd, struct msq
struct __msqid64_ds msqid64, *buf64 = NULL;
if (buf != NULL)
{
- msqid_to_msqid64 (&msqid64, buf);
- buf64 = &msqid64;
+ /* This is a Linux extension where kernel returns a 'struct msginfo'
+ instead. */
+ if (cmd == IPC_INFO || cmd == MSG_INFO)
+ buf64 = (struct __msqid64_ds *) buf;
+ else
+ {
+ msqid_to_msqid64 (&msqid64, buf);
+ buf64 = &msqid64;
+ }
}
int ret = __msgctl64 (msqid, cmd, buf64);
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/semctl.c glibc-2.32/sysdeps/unix/sysv/linux/semctl.c
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/semctl.c 2021-09-18 21:02:32.739185950 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/semctl.c 2021-09-18 21:03:05.313302322 +1000
@@ -102,6 +102,7 @@ semun64_to_ksemun64 (int cmd, union semu
r.array = semun64.array;
break;
case SEM_STAT:
+ case SEM_STAT_ANY:
case IPC_STAT:
case IPC_SET:
r.buf = buf;
@@ -150,6 +151,7 @@ __semctl64 (int semid, int semnum, int c
case IPC_STAT: /* arg.buf */
case IPC_SET:
case SEM_STAT:
+ case SEM_STAT_ANY:
case IPC_INFO: /* arg.__buf */
case SEM_INFO:
va_start (ap, cmd);
@@ -238,6 +240,7 @@ semun_to_semun64 (int cmd, union semun s
r.array = semun.array;
break;
case SEM_STAT:
+ case SEM_STAT_ANY:
case IPC_STAT:
case IPC_SET:
r.buf = semid64;
@@ -267,6 +270,7 @@ __semctl (int semid, int semnum, int cmd
case IPC_STAT: /* arg.buf */
case IPC_SET:
case SEM_STAT:
+ case SEM_STAT_ANY:
case IPC_INFO: /* arg.__buf */
case SEM_INFO:
va_start (ap, cmd);
@@ -321,6 +325,7 @@ __semctl_mode16 (int semid, int semnum,
case IPC_STAT: /* arg.buf */
case IPC_SET:
case SEM_STAT:
+ case SEM_STAT_ANY:
case IPC_INFO: /* arg.__buf */
case SEM_INFO:
va_start (ap, cmd);
@@ -354,6 +359,7 @@ __old_semctl (int semid, int semnum, int
case IPC_STAT: /* arg.buf */
case IPC_SET:
case SEM_STAT:
+ case SEM_STAT_ANY:
case IPC_INFO: /* arg.__buf */
case SEM_INFO:
va_start (ap, cmd);
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/sh/be/sh4/fpu/Implies glibc-2.32/sysdeps/unix/sysv/linux/sh/be/sh4/fpu/Implies
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/sh/be/sh4/fpu/Implies 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/sh/be/sh4/fpu/Implies 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1 @@
+unix/sysv/linux/sh/sh4/fpu
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/sh/le/sh4/fpu/Implies glibc-2.32/sysdeps/unix/sysv/linux/sh/le/sh4/fpu/Implies
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/sh/le/sh4/fpu/Implies 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/sh/le/sh4/fpu/Implies 2021-09-18 21:03:05.313302322 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1 @@
+unix/sysv/linux/sh/sh4/fpu
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/shmctl.c glibc-2.32/sysdeps/unix/sysv/linux/shmctl.c
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/shmctl.c 2021-09-18 21:02:32.740185984 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/shmctl.c 2021-09-18 21:03:05.313302322 +1000
@@ -90,8 +90,15 @@ __shmctl64 (int shmid, int cmd, struct _
struct kernel_shmid64_ds kshmid, *arg = NULL;
if (buf != NULL)
{
- shmid64_to_kshmid64 (buf, &kshmid);
- arg = &kshmid;
+ /* This is a Linux extension where kernel expects either a
+ 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO). */
+ if (cmd == IPC_INFO || cmd == SHM_INFO)
+ arg = (struct kernel_shmid64_ds *) buf;
+ else
+ {
+ shmid64_to_kshmid64 (buf, &kshmid);
+ arg = &kshmid;
+ }
}
# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
if (cmd == IPC_SET)
@@ -107,7 +114,6 @@ __shmctl64 (int shmid, int cmd, struct _
switch (cmd)
{
- case IPC_INFO:
case IPC_STAT:
case SHM_STAT:
case SHM_STAT_ANY:
@@ -168,8 +174,15 @@ __shmctl (int shmid, int cmd, struct shm
struct __shmid64_ds shmid64, *buf64 = NULL;
if (buf != NULL)
{
- shmid_to_shmid64 (&shmid64, buf);
- buf64 = &shmid64;
+ /* This is a Linux extension where kernel expects either a
+ 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO). */
+ if (cmd == IPC_INFO || cmd == SHM_INFO)
+ buf64 = (struct __shmid64_ds *) buf;
+ else
+ {
+ shmid_to_shmid64 (&shmid64, buf);
+ buf64 = &shmid64;
+ }
}
int ret = __shmctl64 (shmid, cmd, buf64);
@@ -178,7 +191,6 @@ __shmctl (int shmid, int cmd, struct shm
switch (cmd)
{
- case IPC_INFO:
case IPC_STAT:
case SHM_STAT:
case SHM_STAT_ANY:
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c glibc-2.32/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c 2021-09-18 21:03:05.313302322 +1000
@@ -0,0 +1,177 @@
+/* Basic tests for Linux SYSV message queue extensions.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#define MSGQ_MODE 0644
+
+/* These are for the temporary file we generate. */
+static char *name;
+static int msqid;
+
+static void
+remove_msq (void)
+{
+ /* Enforce message queue removal in case of early test failure.
+ Ignore error since the msg may already have being removed. */
+ msgctl (msqid, IPC_RMID, NULL);
+}
+
+static void
+do_prepare (int argc, char *argv[])
+{
+ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvmsg.", &name) != -1);
+}
+
+#define PREPARE do_prepare
+
+struct test_msginfo
+{
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+};
+
+/* It tries to obtain some system-wide SysV messsage queue information from
+ /proc to check against IPC_INFO/MSG_INFO. The /proc only returns the
+ tunables value of MSGMAX, MSGMNB, and MSGMNI.
+
+ The kernel also returns constant value for MSGSSZ, MSGSEG and also MSGMAP,
+ MSGPOOL, and MSGTQL (for IPC_INFO). The issue to check them is they might
+ change over kernel releases. */
+
+static int
+read_proc_file (const char *file)
+{
+ FILE *f = fopen (file, "r");
+ if (f == NULL)
+ FAIL_UNSUPPORTED ("/proc is not mounted or %s is not available", file);
+
+ int v;
+ int r = fscanf (f, "%d", & v);
+ TEST_VERIFY_EXIT (r == 1);
+
+ fclose (f);
+ return v;
+}
+
+
+/* Check if the message queue with IDX (index into the kernel's internal
+ array) matches the one with KEY. The CMD is either MSG_STAT or
+ MSG_STAT_ANY. */
+
+static bool
+check_msginfo (int idx, key_t key, int cmd)
+{
+ struct msqid_ds msginfo;
+ int mid = msgctl (idx, cmd, &msginfo);
+ /* Ignore unused array slot returned by the kernel or information from
+ unknown message queue. */
+ if ((mid == -1 && errno == EINVAL) || mid != msqid)
+ return false;
+
+ if (mid == -1)
+ FAIL_EXIT1 ("msgctl with %s failed: %m",
+ cmd == MSG_STAT ? "MSG_STAT" : "MSG_STAT_ANY");
+
+ TEST_COMPARE (msginfo.msg_perm.__key, key);
+ TEST_COMPARE (msginfo.msg_perm.mode, MSGQ_MODE);
+ TEST_COMPARE (msginfo.msg_qnum, 0);
+
+ return true;
+}
+
+static int
+do_test (void)
+{
+ atexit (remove_msq);
+
+ key_t key = ftok (name, 'G');
+ if (key == -1)
+ FAIL_EXIT1 ("ftok failed: %m");
+
+ msqid = msgget (key, MSGQ_MODE | IPC_CREAT);
+ if (msqid == -1)
+ FAIL_EXIT1 ("msgget failed: %m");
+
+ struct test_msginfo tipcinfo;
+ tipcinfo.msgmax = read_proc_file ("/proc/sys/kernel/msgmax");
+ tipcinfo.msgmnb = read_proc_file ("/proc/sys/kernel/msgmnb");
+ tipcinfo.msgmni = read_proc_file ("/proc/sys/kernel/msgmni");
+
+ int msqidx;
+
+ {
+ struct msginfo ipcinfo;
+ msqidx = msgctl (msqid, IPC_INFO, (struct msqid_ds *) &ipcinfo);
+ if (msqidx == -1)
+ FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m");
+
+ TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax);
+ TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb);
+ TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni);
+ }
+
+ /* Same as before but with MSG_INFO. */
+ {
+ struct msginfo ipcinfo;
+ msqidx = msgctl (msqid, MSG_INFO, (struct msqid_ds *) &ipcinfo);
+ if (msqidx == -1)
+ FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m");
+
+ TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax);
+ TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb);
+ TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni);
+ }
+
+ /* We check if the created message queue shows in global list. */
+ bool found = false;
+ for (int i = 0; i <= msqidx; i++)
+ {
+ /* We can't tell apart if MSG_STAT_ANY is not supported (kernel older
+ than 4.17) or if the index used is invalid. So it just check if the
+ value returned from a valid call matches the created message
+ queue. */
+ check_msginfo (i, key, MSG_STAT_ANY);
+
+ if (check_msginfo (i, key, MSG_STAT))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ FAIL_EXIT1 ("msgctl with MSG_STAT/MSG_STAT_ANY could not find the "
+ "created message queue");
+
+ if (msgctl (msqid, IPC_RMID, NULL) == -1)
+ FAIL_EXIT1 ("msgctl failed");
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c glibc-2.32/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c 2021-09-18 21:03:05.314302356 +1000
@@ -0,0 +1,184 @@
+/* Basic tests for Linux SYSV semaphore extensions.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+/* These are for the temporary file we generate. */
+static char *name;
+static int semid;
+
+static void
+remove_sem (void)
+{
+ /* Enforce message queue removal in case of early test failure.
+ Ignore error since the sem may already have being removed. */
+ semctl (semid, 0, IPC_RMID, 0);
+}
+
+static void
+do_prepare (int argc, char *argv[])
+{
+ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvsem.", &name) != -1);
+}
+
+#define PREPARE do_prepare
+
+#define SEM_MODE 0644
+
+union semun
+{
+ int val;
+ struct semid_ds *buf;
+ unsigned short *array;
+ struct seminfo *__buf;
+};
+
+struct test_seminfo
+{
+ int semmsl;
+ int semmns;
+ int semopm;
+ int semmni;
+};
+
+/* It tries to obtain some system-wide SysV semaphore information from /proc
+ to check against IPC_INFO/SEM_INFO. The /proc only returns the tunables
+ value of SEMMSL, SEMMNS, SEMOPM, and SEMMNI.
+
+ The kernel also returns constant value for SEMVMX, SEMMNU, SEMMAP, SEMUME,
+ and also SEMUSZ and SEMAEM (for IPC_INFO). The issue to check them is they
+ might change over kernel releases. */
+
+static void
+read_sem_stat (struct test_seminfo *tseminfo)
+{
+ FILE *f = fopen ("/proc/sys/kernel/sem", "r");
+ if (f == NULL)
+ FAIL_UNSUPPORTED ("/proc is not mounted or /proc/sys/kernel/sem is not "
+ "available");
+
+ int r = fscanf (f, "%d %d %d %d",
+ &tseminfo->semmsl, &tseminfo->semmns, &tseminfo->semopm,
+ &tseminfo->semmni);
+ TEST_VERIFY_EXIT (r == 4);
+
+ fclose (f);
+}
+
+
+/* Check if the semaphore with IDX (index into the kernel's internal array)
+ matches the one with KEY. The CMD is either SEM_STAT or SEM_STAT_ANY. */
+
+static bool
+check_seminfo (int idx, key_t key, int cmd)
+{
+ struct semid_ds seminfo;
+ int sid = semctl (idx, 0, cmd, (union semun) { .buf = &seminfo });
+ /* Ignore unused array slot returned by the kernel or information from
+ unknown semaphores. */
+ if ((sid == -1 && errno == EINVAL) || sid != semid)
+ return false;
+
+ if (sid == -1)
+ FAIL_EXIT1 ("semctl with SEM_STAT failed (errno=%d)", errno);
+
+ TEST_COMPARE (seminfo.sem_perm.__key, key);
+ TEST_COMPARE (seminfo.sem_perm.mode, SEM_MODE);
+ TEST_COMPARE (seminfo.sem_nsems, 1);
+
+ return true;
+}
+
+static int
+do_test (void)
+{
+ atexit (remove_sem);
+
+ key_t key = ftok (name, 'G');
+ if (key == -1)
+ FAIL_EXIT1 ("ftok failed: %m");
+
+ semid = semget (key, 1, IPC_CREAT | IPC_EXCL | SEM_MODE);
+ if (semid == -1)
+ FAIL_EXIT1 ("semget failed: %m");
+
+ struct test_seminfo tipcinfo;
+ read_sem_stat (&tipcinfo);
+
+ int semidx;
+
+ {
+ struct seminfo ipcinfo;
+ semidx = semctl (semid, 0, IPC_INFO, (union semun) { .__buf = &ipcinfo });
+ if (semidx == -1)
+ FAIL_EXIT1 ("semctl with IPC_INFO failed: %m");
+
+ TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl);
+ TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns);
+ TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm);
+ TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni);
+ }
+
+ /* Same as before but with SEM_INFO. */
+ {
+ struct seminfo ipcinfo;
+ semidx = semctl (semid, 0, SEM_INFO, (union semun) { .__buf = &ipcinfo });
+ if (semidx == -1)
+ FAIL_EXIT1 ("semctl with IPC_INFO failed: %m");
+
+ TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl);
+ TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns);
+ TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm);
+ TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni);
+ }
+
+ /* We check if the created semaphore shows in the system-wide status. */
+ bool found = false;
+ for (int i = 0; i <= semidx; i++)
+ {
+ /* We can't tell apart if SEM_STAT_ANY is not supported (kernel older
+ than 4.17) or if the index used is invalid. So it just check if
+ value returned from a valid call matches the created semaphore. */
+ check_seminfo (i, key, SEM_STAT_ANY);
+
+ if (check_seminfo (i, key, SEM_STAT))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ FAIL_EXIT1 ("semctl with SEM_STAT/SEM_STAT_ANY could not find the "
+ "created semaphore");
+
+ if (semctl (semid, 0, IPC_RMID, 0) == -1)
+ FAIL_EXIT1 ("semctl failed: %m");
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c glibc-2.32/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c 2021-09-18 21:03:05.314302356 +1000
@@ -0,0 +1,185 @@
+/* Basic tests for Linux SYSV shared memory extensions.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <limits.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#define SHM_MODE 0644
+
+/* These are for the temporary file we generate. */
+static char *name;
+static int shmid;
+static long int pgsz;
+
+static void
+remove_shm (void)
+{
+ /* Enforce message queue removal in case of early test failure.
+ Ignore error since the shm may already have being removed. */
+ shmctl (shmid, IPC_RMID, NULL);
+}
+
+static void
+do_prepare (int argc, char *argv[])
+{
+ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvshm.", &name) != -1);
+}
+
+#define PREPARE do_prepare
+
+struct test_shminfo
+{
+ unsigned long int shmall;
+ unsigned long int shmmax;
+ unsigned long int shmmni;
+};
+
+/* It tries to obtain some system-wide SysV shared memory information from
+ /proc to check against IPC_INFO/SHM_INFO. The /proc only returns the
+ tunables value of SHMALL, SHMMAX, and SHMMNI. */
+
+static uint64_t
+read_proc_file (const char *file)
+{
+ FILE *f = fopen (file, "r");
+ if (f == NULL)
+ FAIL_UNSUPPORTED ("/proc is not mounted or %s is not available", file);
+
+ /* Handle 32-bit binaries running on 64-bit kernels. */
+ uint64_t v;
+ int r = fscanf (f, "%" SCNu64, &v);
+ TEST_VERIFY_EXIT (r == 1);
+
+ fclose (f);
+ return v;
+}
+
+
+/* Check if the message queue with IDX (index into the kernel's internal
+ array) matches the one with KEY. The CMD is either SHM_STAT or
+ SHM_STAT_ANY. */
+
+static bool
+check_shminfo (int idx, key_t key, int cmd)
+{
+ struct shmid_ds shminfo;
+ int sid = shmctl (idx, cmd, &shminfo);
+ /* Ignore unused array slot returned by the kernel or information from
+ unknown message queue. */
+ if ((sid == -1 && errno == EINVAL) || sid != shmid)
+ return false;
+
+ if (sid == -1)
+ FAIL_EXIT1 ("shmctl with %s failed: %m",
+ cmd == SHM_STAT ? "SHM_STAT" : "SHM_STAT_ANY");
+
+ TEST_COMPARE (shminfo.shm_perm.__key, key);
+ TEST_COMPARE (shminfo.shm_perm.mode, SHM_MODE);
+ TEST_COMPARE (shminfo.shm_segsz, pgsz);
+
+ return true;
+}
+
+static int
+do_test (void)
+{
+ atexit (remove_shm);
+
+ pgsz = sysconf (_SC_PAGESIZE);
+ if (pgsz == -1)
+ FAIL_EXIT1 ("sysconf (_SC_PAGESIZE) failed: %m");
+
+ key_t key = ftok (name, 'G');
+ if (key == -1)
+ FAIL_EXIT1 ("ftok failed: %m");
+
+ shmid = shmget (key, pgsz, IPC_CREAT | IPC_EXCL | SHM_MODE);
+ if (shmid == -1)
+ FAIL_EXIT1 ("shmget failed: %m");
+
+ struct test_shminfo tipcinfo;
+ {
+ uint64_t v = read_proc_file ("/proc/sys/kernel/shmmax");
+#if LONG_MAX == INT_MAX
+ /* Kernel explicit clamp the value for shmmax on compat symbol (32-bit
+ binaries running on 64-bit kernels). */
+ if (v > INT_MAX)
+ v = INT_MAX;
+#endif
+ tipcinfo.shmmax = v;
+ }
+ tipcinfo.shmall = read_proc_file ("/proc/sys/kernel/shmall");
+ tipcinfo.shmmni = read_proc_file ("/proc/sys/kernel/shmmni");
+
+ int shmidx;
+
+ /* Note: SHM_INFO does not return a shminfo, but rather a 'struct shm_info'.
+ It is tricky to verify its values since the syscall returns system wide
+ resources consumed by shared memory. The shmctl implementation handles
+ SHM_INFO as IPC_INFO, so the IPC_INFO test should validate SHM_INFO as
+ well. */
+
+ {
+ struct shminfo ipcinfo;
+ shmidx = shmctl (shmid, IPC_INFO, (struct shmid_ds *) &ipcinfo);
+ if (shmidx == -1)
+ FAIL_EXIT1 ("shmctl with IPC_INFO failed: %m");
+
+ TEST_COMPARE (ipcinfo.shmall, tipcinfo.shmall);
+ TEST_COMPARE (ipcinfo.shmmax, tipcinfo.shmmax);
+ TEST_COMPARE (ipcinfo.shmmni, tipcinfo.shmmni);
+ }
+
+ /* We check if the created shared memory shows in the global list. */
+ bool found = false;
+ for (int i = 0; i <= shmidx; i++)
+ {
+ /* We can't tell apart if SHM_STAT_ANY is not supported (kernel older
+ than 4.17) or if the index used is invalid. So it just check if
+ value returned from a valid call matches the created message
+ queue. */
+ check_shminfo (i, key, SHM_STAT_ANY);
+
+ if (check_shminfo (i, key, SHM_STAT))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ FAIL_EXIT1 ("shmctl with SHM_STAT/SHM_STAT_ANY could not find the "
+ "created shared memory");
+
+ if (shmctl (shmid, IPC_RMID, NULL) == -1)
+ FAIL_EXIT1 ("shmctl failed");
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/64/configure glibc-2.32/sysdeps/unix/sysv/linux/x86_64/64/configure
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/64/configure 2021-09-18 21:02:32.741186019 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/x86_64/64/configure 2021-09-18 21:03:05.314302356 +1000
@@ -4,10 +4,10 @@
test -n "$libc_cv_slibdir" ||
case "$prefix" in
/usr | /usr/)
- libc_cv_slibdir='/lib64'
- libc_cv_rtlddir='/lib64'
+ libc_cv_slibdir='/lib'
+ libc_cv_rtlddir='/lib'
if test "$libdir" = '${exec_prefix}/lib'; then
- libdir='${exec_prefix}/lib64';
+ libdir='${exec_prefix}/lib';
# Locale data can be shared between 32-bit and 64-bit libraries.
libc_cv_complocaledir='${exec_prefix}/lib/locale'
fi
diff -pruN glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/ldconfig.h glibc-2.32/sysdeps/unix/sysv/linux/x86_64/ldconfig.h
--- glibc-2.32.orig/sysdeps/unix/sysv/linux/x86_64/ldconfig.h 2021-09-18 21:02:32.742186053 +1000
+++ glibc-2.32/sysdeps/unix/sysv/linux/x86_64/ldconfig.h 2021-09-18 21:03:05.314302356 +1000
@@ -18,9 +18,9 @@
#include <sysdeps/generic/ldconfig.h>
#define SYSDEP_KNOWN_INTERPRETER_NAMES \
- { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
+ { "/lib32/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
{ "/libx32/ld-linux-x32.so.2", FLAG_ELF_LIBC6 }, \
- { "/lib64/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
+ { "/lib/ld-linux-x86-64.so.2", FLAG_ELF_LIBC6 },
#define SYSDEP_KNOWN_LIBRARY_NAMES \
{ "libc.so.6", FLAG_ELF_LIBC6 }, \
{ "libm.so.6", FLAG_ELF_LIBC6 },
diff -pruN glibc-2.32.orig/sysdeps/x86/cacheinfo.c glibc-2.32/sysdeps/x86/cacheinfo.c
--- glibc-2.32.orig/sysdeps/x86/cacheinfo.c 2021-09-18 21:02:32.742186053 +1000
+++ glibc-2.32/sysdeps/x86/cacheinfo.c 2021-09-18 21:03:05.314302356 +1000
2021-03-22 16:38:00 +01:00
@@ -808,7 +808,7 @@ init_cacheinfo (void)
threads = 1 << ((ecx >> 12) & 0x0f);
}
- if (threads == 0)
+ if (threads == 0 || cpu_features->basic.family >= 0x17)
{
/* If APIC ID width is not available, use logical
processor count. */
@@ -823,8 +823,22 @@ init_cacheinfo (void)
if (threads > 0)
shared /= threads;
- /* Account for exclusive L2 and L3 caches. */
- shared += core;
+ /* Get shared cache per ccx for Zen architectures. */
+ if (cpu_features->basic.family >= 0x17)
+ {
+ unsigned int eax;
+
+ /* Get number of threads share the L3 cache in CCX. */
+ __cpuid_count (0x8000001D, 0x3, eax, ebx, ecx, edx);
+
+ unsigned int threads_per_ccx = ((eax >> 14) & 0xfff) + 1;
+ shared *= threads_per_ccx;
+ }
+ else
+ {
+ /* Account for exclusive L2 and L3 caches. */
+ shared += core;
+ }
}
}
@@ -854,14 +868,20 @@ init_cacheinfo (void)
__x86_shared_cache_size = shared;
}
- /* The large memcpy micro benchmark in glibc shows that 6 times of
- shared cache size is the approximate value above which non-temporal
- store becomes faster on a 8-core processor. This is the 3/4 of the
- total shared cache size. */
+ /* The default setting for the non_temporal threshold is 3/4 of one
+ thread's share of the chip's cache. For most Intel and AMD processors
+ with an initial release date between 2017 and 2020, a thread's typical
+ share of the cache is from 500 KBytes to 2 MBytes. Using the 3/4
+ threshold leaves 125 KBytes to 500 KBytes of the thread's data
+ in cache after a maximum temporal copy, which will maintain
+ in cache a reasonable portion of the thread's stack and other
+ active data. If the threshold is set higher than one thread's
+ share of the cache, it has a substantial risk of negatively
+ impacting the performance of other threads running on the chip. */
__x86_shared_non_temporal_threshold
= (cpu_features->non_temporal_threshold != 0
? cpu_features->non_temporal_threshold
- : __x86_shared_cache_size * threads * 3 / 4);
+ : __x86_shared_cache_size * 3 / 4);
/* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8. */
unsigned int minimum_rep_movsb_threshold;
diff -pruN glibc-2.32.orig/sysdeps/x86/dl-cet.c glibc-2.32/sysdeps/x86/dl-cet.c
--- glibc-2.32.orig/sysdeps/x86/dl-cet.c 2021-09-18 21:02:32.742186053 +1000
+++ glibc-2.32/sysdeps/x86/dl-cet.c 2021-09-18 21:03:05.314302356 +1000
@@ -47,7 +47,10 @@ dl_cet_check (struct link_map *m, const
2021-03-22 16:38:00 +01:00
/* No legacy object check if both IBT and SHSTK are always on. */
if (enable_ibt_type == cet_always_on
&& enable_shstk_type == cet_always_on)
- return;
+ {
+ THREAD_SETMEM (THREAD_SELF, header.feature_1, GL(dl_x86_feature_1));
+ return;
+ }
/* Check if IBT is enabled by kernel. */
bool ibt_enabled
diff -pruN glibc-2.32.orig/sysdeps/x86/dl-prop.h glibc-2.32/sysdeps/x86/dl-prop.h
--- glibc-2.32.orig/sysdeps/x86/dl-prop.h 2021-09-18 21:02:32.742186053 +1000
+++ glibc-2.32/sysdeps/x86/dl-prop.h 2021-09-18 21:03:05.314302356 +1000
@@ -145,15 +145,15 @@ _dl_process_cet_property_note (struct li
2021-03-22 16:38:00 +01:00
}
static inline void __attribute__ ((unused))
-_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph)
+_dl_process_pt_note (struct link_map *l, int fd, const ElfW(Phdr) *ph)
{
const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
_dl_process_cet_property_note (l, note, ph->p_memsz, ph->p_align);
}
static inline int __attribute__ ((always_inline))
-_dl_process_gnu_property (struct link_map *l, uint32_t type, uint32_t datasz,
- void *data)
+_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
+ uint32_t datasz, void *data)
{
return 0;
}
diff -pruN glibc-2.32.orig/sysdeps/x86/Makefile glibc-2.32/sysdeps/x86/Makefile
--- glibc-2.32.orig/sysdeps/x86/Makefile 2021-09-18 21:02:32.742186053 +1000
+++ glibc-2.32/sysdeps/x86/Makefile 2021-09-18 21:03:05.314302356 +1000
@@ -12,6 +12,12 @@ endif
ifeq ($(subdir),setjmp)
gen-as-const-headers += jmp_buf-ssp.sym
sysdep_routines += __longjmp_cancel
+ifneq ($(enable-cet),no)
+ifneq ($(have-tunables),no)
+tests += tst-setjmp-cet
+tst-setjmp-cet-ENV = GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on
+endif
+endif
endif
ifeq ($(subdir),string)
diff -pruN glibc-2.32.orig/sysdeps/x86/tst-setjmp-cet.c glibc-2.32/sysdeps/x86/tst-setjmp-cet.c
--- glibc-2.32.orig/sysdeps/x86/tst-setjmp-cet.c 1970-01-01 10:00:00.000000000 +1000
+++ glibc-2.32/sysdeps/x86/tst-setjmp-cet.c 2021-09-18 21:03:05.314302356 +1000
2021-03-22 16:38:00 +01:00
@@ -0,0 +1 @@
+#include <setjmp/tst-setjmp.c>
diff -pruN glibc-2.32.orig/sysdeps/x86_64/configure glibc-2.32/sysdeps/x86_64/configure
--- glibc-2.32.orig/sysdeps/x86_64/configure 2021-09-18 21:02:32.743186087 +1000
+++ glibc-2.32/sysdeps/x86_64/configure 2021-09-18 21:03:05.314302356 +1000
@@ -107,39 +107,6 @@ if test x"$build_mathvec" = xnotset; the
2021-08-06 12:41:15 +02:00
build_mathvec=yes
fi
-if test "$static_pie" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker static PIE support" >&5
-$as_echo_n "checking for linker static PIE support... " >&6; }
-if ${libc_cv_ld_static_pie+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat > conftest.s <<\EOF
- .text
- .global _start
- .weak foo
-_start:
- leaq foo(%rip), %rax
-EOF
- libc_cv_pie_option="-Wl,-pie"
- if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- libc_cv_ld_static_pie=yes
- else
- libc_cv_ld_static_pie=no
- fi
-rm -f conftest*
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie" >&5
-$as_echo "$libc_cv_ld_static_pie" >&6; }
- if test "$libc_cv_ld_static_pie" != yes; then
- as_fn_error $? "linker support for static PIE needed" "$LINENO" 5
- fi
-fi
-
$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
diff -pruN glibc-2.32.orig/sysdeps/x86_64/configure.ac glibc-2.32/sysdeps/x86_64/configure.ac
--- glibc-2.32.orig/sysdeps/x86_64/configure.ac 2021-09-18 21:02:32.743186087 +1000
+++ glibc-2.32/sysdeps/x86_64/configure.ac 2021-09-18 21:03:05.314302356 +1000
@@ -53,31 +53,6 @@ if test x"$build_mathvec" = xnotset; the
2021-08-06 12:41:15 +02:00
build_mathvec=yes
fi
-dnl Check if linker supports static PIE with the fix for
-dnl
-dnl https://sourceware.org/bugzilla/show_bug.cgi?id=21782
-dnl
-if test "$static_pie" = yes; then
- AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl
-cat > conftest.s <<\EOF
- .text
- .global _start
- .weak foo
-_start:
- leaq foo(%rip), %rax
-EOF
- libc_cv_pie_option="-Wl,-pie"
- if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&AS_MESSAGE_LOG_FD); then
- libc_cv_ld_static_pie=yes
- else
- libc_cv_ld_static_pie=no
- fi
-rm -f conftest*])
- if test "$libc_cv_ld_static_pie" != yes; then
- AC_MSG_ERROR([linker support for static PIE needed])
- fi
-fi
-
dnl It is always possible to access static and hidden symbols in an
dnl position independent way.
AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff -pruN glibc-2.32.orig/sysdeps/x86_64/dl-machine.h glibc-2.32/sysdeps/x86_64/dl-machine.h
--- glibc-2.32.orig/sysdeps/x86_64/dl-machine.h 2021-09-18 21:02:32.743186087 +1000
+++ glibc-2.32/sysdeps/x86_64/dl-machine.h 2021-09-18 21:03:05.314302356 +1000
@@ -315,16 +315,22 @@ elf_machine_rela (struct link_map *map,
2021-03-22 16:38:00 +01:00
{
# ifndef RTLD_BOOTSTRAP
if (sym_map != map
- && sym_map->l_type != lt_executable
&& !sym_map->l_relocated)
{
const char *strtab
= (const char *) D_PTR (map, l_info[DT_STRTAB]);
- _dl_error_printf ("\
+ if (sym_map->l_type == lt_executable)
+ _dl_fatal_printf ("\
+%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
+and creates an unsatisfiable circular dependency.\n",
+ RTLD_PROGNAME, strtab + refsym->st_name,
+ map->l_name);
+ else
+ _dl_error_printf ("\
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
- RTLD_PROGNAME, map->l_name,
- sym_map->l_name,
- strtab + refsym->st_name);
+ RTLD_PROGNAME, map->l_name,
+ sym_map->l_name,
+ strtab + refsym->st_name);
}
# endif
value = ((ElfW(Addr) (*) (void)) value) ();
diff -pruN glibc-2.32.orig/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h glibc-2.32/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h
--- glibc-2.32.orig/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h 2021-09-18 21:02:32.743186087 +1000
+++ glibc-2.32/sysdeps/x86_64/fpu/multiarch/ifunc-fma4.h 2021-09-18 21:03:05.314302356 +1000
@@ -32,7 +32,7 @@ IFUNC_SELECTOR (void)
&& CPU_FEATURE_USABLE_P (cpu_features, AVX2))
return OPTIMIZE (fma);
- if (CPU_FEATURE_USABLE_P (cpu_features, FMA))
+ if (CPU_FEATURE_USABLE_P (cpu_features, FMA4))
return OPTIMIZE (fma4);
return OPTIMIZE (sse2);
diff -pruN glibc-2.32.orig/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S glibc-2.32/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
--- glibc-2.32.orig/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S 2021-09-18 21:02:32.745186156 +1000
+++ glibc-2.32/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S 2021-09-18 21:03:05.314302356 +1000
2021-03-22 16:38:00 +01:00
@@ -56,6 +56,13 @@
# endif
#endif
+/* Avoid short distance rep movsb only with non-SSE vector. */
+#ifndef AVOID_SHORT_DISTANCE_REP_MOVSB
+# define AVOID_SHORT_DISTANCE_REP_MOVSB (VEC_SIZE > 16)
+#else
+# define AVOID_SHORT_DISTANCE_REP_MOVSB 0
+#endif
+
#ifndef PREFETCH
# define PREFETCH(addr) prefetcht0 addr
#endif
@@ -243,7 +250,21 @@ L(movsb):
cmpq %r9, %rdi
/* Avoid slow backward REP MOVSB. */
jb L(more_8x_vec_backward)
+# if AVOID_SHORT_DISTANCE_REP_MOVSB
+ movq %rdi, %rcx
+ subq %rsi, %rcx
+ jmp 2f
+# endif
1:
+# if AVOID_SHORT_DISTANCE_REP_MOVSB
+ movq %rsi, %rcx
+ subq %rdi, %rcx
+2:
+/* Avoid "rep movsb" if RCX, the distance between source and destination,
+ is N*4GB + [1..63] with N >= 0. */
+ cmpl $63, %ecx
+ jbe L(more_2x_vec) /* Avoid "rep movsb" if ECX <= 63. */
+# endif
mov %RDX_LP, %RCX_LP
rep movsb
L(nop):
diff -pruN glibc-2.32.orig/sysvipc/test-sysvsem.c glibc-2.32/sysvipc/test-sysvsem.c
--- glibc-2.32.orig/sysvipc/test-sysvsem.c 2021-09-18 21:02:32.746186190 +1000
+++ glibc-2.32/sysvipc/test-sysvsem.c 2021-09-18 21:03:05.314302356 +1000
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <stdbool.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
diff -pruN glibc-2.32.orig/version.h glibc-2.32/version.h
--- glibc-2.32.orig/version.h 2021-09-18 21:02:32.746186190 +1000
+++ glibc-2.32/version.h 2021-09-18 21:03:05.314302356 +1000
@@ -1,4 +1,4 @@
/* This file just defines the current version number of libc. */
-#define RELEASE "release"
+#define RELEASE "stable"
#define VERSION "2.32"