add missing glibc patches
Signed-off-by: basebuilder_pel7x64builder0 <basebuilder@powerel.org>master
parent
d015312d5b
commit
418e78b115
SOURCES
|
@ -0,0 +1,36 @@
|
|||
From patchwork Thu Jul 3 13:26:40 2014
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: ARM: Define ELF_MACHINE_NO_REL
|
||||
X-Patchwork-Submitter: Will Newton <will.newton@linaro.org>
|
||||
X-Patchwork-Id: 366862
|
||||
Message-Id: <1404394000-13429-1-git-send-email-will.newton@linaro.org>
|
||||
To: libc-alpha@sourceware.org
|
||||
Date: Thu, 3 Jul 2014 14:26:40 +0100
|
||||
From: Will Newton <will.newton@linaro.org>
|
||||
List-Id: <libc-alpha.sourceware.org>
|
||||
|
||||
Fix a -Wundef warning on ARM.
|
||||
|
||||
ChangeLog:
|
||||
|
||||
2014-07-03 Will Newton <will.newton@linaro.org>
|
||||
|
||||
* sysdeps/arm/dl-machine.h (ELF_MACHINE_NO_REL): Define.
|
||||
---
|
||||
sysdeps/arm/dl-machine.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
|
||||
index c5ffc93..d6b0c52 100644
|
||||
--- a/sysdeps/arm/dl-machine.h
|
||||
+++ b/sysdeps/arm/dl-machine.h
|
||||
@@ -296,6 +296,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
|
||||
/* ARM never uses Elf32_Rela relocations for the dynamic linker.
|
||||
Prelinked libraries may use Elf32_Rela though. */
|
||||
#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
|
||||
+#define ELF_MACHINE_NO_REL 0
|
||||
|
||||
/* Names of the architecture-specific auditing callback functions. */
|
||||
#define ARCH_LA_PLTENTER arm_gnu_pltenter
|
|
@ -0,0 +1,185 @@
|
|||
commit 5c1a69238fcb87ff7f916a5ce7960b2864afb3a1
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat Nov 11 11:23:40 2017 +0100
|
||||
|
||||
resolv: Add tst-res_hnok
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index 988871086a70b291..b1fd2e2db8736f9b 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -50,6 +50,7 @@ tests += \
|
||||
tst-ns_name \
|
||||
tst-ns_name_compress \
|
||||
tst-res_hconf_reorder \
|
||||
+ tst-res_hnok \
|
||||
tst-res_use_inet6 \
|
||||
tst-resolv-basic \
|
||||
tst-resolv-edns \
|
||||
@@ -182,6 +183,7 @@ $(objpfx)tst-resolv-canonname: \
|
||||
$(objpfx)tst-ns_name: $(objpfx)libresolv.so
|
||||
$(objpfx)tst-ns_name.out: tst-ns_name.data
|
||||
$(objpfx)tst-ns_name_compress: $(objpfx)libresolv.so
|
||||
+$(objpfx)tst-res_hnok: $(objpfx)libresolv.so
|
||||
|
||||
|
||||
# This test case uses the deprecated RES_USE_INET6 resolver option.
|
||||
diff --git a/resolv/tst-res_hnok.c b/resolv/tst-res_hnok.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..9c923038218e965c
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-res_hnok.c
|
||||
@@ -0,0 +1,153 @@
|
||||
+/* Tests for res_hnok and related functions.
|
||||
+ Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <resolv.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/test-driver.h>
|
||||
+
|
||||
+/* Bits which indicate which functions are supposed to report
|
||||
+ success. */
|
||||
+enum
|
||||
+ {
|
||||
+ hnok = 1,
|
||||
+ dnok = 2,
|
||||
+ mailok = 4,
|
||||
+ ownok = 8,
|
||||
+ allnomailok = hnok | dnok | ownok,
|
||||
+ allok = hnok | dnok | mailok | ownok
|
||||
+ };
|
||||
+
|
||||
+/* A string of 60 characters. */
|
||||
+#define STRING60 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
|
||||
+
|
||||
+/* A string of 63 characters (maximum label length). */
|
||||
+#define STRING63 STRING60 "zzz"
|
||||
+
|
||||
+/* Combines a test name with the expected results. */
|
||||
+struct test_case
|
||||
+{
|
||||
+ const char *dn;
|
||||
+ unsigned int result; /* Combination of the *ok flags. */
|
||||
+};
|
||||
+
|
||||
+static const struct test_case tests[] =
|
||||
+ {
|
||||
+ { "", allok },
|
||||
+ { ".", allok },
|
||||
+ { "www", allnomailok },
|
||||
+ { "example", allnomailok },
|
||||
+ { "example.com", allok },
|
||||
+ { "www.example.com", allok },
|
||||
+ { "www.example.com.", allok },
|
||||
+ { "*.example.com", dnok | mailok | ownok },
|
||||
+ { "-v", dnok },
|
||||
+ { "-v.example.com", mailok | dnok },
|
||||
+ { "**.example.com", dnok | mailok },
|
||||
+ { STRING63, allnomailok },
|
||||
+ { STRING63 ".example.com", allok },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "z", allok },
|
||||
+ { "hostmaster@mail.example.com", dnok | mailok },
|
||||
+ { "with whitespace", 0 },
|
||||
+ { "with\twhitespace", 0 },
|
||||
+ { "with\nwhitespace", 0 },
|
||||
+ { "with.whitespace ", 0 },
|
||||
+ { "with.whitespace\t", 0 },
|
||||
+ { "with.whitespace\n", 0 },
|
||||
+ { "with\\ whitespace", 0 },
|
||||
+ { "with\\\twhitespace", 0 },
|
||||
+ { "with\\\nwhitespace", 0 },
|
||||
+ { "with.whitespace\\ ", 0 },
|
||||
+ { "with.whitespace\\\t", 0 },
|
||||
+ { "with.whitespace\\\n", 0 },
|
||||
+ };
|
||||
+
|
||||
+/* Run test case *TEST with FUNC (named FUNCNAME) and report an error
|
||||
+ if the result does not match the result flag at BIT. */
|
||||
+static void
|
||||
+one_test (const struct test_case *test, const char *funcname,
|
||||
+ int (*func) (const char *), unsigned int bit)
|
||||
+{
|
||||
+ int expected = (test->result & bit) != 0;
|
||||
+ int actual = func (test->dn);
|
||||
+ if (actual != expected)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: %s (\"%s\"): expected=%d, actual=%d\n",
|
||||
+ funcname, test->dn, expected, actual);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Run 255 tests using all the bytes from 1 to 255, surround the byte
|
||||
+ with the strings PREFIX and SUFFIX, and check that FUNC (named
|
||||
+ FUNCNAME) accepts only those bytes listed in ACCEPTED. */
|
||||
+static void
|
||||
+one_char (const char *prefix, const char *accepted, const char *suffix,
|
||||
+ const char *funcname, int (*func) (const char *))
|
||||
+{
|
||||
+ for (int ch = 1; ch <= 255; ++ch)
|
||||
+ {
|
||||
+ char dn[1024];
|
||||
+ snprintf (dn, sizeof (dn), "%s%c%s", prefix, ch, suffix);
|
||||
+ int expected = strchr (accepted, ch) != NULL;
|
||||
+ int actual = func (dn);
|
||||
+ if (actual != expected)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: %s (\"%s\"): expected=%d, actual=%d\n",
|
||||
+ funcname, dn, expected, actual);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ for (const struct test_case *test = tests; test < array_end (tests); ++test)
|
||||
+ {
|
||||
+ if (test_verbose)
|
||||
+ printf ("info: testing domain name [[[%s]]] (0x%x)\n",
|
||||
+ test->dn, test->result);
|
||||
+ one_test (test, "res_hnok", res_hnok, hnok);
|
||||
+ one_test (test, "res_dnok", res_dnok, dnok);
|
||||
+ one_test (test, "res_mailok", res_mailok, mailok);
|
||||
+ one_test (test, "res_ownok", res_ownok, ownok);
|
||||
+ }
|
||||
+
|
||||
+ one_char
|
||||
+ ("", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.",
|
||||
+ "", "res_hnok", res_hnok);
|
||||
+ one_char
|
||||
+ ("middle",
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
|
||||
+ "suffix", "res_hnok", res_hnok);
|
||||
+ one_char
|
||||
+ ("middle",
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_"
|
||||
+ "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~",
|
||||
+ "suffix.example", "res_mailok", res_mailok);
|
||||
+ one_char
|
||||
+ ("mailbox.middle",
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
|
||||
+ "suffix.example", "res_mailok", res_mailok);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,235 @@
|
|||
commit e2a9fca8101443076235a8dbcfceaa2d96bf4801
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat Nov 11 11:33:32 2017 +0100
|
||||
|
||||
resolv: Add tst-ns_name_pton
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index b1fd2e2db8736f9b..0130a09db2d69451 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -49,6 +49,7 @@ tests += \
|
||||
tst-bug18665-tcp \
|
||||
tst-ns_name \
|
||||
tst-ns_name_compress \
|
||||
+ tst-ns_name_pton \
|
||||
tst-res_hconf_reorder \
|
||||
tst-res_hnok \
|
||||
tst-res_use_inet6 \
|
||||
@@ -183,6 +184,7 @@ $(objpfx)tst-resolv-canonname: \
|
||||
$(objpfx)tst-ns_name: $(objpfx)libresolv.so
|
||||
$(objpfx)tst-ns_name.out: tst-ns_name.data
|
||||
$(objpfx)tst-ns_name_compress: $(objpfx)libresolv.so
|
||||
+$(objpfx)tst-ns_name_pton: $(objpfx)libresolv.so
|
||||
$(objpfx)tst-res_hnok: $(objpfx)libresolv.so
|
||||
|
||||
|
||||
diff --git a/resolv/tst-ns_name_pton.c b/resolv/tst-ns_name_pton.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..879d97c9d3816210
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-ns_name_pton.c
|
||||
@@ -0,0 +1,203 @@
|
||||
+/* Tests for ns_name_pton.
|
||||
+ Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <arpa/nameser.h>
|
||||
+#include <array_length.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/test-driver.h>
|
||||
+
|
||||
+/* Bits which indicate which functions are supposed to report
|
||||
+ success. */
|
||||
+enum
|
||||
+ {
|
||||
+ hnok = 1,
|
||||
+ dnok = 2,
|
||||
+ mailok = 4,
|
||||
+ ownok = 8,
|
||||
+ allnomailok = hnok | dnok | ownok,
|
||||
+ allok = hnok | dnok | mailok | ownok
|
||||
+ };
|
||||
+
|
||||
+/* A string of 60 characters. */
|
||||
+#define STRING60 "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
|
||||
+
|
||||
+/* A string of 63 characters (maximum label length). */
|
||||
+#define STRING63 STRING60 "zzz"
|
||||
+
|
||||
+/* A string of 60 bytes (non-ASCII). */
|
||||
+#define STRING60OCT \
|
||||
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
|
||||
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
|
||||
+ "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" \
|
||||
+ "\377\377\377\377\377\377\377\377\377"
|
||||
+
|
||||
+/* A string of 63 bytes (non-ASCII). */
|
||||
+#define STRING63OCT STRING60OCT "\377\377\377"
|
||||
+
|
||||
+/* A string of 60 bytes (non-ASCII, quoted decimal). */
|
||||
+#define STRING60DEC \
|
||||
+ "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
|
||||
+ "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
|
||||
+ "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
|
||||
+ "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
|
||||
+ "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255" \
|
||||
+ "\\255\\255\\255\\255\\255\\255\\255\\255\\255\\255"
|
||||
+
|
||||
+/* A string of 63 bytes (non-ASCII, quoted decimal). */
|
||||
+#define STRING63DEC STRING60DEC "\\255\\255\\255"
|
||||
+
|
||||
+/* Combines a test name with the expected results. */
|
||||
+struct test_case
|
||||
+{
|
||||
+ const char *dn;
|
||||
+ const char *back; /* Expected test result converted using ns_name_ntop. */
|
||||
+ bool fully_qualified; /* True if the domain name has a trailing dot. */
|
||||
+};
|
||||
+
|
||||
+static const struct test_case tests[] =
|
||||
+ {
|
||||
+ { "", ".", false },
|
||||
+ { ".", ".", true },
|
||||
+ { "..", NULL, },
|
||||
+ { "www", "www", false },
|
||||
+ { "www.", "www", true },
|
||||
+ { "www\\.", "www\\.", false },
|
||||
+ { ".www", NULL, },
|
||||
+ { ".www\\.", NULL, },
|
||||
+ { "example.com", "example.com", false },
|
||||
+ { "example.com.", "example.com", true },
|
||||
+ { ".example.com", NULL, },
|
||||
+ { ".example.com.", NULL, },
|
||||
+ { "example\\.com", "example\\.com", false },
|
||||
+ { "example\\.com.", "example\\.com", true },
|
||||
+ { "example..", NULL, },
|
||||
+ { "example..com", NULL, },
|
||||
+ { "example..com", NULL, },
|
||||
+ { "\\0", NULL, },
|
||||
+ { "\\00", NULL, },
|
||||
+ { "\\000", "\\000", false },
|
||||
+ { "\\1", NULL, },
|
||||
+ { "\\01", NULL, },
|
||||
+ { "\\001", "\\001", false },
|
||||
+ { "\\1x", NULL, },
|
||||
+ { "\\01x", NULL, },
|
||||
+ { "\\001x", "\\001x", false },
|
||||
+ { "\\256", NULL, },
|
||||
+ { "\\0641", "\\@1", false },
|
||||
+ { "\\0011", "\\0011", false },
|
||||
+ { STRING63, STRING63, false },
|
||||
+ { STRING63 ".", STRING63, true },
|
||||
+ { STRING63 "z", NULL, },
|
||||
+ { STRING63 "\\.", NULL, },
|
||||
+ { STRING60 "zz\\.", STRING60 "zz\\.", false },
|
||||
+ { STRING60 "zz\\..", STRING60 "zz\\.", true },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "z",
|
||||
+ STRING63 "." STRING63 "." STRING63 "." STRING60 "z", false },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "z.",
|
||||
+ STRING63 "." STRING63 "." STRING63 "." STRING60 "z", true },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "zz", NULL, },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "zzz", NULL, },
|
||||
+ { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT "\377",
|
||||
+ STRING63DEC "." STRING63DEC "." STRING63DEC "." STRING60DEC "\\255",
|
||||
+ false },
|
||||
+ { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT "\377.",
|
||||
+ STRING63DEC "." STRING63DEC "." STRING63DEC "." STRING60DEC "\\255",
|
||||
+ true },
|
||||
+ { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
|
||||
+ "\377\377", NULL, },
|
||||
+ { STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
|
||||
+ "\377\377\377", NULL, },
|
||||
+ };
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ unsigned char *wire = xmalloc (NS_MAXCDNAME);
|
||||
+ char *text = xmalloc (NS_MAXDNAME);
|
||||
+ for (const struct test_case *test = tests; test < array_end (tests); ++test)
|
||||
+ {
|
||||
+ if (test_verbose)
|
||||
+ printf ("info: testing domain name [[[%s]]]\n", test->dn);
|
||||
+ int ret = ns_name_pton (test->dn, wire, NS_MAXCDNAME);
|
||||
+ if (ret == -1)
|
||||
+ {
|
||||
+ if (test->back != NULL)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: unexpected decoding failure for [[%s]]\n",
|
||||
+ test->dn);
|
||||
+ }
|
||||
+ /* Otherwise, we have an expected decoding failure. */
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (ret < -1 || ret > 1)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: invalid return value %d for [[%s]]\n",
|
||||
+ ret, test->dn);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ int ret2 = ns_name_ntop (wire, text, NS_MAXDNAME);
|
||||
+
|
||||
+ if (ret2 < 0)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: failure to convert back [[%s]]\n", test->dn);
|
||||
+ }
|
||||
+
|
||||
+ if (test->back == NULL)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: unexpected success converting [[%s]]\n", test->dn);
|
||||
+ if (ret2 >= 1)
|
||||
+ printf ("error: result converts back to [[%s]]\n", test->dn);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp (text, test->back) != 0)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: back-conversion of [[%s]] did not match\n",
|
||||
+ test->dn);
|
||||
+ printf ("error: expected: [[%s]]\n", test->back);
|
||||
+ printf ("error: actual: [[%s]]\n", text);
|
||||
+ }
|
||||
+
|
||||
+ if (ret != test->fully_qualified)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ printf ("error: invalid fully-qualified status for [[%s]]\n",
|
||||
+ test->dn);
|
||||
+ printf ("error: expected: %d\n", (int) test->fully_qualified);
|
||||
+ printf ("error: actual: %d\n", ret);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ free (text);
|
||||
+ free (wire);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,40 @@
|
|||
commit 9e0ad3049dbae88d615bfb038e53bf365a39a634
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat Nov 11 11:41:45 2017 +0100
|
||||
|
||||
resolv: ns_name_pton should report trailing \ as error [BZ #22413]
|
||||
|
||||
diff --git a/resolv/ns_name.c b/resolv/ns_name.c
|
||||
index 08a75e2fe0b4edd6..73213fee2dca530b 100644
|
||||
--- a/resolv/ns_name.c
|
||||
+++ b/resolv/ns_name.c
|
||||
@@ -222,6 +222,11 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
|
||||
}
|
||||
*bp++ = (u_char)c;
|
||||
}
|
||||
+ if (escaped) {
|
||||
+ /* Trailing backslash. */
|
||||
+ __set_errno (EMSGSIZE);
|
||||
+ return -1;
|
||||
+ }
|
||||
c = (bp - label - 1);
|
||||
if ((c & NS_CMPRSFLGS) != 0) { /*%< Label too big. */
|
||||
__set_errno (EMSGSIZE);
|
||||
diff --git a/resolv/tst-ns_name_pton.c b/resolv/tst-ns_name_pton.c
|
||||
index 879d97c9d3816210..73bdb05e08e405dc 100644
|
||||
--- a/resolv/tst-ns_name_pton.c
|
||||
+++ b/resolv/tst-ns_name_pton.c
|
||||
@@ -127,6 +127,13 @@ static const struct test_case tests[] =
|
||||
"\377\377", NULL, },
|
||||
{ STRING63OCT "." STRING63OCT "." STRING63OCT "." STRING60OCT
|
||||
"\377\377\377", NULL, },
|
||||
+ { "\\", NULL, },
|
||||
+ { "\\\\", "\\\\", false },
|
||||
+ { "\\\\.", "\\\\", true },
|
||||
+ { "\\\\\\", NULL, },
|
||||
+ { "a\\", NULL, },
|
||||
+ { "a.\\", NULL, },
|
||||
+ { "a.b\\", NULL, },
|
||||
};
|
||||
|
||||
static int
|
|
@ -0,0 +1,322 @@
|
|||
commit c0a25aa92b612786f4e45292c4aee1d7d47123f8
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat Nov 11 11:51:08 2017 +0100
|
||||
|
||||
resolv: More precise checks in res_hnok, res_dnok [BZ #22409] [BZ #22412]
|
||||
|
||||
res_hnok rejected some host names used on the Internet, such as
|
||||
www-.example.com. res_hnok and res_dnok failed to perform basic syntax
|
||||
checking on DNS domain names.
|
||||
|
||||
Also fix res_mailok, res_ownok.
|
||||
|
||||
diff --git a/resolv/res_comp.c b/resolv/res_comp.c
|
||||
index ffb2ed59147d3680..79760e891f607daa 100644
|
||||
--- a/resolv/res_comp.c
|
||||
+++ b/resolv/res_comp.c
|
||||
@@ -1,3 +1,21 @@
|
||||
+/* Domain name processing functions.
|
||||
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -121,110 +139,118 @@ dn_skipname(const u_char *ptr, const u_char *eom) {
|
||||
}
|
||||
libresolv_hidden_def (dn_skipname)
|
||||
|
||||
-/*
|
||||
- * Verify that a domain name uses an acceptable character set.
|
||||
- */
|
||||
+/* Return true if the string consists of printable ASCII characters
|
||||
+ only. */
|
||||
+static bool
|
||||
+printable_string (const char *dn)
|
||||
+{
|
||||
+ while (true)
|
||||
+ {
|
||||
+ char ch = *dn;
|
||||
+ if (ch == '\0')
|
||||
+ return true;
|
||||
+ if (ch <= ' ' || ch > '~')
|
||||
+ return false;
|
||||
+ ++dn;
|
||||
+ }
|
||||
+}
|
||||
|
||||
-/*
|
||||
- * Note the conspicuous absence of ctype macros in these definitions. On
|
||||
- * non-ASCII hosts, we can't depend on string literals or ctype macros to
|
||||
- * tell us anything about network-format data. The rest of the BIND system
|
||||
- * is not careful about this, but for some reason, we're doing it right here.
|
||||
- */
|
||||
-#define PERIOD 0x2e
|
||||
-#define hyphenchar(c) ((c) == 0x2d)
|
||||
-#define underscorechar(c) ((c) == 0x5f)
|
||||
-#define bslashchar(c) ((c) == 0x5c)
|
||||
-#define periodchar(c) ((c) == PERIOD)
|
||||
-#define asterchar(c) ((c) == 0x2a)
|
||||
-#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
|
||||
- || ((c) >= 0x61 && (c) <= 0x7a))
|
||||
-#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
|
||||
-
|
||||
-#define borderchar(c) (alphachar(c) || digitchar(c))
|
||||
-#define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c))
|
||||
-#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
|
||||
+/* Return true if DN points to a name consisting only of [0-9a-zA-Z_-]
|
||||
+ characters. DN must be in DNS wire format, without
|
||||
+ compression. */
|
||||
+static bool
|
||||
+binary_hnok (const unsigned char *dn)
|
||||
+{
|
||||
+ while (true)
|
||||
+ {
|
||||
+ size_t label_length = *dn;
|
||||
+ if (label_length == 0)
|
||||
+ break;
|
||||
+ ++dn;
|
||||
+ const unsigned char *label_end = dn + label_length;
|
||||
+ do
|
||||
+ {
|
||||
+ unsigned char ch = *dn;
|
||||
+ if (!(('0' <= ch && ch <= '9')
|
||||
+ || ('A' <= ch && ch <= 'Z')
|
||||
+ || ('a' <= ch && ch <= 'z')
|
||||
+ || ch == '-' || ch == '_'))
|
||||
+ return false;
|
||||
+ ++dn;
|
||||
+ }
|
||||
+ while (dn < label_end);
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/* Return true if the binary domain name has a first labels which
|
||||
+ starts with '-'. */
|
||||
+static inline bool
|
||||
+binary_leading_dash (const unsigned char *dn)
|
||||
+{
|
||||
+ return dn[0] > 0 && dn[1] == '-';
|
||||
+}
|
||||
|
||||
+/* Return 1 if res_hnok is a valid host name. Labels must only
|
||||
+ contain [0-9a-zA-Z_-] characters, and the name must not start with
|
||||
+ a '-'. The latter is to avoid confusion with program options. */
|
||||
int
|
||||
-res_hnok(const char *dn) {
|
||||
- int pch = PERIOD, ch = *dn++;
|
||||
-
|
||||
- while (ch != '\0') {
|
||||
- int nch = *dn++;
|
||||
-
|
||||
- if (periodchar(ch)) {
|
||||
- (void)NULL;
|
||||
- } else if (periodchar(pch)) {
|
||||
- if (!borderchar(ch))
|
||||
- return (0);
|
||||
- } else if (periodchar(nch) || nch == '\0') {
|
||||
- if (!borderchar(ch))
|
||||
- return (0);
|
||||
- } else {
|
||||
- if (!middlechar(ch))
|
||||
- return (0);
|
||||
- }
|
||||
- pch = ch, ch = nch;
|
||||
- }
|
||||
- return (1);
|
||||
+res_hnok (const char *dn)
|
||||
+{
|
||||
+ unsigned char buf[NS_MAXCDNAME];
|
||||
+ if (!printable_string (dn)
|
||||
+ || ns_name_pton (dn, buf, sizeof (buf)) < 0
|
||||
+ || binary_leading_dash (buf))
|
||||
+ return 0;
|
||||
+ return binary_hnok (buf);
|
||||
}
|
||||
libresolv_hidden_def (res_hnok)
|
||||
|
||||
-/*
|
||||
- * hostname-like (A, MX, WKS) owners can have "*" as their first label
|
||||
- * but must otherwise be as a host name.
|
||||
- */
|
||||
+/* Hostname-like (A, MX, WKS) owners can have "*" as their first label
|
||||
+ but must otherwise be as a host name. */
|
||||
int
|
||||
-res_ownok(const char *dn) {
|
||||
- if (asterchar(dn[0])) {
|
||||
- if (periodchar(dn[1]))
|
||||
- return (res_hnok(dn+2));
|
||||
- if (dn[1] == '\0')
|
||||
- return (1);
|
||||
- }
|
||||
- return (res_hnok(dn));
|
||||
+res_ownok (const char *dn)
|
||||
+{
|
||||
+ unsigned char buf[NS_MAXCDNAME];
|
||||
+ if (!printable_string (dn)
|
||||
+ || ns_name_pton (dn, buf, sizeof (buf)) < 0
|
||||
+ || binary_leading_dash (buf))
|
||||
+ return 0;
|
||||
+ if (buf[0] == 1 && buf [1] == '*')
|
||||
+ /* Skip over the leading "*." part. */
|
||||
+ return binary_hnok (buf + 2);
|
||||
+ else
|
||||
+ return binary_hnok (buf);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * SOA RNAMEs and RP RNAMEs can have any printable character in their first
|
||||
- * label, but the rest of the name has to look like a host name.
|
||||
- */
|
||||
+/* SOA RNAMEs and RP RNAMEs can have any byte in their first label,
|
||||
+ but the rest of the name has to look like a host name. */
|
||||
int
|
||||
-res_mailok(const char *dn) {
|
||||
- int ch, escaped = 0;
|
||||
-
|
||||
- /* "." is a valid missing representation */
|
||||
- if (*dn == '\0')
|
||||
- return (1);
|
||||
-
|
||||
- /* otherwise <label>.<hostname> */
|
||||
- while ((ch = *dn++) != '\0') {
|
||||
- if (!domainchar(ch))
|
||||
- return (0);
|
||||
- if (!escaped && periodchar(ch))
|
||||
- break;
|
||||
- if (escaped)
|
||||
- escaped = 0;
|
||||
- else if (bslashchar(ch))
|
||||
- escaped = 1;
|
||||
- }
|
||||
- if (periodchar(ch))
|
||||
- return (res_hnok(dn));
|
||||
- return (0);
|
||||
+res_mailok (const char *dn)
|
||||
+{
|
||||
+ unsigned char buf[NS_MAXCDNAME];
|
||||
+ if (!printable_string (dn)
|
||||
+ || ns_name_pton (dn, buf, sizeof (buf)) < 0)
|
||||
+ return 0;
|
||||
+ unsigned char label_length = buf[0];
|
||||
+ /* "." is a valid missing representation */
|
||||
+ if (label_length == 0)
|
||||
+ return 1;
|
||||
+ /* Skip over the first label. */
|
||||
+ unsigned char *tail = buf + 1 + label_length;
|
||||
+ if (*tail == 0)
|
||||
+ /* More than one label is required (except for "."). */
|
||||
+ return 0;
|
||||
+ return binary_hnok (tail);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * This function is quite liberal, since RFC 1034's character sets are only
|
||||
- * recommendations.
|
||||
- */
|
||||
+/* Return 1 if DN is a syntactically valid domain name. Empty names
|
||||
+ are accepted. */
|
||||
int
|
||||
-res_dnok(const char *dn) {
|
||||
- int ch;
|
||||
-
|
||||
- while ((ch = *dn++) != '\0')
|
||||
- if (!domainchar(ch))
|
||||
- return (0);
|
||||
- return (1);
|
||||
+res_dnok (const char *dn)
|
||||
+{
|
||||
+ unsigned char buf[NS_MAXCDNAME];
|
||||
+ return printable_string (dn) && ns_name_pton (dn, buf, sizeof (buf)) >= 0;
|
||||
}
|
||||
libresolv_hidden_def (res_dnok)
|
||||
|
||||
diff --git a/resolv/tst-res_hnok.c b/resolv/tst-res_hnok.c
|
||||
index 9c923038218e965c..314477a2ce2661c0 100644
|
||||
--- a/resolv/tst-res_hnok.c
|
||||
+++ b/resolv/tst-res_hnok.c
|
||||
@@ -51,19 +51,31 @@ static const struct test_case tests[] =
|
||||
{
|
||||
{ "", allok },
|
||||
{ ".", allok },
|
||||
+ { "..", 0 },
|
||||
{ "www", allnomailok },
|
||||
+ { "www.", allnomailok },
|
||||
{ "example", allnomailok },
|
||||
{ "example.com", allok },
|
||||
{ "www.example.com", allok },
|
||||
{ "www.example.com.", allok },
|
||||
+ { "www-.example.com.", allok },
|
||||
+ { "www.-example.com.", allok },
|
||||
{ "*.example.com", dnok | mailok | ownok },
|
||||
{ "-v", dnok },
|
||||
{ "-v.example.com", mailok | dnok },
|
||||
{ "**.example.com", dnok | mailok },
|
||||
+ { "www.example.com\\", 0 },
|
||||
{ STRING63, allnomailok },
|
||||
+ { STRING63 ".", allnomailok },
|
||||
+ { STRING63 "\\.", 0 },
|
||||
+ { STRING63 "z", 0 },
|
||||
{ STRING63 ".example.com", allok },
|
||||
{ STRING63 "." STRING63 "." STRING63 "." STRING60 "z", allok },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "z.", allok },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "zz", 0 },
|
||||
+ { STRING63 "." STRING63 "." STRING63 "." STRING60 "zzz", 0 },
|
||||
{ "hostmaster@mail.example.com", dnok | mailok },
|
||||
+ { "hostmaster\\@mail.example.com", dnok | mailok },
|
||||
{ "with whitespace", 0 },
|
||||
{ "with\twhitespace", 0 },
|
||||
{ "with\nwhitespace", 0 },
|
||||
@@ -116,6 +128,12 @@ one_char (const char *prefix, const char *accepted, const char *suffix,
|
||||
}
|
||||
}
|
||||
|
||||
+#define LETTERSDIGITS \
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
+
|
||||
+#define PRINTABLE \
|
||||
+ "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~"
|
||||
+
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
@@ -131,20 +149,18 @@ do_test (void)
|
||||
}
|
||||
|
||||
one_char
|
||||
- ("", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.",
|
||||
- "", "res_hnok", res_hnok);
|
||||
+ ("", LETTERSDIGITS "._", "", "res_hnok", res_hnok);
|
||||
one_char
|
||||
("middle",
|
||||
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
|
||||
+ LETTERSDIGITS ".-_\\", /* "middle\\suffix" == "middlesuffix", so good. */
|
||||
"suffix", "res_hnok", res_hnok);
|
||||
one_char
|
||||
("middle",
|
||||
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_"
|
||||
- "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~",
|
||||
+ LETTERSDIGITS ".-_" PRINTABLE,
|
||||
"suffix.example", "res_mailok", res_mailok);
|
||||
one_char
|
||||
("mailbox.middle",
|
||||
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
|
||||
+ LETTERSDIGITS ".-_\\",
|
||||
"suffix.example", "res_mailok", res_mailok);
|
||||
|
||||
return 0;
|
|
@ -0,0 +1,38 @@
|
|||
commit 8b35e35d0f4eae28a47c23e2aa15ddf570fa86ef
|
||||
Author: Ondřej Bílka <neleai@seznam.cz>
|
||||
Date: Fri Nov 1 15:39:26 2013 +0100
|
||||
|
||||
Fix malloc_info statistic. Fixes bug 16112
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index b47d99ac65344c82..c98b3f79ed38b4f0 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -5068,23 +5068,11 @@ malloc_info (int options, FILE *fp)
|
||||
sizes[i].total = sizes[i].count * sizes[i].to;
|
||||
}
|
||||
|
||||
- mbinptr bin = bin_at (ar_ptr, 1);
|
||||
- struct malloc_chunk *r = bin->fd;
|
||||
- if (r != NULL)
|
||||
- {
|
||||
- while (r != bin)
|
||||
- {
|
||||
- ++sizes[NFASTBINS].count;
|
||||
- sizes[NFASTBINS].total += r->size;
|
||||
- sizes[NFASTBINS].from = MIN (sizes[NFASTBINS].from, r->size);
|
||||
- sizes[NFASTBINS].to = MAX (sizes[NFASTBINS].to, r->size);
|
||||
- r = r->fd;
|
||||
- }
|
||||
- nblocks += sizes[NFASTBINS].count;
|
||||
- avail += sizes[NFASTBINS].total;
|
||||
- }
|
||||
|
||||
- for (size_t i = 2; i < NBINS; ++i)
|
||||
+ mbinptr bin;
|
||||
+ struct malloc_chunk *r;
|
||||
+
|
||||
+ for (size_t i = 1; i < NBINS; ++i)
|
||||
{
|
||||
bin = bin_at (ar_ptr, i);
|
||||
r = bin->fd;
|
|
@ -0,0 +1,236 @@
|
|||
This is a partial recreation of this upstream commit, restricted to
|
||||
the malloc_info function:
|
||||
|
||||
commit 6c8dbf00f536d78b1937b5af6f57be47fd376344
|
||||
Author: Ondřej Bílka <neleai@seznam.cz>
|
||||
Date: Thu Jan 2 09:38:18 2014 +0100
|
||||
|
||||
Reformat malloc to gnu style.
|
||||
|
||||
It is not an exact copy because glibc-rh1103856.patch backported
|
||||
commit 4d653a59ffeae0f46f76a40230e2cfa9587b7e7e ("Add mmap usage in
|
||||
malloc_info output"), which came after the reformatting upstream.
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index c98b3f79ed38b4f0..5c7a27129d66e06a 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -5023,7 +5023,8 @@ malloc_info (int options, FILE *fp)
|
||||
size_t total_aspace = 0;
|
||||
size_t total_aspace_mprotect = 0;
|
||||
|
||||
- void mi_arena (mstate ar_ptr)
|
||||
+ void
|
||||
+ mi_arena (mstate ar_ptr)
|
||||
{
|
||||
fprintf (fp, "<heap nr=\"%d\">\n<sizes>\n", n++);
|
||||
|
||||
@@ -5044,28 +5045,28 @@ malloc_info (int options, FILE *fp)
|
||||
|
||||
for (size_t i = 0; i < NFASTBINS; ++i)
|
||||
{
|
||||
- mchunkptr p = fastbin (ar_ptr, i);
|
||||
- if (p != NULL)
|
||||
- {
|
||||
- size_t nthissize = 0;
|
||||
- size_t thissize = chunksize (p);
|
||||
-
|
||||
- while (p != NULL)
|
||||
- {
|
||||
- ++nthissize;
|
||||
- p = p->fd;
|
||||
- }
|
||||
-
|
||||
- fastavail += nthissize * thissize;
|
||||
- nfastblocks += nthissize;
|
||||
- sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
|
||||
- sizes[i].to = thissize;
|
||||
- sizes[i].count = nthissize;
|
||||
- }
|
||||
- else
|
||||
- sizes[i].from = sizes[i].to = sizes[i].count = 0;
|
||||
-
|
||||
- sizes[i].total = sizes[i].count * sizes[i].to;
|
||||
+ mchunkptr p = fastbin (ar_ptr, i);
|
||||
+ if (p != NULL)
|
||||
+ {
|
||||
+ size_t nthissize = 0;
|
||||
+ size_t thissize = chunksize (p);
|
||||
+
|
||||
+ while (p != NULL)
|
||||
+ {
|
||||
+ ++nthissize;
|
||||
+ p = p->fd;
|
||||
+ }
|
||||
+
|
||||
+ fastavail += nthissize * thissize;
|
||||
+ nfastblocks += nthissize;
|
||||
+ sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
|
||||
+ sizes[i].to = thissize;
|
||||
+ sizes[i].count = nthissize;
|
||||
+ }
|
||||
+ else
|
||||
+ sizes[i].from = sizes[i].to = sizes[i].count = 0;
|
||||
+
|
||||
+ sizes[i].total = sizes[i].count * sizes[i].to;
|
||||
}
|
||||
|
||||
|
||||
@@ -5074,29 +5075,29 @@ malloc_info (int options, FILE *fp)
|
||||
|
||||
for (size_t i = 1; i < NBINS; ++i)
|
||||
{
|
||||
- bin = bin_at (ar_ptr, i);
|
||||
- r = bin->fd;
|
||||
- sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
|
||||
- sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
|
||||
- = sizes[NFASTBINS - 1 + i].count = 0;
|
||||
-
|
||||
- if (r != NULL)
|
||||
- while (r != bin)
|
||||
- {
|
||||
- ++sizes[NFASTBINS - 1 + i].count;
|
||||
- sizes[NFASTBINS - 1 + i].total += r->size;
|
||||
- sizes[NFASTBINS - 1 + i].from
|
||||
- = MIN (sizes[NFASTBINS - 1 + i].from, r->size);
|
||||
- sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
|
||||
- r->size);
|
||||
-
|
||||
- r = r->fd;
|
||||
- }
|
||||
-
|
||||
- if (sizes[NFASTBINS - 1 + i].count == 0)
|
||||
- sizes[NFASTBINS - 1 + i].from = 0;
|
||||
- nblocks += sizes[NFASTBINS - 1 + i].count;
|
||||
- avail += sizes[NFASTBINS - 1 + i].total;
|
||||
+ bin = bin_at (ar_ptr, i);
|
||||
+ r = bin->fd;
|
||||
+ sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
|
||||
+ sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
|
||||
+ = sizes[NFASTBINS - 1 + i].count = 0;
|
||||
+
|
||||
+ if (r != NULL)
|
||||
+ while (r != bin)
|
||||
+ {
|
||||
+ ++sizes[NFASTBINS - 1 + i].count;
|
||||
+ sizes[NFASTBINS - 1 + i].total += r->size;
|
||||
+ sizes[NFASTBINS - 1 + i].from
|
||||
+ = MIN (sizes[NFASTBINS - 1 + i].from, r->size);
|
||||
+ sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
|
||||
+ r->size);
|
||||
+
|
||||
+ r = r->fd;
|
||||
+ }
|
||||
+
|
||||
+ if (sizes[NFASTBINS - 1 + i].count == 0)
|
||||
+ sizes[NFASTBINS - 1 + i].from = 0;
|
||||
+ nblocks += sizes[NFASTBINS - 1 + i].count;
|
||||
+ avail += sizes[NFASTBINS - 1 + i].total;
|
||||
}
|
||||
|
||||
mutex_unlock (&ar_ptr->mutex);
|
||||
@@ -5109,51 +5110,51 @@ malloc_info (int options, FILE *fp)
|
||||
|
||||
for (size_t i = 0; i < nsizes; ++i)
|
||||
if (sizes[i].count != 0 && i != NFASTBINS)
|
||||
- fprintf (fp, "\
|
||||
+ fprintf (fp, " \
|
||||
<size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
|
||||
- sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
|
||||
+ sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
|
||||
|
||||
if (sizes[NFASTBINS].count != 0)
|
||||
fprintf (fp, "\
|
||||
<unsorted from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
|
||||
- sizes[NFASTBINS].from, sizes[NFASTBINS].to,
|
||||
- sizes[NFASTBINS].total, sizes[NFASTBINS].count);
|
||||
+ sizes[NFASTBINS].from, sizes[NFASTBINS].to,
|
||||
+ sizes[NFASTBINS].total, sizes[NFASTBINS].count);
|
||||
|
||||
total_system += ar_ptr->system_mem;
|
||||
total_max_system += ar_ptr->max_system_mem;
|
||||
|
||||
fprintf (fp,
|
||||
- "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
- "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
- "<system type=\"current\" size=\"%zu\"/>\n"
|
||||
- "<system type=\"max\" size=\"%zu\"/>\n",
|
||||
- nfastblocks, fastavail, nblocks, avail,
|
||||
- ar_ptr->system_mem, ar_ptr->max_system_mem);
|
||||
+ "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
+ "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
+ "<system type=\"current\" size=\"%zu\"/>\n"
|
||||
+ "<system type=\"max\" size=\"%zu\"/>\n",
|
||||
+ nfastblocks, fastavail, nblocks, avail,
|
||||
+ ar_ptr->system_mem, ar_ptr->max_system_mem);
|
||||
|
||||
if (ar_ptr != &main_arena)
|
||||
{
|
||||
- heap_info *heap = heap_for_ptr(top(ar_ptr));
|
||||
- fprintf (fp,
|
||||
- "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
- "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
- heap->size, heap->mprotect_size);
|
||||
- total_aspace += heap->size;
|
||||
- total_aspace_mprotect += heap->mprotect_size;
|
||||
+ heap_info *heap = heap_for_ptr (top (ar_ptr));
|
||||
+ fprintf (fp,
|
||||
+ "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
+ "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
+ heap->size, heap->mprotect_size);
|
||||
+ total_aspace += heap->size;
|
||||
+ total_aspace_mprotect += heap->mprotect_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
- fprintf (fp,
|
||||
- "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
- "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
- ar_ptr->system_mem, ar_ptr->system_mem);
|
||||
- total_aspace += ar_ptr->system_mem;
|
||||
- total_aspace_mprotect += ar_ptr->system_mem;
|
||||
+ fprintf (fp,
|
||||
+ "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
+ "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
+ ar_ptr->system_mem, ar_ptr->system_mem);
|
||||
+ total_aspace += ar_ptr->system_mem;
|
||||
+ total_aspace_mprotect += ar_ptr->system_mem;
|
||||
}
|
||||
|
||||
fputs ("</heap>\n", fp);
|
||||
}
|
||||
|
||||
- if(__malloc_initialized < 0)
|
||||
+ if (__malloc_initialized < 0)
|
||||
ptmalloc_init ();
|
||||
|
||||
fputs ("<malloc version=\"1\">\n", fp);
|
||||
@@ -5168,18 +5169,18 @@ malloc_info (int options, FILE *fp)
|
||||
while (ar_ptr != &main_arena);
|
||||
|
||||
fprintf (fp,
|
||||
- "<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
- "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
+ "<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
+ "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
"<total type=\"mmap\" count=\"%d\" size=\"%zu\"/>\n"
|
||||
- "<system type=\"current\" size=\"%zu\"/>\n"
|
||||
- "<system type=\"max\" size=\"%zu\"/>\n"
|
||||
- "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
- "<aspace type=\"mprotect\" size=\"%zu\"/>\n"
|
||||
- "</malloc>\n",
|
||||
- total_nfastblocks, total_fastavail, total_nblocks, total_avail,
|
||||
+ "<system type=\"current\" size=\"%zu\"/>\n"
|
||||
+ "<system type=\"max\" size=\"%zu\"/>\n"
|
||||
+ "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
+ "<aspace type=\"mprotect\" size=\"%zu\"/>\n"
|
||||
+ "</malloc>\n",
|
||||
+ total_nfastblocks, total_fastavail, total_nblocks, total_avail,
|
||||
mp_.n_mmaps, mp_.mmapped_mem,
|
||||
- total_system, total_max_system,
|
||||
- total_aspace, total_aspace_mprotect);
|
||||
+ total_system, total_max_system,
|
||||
+ total_aspace, total_aspace_mprotect);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
commit 987c02692a88b8c9024cb99187434aad02c3c047
|
||||
Author: Ondřej Bílka <neleai@seznam.cz>
|
||||
Date: Fri May 30 13:24:56 2014 +0200
|
||||
|
||||
Remove mi_arena nested function.
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index 5c7a27129d66e06a..c99b26d4a85e1b22 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -5023,147 +5023,143 @@ malloc_info (int options, FILE *fp)
|
||||
size_t total_aspace = 0;
|
||||
size_t total_aspace_mprotect = 0;
|
||||
|
||||
- void
|
||||
- mi_arena (mstate ar_ptr)
|
||||
- {
|
||||
- fprintf (fp, "<heap nr=\"%d\">\n<sizes>\n", n++);
|
||||
|
||||
- size_t nblocks = 0;
|
||||
- size_t nfastblocks = 0;
|
||||
- size_t avail = 0;
|
||||
- size_t fastavail = 0;
|
||||
- struct
|
||||
- {
|
||||
- size_t from;
|
||||
- size_t to;
|
||||
- size_t total;
|
||||
- size_t count;
|
||||
- } sizes[NFASTBINS + NBINS - 1];
|
||||
-#define nsizes (sizeof (sizes) / sizeof (sizes[0]))
|
||||
|
||||
- mutex_lock (&ar_ptr->mutex);
|
||||
+ if (__malloc_initialized < 0)
|
||||
+ ptmalloc_init ();
|
||||
+
|
||||
+ fputs ("<malloc version=\"1\">\n", fp);
|
||||
+
|
||||
+ /* Iterate over all arenas currently in use. */
|
||||
+ mstate ar_ptr = &main_arena;
|
||||
+ do
|
||||
+ {
|
||||
+ fprintf (fp, "<heap nr=\"%d\">\n<sizes>\n", n++);
|
||||
|
||||
- for (size_t i = 0; i < NFASTBINS; ++i)
|
||||
+ size_t nblocks = 0;
|
||||
+ size_t nfastblocks = 0;
|
||||
+ size_t avail = 0;
|
||||
+ size_t fastavail = 0;
|
||||
+ struct
|
||||
{
|
||||
- mchunkptr p = fastbin (ar_ptr, i);
|
||||
- if (p != NULL)
|
||||
- {
|
||||
- size_t nthissize = 0;
|
||||
- size_t thissize = chunksize (p);
|
||||
-
|
||||
- while (p != NULL)
|
||||
- {
|
||||
- ++nthissize;
|
||||
- p = p->fd;
|
||||
- }
|
||||
-
|
||||
- fastavail += nthissize * thissize;
|
||||
- nfastblocks += nthissize;
|
||||
- sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
|
||||
- sizes[i].to = thissize;
|
||||
- sizes[i].count = nthissize;
|
||||
- }
|
||||
- else
|
||||
- sizes[i].from = sizes[i].to = sizes[i].count = 0;
|
||||
-
|
||||
- sizes[i].total = sizes[i].count * sizes[i].to;
|
||||
- }
|
||||
+ size_t from;
|
||||
+ size_t to;
|
||||
+ size_t total;
|
||||
+ size_t count;
|
||||
+ } sizes[NFASTBINS + NBINS - 1];
|
||||
+#define nsizes (sizeof (sizes) / sizeof (sizes[0]))
|
||||
|
||||
+ mutex_lock (&ar_ptr->mutex);
|
||||
|
||||
- mbinptr bin;
|
||||
- struct malloc_chunk *r;
|
||||
+ for (size_t i = 0; i < NFASTBINS; ++i)
|
||||
+ {
|
||||
+ mchunkptr p = fastbin (ar_ptr, i);
|
||||
+ if (p != NULL)
|
||||
+ {
|
||||
+ size_t nthissize = 0;
|
||||
+ size_t thissize = chunksize (p);
|
||||
+
|
||||
+ while (p != NULL)
|
||||
+ {
|
||||
+ ++nthissize;
|
||||
+ p = p->fd;
|
||||
+ }
|
||||
+
|
||||
+ fastavail += nthissize * thissize;
|
||||
+ nfastblocks += nthissize;
|
||||
+ sizes[i].from = thissize - (MALLOC_ALIGNMENT - 1);
|
||||
+ sizes[i].to = thissize;
|
||||
+ sizes[i].count = nthissize;
|
||||
+ }
|
||||
+ else
|
||||
+ sizes[i].from = sizes[i].to = sizes[i].count = 0;
|
||||
|
||||
- for (size_t i = 1; i < NBINS; ++i)
|
||||
- {
|
||||
- bin = bin_at (ar_ptr, i);
|
||||
- r = bin->fd;
|
||||
- sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
|
||||
- sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
|
||||
- = sizes[NFASTBINS - 1 + i].count = 0;
|
||||
-
|
||||
- if (r != NULL)
|
||||
- while (r != bin)
|
||||
- {
|
||||
- ++sizes[NFASTBINS - 1 + i].count;
|
||||
- sizes[NFASTBINS - 1 + i].total += r->size;
|
||||
- sizes[NFASTBINS - 1 + i].from
|
||||
- = MIN (sizes[NFASTBINS - 1 + i].from, r->size);
|
||||
- sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
|
||||
- r->size);
|
||||
-
|
||||
- r = r->fd;
|
||||
- }
|
||||
-
|
||||
- if (sizes[NFASTBINS - 1 + i].count == 0)
|
||||
- sizes[NFASTBINS - 1 + i].from = 0;
|
||||
- nblocks += sizes[NFASTBINS - 1 + i].count;
|
||||
- avail += sizes[NFASTBINS - 1 + i].total;
|
||||
- }
|
||||
+ sizes[i].total = sizes[i].count * sizes[i].to;
|
||||
+ }
|
||||
|
||||
- mutex_unlock (&ar_ptr->mutex);
|
||||
|
||||
- total_nfastblocks += nfastblocks;
|
||||
- total_fastavail += fastavail;
|
||||
+ mbinptr bin;
|
||||
+ struct malloc_chunk *r;
|
||||
|
||||
- total_nblocks += nblocks;
|
||||
- total_avail += avail;
|
||||
+ for (size_t i = 1; i < NBINS; ++i)
|
||||
+ {
|
||||
+ bin = bin_at (ar_ptr, i);
|
||||
+ r = bin->fd;
|
||||
+ sizes[NFASTBINS - 1 + i].from = ~((size_t) 0);
|
||||
+ sizes[NFASTBINS - 1 + i].to = sizes[NFASTBINS - 1 + i].total
|
||||
+ = sizes[NFASTBINS - 1 + i].count = 0;
|
||||
+
|
||||
+ if (r != NULL)
|
||||
+ while (r != bin)
|
||||
+ {
|
||||
+ ++sizes[NFASTBINS - 1 + i].count;
|
||||
+ sizes[NFASTBINS - 1 + i].total += r->size;
|
||||
+ sizes[NFASTBINS - 1 + i].from
|
||||
+ = MIN (sizes[NFASTBINS - 1 + i].from, r->size);
|
||||
+ sizes[NFASTBINS - 1 + i].to = MAX (sizes[NFASTBINS - 1 + i].to,
|
||||
+ r->size);
|
||||
+
|
||||
+ r = r->fd;
|
||||
+ }
|
||||
|
||||
- for (size_t i = 0; i < nsizes; ++i)
|
||||
- if (sizes[i].count != 0 && i != NFASTBINS)
|
||||
- fprintf (fp, " \
|
||||
-<size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
|
||||
- sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
|
||||
+ if (sizes[NFASTBINS - 1 + i].count == 0)
|
||||
+ sizes[NFASTBINS - 1 + i].from = 0;
|
||||
+ nblocks += sizes[NFASTBINS - 1 + i].count;
|
||||
+ avail += sizes[NFASTBINS - 1 + i].total;
|
||||
+ }
|
||||
|
||||
- if (sizes[NFASTBINS].count != 0)
|
||||
- fprintf (fp, "\
|
||||
-<unsorted from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
|
||||
- sizes[NFASTBINS].from, sizes[NFASTBINS].to,
|
||||
- sizes[NFASTBINS].total, sizes[NFASTBINS].count);
|
||||
+ mutex_unlock (&ar_ptr->mutex);
|
||||
|
||||
- total_system += ar_ptr->system_mem;
|
||||
- total_max_system += ar_ptr->max_system_mem;
|
||||
+ total_nfastblocks += nfastblocks;
|
||||
+ total_fastavail += fastavail;
|
||||
|
||||
- fprintf (fp,
|
||||
- "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
- "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
- "<system type=\"current\" size=\"%zu\"/>\n"
|
||||
- "<system type=\"max\" size=\"%zu\"/>\n",
|
||||
- nfastblocks, fastavail, nblocks, avail,
|
||||
- ar_ptr->system_mem, ar_ptr->max_system_mem);
|
||||
+ total_nblocks += nblocks;
|
||||
+ total_avail += avail;
|
||||
|
||||
- if (ar_ptr != &main_arena)
|
||||
- {
|
||||
- heap_info *heap = heap_for_ptr (top (ar_ptr));
|
||||
- fprintf (fp,
|
||||
- "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
- "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
- heap->size, heap->mprotect_size);
|
||||
- total_aspace += heap->size;
|
||||
- total_aspace_mprotect += heap->mprotect_size;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- fprintf (fp,
|
||||
- "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
- "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
- ar_ptr->system_mem, ar_ptr->system_mem);
|
||||
- total_aspace += ar_ptr->system_mem;
|
||||
- total_aspace_mprotect += ar_ptr->system_mem;
|
||||
- }
|
||||
+ for (size_t i = 0; i < nsizes; ++i)
|
||||
+ if (sizes[i].count != 0 && i != NFASTBINS)
|
||||
+ fprintf (fp, " \
|
||||
+ <size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
|
||||
+ sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
|
||||
|
||||
- fputs ("</heap>\n", fp);
|
||||
- }
|
||||
+ if (sizes[NFASTBINS].count != 0)
|
||||
+ fprintf (fp, "\
|
||||
+ <unsorted from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
|
||||
+ sizes[NFASTBINS].from, sizes[NFASTBINS].to,
|
||||
+ sizes[NFASTBINS].total, sizes[NFASTBINS].count);
|
||||
|
||||
- if (__malloc_initialized < 0)
|
||||
- ptmalloc_init ();
|
||||
+ total_system += ar_ptr->system_mem;
|
||||
+ total_max_system += ar_ptr->max_system_mem;
|
||||
|
||||
- fputs ("<malloc version=\"1\">\n", fp);
|
||||
+ fprintf (fp,
|
||||
+ "</sizes>\n<total type=\"fast\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
+ "<total type=\"rest\" count=\"%zu\" size=\"%zu\"/>\n"
|
||||
+ "<system type=\"current\" size=\"%zu\"/>\n"
|
||||
+ "<system type=\"max\" size=\"%zu\"/>\n",
|
||||
+ nfastblocks, fastavail, nblocks, avail,
|
||||
+ ar_ptr->system_mem, ar_ptr->max_system_mem);
|
||||
|
||||
- /* Iterate over all arenas currently in use. */
|
||||
- mstate ar_ptr = &main_arena;
|
||||
- do
|
||||
- {
|
||||
- mi_arena (ar_ptr);
|
||||
+ if (ar_ptr != &main_arena)
|
||||
+ {
|
||||
+ heap_info *heap = heap_for_ptr (top (ar_ptr));
|
||||
+ fprintf (fp,
|
||||
+ "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
+ "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
+ heap->size, heap->mprotect_size);
|
||||
+ total_aspace += heap->size;
|
||||
+ total_aspace_mprotect += heap->mprotect_size;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ fprintf (fp,
|
||||
+ "<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
+ "<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
+ ar_ptr->system_mem, ar_ptr->system_mem);
|
||||
+ total_aspace += ar_ptr->system_mem;
|
||||
+ total_aspace_mprotect += ar_ptr->system_mem;
|
||||
+ }
|
||||
+
|
||||
+ fputs ("</heap>\n", fp);
|
||||
ar_ptr = ar_ptr->next;
|
||||
}
|
||||
while (ar_ptr != &main_arena);
|
|
@ -0,0 +1,38 @@
|
|||
commit c52ff39e8ee052e4a57676d65a27f09bd0a859ad
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Wed Nov 12 22:31:38 2014 +0000
|
||||
|
||||
Fix malloc_info namespace (bug 17570).
|
||||
|
||||
malloc_info is defined in the same file as malloc and free, but is not
|
||||
an ISO C function, so should be a weak symbol. This patch makes it
|
||||
so.
|
||||
|
||||
Tested for x86_64 (testsuite, and that disassembly of installed shared
|
||||
libraries is unchanged by the patch).
|
||||
|
||||
[BZ #17570]
|
||||
* malloc/malloc.c (malloc_info): Rename to __malloc_info and
|
||||
define as weak alias of __malloc_info.
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index c99b26d4a85e1b22..18e00315c6edba4d 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -5007,7 +5007,7 @@ weak_alias (__posix_memalign, posix_memalign)
|
||||
|
||||
|
||||
int
|
||||
-malloc_info (int options, FILE *fp)
|
||||
+__malloc_info (int options, FILE *fp)
|
||||
{
|
||||
/* For now, at least. */
|
||||
if (options != 0)
|
||||
@@ -5180,6 +5180,7 @@ malloc_info (int options, FILE *fp)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+weak_alias (__malloc_info, malloc_info)
|
||||
|
||||
|
||||
strong_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
|
|
@ -0,0 +1,31 @@
|
|||
This is a partial recreation of this upstream commit, restricted to
|
||||
the __malloc_info function:
|
||||
|
||||
commit 4bf5f2224baa1590f92f7a26930928fe9f7e4b57
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 6 12:49:54 2016 +0200
|
||||
|
||||
malloc: Automated part of conversion to __libc_lock
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index 18e00315c6edba4d..d2a5e251da4f1191 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -5049,7 +5049,7 @@ __malloc_info (int options, FILE *fp)
|
||||
} sizes[NFASTBINS + NBINS - 1];
|
||||
#define nsizes (sizeof (sizes) / sizeof (sizes[0]))
|
||||
|
||||
- mutex_lock (&ar_ptr->mutex);
|
||||
+ __libc_lock_lock (ar_ptr->mutex);
|
||||
|
||||
for (size_t i = 0; i < NFASTBINS; ++i)
|
||||
{
|
||||
@@ -5108,7 +5108,7 @@ __malloc_info (int options, FILE *fp)
|
||||
avail += sizes[NFASTBINS - 1 + i].total;
|
||||
}
|
||||
|
||||
- mutex_unlock (&ar_ptr->mutex);
|
||||
+ __libc_lock_unlock (ar_ptr->mutex);
|
||||
|
||||
total_nfastblocks += nfastblocks;
|
||||
total_fastavail += fastavail;
|
|
@ -0,0 +1,175 @@
|
|||
commit 7a9368a1174cb15b9f1d6342e0e10dd90dae238d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Nov 15 11:39:01 2017 +0100
|
||||
|
||||
malloc: Add missing arena lock in malloc_info [BZ #22408]
|
||||
|
||||
Obtain the size information while the arena lock is acquired, and only
|
||||
print it later.
|
||||
|
||||
Conflicts:
|
||||
malloc/Makefile
|
||||
(Differences in available tests.)
|
||||
|
||||
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||
index 992cec6b03115a76..6f216f423293dc6c 100644
|
||||
--- a/malloc/Makefile
|
||||
+++ b/malloc/Makefile
|
||||
@@ -31,6 +31,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
||||
tst-malloc-thread-fail tst-malloc-fork-deadlock \
|
||||
tst-interpose-nothread \
|
||||
tst-interpose-thread \
|
||||
+ tst-malloc_info \
|
||||
tst-interpose-static-nothread \
|
||||
tst-interpose-static-thread \
|
||||
tst-scratch_buffer \
|
||||
@@ -214,3 +215,5 @@ $(objpfx)tst-dynarray-mem: $(objpfx)tst-dynarray.out
|
||||
tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace
|
||||
$(objpfx)tst-dynarray-fail-mem: $(objpfx)tst-dynarray-fail.out
|
||||
$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@
|
||||
+
|
||||
+$(objpfx)tst-malloc_info: $(shared-thread-library)
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index d2a5e251da4f1191..035f2167be7019d8 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -5108,6 +5108,15 @@ __malloc_info (int options, FILE *fp)
|
||||
avail += sizes[NFASTBINS - 1 + i].total;
|
||||
}
|
||||
|
||||
+ size_t heap_size = 0;
|
||||
+ size_t heap_mprotect_size = 0;
|
||||
+ if (ar_ptr != &main_arena)
|
||||
+ {
|
||||
+ heap_info *heap = heap_for_ptr (top (ar_ptr));
|
||||
+ heap_size = heap->size;
|
||||
+ heap_mprotect_size = heap->mprotect_size;
|
||||
+ }
|
||||
+
|
||||
__libc_lock_unlock (ar_ptr->mutex);
|
||||
|
||||
total_nfastblocks += nfastblocks;
|
||||
@@ -5141,13 +5150,12 @@ __malloc_info (int options, FILE *fp)
|
||||
|
||||
if (ar_ptr != &main_arena)
|
||||
{
|
||||
- heap_info *heap = heap_for_ptr (top (ar_ptr));
|
||||
fprintf (fp,
|
||||
"<aspace type=\"total\" size=\"%zu\"/>\n"
|
||||
"<aspace type=\"mprotect\" size=\"%zu\"/>\n",
|
||||
- heap->size, heap->mprotect_size);
|
||||
- total_aspace += heap->size;
|
||||
- total_aspace_mprotect += heap->mprotect_size;
|
||||
+ heap_size, heap_mprotect_size);
|
||||
+ total_aspace += heap_size;
|
||||
+ total_aspace_mprotect += heap_mprotect_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff --git a/malloc/tst-malloc_info.c b/malloc/tst-malloc_info.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a25b8cbeae78e710
|
||||
--- /dev/null
|
||||
+++ b/malloc/tst-malloc_info.c
|
||||
@@ -0,0 +1,101 @@
|
||||
+/* Smoke test for malloc_info.
|
||||
+ Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* The purpose of this test is to provide a quick way to run
|
||||
+ malloc_info in a multi-threaded process. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <malloc.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xthread.h>
|
||||
+
|
||||
+/* This barrier is used to have the main thread wait until the helper
|
||||
+ threads have performed their allocations. */
|
||||
+static pthread_barrier_t barrier;
|
||||
+
|
||||
+enum
|
||||
+ {
|
||||
+ /* Number of threads performing allocations. */
|
||||
+ thread_count = 4,
|
||||
+
|
||||
+ /* Amount of memory allocation per thread. This should be large
|
||||
+ enough to cause the allocation of multiple heaps per arena. */
|
||||
+ per_thread_allocations
|
||||
+ = sizeof (void *) == 4 ? 16 * 1024 * 1024 : 128 * 1024 * 1024,
|
||||
+ };
|
||||
+
|
||||
+static void *
|
||||
+allocation_thread_function (void *closure)
|
||||
+{
|
||||
+ struct list
|
||||
+ {
|
||||
+ struct list *next;
|
||||
+ long dummy[4];
|
||||
+ };
|
||||
+
|
||||
+ struct list *head = NULL;
|
||||
+ size_t allocated = 0;
|
||||
+ while (allocated < per_thread_allocations)
|
||||
+ {
|
||||
+ struct list *new_head = xmalloc (sizeof (*new_head));
|
||||
+ allocated += sizeof (*new_head);
|
||||
+ new_head->next = head;
|
||||
+ head = new_head;
|
||||
+ }
|
||||
+
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+
|
||||
+ /* Main thread prints first statistics here. */
|
||||
+
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+
|
||||
+ while (head != NULL)
|
||||
+ {
|
||||
+ struct list *next_head = head->next;
|
||||
+ free (head);
|
||||
+ head = next_head;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ xpthread_barrier_init (&barrier, NULL, thread_count + 1);
|
||||
+
|
||||
+ pthread_t threads[thread_count];
|
||||
+ for (size_t i = 0; i < array_length (threads); ++i)
|
||||
+ threads[i] = xpthread_create (NULL, allocation_thread_function, NULL);
|
||||
+
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+ puts ("info: After allocation:");
|
||||
+ malloc_info (0, stdout);
|
||||
+
|
||||
+ xpthread_barrier_wait (&barrier);
|
||||
+ for (size_t i = 0; i < array_length (threads); ++i)
|
||||
+ xpthread_join (threads[i]);
|
||||
+
|
||||
+ puts ("\ninfo: After deallocation:");
|
||||
+ malloc_info (0, stdout);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,24 @@
|
|||
commit b0f6679bcd738ea244a14acd879d974901e56c8e
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Aug 1 14:06:24 2019 +0200
|
||||
|
||||
malloc: Remove unwanted leading whitespace in malloc_info [BZ #24867]
|
||||
|
||||
It was introduced in commit 6c8dbf00f536d78b1937b5af6f57be47fd376344
|
||||
("Reformat malloc to gnu style.").
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index 035f2167be7019d8..ffa0f7f00152f339 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -5127,7 +5127,7 @@ __malloc_info (int options, FILE *fp)
|
||||
|
||||
for (size_t i = 0; i < nsizes; ++i)
|
||||
if (sizes[i].count != 0 && i != NFASTBINS)
|
||||
- fprintf (fp, " \
|
||||
+ fprintf (fp, "\
|
||||
<size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
|
||||
sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
|
||||
|
|
@ -0,0 +1,834 @@
|
|||
Note: The __pthread_once definition in the new unified implementation in
|
||||
this patch has been edited. The original version of the patch had an old
|
||||
style declaration that was causing a -Werror=old-style-definition failure.
|
||||
|
||||
commit 36875b06e0ed7f137190b9228bef553adfc338ba
|
||||
Author: Torvald Riegel <triegel@redhat.com>
|
||||
Date: Wed May 8 16:35:10 2013 +0200
|
||||
|
||||
Fixed and unified pthread_once.
|
||||
|
||||
[BZ #15215] This unifies various pthread_once architecture-specific
|
||||
implementations which were using the same algorithm with slightly different
|
||||
implementations. It also adds missing memory barriers that are required for
|
||||
correctness.
|
||||
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..2684b660958361d4
|
||||
--- /dev/null
|
||||
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
|
||||
@@ -0,0 +1,129 @@
|
||||
+/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "pthreadP.h"
|
||||
+#include <lowlevellock.h>
|
||||
+#include <atomic.h>
|
||||
+
|
||||
+
|
||||
+unsigned long int __fork_generation attribute_hidden;
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+clear_once_control (void *arg)
|
||||
+{
|
||||
+ pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
+
|
||||
+ /* Reset to the uninitialized state here. We don't need a stronger memory
|
||||
+ order because we do not need to make any other of our writes visible to
|
||||
+ other threads that see this value: This function will be called if we
|
||||
+ get interrupted (see __pthread_once), so all we need to relay to other
|
||||
+ threads is the state being reset again. */
|
||||
+ *once_control = 0;
|
||||
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* This is similar to a lock implementation, but we distinguish between three
|
||||
+ states: not yet initialized (0), initialization finished (2), and
|
||||
+ initialization in progress (__fork_generation | 1). If in the first state,
|
||||
+ threads will try to run the initialization by moving to the second state;
|
||||
+ the first thread to do so via a CAS on once_control runs init_routine,
|
||||
+ other threads block.
|
||||
+ When forking the process, some threads can be interrupted during the second
|
||||
+ state; they won't be present in the forked child, so we need to restart
|
||||
+ initialization in the child. To distinguish an in-progress initialization
|
||||
+ from an interrupted initialization (in which case we need to reclaim the
|
||||
+ lock), we look at the fork generation that's part of the second state: We
|
||||
+ can reclaim iff it differs from the current fork generation.
|
||||
+ XXX: This algorithm has an ABA issue on the fork generation: If an
|
||||
+ initialization is interrupted, we then fork 2^30 times (30 bits of
|
||||
+ once_control are used for the fork generation), and try to initialize
|
||||
+ again, we can deadlock because we can't distinguish the in-progress and
|
||||
+ interrupted cases anymore. */
|
||||
+int
|
||||
+__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
+{
|
||||
+ while (1)
|
||||
+ {
|
||||
+ int oldval, val, newval;
|
||||
+
|
||||
+ /* We need acquire memory order for this load because if the value
|
||||
+ signals that initialization has finished, we need to be see any
|
||||
+ data modifications done during initialization. */
|
||||
+ val = *once_control;
|
||||
+ atomic_read_barrier();
|
||||
+ do
|
||||
+ {
|
||||
+ /* Check if the initialization has already been done. */
|
||||
+ if (__glibc_likely ((val & 2) != 0))
|
||||
+ return 0;
|
||||
+
|
||||
+ oldval = val;
|
||||
+ /* We try to set the state to in-progress and having the current
|
||||
+ fork generation. We don't need atomic accesses for the fork
|
||||
+ generation because it's immutable in a particular process, and
|
||||
+ forked child processes start with a single thread that modified
|
||||
+ the generation. */
|
||||
+ newval = __fork_generation | 1;
|
||||
+ /* We need acquire memory order here for the same reason as for the
|
||||
+ load from once_control above. */
|
||||
+ val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
+ oldval);
|
||||
+ }
|
||||
+ while (__glibc_unlikely (val != oldval));
|
||||
+
|
||||
+ /* Check if another thread already runs the initializer. */
|
||||
+ if ((oldval & 1) != 0)
|
||||
+ {
|
||||
+ /* Check whether the initializer execution was interrupted by a
|
||||
+ fork. We know that for both values, bit 0 is set and bit 1 is
|
||||
+ not. */
|
||||
+ if (oldval == newval)
|
||||
+ {
|
||||
+ /* Same generation, some other thread was faster. Wait. */
|
||||
+ lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* This thread is the first here. Do the initialization.
|
||||
+ Register a cleanup handler so that in case the thread gets
|
||||
+ interrupted the initialization can be restarted. */
|
||||
+ pthread_cleanup_push (clear_once_control, once_control);
|
||||
+
|
||||
+ init_routine ();
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+
|
||||
+
|
||||
+ /* Mark *once_control as having finished the initialization. We need
|
||||
+ release memory order here because we need to synchronize with other
|
||||
+ threads that want to use the initialized data. */
|
||||
+ atomic_write_barrier();
|
||||
+ *once_control = 2;
|
||||
+
|
||||
+ /* Wake up all other threads. */
|
||||
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+weak_alias (__pthread_once, pthread_once)
|
||||
+hidden_def (__pthread_once)
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index a2111756374174f2..0000000000000000
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,93 +0,0 @@
|
||||
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-__pthread_once (once_control, init_routine)
|
||||
- pthread_once_t *once_control;
|
||||
- void (*init_routine) (void);
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- int oldval, val, newval;
|
||||
-
|
||||
- val = *once_control;
|
||||
- do
|
||||
- {
|
||||
- /* Check if the initialized has already been done. */
|
||||
- if ((val & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- oldval = val;
|
||||
- newval = (oldval & 3) | __fork_generation | 1;
|
||||
- val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
- oldval);
|
||||
- }
|
||||
- while (__builtin_expect (val != oldval, 0));
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
- {
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- if (((oldval ^ newval) & -4) == 0)
|
||||
- {
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Add one to *once_control. */
|
||||
- atomic_increment (once_control);
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/aarch64/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/aarch64/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 0897e1e004ef3278..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/aarch64/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,90 +0,0 @@
|
||||
-/* Copyright (C) 2004-2012 Free Software Foundation, Inc.
|
||||
-
|
||||
- This file is part of the GNU C Library.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public License as
|
||||
- published by the Free Software Foundation; either version 2.1 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
-{
|
||||
- for (;;)
|
||||
- {
|
||||
- int oldval;
|
||||
- int newval;
|
||||
-
|
||||
- /* Pseudo code:
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if ((oldval & 2) == 0)
|
||||
- *once_control = newval;
|
||||
- Do this atomically.
|
||||
- */
|
||||
- do
|
||||
- {
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if (oldval & 2)
|
||||
- break;
|
||||
- } while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
|
||||
-
|
||||
- /* Check if the initializer has already been done. */
|
||||
- if ((oldval & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) == 0)
|
||||
- break;
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted by a fork. */
|
||||
- if (oldval != newval)
|
||||
- break;
|
||||
-
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, oldval, LLL_PRIVATE);
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
- /* Say that the initialisation is done. */
|
||||
- *once_control = __fork_generation | 2;
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 0c03f1c816a2fad5..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,89 +0,0 @@
|
||||
-/* Copyright (C) 2004-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library. If not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
-{
|
||||
- for (;;)
|
||||
- {
|
||||
- int oldval;
|
||||
- int newval;
|
||||
-
|
||||
- /* Pseudo code:
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if ((oldval & 2) == 0)
|
||||
- *once_control = newval;
|
||||
- Do this atomically.
|
||||
- */
|
||||
- do
|
||||
- {
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if (oldval & 2)
|
||||
- break;
|
||||
- } while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
|
||||
-
|
||||
- /* Check if the initializer has already been done. */
|
||||
- if ((oldval & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) == 0)
|
||||
- break;
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted by a fork. */
|
||||
- if (oldval != newval)
|
||||
- break;
|
||||
-
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, oldval, LLL_PRIVATE);
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
- /* Say that the initialisation is done. */
|
||||
- *once_control = __fork_generation | 2;
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/ia64/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/ia64/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 7730935dfec85ae6..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,93 +0,0 @@
|
||||
-/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-__pthread_once (once_control, init_routine)
|
||||
- pthread_once_t *once_control;
|
||||
- void (*init_routine) (void);
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- int oldval, val, newval;
|
||||
-
|
||||
- val = *once_control;
|
||||
- do
|
||||
- {
|
||||
- /* Check if the initialized has already been done. */
|
||||
- if ((val & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- oldval = val;
|
||||
- newval = (oldval & 3) | __fork_generation | 1;
|
||||
- val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
- oldval);
|
||||
- }
|
||||
- while (__builtin_expect (val != oldval, 0));
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
- {
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- if (((oldval ^ newval) & -4) == 0)
|
||||
- {
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Add one to *once_control. */
|
||||
- atomic_increment (once_control);
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/m68k/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/m68k/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 8d81db602eee601f..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/m68k/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,90 +0,0 @@
|
||||
-/* Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library. If not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
-{
|
||||
- for (;;)
|
||||
- {
|
||||
- int oldval;
|
||||
- int newval;
|
||||
-
|
||||
- /* Pseudo code:
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if ((oldval & 2) == 0)
|
||||
- *once_control = newval;
|
||||
- Do this atomically.
|
||||
- */
|
||||
- do
|
||||
- {
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if (oldval & 2)
|
||||
- break;
|
||||
- } while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
|
||||
-
|
||||
- /* Check if the initializer has already been done. */
|
||||
- if ((oldval & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) == 0)
|
||||
- break;
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted by a fork. */
|
||||
- if (oldval != newval)
|
||||
- break;
|
||||
-
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, oldval, LLL_PRIVATE);
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
- /* Say that the initialisation is done. */
|
||||
- *once_control = __fork_generation | 2;
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 308da8bbce0c3800..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,93 +0,0 @@
|
||||
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library. If not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-__pthread_once (once_control, init_routine)
|
||||
- pthread_once_t *once_control;
|
||||
- void (*init_routine) (void);
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- int oldval, val, newval;
|
||||
-
|
||||
- val = *once_control;
|
||||
- do
|
||||
- {
|
||||
- /* Check if the initialized has already been done. */
|
||||
- if ((val & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- oldval = val;
|
||||
- newval = (oldval & 3) | __fork_generation | 1;
|
||||
- val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
- oldval);
|
||||
- }
|
||||
- while (__builtin_expect (val != oldval, 0));
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
- {
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- if (((oldval ^ newval) & -4) == 0)
|
||||
- {
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Add one to *once_control. */
|
||||
- atomic_increment (once_control);
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 93ac29b24c440b2c..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,94 +0,0 @@
|
||||
-/* Copyright (C) 2011-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
|
||||
- Based on work contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library. If not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <nptl/pthreadP.h>
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-__pthread_once (once_control, init_routine)
|
||||
- pthread_once_t *once_control;
|
||||
- void (*init_routine) (void);
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- int oldval, val, newval;
|
||||
-
|
||||
- val = *once_control;
|
||||
- do
|
||||
- {
|
||||
- /* Check if the initialized has already been done. */
|
||||
- if ((val & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- oldval = val;
|
||||
- newval = (oldval & 3) | __fork_generation | 1;
|
||||
- val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
- oldval);
|
||||
- }
|
||||
- while (__builtin_expect (val != oldval, 0));
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
- {
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- if (((oldval ^ newval) & -4) == 0)
|
||||
- {
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Add one to *once_control. */
|
||||
- atomic_increment (once_control);
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
|
@ -0,0 +1,294 @@
|
|||
This patch is based on the below upstream commit.
|
||||
It only includes relevant pthread_once bits.
|
||||
|
||||
commit 08192659bbeae149e7cb1f4c43547257f7099bb0
|
||||
Author: Roland McGrath <roland@hack.frob.com>
|
||||
Date: Mon Jul 7 09:28:38 2014 -0700
|
||||
|
||||
Get rid of nptl/sysdeps/ entirely!
|
||||
|
||||
diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
|
||||
index ed1ea3498c397e5c..10c01d6023508e3c 100644
|
||||
--- a/nptl/pthread_once.c
|
||||
+++ b/nptl/pthread_once.c
|
||||
@@ -1,6 +1,6 @@
|
||||
-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||
+/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
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
|
||||
+ 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
|
||||
@@ -18,37 +18,114 @@
|
||||
|
||||
#include "pthreadP.h"
|
||||
#include <lowlevellock.h>
|
||||
+#include <atomic.h>
|
||||
|
||||
|
||||
+unsigned long int __fork_generation attribute_hidden;
|
||||
|
||||
-static int once_lock = LLL_LOCK_INITIALIZER;
|
||||
|
||||
+static void
|
||||
+clear_once_control (void *arg)
|
||||
+{
|
||||
+ pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
+
|
||||
+ /* Reset to the uninitialized state here. We don't need a stronger memory
|
||||
+ order because we do not need to make any other of our writes visible to
|
||||
+ other threads that see this value: This function will be called if we
|
||||
+ get interrupted (see __pthread_once), so all we need to relay to other
|
||||
+ threads is the state being reset again. */
|
||||
+ *once_control = 0;
|
||||
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
+}
|
||||
|
||||
+
|
||||
+/* This is similar to a lock implementation, but we distinguish between three
|
||||
+ states: not yet initialized (0), initialization finished (2), and
|
||||
+ initialization in progress (__fork_generation | 1). If in the first state,
|
||||
+ threads will try to run the initialization by moving to the second state;
|
||||
+ the first thread to do so via a CAS on once_control runs init_routine,
|
||||
+ other threads block.
|
||||
+ When forking the process, some threads can be interrupted during the second
|
||||
+ state; they won't be present in the forked child, so we need to restart
|
||||
+ initialization in the child. To distinguish an in-progress initialization
|
||||
+ from an interrupted initialization (in which case we need to reclaim the
|
||||
+ lock), we look at the fork generation that's part of the second state: We
|
||||
+ can reclaim iff it differs from the current fork generation.
|
||||
+ XXX: This algorithm has an ABA issue on the fork generation: If an
|
||||
+ initialization is interrupted, we then fork 2^30 times (30 bits of
|
||||
+ once_control are used for the fork generation), and try to initialize
|
||||
+ again, we can deadlock because we can't distinguish the in-progress and
|
||||
+ interrupted cases anymore. */
|
||||
int
|
||||
__pthread_once (once_control, init_routine)
|
||||
pthread_once_t *once_control;
|
||||
void (*init_routine) (void);
|
||||
{
|
||||
- /* XXX Depending on whether the LOCK_IN_ONCE_T is defined use a
|
||||
- global lock variable or one which is part of the pthread_once_t
|
||||
- object. */
|
||||
- if (*once_control == PTHREAD_ONCE_INIT)
|
||||
+ while (1)
|
||||
{
|
||||
- lll_lock (once_lock, LLL_PRIVATE);
|
||||
+ int oldval, val, newval;
|
||||
|
||||
- /* XXX This implementation is not complete. It doesn't take
|
||||
- cancelation and fork into account. */
|
||||
- if (*once_control == PTHREAD_ONCE_INIT)
|
||||
+ /* We need acquire memory order for this load because if the value
|
||||
+ signals that initialization has finished, we need to be see any
|
||||
+ data modifications done during initialization. */
|
||||
+ val = *once_control;
|
||||
+ atomic_read_barrier();
|
||||
+ do
|
||||
{
|
||||
- init_routine ();
|
||||
+ /* Check if the initialization has already been done. */
|
||||
+ if (__glibc_likely ((val & 2) != 0))
|
||||
+ return 0;
|
||||
+
|
||||
+ oldval = val;
|
||||
+ /* We try to set the state to in-progress and having the current
|
||||
+ fork generation. We don't need atomic accesses for the fork
|
||||
+ generation because it's immutable in a particular process, and
|
||||
+ forked child processes start with a single thread that modified
|
||||
+ the generation. */
|
||||
+ newval = __fork_generation | 1;
|
||||
+ /* We need acquire memory order here for the same reason as for the
|
||||
+ load from once_control above. */
|
||||
+ val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
+ oldval);
|
||||
+ }
|
||||
+ while (__glibc_unlikely (val != oldval));
|
||||
|
||||
- *once_control = !PTHREAD_ONCE_INIT;
|
||||
+ /* Check if another thread already runs the initializer. */
|
||||
+ if ((oldval & 1) != 0)
|
||||
+ {
|
||||
+ /* Check whether the initializer execution was interrupted by a
|
||||
+ fork. We know that for both values, bit 0 is set and bit 1 is
|
||||
+ not. */
|
||||
+ if (oldval == newval)
|
||||
+ {
|
||||
+ /* Same generation, some other thread was faster. Wait. */
|
||||
+ lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
+ continue;
|
||||
+ }
|
||||
}
|
||||
|
||||
- lll_unlock (once_lock, LLL_PRIVATE);
|
||||
+ /* This thread is the first here. Do the initialization.
|
||||
+ Register a cleanup handler so that in case the thread gets
|
||||
+ interrupted the initialization can be restarted. */
|
||||
+ pthread_cleanup_push (clear_once_control, once_control);
|
||||
+
|
||||
+ init_routine ();
|
||||
+
|
||||
+ pthread_cleanup_pop (0);
|
||||
+
|
||||
+
|
||||
+ /* Mark *once_control as having finished the initialization. We need
|
||||
+ release memory order here because we need to synchronize with other
|
||||
+ threads that want to use the initialized data. */
|
||||
+ atomic_write_barrier();
|
||||
+ *once_control = 2;
|
||||
+
|
||||
+ /* Wake up all other threads. */
|
||||
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
+ break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
-strong_alias (__pthread_once, pthread_once)
|
||||
+weak_alias (__pthread_once, pthread_once)
|
||||
hidden_def (__pthread_once)
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 2684b660958361d4..0000000000000000
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,129 +0,0 @@
|
||||
-/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-#include <atomic.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- /* Reset to the uninitialized state here. We don't need a stronger memory
|
||||
- order because we do not need to make any other of our writes visible to
|
||||
- other threads that see this value: This function will be called if we
|
||||
- get interrupted (see __pthread_once), so all we need to relay to other
|
||||
- threads is the state being reset again. */
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* This is similar to a lock implementation, but we distinguish between three
|
||||
- states: not yet initialized (0), initialization finished (2), and
|
||||
- initialization in progress (__fork_generation | 1). If in the first state,
|
||||
- threads will try to run the initialization by moving to the second state;
|
||||
- the first thread to do so via a CAS on once_control runs init_routine,
|
||||
- other threads block.
|
||||
- When forking the process, some threads can be interrupted during the second
|
||||
- state; they won't be present in the forked child, so we need to restart
|
||||
- initialization in the child. To distinguish an in-progress initialization
|
||||
- from an interrupted initialization (in which case we need to reclaim the
|
||||
- lock), we look at the fork generation that's part of the second state: We
|
||||
- can reclaim iff it differs from the current fork generation.
|
||||
- XXX: This algorithm has an ABA issue on the fork generation: If an
|
||||
- initialization is interrupted, we then fork 2^30 times (30 bits of
|
||||
- once_control are used for the fork generation), and try to initialize
|
||||
- again, we can deadlock because we can't distinguish the in-progress and
|
||||
- interrupted cases anymore. */
|
||||
-int
|
||||
-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- int oldval, val, newval;
|
||||
-
|
||||
- /* We need acquire memory order for this load because if the value
|
||||
- signals that initialization has finished, we need to be see any
|
||||
- data modifications done during initialization. */
|
||||
- val = *once_control;
|
||||
- atomic_read_barrier();
|
||||
- do
|
||||
- {
|
||||
- /* Check if the initialization has already been done. */
|
||||
- if (__glibc_likely ((val & 2) != 0))
|
||||
- return 0;
|
||||
-
|
||||
- oldval = val;
|
||||
- /* We try to set the state to in-progress and having the current
|
||||
- fork generation. We don't need atomic accesses for the fork
|
||||
- generation because it's immutable in a particular process, and
|
||||
- forked child processes start with a single thread that modified
|
||||
- the generation. */
|
||||
- newval = __fork_generation | 1;
|
||||
- /* We need acquire memory order here for the same reason as for the
|
||||
- load from once_control above. */
|
||||
- val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
- oldval);
|
||||
- }
|
||||
- while (__glibc_unlikely (val != oldval));
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
- {
|
||||
- /* Check whether the initializer execution was interrupted by a
|
||||
- fork. We know that for both values, bit 0 is set and bit 1 is
|
||||
- not. */
|
||||
- if (oldval == newval)
|
||||
- {
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Mark *once_control as having finished the initialization. We need
|
||||
- release memory order here because we need to synchronize with other
|
||||
- threads that want to use the initialized data. */
|
||||
- atomic_write_barrier();
|
||||
- *once_control = 2;
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
|
@ -0,0 +1,108 @@
|
|||
commit 63668b7084ac26865136e59fdf17781f9f49bd99
|
||||
Author: Torvald Riegel <triegel@redhat.com>
|
||||
Date: Fri Oct 11 18:58:04 2013 +0300
|
||||
|
||||
pthread_once: Clean up constants.
|
||||
|
||||
[BZ #15215] This just gives a name to the integer constants being used.
|
||||
|
||||
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
|
||||
index dda1032d5aa95234..1a842e06bff82479 100644
|
||||
--- a/nptl/pthreadP.h
|
||||
+++ b/nptl/pthreadP.h
|
||||
@@ -159,6 +159,12 @@ enum
|
||||
#define FUTEX_TID_MASK 0x3fffffff
|
||||
|
||||
|
||||
+/* pthread_once definitions. See __pthread_once for how these are used. */
|
||||
+#define __PTHREAD_ONCE_INPROGRESS 1
|
||||
+#define __PTHREAD_ONCE_DONE 2
|
||||
+#define __PTHREAD_ONCE_FORK_GEN_INCR 4
|
||||
+
|
||||
+
|
||||
/* Internal variables. */
|
||||
|
||||
|
||||
diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
|
||||
index 10c01d6023508e3c..595bd7e298003e00 100644
|
||||
--- a/nptl/pthread_once.c
|
||||
+++ b/nptl/pthread_once.c
|
||||
@@ -40,8 +40,11 @@ clear_once_control (void *arg)
|
||||
|
||||
|
||||
/* This is similar to a lock implementation, but we distinguish between three
|
||||
- states: not yet initialized (0), initialization finished (2), and
|
||||
- initialization in progress (__fork_generation | 1). If in the first state,
|
||||
+ states: not yet initialized (0), initialization in progress
|
||||
+ (__fork_generation | __PTHREAD_ONCE_INPROGRESS), and initialization
|
||||
+ finished (__PTHREAD_ONCE_DONE); __fork_generation does not use the bits
|
||||
+ that are used for __PTHREAD_ONCE_INPROGRESS and __PTHREAD_ONCE_DONE (which
|
||||
+ is what __PTHREAD_ONCE_FORK_GEN_INCR is used for). If in the first state,
|
||||
threads will try to run the initialization by moving to the second state;
|
||||
the first thread to do so via a CAS on once_control runs init_routine,
|
||||
other threads block.
|
||||
@@ -66,14 +69,14 @@ __pthread_once (once_control, init_routine)
|
||||
int oldval, val, newval;
|
||||
|
||||
/* We need acquire memory order for this load because if the value
|
||||
- signals that initialization has finished, we need to be see any
|
||||
+ signals that initialization has finished, we need to see any
|
||||
data modifications done during initialization. */
|
||||
val = *once_control;
|
||||
atomic_read_barrier();
|
||||
do
|
||||
{
|
||||
/* Check if the initialization has already been done. */
|
||||
- if (__glibc_likely ((val & 2) != 0))
|
||||
+ if (__glibc_likely ((val & __PTHREAD_ONCE_DONE) != 0))
|
||||
return 0;
|
||||
|
||||
oldval = val;
|
||||
@@ -82,7 +85,7 @@ __pthread_once (once_control, init_routine)
|
||||
generation because it's immutable in a particular process, and
|
||||
forked child processes start with a single thread that modified
|
||||
the generation. */
|
||||
- newval = __fork_generation | 1;
|
||||
+ newval = __fork_generation | __PTHREAD_ONCE_INPROGRESS;
|
||||
/* We need acquire memory order here for the same reason as for the
|
||||
load from once_control above. */
|
||||
val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
@@ -91,11 +94,11 @@ __pthread_once (once_control, init_routine)
|
||||
while (__glibc_unlikely (val != oldval));
|
||||
|
||||
/* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
+ if ((oldval & __PTHREAD_ONCE_INPROGRESS) != 0)
|
||||
{
|
||||
/* Check whether the initializer execution was interrupted by a
|
||||
- fork. We know that for both values, bit 0 is set and bit 1 is
|
||||
- not. */
|
||||
+ fork. We know that for both values, __PTHREAD_ONCE_INPROGRESS
|
||||
+ is set and __PTHREAD_ONCE_DONE is not. */
|
||||
if (oldval == newval)
|
||||
{
|
||||
/* Same generation, some other thread was faster. Wait. */
|
||||
@@ -118,7 +121,7 @@ __pthread_once (once_control, init_routine)
|
||||
release memory order here because we need to synchronize with other
|
||||
threads that want to use the initialized data. */
|
||||
atomic_write_barrier();
|
||||
- *once_control = 2;
|
||||
+ *once_control = __PTHREAD_ONCE_DONE;
|
||||
|
||||
/* Wake up all other threads. */
|
||||
lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
|
||||
index 0635bfdb6cdf0aa8..8c197cb8e4347959 100644
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
|
||||
+++ b/nptl/sysdeps/unix/sysv/linux/fork.c
|
||||
@@ -146,8 +146,9 @@ __libc_fork (void)
|
||||
|
||||
assert (THREAD_GETMEM (self, tid) != ppid);
|
||||
|
||||
+ /* See __pthread_once. */
|
||||
if (__fork_generation_pointer != NULL)
|
||||
- *__fork_generation_pointer += 4;
|
||||
+ *__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
|
||||
|
||||
/* Adjust the PID field for the new process. */
|
||||
THREAD_SETMEM (self, pid, THREAD_GETMEM (self, tid));
|
|
@ -0,0 +1,443 @@
|
|||
This patch is based on the below upstream commit.
|
||||
File deletions were altered to reflect file renames.
|
||||
|
||||
commit f50277c19df0937ea9691ab7e7c642ecd3ed3d94
|
||||
Author: Torvald Riegel <triegel@redhat.com>
|
||||
Date: Sun Oct 19 21:59:26 2014 +0200
|
||||
|
||||
pthread_once: Add fast path and remove x86 variants.
|
||||
|
||||
diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
|
||||
index 595bd7e298003e00..2afb79c01fe0a61e 100644
|
||||
--- a/nptl/pthread_once.c
|
||||
+++ b/nptl/pthread_once.c
|
||||
@@ -58,11 +58,13 @@ clear_once_control (void *arg)
|
||||
initialization is interrupted, we then fork 2^30 times (30 bits of
|
||||
once_control are used for the fork generation), and try to initialize
|
||||
again, we can deadlock because we can't distinguish the in-progress and
|
||||
- interrupted cases anymore. */
|
||||
-int
|
||||
-__pthread_once (once_control, init_routine)
|
||||
- pthread_once_t *once_control;
|
||||
- void (*init_routine) (void);
|
||||
+ interrupted cases anymore.
|
||||
+ XXX: We split out this slow path because current compilers do not generate
|
||||
+ as efficient code when the fast path in __pthread_once below is not in a
|
||||
+ separate function. */
|
||||
+static int
|
||||
+__attribute__ ((noinline))
|
||||
+__pthread_once_slow (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
@@ -72,7 +74,7 @@ __pthread_once (once_control, init_routine)
|
||||
signals that initialization has finished, we need to see any
|
||||
data modifications done during initialization. */
|
||||
val = *once_control;
|
||||
- atomic_read_barrier();
|
||||
+ atomic_read_barrier ();
|
||||
do
|
||||
{
|
||||
/* Check if the initialization has already been done. */
|
||||
@@ -130,5 +132,18 @@ __pthread_once (once_control, init_routine)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
+{
|
||||
+ /* Fast path. See __pthread_once_slow. */
|
||||
+ int val;
|
||||
+ val = *once_control;
|
||||
+ atomic_read_barrier ();
|
||||
+ if (__glibc_likely ((val & __PTHREAD_ONCE_DONE) != 0))
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return __pthread_once_slow (once_control, init_routine);
|
||||
+}
|
||||
weak_alias (__pthread_once, pthread_once)
|
||||
hidden_def (__pthread_once)
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
|
||||
deleted file mode 100644
|
||||
index ca3b860a7f6f95ae..0000000000000000
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
|
||||
+++ /dev/null
|
||||
@@ -1,178 +0,0 @@
|
||||
-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <unwindbuf.h>
|
||||
-#include <sysdep.h>
|
||||
-#include <kernel-features.h>
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
- .comm __fork_generation, 4, 4
|
||||
-
|
||||
- .text
|
||||
-
|
||||
-
|
||||
- .globl __pthread_once
|
||||
- .type __pthread_once,@function
|
||||
- .align 16
|
||||
- cfi_startproc
|
||||
-__pthread_once:
|
||||
- movl 4(%esp), %ecx
|
||||
- testl $2, (%ecx)
|
||||
- jz 1f
|
||||
- xorl %eax, %eax
|
||||
- ret
|
||||
-
|
||||
-1: pushl %ebx
|
||||
- cfi_adjust_cfa_offset (4)
|
||||
- cfi_rel_offset (3, 0)
|
||||
- pushl %esi
|
||||
- cfi_adjust_cfa_offset (4)
|
||||
- cfi_rel_offset (6, 0)
|
||||
- movl %ecx, %ebx
|
||||
- xorl %esi, %esi
|
||||
-
|
||||
- /* Not yet initialized or initialization in progress.
|
||||
- Get the fork generation counter now. */
|
||||
-6: movl (%ebx), %eax
|
||||
-#ifdef PIC
|
||||
- LOAD_PIC_REG(cx)
|
||||
-#endif
|
||||
-
|
||||
-5: movl %eax, %edx
|
||||
-
|
||||
- testl $2, %eax
|
||||
- jnz 4f
|
||||
-
|
||||
- andl $3, %edx
|
||||
-#ifdef PIC
|
||||
- orl __fork_generation@GOTOFF(%ecx), %edx
|
||||
-#else
|
||||
- orl __fork_generation, %edx
|
||||
-#endif
|
||||
- orl $1, %edx
|
||||
-
|
||||
- LOCK
|
||||
- cmpxchgl %edx, (%ebx)
|
||||
- jnz 5b
|
||||
-
|
||||
- /* Check whether another thread already runs the initializer. */
|
||||
- testl $1, %eax
|
||||
- jz 3f /* No -> do it. */
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- xorl %edx, %eax
|
||||
- testl $0xfffffffc, %eax
|
||||
- jnz 3f /* Different for generation -> run initializer. */
|
||||
-
|
||||
- /* Somebody else got here first. Wait. */
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- movl $FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %ecx
|
||||
-#else
|
||||
-# if FUTEX_WAIT == 0
|
||||
- movl %gs:PRIVATE_FUTEX, %ecx
|
||||
-# else
|
||||
- movl $FUTEX_WAIT, %ecx
|
||||
- orl %gs:PRIVATE_FUTEX, %ecx
|
||||
-# endif
|
||||
-#endif
|
||||
- movl $SYS_futex, %eax
|
||||
- ENTER_KERNEL
|
||||
- jmp 6b
|
||||
-
|
||||
-3: /* Call the initializer function after setting up the
|
||||
- cancellation handler. Note that it is not possible here
|
||||
- to use the unwind-based cleanup handling. This would require
|
||||
- that the user-provided function and all the code it calls
|
||||
- is compiled with exceptions. Unfortunately this cannot be
|
||||
- guaranteed. */
|
||||
- subl $UNWINDBUFSIZE+8, %esp
|
||||
- cfi_adjust_cfa_offset (UNWINDBUFSIZE+8)
|
||||
- movl %ecx, %ebx /* PIC register value. */
|
||||
-
|
||||
- leal 8+UWJMPBUF(%esp), %eax
|
||||
- movl $0, 4(%esp)
|
||||
- movl %eax, (%esp)
|
||||
- call __sigsetjmp@PLT
|
||||
- testl %eax, %eax
|
||||
- jne 7f
|
||||
-
|
||||
- leal 8(%esp), %eax
|
||||
- call HIDDEN_JUMPTARGET(__pthread_register_cancel)
|
||||
-
|
||||
- /* Call the user-provided initialization function. */
|
||||
- call *24+UNWINDBUFSIZE(%esp)
|
||||
-
|
||||
- /* Pop the cleanup handler. */
|
||||
- leal 8(%esp), %eax
|
||||
- call HIDDEN_JUMPTARGET(__pthread_unregister_cancel)
|
||||
- addl $UNWINDBUFSIZE+8, %esp
|
||||
- cfi_adjust_cfa_offset (-UNWINDBUFSIZE-8)
|
||||
-
|
||||
- /* Sucessful run of the initializer. Signal that we are done. */
|
||||
- movl 12(%esp), %ebx
|
||||
- LOCK
|
||||
- addl $1, (%ebx)
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- movl $0x7fffffff, %edx
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
|
||||
-#else
|
||||
- movl $FUTEX_WAKE, %ecx
|
||||
- orl %gs:PRIVATE_FUTEX, %ecx
|
||||
-#endif
|
||||
- movl $SYS_futex, %eax
|
||||
- ENTER_KERNEL
|
||||
-
|
||||
-4: popl %esi
|
||||
- cfi_adjust_cfa_offset (-4)
|
||||
- cfi_restore (6)
|
||||
- popl %ebx
|
||||
- cfi_adjust_cfa_offset (-4)
|
||||
- cfi_restore (3)
|
||||
- xorl %eax, %eax
|
||||
- ret
|
||||
-
|
||||
-7: /* __sigsetjmp returned for the second time. */
|
||||
- movl 20+UNWINDBUFSIZE(%esp), %ebx
|
||||
- cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
|
||||
- cfi_offset (3, -8)
|
||||
- cfi_offset (6, -12)
|
||||
- movl $0, (%ebx)
|
||||
-
|
||||
- movl $0x7fffffff, %edx
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
|
||||
-#else
|
||||
- movl $FUTEX_WAKE, %ecx
|
||||
- orl %gs:PRIVATE_FUTEX, %ecx
|
||||
-#endif
|
||||
- movl $SYS_futex, %eax
|
||||
- ENTER_KERNEL
|
||||
-
|
||||
- leal 8(%esp), %eax
|
||||
- call HIDDEN_JUMPTARGET (__pthread_unwind_next)
|
||||
- /* NOTREACHED */
|
||||
- hlt
|
||||
- cfi_endproc
|
||||
- .size __pthread_once,.-__pthread_once
|
||||
-
|
||||
-hidden_def (__pthread_once)
|
||||
-strong_alias (__pthread_once, pthread_once)
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
|
||||
deleted file mode 100644
|
||||
index 7f5c0810fa16b987..0000000000000000
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
|
||||
+++ /dev/null
|
||||
@@ -1,193 +0,0 @@
|
||||
-/* Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <sysdep.h>
|
||||
-#include <kernel-features.h>
|
||||
-#include <tcb-offsets.h>
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
- .comm __fork_generation, 4, 4
|
||||
-
|
||||
- .text
|
||||
-
|
||||
-
|
||||
- .globl __pthread_once
|
||||
- .type __pthread_once,@function
|
||||
- .align 16
|
||||
-__pthread_once:
|
||||
-.LSTARTCODE:
|
||||
- cfi_startproc
|
||||
-#ifdef SHARED
|
||||
- cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
|
||||
- DW.ref.__gcc_personality_v0)
|
||||
- cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
|
||||
-#else
|
||||
- cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
|
||||
- cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
|
||||
-#endif
|
||||
- testl $2, (%rdi)
|
||||
- jz 1f
|
||||
- xorl %eax, %eax
|
||||
- retq
|
||||
-
|
||||
- /* Preserve the function pointer. */
|
||||
-1: pushq %rsi
|
||||
- cfi_adjust_cfa_offset(8)
|
||||
- xorq %r10, %r10
|
||||
-
|
||||
- /* Not yet initialized or initialization in progress.
|
||||
- Get the fork generation counter now. */
|
||||
-6: movl (%rdi), %eax
|
||||
-
|
||||
-5: movl %eax, %edx
|
||||
-
|
||||
- testl $2, %eax
|
||||
- jnz 4f
|
||||
-
|
||||
- andl $3, %edx
|
||||
- orl __fork_generation(%rip), %edx
|
||||
- orl $1, %edx
|
||||
-
|
||||
- LOCK
|
||||
- cmpxchgl %edx, (%rdi)
|
||||
- jnz 5b
|
||||
-
|
||||
- /* Check whether another thread already runs the initializer. */
|
||||
- testl $1, %eax
|
||||
- jz 3f /* No -> do it. */
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- xorl %edx, %eax
|
||||
- testl $0xfffffffc, %eax
|
||||
- jnz 3f /* Different for generation -> run initializer. */
|
||||
-
|
||||
- /* Somebody else got here first. Wait. */
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- movl $FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %esi
|
||||
-#else
|
||||
-# if FUTEX_WAIT == 0
|
||||
- movl %fs:PRIVATE_FUTEX, %esi
|
||||
-# else
|
||||
- movl $FUTEX_WAIT, %esi
|
||||
- orl %fs:PRIVATE_FUTEX, %esi
|
||||
-# endif
|
||||
-#endif
|
||||
- movl $SYS_futex, %eax
|
||||
- syscall
|
||||
- jmp 6b
|
||||
-
|
||||
- /* Preserve the pointer to the control variable. */
|
||||
-3: pushq %rdi
|
||||
- cfi_adjust_cfa_offset(8)
|
||||
- pushq %rdi
|
||||
- cfi_adjust_cfa_offset(8)
|
||||
-
|
||||
-.LcleanupSTART:
|
||||
- callq *16(%rsp)
|
||||
-.LcleanupEND:
|
||||
-
|
||||
- /* Get the control variable address back. */
|
||||
- popq %rdi
|
||||
- cfi_adjust_cfa_offset(-8)
|
||||
-
|
||||
- /* Sucessful run of the initializer. Signal that we are done. */
|
||||
- LOCK
|
||||
- incl (%rdi)
|
||||
-
|
||||
- addq $8, %rsp
|
||||
- cfi_adjust_cfa_offset(-8)
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- movl $0x7fffffff, %edx
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
|
||||
-#else
|
||||
- movl $FUTEX_WAKE, %esi
|
||||
- orl %fs:PRIVATE_FUTEX, %esi
|
||||
-#endif
|
||||
- movl $SYS_futex, %eax
|
||||
- syscall
|
||||
-
|
||||
-4: addq $8, %rsp
|
||||
- cfi_adjust_cfa_offset(-8)
|
||||
- xorl %eax, %eax
|
||||
- retq
|
||||
- .size __pthread_once,.-__pthread_once
|
||||
-
|
||||
-
|
||||
-hidden_def (__pthread_once)
|
||||
-strong_alias (__pthread_once, pthread_once)
|
||||
-
|
||||
-
|
||||
- .type clear_once_control,@function
|
||||
- .align 16
|
||||
-clear_once_control:
|
||||
- cfi_adjust_cfa_offset(3 * 8)
|
||||
- movq (%rsp), %rdi
|
||||
- movq %rax, %r8
|
||||
- movl $0, (%rdi)
|
||||
-
|
||||
- movl $0x7fffffff, %edx
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
|
||||
-#else
|
||||
- movl $FUTEX_WAKE, %esi
|
||||
- orl %fs:PRIVATE_FUTEX, %esi
|
||||
-#endif
|
||||
- movl $SYS_futex, %eax
|
||||
- syscall
|
||||
-
|
||||
- movq %r8, %rdi
|
||||
-.LcallUR:
|
||||
- call _Unwind_Resume@PLT
|
||||
- hlt
|
||||
-.LENDCODE:
|
||||
- cfi_endproc
|
||||
- .size clear_once_control,.-clear_once_control
|
||||
-
|
||||
-
|
||||
- .section .gcc_except_table,"a",@progbits
|
||||
-.LexceptSTART:
|
||||
- .byte DW_EH_PE_omit # @LPStart format
|
||||
- .byte DW_EH_PE_omit # @TType format
|
||||
- .byte DW_EH_PE_uleb128 # call-site format
|
||||
- .uleb128 .Lcstend-.Lcstbegin
|
||||
-.Lcstbegin:
|
||||
- .uleb128 .LcleanupSTART-.LSTARTCODE
|
||||
- .uleb128 .LcleanupEND-.LcleanupSTART
|
||||
- .uleb128 clear_once_control-.LSTARTCODE
|
||||
- .uleb128 0
|
||||
- .uleb128 .LcallUR-.LSTARTCODE
|
||||
- .uleb128 .LENDCODE-.LcallUR
|
||||
- .uleb128 0
|
||||
- .uleb128 0
|
||||
-.Lcstend:
|
||||
-
|
||||
-
|
||||
-#ifdef SHARED
|
||||
- .hidden DW.ref.__gcc_personality_v0
|
||||
- .weak DW.ref.__gcc_personality_v0
|
||||
- .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
|
||||
- .align LP_SIZE
|
||||
- .type DW.ref.__gcc_personality_v0, @object
|
||||
- .size DW.ref.__gcc_personality_v0, LP_SIZE
|
||||
-DW.ref.__gcc_personality_v0:
|
||||
- ASM_ADDR __gcc_personality_v0
|
||||
-#endif
|
|
@ -0,0 +1,720 @@
|
|||
This patch removes the following remaining architecture specific
|
||||
pthread_once implementations:
|
||||
|
||||
- alpha, hppa, sh: Not used in RHEL.
|
||||
|
||||
- s390: Was first moved, then renamed upstream by the following commits:
|
||||
|
||||
commit 52ae23b4bfa09fa1f42e3f659aaa057d1176d06b
|
||||
Author: Roland McGrath <roland@hack.frob.com>
|
||||
Date: Thu Jun 26 09:31:11 2014 -0700
|
||||
|
||||
Move remaining S390 code out of nptl/.
|
||||
|
||||
commit bc89c0fc70ba952f78fc27fc261ec209be0a6732
|
||||
Author: Torvald Riegel <triegel@redhat.com>
|
||||
Date: Mon Dec 8 18:32:14 2014 +0100
|
||||
|
||||
Remove custom pthread_once implementation on s390.
|
||||
|
||||
- powerpc: Was removed upstream by the following commit:
|
||||
|
||||
commit 75ffb047f6ee2a545da8cf69dba9a979ca6271ce
|
||||
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||
Date: Sun Apr 13 18:13:42 2014 -0500
|
||||
|
||||
PowerPC: Sync pthread_once with default implementation
|
||||
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 52ab53f0a912d107..0000000000000000
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,110 +0,0 @@
|
||||
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- __asm __volatile (__lll_rel_instr);
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
-{
|
||||
- for (;;)
|
||||
- {
|
||||
- int oldval;
|
||||
- int newval;
|
||||
- int tmp;
|
||||
-
|
||||
- /* Pseudo code:
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if ((oldval & 2) == 0)
|
||||
- *once_control = newval;
|
||||
- Do this atomically with an acquire barrier.
|
||||
- */
|
||||
- newval = __fork_generation | 1;
|
||||
- __asm __volatile ("1: lwarx %0,0,%3" MUTEX_HINT_ACQ "\n"
|
||||
- " andi. %1,%0,2\n"
|
||||
- " bne 2f\n"
|
||||
- " stwcx. %4,0,%3\n"
|
||||
- " bne 1b\n"
|
||||
- "2: " __lll_acq_instr
|
||||
- : "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
|
||||
- : "r" (once_control), "r" (newval), "m" (*once_control)
|
||||
- : "cr0");
|
||||
-
|
||||
- /* Check if the initializer has already been done. */
|
||||
- if ((oldval & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) == 0)
|
||||
- break;
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted by a fork. */
|
||||
- if (oldval != newval)
|
||||
- break;
|
||||
-
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, oldval, LLL_PRIVATE);
|
||||
- }
|
||||
-
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Add one to *once_control to take the bottom 2 bits from 01 to 10.
|
||||
- A release barrier is needed to ensure memory written by init_routine
|
||||
- is seen in other threads before *once_control changes. */
|
||||
- int tmp;
|
||||
- __asm __volatile (__lll_rel_instr "\n"
|
||||
- "1: lwarx %0,0,%2" MUTEX_HINT_REL "\n"
|
||||
- " addi %0,%0,1\n"
|
||||
- " stwcx. %0,0,%2\n"
|
||||
- " bne- 1b"
|
||||
- : "=&b" (tmp), "=m" (*once_control)
|
||||
- : "r" (once_control), "m" (*once_control)
|
||||
- : "cr0");
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index 4bce7fec13ea3bb2..0000000000000000
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,108 +0,0 @@
|
||||
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- int oldval;
|
||||
- int newval;
|
||||
-
|
||||
- /* Pseudo code:
|
||||
- oldval = *once_control;
|
||||
- if ((oldval & 2) == 0)
|
||||
- {
|
||||
- newval = (oldval & 3) | __fork_generation | 1;
|
||||
- *once_control = newval;
|
||||
- }
|
||||
- Do this atomically. */
|
||||
- __asm __volatile (" l %1,%0\n"
|
||||
- "0: lhi %2,2\n"
|
||||
- " tml %1,2\n"
|
||||
- " jnz 1f\n"
|
||||
- " nr %2,%1\n"
|
||||
- " ahi %2,1\n"
|
||||
- " o %2,%3\n"
|
||||
- " cs %1,%2,%0\n"
|
||||
- " jl 0b\n"
|
||||
- "1:"
|
||||
- : "=Q" (*once_control), "=&d" (oldval), "=&d" (newval)
|
||||
- : "m" (__fork_generation), "m" (*once_control)
|
||||
- : "cc" );
|
||||
- /* Check if the initialized has already been done. */
|
||||
- if ((oldval & 2) != 0)
|
||||
- break;
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
- {
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- if (((oldval ^ newval) & -4) == 0)
|
||||
- {
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, newval, LLL_PRIVATE);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Add one to *once_control. */
|
||||
- __asm __volatile (" l %1,%0\n"
|
||||
- "0: lr %2,%1\n"
|
||||
- " ahi %2,1\n"
|
||||
- " cs %1,%2,%0\n"
|
||||
- " jl 0b\n"
|
||||
- : "=Q" (*once_control), "=&d" (oldval), "=&d" (newval)
|
||||
- : "m" (*once_control) : "cc" );
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
|
||||
deleted file mode 100644
|
||||
index 62b92d8b103ded65..0000000000000000
|
||||
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
|
||||
+++ /dev/null
|
||||
@@ -1,257 +0,0 @@
|
||||
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library; if not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include <unwindbuf.h>
|
||||
-#include <sysdep.h>
|
||||
-#include <kernel-features.h>
|
||||
-#include <lowlevellock.h>
|
||||
-#include "lowlevel-atomic.h"
|
||||
-
|
||||
-
|
||||
- .comm __fork_generation, 4, 4
|
||||
-
|
||||
- .text
|
||||
- .globl __pthread_once
|
||||
- .type __pthread_once,@function
|
||||
- .align 5
|
||||
- cfi_startproc
|
||||
-__pthread_once:
|
||||
- mov.l @r4, r0
|
||||
- tst #2, r0
|
||||
- bt 1f
|
||||
- rts
|
||||
- mov #0, r0
|
||||
-
|
||||
-1:
|
||||
- mov.l r12, @-r15
|
||||
- cfi_adjust_cfa_offset (4)
|
||||
- cfi_rel_offset (r12, 0)
|
||||
- mov.l r9, @-r15
|
||||
- cfi_adjust_cfa_offset (4)
|
||||
- cfi_rel_offset (r9, 0)
|
||||
- mov.l r8, @-r15
|
||||
- cfi_adjust_cfa_offset (4)
|
||||
- cfi_rel_offset (r8, 0)
|
||||
- sts.l pr, @-r15
|
||||
- cfi_adjust_cfa_offset (4)
|
||||
- cfi_rel_offset (pr, 0)
|
||||
- mov r5, r8
|
||||
- mov r4, r9
|
||||
-
|
||||
- /* Not yet initialized or initialization in progress.
|
||||
- Get the fork generation counter now. */
|
||||
-6:
|
||||
- mov.l @r4, r1
|
||||
- mova .Lgot, r0
|
||||
- mov.l .Lgot, r12
|
||||
- add r0, r12
|
||||
-
|
||||
-5:
|
||||
- mov r1, r0
|
||||
-
|
||||
- tst #2, r0
|
||||
- bf 4f
|
||||
-
|
||||
- and #3, r0
|
||||
- mov.l .Lfgen, r2
|
||||
-#ifdef PIC
|
||||
- add r12, r2
|
||||
-#endif
|
||||
- mov.l @r2, r3
|
||||
- or r3, r0
|
||||
- or #1, r0
|
||||
- mov r0, r3
|
||||
- mov r1, r5
|
||||
-
|
||||
- CMPXCHG (r5, @r4, r3, r2)
|
||||
- bf 5b
|
||||
-
|
||||
- /* Check whether another thread already runs the initializer. */
|
||||
- mov r2, r0
|
||||
- tst #1, r0
|
||||
- bt 3f /* No -> do it. */
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- xor r3, r0
|
||||
- mov #-4, r1 /* -4 = 0xfffffffc */
|
||||
- tst r1, r0
|
||||
- bf 3f /* Different for generation -> run initializer. */
|
||||
-
|
||||
- /* Somebody else got here first. Wait. */
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5
|
||||
- extu.b r5, r5
|
||||
-#else
|
||||
- stc gbr, r1
|
||||
- mov.w .Lpfoff, r2
|
||||
- add r2, r1
|
||||
- mov.l @r1, r5
|
||||
-# if FUTEX_WAIT != 0
|
||||
- mov #FUTEX_WAIT, r0
|
||||
- or r0, r5
|
||||
-# endif
|
||||
-#endif
|
||||
- mov r3, r6
|
||||
- mov #0, r7
|
||||
- mov #SYS_futex, r3
|
||||
- extu.b r3, r3
|
||||
- trapa #0x14
|
||||
- SYSCALL_INST_PAD
|
||||
- bra 6b
|
||||
- nop
|
||||
-
|
||||
- .align 2
|
||||
-.Lgot:
|
||||
- .long _GLOBAL_OFFSET_TABLE_
|
||||
-#ifdef PIC
|
||||
-.Lfgen:
|
||||
- .long __fork_generation@GOTOFF
|
||||
-#else
|
||||
-.Lfgen:
|
||||
- .long __fork_generation
|
||||
-#endif
|
||||
-
|
||||
-3:
|
||||
- /* Call the initializer function after setting up the
|
||||
- cancellation handler. Note that it is not possible here
|
||||
- to use the unwind-based cleanup handling. This would require
|
||||
- that the user-provided function and all the code it calls
|
||||
- is compiled with exceptions. Unfortunately this cannot be
|
||||
- guaranteed. */
|
||||
- add #-UNWINDBUFSIZE, r15
|
||||
- cfi_adjust_cfa_offset (UNWINDBUFSIZE)
|
||||
-
|
||||
- mov.l .Lsigsetjmp, r1
|
||||
- mov #UWJMPBUF, r4
|
||||
- add r15, r4
|
||||
- bsrf r1
|
||||
- mov #0, r5
|
||||
-.Lsigsetjmp0:
|
||||
- tst r0, r0
|
||||
- bf 7f
|
||||
-
|
||||
- mov.l .Lcpush, r1
|
||||
- bsrf r1
|
||||
- mov r15, r4
|
||||
-.Lcpush0:
|
||||
-
|
||||
- /* Call the user-provided initialization function. */
|
||||
- jsr @r8
|
||||
- nop
|
||||
-
|
||||
- /* Pop the cleanup handler. */
|
||||
- mov.l .Lcpop, r1
|
||||
- bsrf r1
|
||||
- mov r15, r4
|
||||
-.Lcpop0:
|
||||
-
|
||||
- add #UNWINDBUFSIZE, r15
|
||||
- cfi_adjust_cfa_offset (-UNWINDBUFSIZE)
|
||||
-
|
||||
- /* Sucessful run of the initializer. Signal that we are done. */
|
||||
- INC (@r9, r2)
|
||||
- /* Wake up all other threads. */
|
||||
- mov r9, r4
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
|
||||
- extu.b r5, r5
|
||||
-#else
|
||||
- stc gbr, r1
|
||||
- mov.w .Lpfoff, r2
|
||||
- add r2, r1
|
||||
- mov.l @r1, r5
|
||||
- mov #FUTEX_WAKE, r0
|
||||
- or r0, r5
|
||||
-#endif
|
||||
- mov #-1, r6
|
||||
- shlr r6 /* r6 = 0x7fffffff */
|
||||
- mov #0, r7
|
||||
- mov #SYS_futex, r3
|
||||
- extu.b r3, r3
|
||||
- trapa #0x14
|
||||
- SYSCALL_INST_PAD
|
||||
-
|
||||
-4:
|
||||
- lds.l @r15+, pr
|
||||
- cfi_adjust_cfa_offset (-4)
|
||||
- cfi_restore (pr)
|
||||
- mov.l @r15+, r8
|
||||
- cfi_adjust_cfa_offset (-4)
|
||||
- cfi_restore (r8)
|
||||
- mov.l @r15+, r9
|
||||
- cfi_adjust_cfa_offset (-4)
|
||||
- cfi_restore (r9)
|
||||
- mov.l @r15+, r12
|
||||
- cfi_adjust_cfa_offset (-4)
|
||||
- cfi_restore (r12)
|
||||
- rts
|
||||
- mov #0, r0
|
||||
-
|
||||
-7:
|
||||
- /* __sigsetjmp returned for the second time. */
|
||||
- cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
|
||||
- cfi_offset (r12, -4)
|
||||
- cfi_offset (r9, -8)
|
||||
- cfi_offset (r8, -12)
|
||||
- cfi_offset (pr, -16)
|
||||
- mov #0, r7
|
||||
- mov.l r7, @r9
|
||||
- mov r9, r4
|
||||
-#ifdef __ASSUME_PRIVATE_FUTEX
|
||||
- mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
|
||||
-#else
|
||||
- stc gbr, r1
|
||||
- mov.w .Lpfoff, r2
|
||||
- add r2, r1
|
||||
- mov.l @r1, r5
|
||||
- mov #FUTEX_WAKE, r0
|
||||
- or r0, r5
|
||||
-#endif
|
||||
- extu.b r5, r5
|
||||
- mov #-1, r6
|
||||
- shlr r6 /* r6 = 0x7fffffff */
|
||||
- mov #SYS_futex, r3
|
||||
- extu.b r3, r3
|
||||
- trapa #0x14
|
||||
- SYSCALL_INST_PAD
|
||||
-
|
||||
- mov.l .Lunext, r1
|
||||
- bsrf r1
|
||||
- mov r15, r4
|
||||
-.Lunext0:
|
||||
- /* NOTREACHED */
|
||||
- sleep
|
||||
- cfi_endproc
|
||||
-
|
||||
-#ifndef __ASSUME_PRIVATE_FUTEX
|
||||
-.Lpfoff:
|
||||
- .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
|
||||
-#endif
|
||||
- .align 2
|
||||
-.Lsigsetjmp:
|
||||
- .long __sigsetjmp@PLT-(.Lsigsetjmp0-.)
|
||||
-.Lcpush:
|
||||
- .long HIDDEN_JUMPTARGET(__pthread_register_cancel)-.Lcpush0
|
||||
-.Lcpop:
|
||||
- .long HIDDEN_JUMPTARGET(__pthread_unregister_cancel)-.Lcpop0
|
||||
-.Lunext:
|
||||
- .long HIDDEN_JUMPTARGET(__pthread_unwind_next)-.Lunext0
|
||||
- .size __pthread_once,.-__pthread_once
|
||||
-
|
||||
-hidden_def (__pthread_once)
|
||||
-strong_alias (__pthread_once, pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/alpha/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/alpha/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index c342e0a7a0965086..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/alpha/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,95 +0,0 @@
|
||||
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library. If not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||
-{
|
||||
- for (;;)
|
||||
- {
|
||||
- int oldval;
|
||||
- int newval;
|
||||
- int tmp;
|
||||
-
|
||||
- /* Pseudo code:
|
||||
- newval = __fork_generation | 1;
|
||||
- oldval = *once_control;
|
||||
- if ((oldval & 2) == 0)
|
||||
- *once_control = newval;
|
||||
- Do this atomically.
|
||||
- */
|
||||
- newval = __fork_generation | 1;
|
||||
- __asm __volatile (
|
||||
- "1: ldl_l %0, %2\n"
|
||||
- " and %0, 2, %1\n"
|
||||
- " bne %1, 2f\n"
|
||||
- " mov %3, %1\n"
|
||||
- " stl_c %1, %2\n"
|
||||
- " beq %1, 1b\n"
|
||||
- "2: mb"
|
||||
- : "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
|
||||
- : "r" (newval), "m" (*once_control));
|
||||
-
|
||||
- /* Check if the initializer has already been done. */
|
||||
- if ((oldval & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) == 0)
|
||||
- break;
|
||||
-
|
||||
- /* Check whether the initializer execution was interrupted by a fork. */
|
||||
- if (oldval != newval)
|
||||
- break;
|
||||
-
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_futex_wait (once_control, oldval, LLL_PRIVATE);
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
- /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */
|
||||
- atomic_increment (once_control);
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
||||
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c
|
||||
deleted file mode 100644
|
||||
index b920ebb22c10a569..0000000000000000
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c
|
||||
+++ /dev/null
|
||||
@@ -1,93 +0,0 @@
|
||||
-/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
||||
- This file is part of the GNU C Library.
|
||||
- Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
-
|
||||
- The GNU C Library is free software; you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Lesser General Public
|
||||
- License as published by the Free Software Foundation; either
|
||||
- version 2.1 of the License, or (at your option) any later version.
|
||||
-
|
||||
- The GNU C Library is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Lesser General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Lesser General Public
|
||||
- License along with the GNU C Library. If not, see
|
||||
- <http://www.gnu.org/licenses/>. */
|
||||
-
|
||||
-#include "pthreadP.h"
|
||||
-#include <lowlevellock.h>
|
||||
-
|
||||
-
|
||||
-unsigned long int __fork_generation attribute_hidden;
|
||||
-
|
||||
-
|
||||
-static void
|
||||
-clear_once_control (void *arg)
|
||||
-{
|
||||
- pthread_once_t *once_control = (pthread_once_t *) arg;
|
||||
-
|
||||
- *once_control = 0;
|
||||
- lll_private_futex_wake (once_control, INT_MAX);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int
|
||||
-__pthread_once (once_control, init_routine)
|
||||
- pthread_once_t *once_control;
|
||||
- void (*init_routine) (void);
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- int oldval, val, newval;
|
||||
-
|
||||
- val = *once_control;
|
||||
- do
|
||||
- {
|
||||
- /* Check if the initialized has already been done. */
|
||||
- if ((val & 2) != 0)
|
||||
- return 0;
|
||||
-
|
||||
- oldval = val;
|
||||
- newval = (oldval & 3) | __fork_generation | 1;
|
||||
- val = atomic_compare_and_exchange_val_acq (once_control, newval,
|
||||
- oldval);
|
||||
- }
|
||||
- while (__builtin_expect (val != oldval, 0));
|
||||
-
|
||||
- /* Check if another thread already runs the initializer. */
|
||||
- if ((oldval & 1) != 0)
|
||||
- {
|
||||
- /* Check whether the initializer execution was interrupted
|
||||
- by a fork. */
|
||||
- if (((oldval ^ newval) & -4) == 0)
|
||||
- {
|
||||
- /* Same generation, some other thread was faster. Wait. */
|
||||
- lll_private_futex_wait (once_control, newval);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* This thread is the first here. Do the initialization.
|
||||
- Register a cleanup handler so that in case the thread gets
|
||||
- interrupted the initialization can be restarted. */
|
||||
- pthread_cleanup_push (clear_once_control, once_control);
|
||||
-
|
||||
- init_routine ();
|
||||
-
|
||||
- pthread_cleanup_pop (0);
|
||||
-
|
||||
-
|
||||
- /* Add one to *once_control. */
|
||||
- atomic_increment (once_control);
|
||||
-
|
||||
- /* Wake up all other threads. */
|
||||
- lll_private_futex_wake (once_control, INT_MAX);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-weak_alias (__pthread_once, pthread_once)
|
||||
-hidden_def (__pthread_once)
|
|
@ -0,0 +1,60 @@
|
|||
commit a58ad3f801960fa0dc0bb1106eb0d99f7ebd77b1
|
||||
Author: Roland McGrath <roland@hack.frob.com>
|
||||
Date: Thu Jun 13 15:09:29 2013 -0700
|
||||
|
||||
Fix raciness in waitid test.
|
||||
|
||||
diff --git a/posix/tst-waitid.c b/posix/tst-waitid.c
|
||||
index f8a302ea3153a853..d63ad65fbefc64ad 100644
|
||||
--- a/posix/tst-waitid.c
|
||||
+++ b/posix/tst-waitid.c
|
||||
@@ -145,7 +145,7 @@ do_test (int argc, char *argv[])
|
||||
/* Give the child a chance to stop. */
|
||||
sleep (3);
|
||||
|
||||
- CHECK_SIGCHLD ("stopped", CLD_STOPPED, SIGSTOP);
|
||||
+ CHECK_SIGCHLD ("stopped (before waitid)", CLD_STOPPED, SIGSTOP);
|
||||
|
||||
/* Now try a wait that should not succeed. */
|
||||
siginfo_t info;
|
||||
@@ -227,7 +227,7 @@ do_test (int argc, char *argv[])
|
||||
expecting_sigchld = 0;
|
||||
}
|
||||
else
|
||||
- CHECK_SIGCHLD ("continued", CLD_CONTINUED, SIGCONT);
|
||||
+ CHECK_SIGCHLD ("continued (before waitid)", CLD_CONTINUED, SIGCONT);
|
||||
|
||||
info.si_signo = 0; /* A successful call sets it to SIGCHLD. */
|
||||
info.si_pid = -1;
|
||||
@@ -336,6 +336,13 @@ do_test (int argc, char *argv[])
|
||||
printf ("kill (%d, SIGSTOP): %m\n", pid);
|
||||
RETURN (EXIT_FAILURE);
|
||||
}
|
||||
+
|
||||
+ /* Give the child a chance to stop. The waitpid call below will block
|
||||
+ until it has stopped, but if we are real quick and enter the waitpid
|
||||
+ system call before the SIGCHLD has been generated, then it will be
|
||||
+ discarded and never delivered. */
|
||||
+ sleep (3);
|
||||
+
|
||||
pid_t wpid = waitpid (pid, &fail, WUNTRACED);
|
||||
if (wpid < 0)
|
||||
{
|
||||
@@ -354,7 +361,7 @@ do_test (int argc, char *argv[])
|
||||
printf ("waitpid WUNTRACED on stopped: status %x\n", fail);
|
||||
RETURN (EXIT_FAILURE);
|
||||
}
|
||||
- CHECK_SIGCHLD ("stopped", CLD_STOPPED, SIGSTOP);
|
||||
+ CHECK_SIGCHLD ("stopped (after waitpid)", CLD_STOPPED, SIGSTOP);
|
||||
|
||||
expecting_sigchld = 1;
|
||||
if (kill (pid, SIGCONT) != 0)
|
||||
@@ -372,7 +379,7 @@ do_test (int argc, char *argv[])
|
||||
expecting_sigchld = 0;
|
||||
}
|
||||
else
|
||||
- CHECK_SIGCHLD ("continued", CLD_CONTINUED, SIGCONT);
|
||||
+ CHECK_SIGCHLD ("continued (before waitpid)", CLD_CONTINUED, SIGCONT);
|
||||
|
||||
wpid = waitpid (pid, &fail, WCONTINUED);
|
||||
if (wpid < 0)
|
|
@ -0,0 +1,11 @@
|
|||
--- a/sysdeps/unix/arm/sysdep.S 2016-11-05 11:44:45.561945344 +0100
|
||||
+++ b/sysdeps/unix/arm/sysdep.S 2016-11-05 11:44:19.542069815 +0100
|
||||
@@ -37,7 +37,7 @@
|
||||
moveq r0, $EAGAIN /* Yes; translate it to EAGAIN. */
|
||||
#endif
|
||||
|
||||
-#ifndef IS_IN_rtld
|
||||
+#if !IS_IN (rtld)
|
||||
mov ip, lr
|
||||
cfi_register (lr, ip)
|
||||
mov r1, r0
|
|
@ -0,0 +1,98 @@
|
|||
This patch is based on the following upstream commit:
|
||||
|
||||
commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Mar 2 14:44:28 2017 +0100
|
||||
|
||||
Document and fix --enable-bind-now [BZ #21015]
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index 82b29f5d8746f929..230be71b9d0821c2 100644
|
||||
--- a/INSTALL
|
||||
+++ b/INSTALL
|
||||
@@ -143,6 +143,12 @@ will be used, and CFLAGS sets optimization options for the compiler.
|
||||
`--enable-lock-elision=yes'
|
||||
Enable lock elision for pthread mutexes by default.
|
||||
|
||||
+'--enable-bind-now'
|
||||
+ Disable lazy binding for installed shared objects. This provides
|
||||
+ additional security hardening because it enables full RELRO and a
|
||||
+ read-only global offset table (GOT), at the cost of slightly
|
||||
+ increased program load times.
|
||||
+
|
||||
`--disable-werror'
|
||||
By default, the GNU C Library is built with `-Werror'. If you wish
|
||||
to build without this option (for example, if building with a newer
|
||||
diff --git a/Makeconfig b/Makeconfig
|
||||
index f8313c9774d47522..1ad9b6f0d494c027 100644
|
||||
--- a/Makeconfig
|
||||
+++ b/Makeconfig
|
||||
@@ -384,6 +384,13 @@ LDFLAGS.so += $(hashstyle-LDFLAGS)
|
||||
LDFLAGS-rtld += $(hashstyle-LDFLAGS)
|
||||
endif
|
||||
|
||||
+# If lazy relocations are disabled, add the -z now flag. Use
|
||||
+# LDFLAGS-lib.so instead of LDFLAGS.so, to avoid adding the flag to
|
||||
+# test modules.
|
||||
+ifeq ($(bind-now),yes)
|
||||
+LDFLAGS-lib.so += -Wl,-z,now
|
||||
+endif
|
||||
+
|
||||
# Additional libraries to link into every test.
|
||||
link-extra-libs-tests = $(libsupport)
|
||||
|
||||
diff --git a/Makerules b/Makerules
|
||||
index 9bd7d603fc28a4de..50fe7e48187f0e68 100644
|
||||
--- a/Makerules
|
||||
+++ b/Makerules
|
||||
@@ -477,7 +477,7 @@ $(LINK.o) -shared $(static-libgcc) -Wl,-O1 $(sysdep-LDFLAGS) \
|
||||
$(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
|
||||
$(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
|
||||
-Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
|
||||
- $(LDFLAGS.so) $(LDFLAGS-$(@F:lib%.so=%).so) \
|
||||
+ $(LDFLAGS.so) $(LDFLAGS-lib.so) $(LDFLAGS-$(@F:lib%.so=%).so) \
|
||||
-L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)
|
||||
endef
|
||||
|
||||
@@ -938,7 +938,8 @@ $(common-objpfx)format.lds: $(..)scripts/output-format.sed \
|
||||
ifneq (unknown,$(output-format))
|
||||
echo > $@.new 'OUTPUT_FORMAT($(output-format))'
|
||||
else
|
||||
- $(LINK.o) -shared $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS.so) \
|
||||
+ $(LINK.o) -shared $(sysdep-LDFLAGS) $(config-LDFLAGS) \
|
||||
+ $(LDFLAGS.so) $(LDFLAGS-lib.so) \
|
||||
-x c /dev/null -o $@.so -Wl,--verbose -v 2>&1 \
|
||||
| sed -n -f $< > $@.new
|
||||
test -s $@.new
|
||||
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
|
||||
index 7930dcd49d77c818..ddb2dc6a3c6500c8 100644
|
||||
--- a/iconvdata/Makefile
|
||||
+++ b/iconvdata/Makefile
|
||||
@@ -65,6 +65,10 @@ modules.so := $(addsuffix .so, $(modules))
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
+ifeq ($(bind-now),yes)
|
||||
+LDFLAGS.so += -Wl,-z,now
|
||||
+endif
|
||||
+
|
||||
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 \
|
||||
diff --git a/manual/install.texi b/manual/install.texi
|
||||
index 3799cee621ddc4f9..47d832cc59bc695e 100644
|
||||
--- a/manual/install.texi
|
||||
+++ b/manual/install.texi
|
||||
@@ -160,6 +160,12 @@ so that they can be invoked directly.
|
||||
@item --enable-lock-elision=yes
|
||||
Enable lock elision for pthread mutexes by default.
|
||||
|
||||
+@item --enable-bind-now
|
||||
+Disable lazy binding for installed shared objects. This provides
|
||||
+additional security hardening because it enables full RELRO and a
|
||||
+read-only global offset table (GOT), at the cost of slightly increased
|
||||
+program load times.
|
||||
+
|
||||
@pindex pt_chown
|
||||
@findex grantpt
|
||||
@item --enable-pt_chown
|
|
@ -0,0 +1,96 @@
|
|||
This patch is based on the following upstream commit:
|
||||
|
||||
commit 94a4e9e4f401ffe829a992820439977ead0a0ce7
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Apr 25 10:41:43 2019 +0200
|
||||
|
||||
Extend BIND_NOW to installed programs with --enable-bind-now
|
||||
|
||||
Commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix
|
||||
--enable-bind-now [BZ #21015]") extended BIND_NOW to all installed
|
||||
shared objects. This change also covers installed programs.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index 230be71b9d0821c2..277ea46d9c25a9ae 100644
|
||||
--- a/INSTALL
|
||||
+++ b/INSTALL
|
||||
@@ -144,10 +144,10 @@ will be used, and CFLAGS sets optimization options for the compiler.
|
||||
Enable lock elision for pthread mutexes by default.
|
||||
|
||||
'--enable-bind-now'
|
||||
- Disable lazy binding for installed shared objects. This provides
|
||||
- additional security hardening because it enables full RELRO and a
|
||||
- read-only global offset table (GOT), at the cost of slightly
|
||||
- increased program load times.
|
||||
+ Disable lazy binding for installed shared objects and programs.
|
||||
+ This provides additional security hardening because it enables full
|
||||
+ RELRO and a read-only global offset table (GOT), at the cost of
|
||||
+ slightly increased program load times.
|
||||
|
||||
`--disable-werror'
|
||||
By default, the GNU C Library is built with `-Werror'. If you wish
|
||||
diff --git a/Makeconfig b/Makeconfig
|
||||
index 1ad9b6f0d494c027..bc13b39c2ea5708a 100644
|
||||
--- a/Makeconfig
|
||||
+++ b/Makeconfig
|
||||
@@ -389,6 +389,8 @@ endif
|
||||
# test modules.
|
||||
ifeq ($(bind-now),yes)
|
||||
LDFLAGS-lib.so += -Wl,-z,now
|
||||
+# Extra flags for dynamically linked non-test main programs.
|
||||
+link-extra-flags += -Wl,-z,now
|
||||
endif
|
||||
|
||||
# Additional libraries to link into every test.
|
||||
@@ -405,7 +407,8 @@ ifndef +link-pie
|
||||
S$(start-installed-name))\
|
||||
$(+preinit) $(link-extra-libs) \
|
||||
$(common-objpfx)libc% $(+postinit),$^) \
|
||||
- $(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit)
|
||||
+ $(link-extra-libs) $(link-extra-flags) $(link-libc) \
|
||||
+ $(+postctorS) $(+postinit)
|
||||
endif
|
||||
# Command for statically linking programs with the C library.
|
||||
ifndef +link-static
|
||||
@@ -419,8 +422,8 @@ ifndef +link-static
|
||||
$(common-objpfx)libc% $(+postinit),$^) \
|
||||
$(link-extra-libs-static)
|
||||
+link-static-after-libc = $(+postctorT) $(+postinit)
|
||||
-+link-static = $(+link-static-before-libc) $(link-libc-static) \
|
||||
- $(+link-static-after-libc)
|
||||
++link-static = $(+link-static-before-libc) $(link-extra-flags) \
|
||||
+ $(link-libc-static) $(+link-static-after-libc)
|
||||
+link-static-tests = $(+link-static-before-libc) $(link-libc-static-tests) \
|
||||
$(+link-static-after-libc)
|
||||
endif
|
||||
@@ -438,7 +441,8 @@ ifeq (yes,$(build-shared))
|
||||
$(common-objpfx)libc% $(+postinit),$^) \
|
||||
$(link-extra-libs)
|
||||
+link-after-libc = $(+postctor) $(+postinit)
|
||||
-+link = $(+link-before-libc) $(link-libc) $(+link-after-libc)
|
||||
++link = $(+link-before-libc) $(link-extra-flags) $(link-libc) \
|
||||
+ $(+link-after-libc)
|
||||
+link-tests = $(+link-before-libc) $(link-libc-tests) $(+link-after-libc)
|
||||
else
|
||||
+link = $(+link-static)
|
||||
diff --git a/manual/install.texi b/manual/install.texi
|
||||
index 47d832cc59bc695e..5cacd974ce093ce9 100644
|
||||
--- a/manual/install.texi
|
||||
+++ b/manual/install.texi
|
||||
@@ -161,10 +161,10 @@ so that they can be invoked directly.
|
||||
Enable lock elision for pthread mutexes by default.
|
||||
|
||||
@item --enable-bind-now
|
||||
-Disable lazy binding for installed shared objects. This provides
|
||||
-additional security hardening because it enables full RELRO and a
|
||||
-read-only global offset table (GOT), at the cost of slightly increased
|
||||
-program load times.
|
||||
+Disable lazy binding for installed shared objects and programs. This
|
||||
+provides additional security hardening because it enables full RELRO
|
||||
+and a read-only global offset table (GOT), at the cost of slightly
|
||||
+increased program load times.
|
||||
|
||||
@pindex pt_chown
|
||||
@findex grantpt
|
|
@ -0,0 +1,44 @@
|
|||
This patch is based on the following upstream commit:
|
||||
|
||||
commit b5ffdc48c20ae865b197b67e5a9068a528fbc198
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Apr 25 10:41:52 2019 +0200
|
||||
|
||||
benchtests: Enable BIND_NOW if configured with --enable-bind-now
|
||||
|
||||
Benchmarks should reflect distribution build policies, so it makes
|
||||
sense to honor the BIND_NOW configuration for them.
|
||||
|
||||
This commit keeps using $(+link-tests), so that the benchmarks are
|
||||
linked according to the --enable-hardcoded-path-in-tests configure
|
||||
option.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/benchtests/Makefile b/benchtests/Makefile
|
||||
index 911b6df04cc323ac..bb02d26e1847d424 100644
|
||||
--- a/benchtests/Makefile
|
||||
+++ b/benchtests/Makefile
|
||||
@@ -153,12 +153,20 @@ bench-func: $(binaries-bench)
|
||||
$(PYTHON) scripts/validate_benchout.py $(objpfx)bench.out \
|
||||
scripts/benchout.schema.json
|
||||
|
||||
-$(timing-type) $(binaries-bench) $(binaries-benchset) \
|
||||
- $(binaries-bench-malloc): %: %.o $(objpfx)json-lib.o \
|
||||
+ifeq ($(bind-now),yes)
|
||||
+link-bench-bind-now = -Wl,-z,now
|
||||
+endif
|
||||
+
|
||||
+bench-link-targets = $(timing-type) $(binaries-bench) $(binaries-benchset) \
|
||||
+ $(binaries-bench-malloc)
|
||||
+
|
||||
+$(bench-link-targets): %: %.o $(objpfx)json-lib.o \
|
||||
$(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
|
||||
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
|
||||
$(+link)
|
||||
|
||||
+$(bench-link-targets): LDFLAGS += $(link-bench-bind-now)
|
||||
+
|
||||
$(objpfx)bench-%.c: %-inputs $(bench-deps)
|
||||
{ if [ -n "$($*-INCLUDE)" ]; then \
|
||||
cat $($*-INCLUDE); \
|
|
@ -0,0 +1,25 @@
|
|||
commit c57afec0a9b318bb691e0f5fa4e9681cf30df7a4
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Apr 26 07:16:56 2019 +0200
|
||||
|
||||
elf: Link sotruss-lib.so with BIND_NOW for --enable-bind-now
|
||||
|
||||
The audit module itself can be linked with BIND_NOW; it does not
|
||||
affect its functionality.
|
||||
|
||||
This should complete the leftovers from commit
|
||||
2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix
|
||||
--enable-bind-now [BZ #21015]").
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 2b2662d5cf96c437..cfd039fc9dfb0be7 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -103,6 +103,7 @@ install-others += $(inst_auditdir)/sotruss-lib.so
|
||||
install-bin-script += sotruss
|
||||
generated += sotruss
|
||||
libof-sotruss-lib = extramodules
|
||||
+LDFLAGS-sotruss-lib.so += $(z-now-$(bind-now))
|
||||
$(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os
|
||||
$(build-module-asneeded)
|
||||
$(objpfx)sotruss-lib.so: $(common-objpfx)libc.so $(objpfx)ld.so \
|
|
@ -0,0 +1,26 @@
|
|||
This patch enables building memusagestat with BIND_NOW enabled.
|
||||
|
||||
Upstream, this change was part of the following commit...
|
||||
|
||||
commit f9b645b4b0a10c43753296ce3fa40053fa44606a
|
||||
Author: Mike Frysinger <vapier@gentoo.org>
|
||||
Date: Wed Apr 24 13:32:22 2019 +0200
|
||||
|
||||
memusagestat: use local glibc when linking [BZ #18465]
|
||||
|
||||
...but since that commit cannot be backported to RHEL-7, this patch
|
||||
adds only the BIND_NOW linker flag at the appropriate place instead.
|
||||
|
||||
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||
index 476208cf43d211c9..992cec6b03115a76 100644
|
||||
--- a/malloc/Makefile
|
||||
+++ b/malloc/Makefile
|
||||
@@ -142,7 +142,7 @@ lib := memusagestat
|
||||
include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
|
||||
|
||||
$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
|
||||
- $(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
|
||||
+ $(LINK.o) -Wl,-z,now -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
|
||||
|
||||
include ../Rules
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
This is a downstream only patch for RHEL 7.
|
||||
|
||||
See bug 1790475 for the history behind --disable-bind-now for ppc64.
|
||||
In summary: COPY relocations and BIND_NOW are incompatible on ppc64.
|
||||
The solution is to globally disable BIND_NOW hardening on ppc64 with
|
||||
--disable-bind-now and then use a downstream-only patch to partially
|
||||
enable BIND_NOW hardening for ppc64 to the level of hardening that
|
||||
works given the toolchain.
|
||||
|
||||
diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
|
||||
index b11edd77bd2c22d4..47a9e7bcf66a8531 100644
|
||||
--- a/sysdeps/powerpc/Makefile
|
||||
+++ b/sysdeps/powerpc/Makefile
|
||||
@@ -1,3 +1,29 @@
|
||||
+################################################################################
|
||||
+# Only enabled if we are not building for ppc64le.
|
||||
+ifeq (,$(filter %le,$(config-machine)))
|
||||
+# Enable bind-now behaviour by default for POWER. This is a downstream specific
|
||||
+# change that is required due to a toolchain limitation in handling COPY
|
||||
+# relocations and BIND_NOW (see rhbz#1790475).
|
||||
+LDCFLAGS-c.so += -Wl,-z,now
|
||||
+# Likewise. Take care that this is carefully selected to turn BIND_NOW back on
|
||||
+# for ld.so without turning it back on for libpthread.so which has the
|
||||
+# problematic OPD that generates a COPY relocation. Enable these only for the
|
||||
+# elf subdir which is also used to build libc.so.6. This avoids enabling
|
||||
+# BIND_NOW for libpthread.
|
||||
+ifeq ($(subdir),elf)
|
||||
+z-now-no = -Wl,-z,now
|
||||
+LDFLAGS-lib.so += -Wl,-z,now
|
||||
+link-extra-flags += -Wl,-z,now
|
||||
+endif
|
||||
+# Likewise. Take care that this is carefully selected to turn BIND_NOW
|
||||
+# back on for iconv modules to ensure the data-only DSOs have consistently the
|
||||
+# correct expected flags for DSOs (even if they don't really need them).
|
||||
+ifeq ($(subdir),iconvdata)
|
||||
+LDFLAGS.so += -Wl,-z,now
|
||||
+endif
|
||||
+endif
|
||||
+################################################################################
|
||||
+
|
||||
ifeq ($(subdir),string)
|
||||
CFLAGS-memcmp.c += -Wno-uninitialized
|
||||
endif
|
|
@ -0,0 +1,423 @@
|
|||
commit 799c8d6905433ad56f26ccab4855b36f1d1ddbfc
|
||||
Author: Mike FABIAN <mfabian@redhat.com>
|
||||
Date: Thu Sep 7 15:28:28 2017 +0200
|
||||
|
||||
Add new codepage charmaps/IBM858 [BZ #21084]
|
||||
|
||||
This code page is identical to code page 850 except that X'D5'
|
||||
has been changed from LI61 (dotless i) to SC20 (euro symbol).
|
||||
|
||||
The code points from /x01 to /x1f in the /localedata/charmaps/IBM858
|
||||
file have the same mapping as those in localedata/charmaps/ANSI_X3.4-1968.
|
||||
That means they disagree with with
|
||||
|
||||
ftp://ftp.software.ibm.com/software/globalization/gcoc/attachments/CP00858.txt
|
||||
|
||||
in that range.
|
||||
For example, localedata/charmaps/IBM858 and localedata/charmaps/ANSI_X3.4-1968 have:
|
||||
|
||||
“<U0001> /x01 START OF HEADING (SOH)”
|
||||
|
||||
whereas CP00858.txt has:
|
||||
|
||||
“01 SS000000 Smiling Face”
|
||||
|
||||
That means that CP00858.txt is not really ASCII-compatible and to make
|
||||
it ASCII-compatible we deviate fro CP00858.txt in the code points from /x01
|
||||
to /x1f.
|
||||
|
||||
[BZ #21084]
|
||||
* benchtests/strcoll-inputs/filelist#en_US.UTF-8: Add IBM858 and ibm858.c.
|
||||
* iconvdata/Makefile: Add IBM858.
|
||||
* iconvdata/gconv-modules: Add IBM858.
|
||||
* iconvdata/ibm858.c: New file.
|
||||
* iconvdata/tst-tables.sh: Add IBM858
|
||||
* localedata/charmaps/IBM858: New file.
|
||||
|
||||
# Conflicts:
|
||||
# benchtests/strcoll-inputs/filelist#en_US.UTF-8
|
||||
|
||||
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
|
||||
index c4e6c510d7abc055..7930dcd49d77c818 100644
|
||||
--- a/iconvdata/Makefile
|
||||
+++ b/iconvdata/Makefile
|
||||
@@ -34,9 +34,9 @@ modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
|
||||
IBM874 CP737 CP775 ISO-2022-KR HP-TURKISH8 HP-THAI8 HP-GREEK8 \
|
||||
KOI8-R LATIN-GREEK LATIN-GREEK-1 IBM256 IBM273 IBM277 IBM278 \
|
||||
IBM280 IBM281 IBM284 IBM285 IBM290 IBM297 IBM420 IBM424 \
|
||||
- IBM437 IBM850 IBM851 IBM852 IBM855 IBM857 IBM860 IBM861 \
|
||||
- IBM862 IBM863 IBM864 IBM865 IBM868 IBM869 IBM875 IBM880 \
|
||||
- IBM866 CP1258 IBM922 IBM1124 IBM1129 IBM932 IBM943 \
|
||||
+ IBM437 IBM850 IBM851 IBM852 IBM855 IBM857 IBM858 IBM860 \
|
||||
+ IBM861 IBM862 IBM863 IBM864 IBM865 IBM868 IBM869 IBM875 \
|
||||
+ IBM880 IBM866 CP1258 IBM922 IBM1124 IBM1129 IBM932 IBM943 \
|
||||
IBM856 IBM930 IBM933 IBM935 IBM937 IBM939 IBM1046 \
|
||||
IBM1132 IBM1133 IBM1160 IBM1161 IBM1162 IBM1163 IBM1164 \
|
||||
IBM918 IBM1004 IBM1026 CP1125 CP1250 CP1251 CP1252 CP1253 \
|
||||
@@ -148,11 +148,11 @@ gen-8bit-modules := iso8859-2 iso8859-3 iso8859-4 iso8859-6 iso8859-9 koi-8 \
|
||||
gen-8bit-gap-modules := koi8-r latin-greek latin-greek-1 ibm256 ibm273 \
|
||||
ibm277 ibm278 ibm280 ibm281 ibm284 ibm285 ibm290 \
|
||||
ibm297 ibm420 ibm424 ibm437 ibm850 ibm851 ibm852 \
|
||||
- ibm855 ibm857 ibm860 ibm861 ibm862 ibm863 ibm864 \
|
||||
- ibm865 ibm868 ibm869 ibm875 ibm880 ibm918 ibm1004 \
|
||||
- ibm1026 cp1125 cp1250 cp1251 cp1252 cp1253 cp1254 \
|
||||
- cp1256 cp1257 ibm866 iso8859-5 iso8859-7 iso8859-8 \
|
||||
- iso8859-10 macintosh iec_p27-1 asmo_449 \
|
||||
+ ibm855 ibm857 ibm858 ibm860 ibm861 ibm862 ibm863 \
|
||||
+ ibm864 ibm865 ibm868 ibm869 ibm875 ibm880 ibm918 \
|
||||
+ ibm1004 ibm1026 cp1125 cp1250 cp1251 cp1252 cp1253 \
|
||||
+ cp1254 cp1256 cp1257 ibm866 iso8859-5 iso8859-7 \
|
||||
+ iso8859-8 iso8859-10 macintosh iec_p27-1 asmo_449 \
|
||||
csn_369103 cwi dec-mcs ecma-cyrillic gost_19768-74 \
|
||||
greek-ccitt greek7 greek7-old inis inis-8 \
|
||||
inis-cyrillic iso_2033 iso_5427 iso_5427-ext \
|
||||
diff --git a/iconvdata/gconv-modules b/iconvdata/gconv-modules
|
||||
index d640ea4eadab2382..039b1b5b385619a8 100644
|
||||
--- a/iconvdata/gconv-modules
|
||||
+++ b/iconvdata/gconv-modules
|
||||
@@ -743,6 +743,13 @@ alias OSF10020352// IBM850//
|
||||
module IBM850// INTERNAL IBM850 1
|
||||
module INTERNAL IBM850// IBM850 1
|
||||
|
||||
+# from to module cost
|
||||
+alias CP858// IBM858//
|
||||
+alias 858// IBM858//
|
||||
+alias CSPC858MULTILINGUAL// IBM858//
|
||||
+module IBM858// INTERNAL IBM858 1
|
||||
+module INTERNAL IBM858// IBM858 1
|
||||
+
|
||||
# from to module cost
|
||||
alias CP851// IBM851//
|
||||
alias 851// IBM851//
|
||||
diff --git a/iconvdata/ibm858.c b/iconvdata/ibm858.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..ed2a48e3cf79e2b9
|
||||
--- /dev/null
|
||||
+++ b/iconvdata/ibm858.c
|
||||
@@ -0,0 +1,27 @@
|
||||
+/* Conversion from and to IBM858.
|
||||
+ Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+/* Get the conversion table. */
|
||||
+#define TABLES <ibm858.h>
|
||||
+
|
||||
+#define CHARSET_NAME "IBM858//"
|
||||
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
+
|
||||
+#include <8bit-gap.c>
|
||||
diff --git a/iconvdata/tst-tables.sh b/iconvdata/tst-tables.sh
|
||||
index 77d9d182c7dc2205..2ee6cf0d0b25961b 100755
|
||||
--- a/iconvdata/tst-tables.sh
|
||||
+++ b/iconvdata/tst-tables.sh
|
||||
@@ -125,6 +125,7 @@ cat <<EOF |
|
||||
IBM855
|
||||
IBM856
|
||||
IBM857
|
||||
+ IBM858
|
||||
IBM860
|
||||
IBM861
|
||||
IBM862
|
||||
diff --git a/localedata/charmaps/IBM858 b/localedata/charmaps/IBM858
|
||||
new file mode 100644
|
||||
index 0000000000000000..d8600e2456c87b48
|
||||
--- /dev/null
|
||||
+++ b/localedata/charmaps/IBM858
|
||||
@@ -0,0 +1,281 @@
|
||||
+<code_set_name> IBM858
|
||||
+<comment_char> %
|
||||
+<escape_char> /
|
||||
+% version: 1.0
|
||||
+% source: ftp://ftp.software.ibm.com/software/globalization/gcoc/attachments/CP00858.txt, 1998
|
||||
+
|
||||
+% source: UNICODE 1.0
|
||||
+
|
||||
+% This code page is identical to code page 850 except that X'D5'
|
||||
+% has been changed from LI61 (dotless i) to SC20 (euro symbol).
|
||||
+
|
||||
+% The code points from /x01 to /x1f in this file have the same mapping
|
||||
+% as those in ANSI_X3.4-1968. That means they disagree with with CP00858.txt
|
||||
+% in that range. For example, this file and ANSI_X3.4-1968 have:
|
||||
+% “<U0001> /x01 START OF HEADING (SOH)”
|
||||
+% whereas CP00858.txt has:
|
||||
+% “01 SS000000 Smiling Face”
|
||||
+% That means that CP00858.txt is not really ASCII-compatible and to make
|
||||
+% it ASCII-compatible we deviate fro CP00858.txt in the code points from /x01
|
||||
+% to /x1f.
|
||||
+
|
||||
+% alias CP858
|
||||
+% alias 858
|
||||
+CHARMAP
|
||||
+<U0000> /x00 NULL (NUL)
|
||||
+<U0001> /x01 START OF HEADING (SOH)
|
||||
+<U0002> /x02 START OF TEXT (STX)
|
||||
+<U0003> /x03 END OF TEXT (ETX)
|
||||
+<U0004> /x04 END OF TRANSMISSION (EOT)
|
||||
+<U0005> /x05 ENQUIRY (ENQ)
|
||||
+<U0006> /x06 ACKNOWLEDGE (ACK)
|
||||
+<U0007> /x07 BELL (BEL)
|
||||
+<U0008> /x08 BACKSPACE (BS)
|
||||
+<U0009> /x09 CHARACTER TABULATION (HT)
|
||||
+<U000A> /x0a LINE FEED (LF)
|
||||
+<U000B> /x0b LINE TABULATION (VT)
|
||||
+<U000C> /x0c FORM FEED (FF)
|
||||
+<U000D> /x0d CARRIAGE RETURN (CR)
|
||||
+<U000E> /x0e SHIFT OUT (SO)
|
||||
+<U000F> /x0f SHIFT IN (SI)
|
||||
+<U0010> /x10 DATALINK ESCAPE (DLE)
|
||||
+<U0011> /x11 DEVICE CONTROL ONE (DC1)
|
||||
+<U0012> /x12 DEVICE CONTROL TWO (DC2)
|
||||
+<U0013> /x13 DEVICE CONTROL THREE (DC3)
|
||||
+<U0014> /x14 DEVICE CONTROL FOUR (DC4)
|
||||
+<U0015> /x15 NEGATIVE ACKNOWLEDGE (NAK)
|
||||
+<U0016> /x16 SYNCHRONOUS IDLE (SYN)
|
||||
+<U0017> /x17 END OF TRANSMISSION BLOCK (ETB)
|
||||
+<U0018> /x18 CANCEL (CAN)
|
||||
+<U0019> /x19 END OF MEDIUM (EM)
|
||||
+<U001A> /x1a SUBSTITUTE (SUB)
|
||||
+<U001B> /x1b ESCAPE (ESC)
|
||||
+<U001C> /x1c FILE SEPARATOR (IS4)
|
||||
+<U001D> /x1d GROUP SEPARATOR (IS3)
|
||||
+<U001E> /x1e RECORD SEPARATOR (IS2)
|
||||
+<U001F> /x1f UNIT SEPARATOR (IS1)
|
||||
+<U0020> /x20 SPACE
|
||||
+<U0021> /x21 EXCLAMATION MARK
|
||||
+<U0022> /x22 QUOTATION MARK
|
||||
+<U0023> /x23 NUMBER SIGN
|
||||
+<U0024> /x24 DOLLAR SIGN
|
||||
+<U0025> /x25 PERCENT SIGN
|
||||
+<U0026> /x26 AMPERSAND
|
||||
+<U0027> /x27 APOSTROPHE
|
||||
+<U0028> /x28 LEFT PARENTHESIS
|
||||
+<U0029> /x29 RIGHT PARENTHESIS
|
||||
+<U002A> /x2a ASTERISK
|
||||
+<U002B> /x2b PLUS SIGN
|
||||
+<U002C> /x2c COMMA
|
||||
+<U002D> /x2d HYPHEN-MINUS
|
||||
+<U002E> /x2e FULL STOP
|
||||
+<U002F> /x2f SOLIDUS
|
||||
+<U0030> /x30 DIGIT ZERO
|
||||
+<U0031> /x31 DIGIT ONE
|
||||
+<U0032> /x32 DIGIT TWO
|
||||
+<U0033> /x33 DIGIT THREE
|
||||
+<U0034> /x34 DIGIT FOUR
|
||||
+<U0035> /x35 DIGIT FIVE
|
||||
+<U0036> /x36 DIGIT SIX
|
||||
+<U0037> /x37 DIGIT SEVEN
|
||||
+<U0038> /x38 DIGIT EIGHT
|
||||
+<U0039> /x39 DIGIT NINE
|
||||
+<U003A> /x3a COLON
|
||||
+<U003B> /x3b SEMICOLON
|
||||
+<U003C> /x3c LESS-THAN SIGN
|
||||
+<U003D> /x3d EQUALS SIGN
|
||||
+<U003E> /x3e GREATER-THAN SIGN
|
||||
+<U003F> /x3f QUESTION MARK
|
||||
+<U0040> /x40 COMMERCIAL AT
|
||||
+<U0041> /x41 LATIN CAPITAL LETTER A
|
||||
+<U0042> /x42 LATIN CAPITAL LETTER B
|
||||
+<U0043> /x43 LATIN CAPITAL LETTER C
|
||||
+<U0044> /x44 LATIN CAPITAL LETTER D
|
||||
+<U0045> /x45 LATIN CAPITAL LETTER E
|
||||
+<U0046> /x46 LATIN CAPITAL LETTER F
|
||||
+<U0047> /x47 LATIN CAPITAL LETTER G
|
||||
+<U0048> /x48 LATIN CAPITAL LETTER H
|
||||
+<U0049> /x49 LATIN CAPITAL LETTER I
|
||||
+<U004A> /x4a LATIN CAPITAL LETTER J
|
||||
+<U004B> /x4b LATIN CAPITAL LETTER K
|
||||
+<U004C> /x4c LATIN CAPITAL LETTER L
|
||||
+<U004D> /x4d LATIN CAPITAL LETTER M
|
||||
+<U004E> /x4e LATIN CAPITAL LETTER N
|
||||
+<U004F> /x4f LATIN CAPITAL LETTER O
|
||||
+<U0050> /x50 LATIN CAPITAL LETTER P
|
||||
+<U0051> /x51 LATIN CAPITAL LETTER Q
|
||||
+<U0052> /x52 LATIN CAPITAL LETTER R
|
||||
+<U0053> /x53 LATIN CAPITAL LETTER S
|
||||
+<U0054> /x54 LATIN CAPITAL LETTER T
|
||||
+<U0055> /x55 LATIN CAPITAL LETTER U
|
||||
+<U0056> /x56 LATIN CAPITAL LETTER V
|
||||
+<U0057> /x57 LATIN CAPITAL LETTER W
|
||||
+<U0058> /x58 LATIN CAPITAL LETTER X
|
||||
+<U0059> /x59 LATIN CAPITAL LETTER Y
|
||||
+<U005A> /x5a LATIN CAPITAL LETTER Z
|
||||
+<U005B> /x5b LEFT SQUARE BRACKET
|
||||
+<U005C> /x5c REVERSE SOLIDUS
|
||||
+<U005D> /x5d RIGHT SQUARE BRACKET
|
||||
+<U005E> /x5e CIRCUMFLEX ACCENT
|
||||
+<U005F> /x5f LOW LINE
|
||||
+<U0060> /x60 GRAVE ACCENT
|
||||
+<U0061> /x61 LATIN SMALL LETTER A
|
||||
+<U0062> /x62 LATIN SMALL LETTER B
|
||||
+<U0063> /x63 LATIN SMALL LETTER C
|
||||
+<U0064> /x64 LATIN SMALL LETTER D
|
||||
+<U0065> /x65 LATIN SMALL LETTER E
|
||||
+<U0066> /x66 LATIN SMALL LETTER F
|
||||
+<U0067> /x67 LATIN SMALL LETTER G
|
||||
+<U0068> /x68 LATIN SMALL LETTER H
|
||||
+<U0069> /x69 LATIN SMALL LETTER I
|
||||
+<U006A> /x6a LATIN SMALL LETTER J
|
||||
+<U006B> /x6b LATIN SMALL LETTER K
|
||||
+<U006C> /x6c LATIN SMALL LETTER L
|
||||
+<U006D> /x6d LATIN SMALL LETTER M
|
||||
+<U006E> /x6e LATIN SMALL LETTER N
|
||||
+<U006F> /x6f LATIN SMALL LETTER O
|
||||
+<U0070> /x70 LATIN SMALL LETTER P
|
||||
+<U0071> /x71 LATIN SMALL LETTER Q
|
||||
+<U0072> /x72 LATIN SMALL LETTER R
|
||||
+<U0073> /x73 LATIN SMALL LETTER S
|
||||
+<U0074> /x74 LATIN SMALL LETTER T
|
||||
+<U0075> /x75 LATIN SMALL LETTER U
|
||||
+<U0076> /x76 LATIN SMALL LETTER V
|
||||
+<U0077> /x77 LATIN SMALL LETTER W
|
||||
+<U0078> /x78 LATIN SMALL LETTER X
|
||||
+<U0079> /x79 LATIN SMALL LETTER Y
|
||||
+<U007A> /x7a LATIN SMALL LETTER Z
|
||||
+<U007B> /x7b LEFT CURLY BRACKET
|
||||
+<U007C> /x7c VERTICAL LINE
|
||||
+<U007D> /x7d RIGHT CURLY BRACKET
|
||||
+<U007E> /x7e TILDE
|
||||
+<U007F> /x7f DELETE (DEL)
|
||||
+<U00C7> /x80 LATIN CAPITAL LETTER C WITH CEDILLA
|
||||
+<U00FC> /x81 LATIN SMALL LETTER U WITH DIAERESIS
|
||||
+<U00E9> /x82 LATIN SMALL LETTER E WITH ACUTE
|
||||
+<U00E2> /x83 LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||
+<U00E4> /x84 LATIN SMALL LETTER A WITH DIAERESIS
|
||||
+<U00E0> /x85 LATIN SMALL LETTER A WITH GRAVE
|
||||
+<U00E5> /x86 LATIN SMALL LETTER A WITH RING ABOVE
|
||||
+<U00E7> /x87 LATIN SMALL LETTER C WITH CEDILLA
|
||||
+<U00EA> /x88 LATIN SMALL LETTER E WITH CIRCUMFLEX
|
||||
+<U00EB> /x89 LATIN SMALL LETTER E WITH DIAERESIS
|
||||
+<U00E8> /x8a LATIN SMALL LETTER E WITH GRAVE
|
||||
+<U00EF> /x8b LATIN SMALL LETTER I WITH DIAERESIS
|
||||
+<U00EE> /x8c LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||
+<U00EC> /x8d LATIN SMALL LETTER I WITH GRAVE
|
||||
+<U00C4> /x8e LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||
+<U00C5> /x8f LATIN CAPITAL LETTER A WITH RING ABOVE
|
||||
+<U00C9> /x90 LATIN CAPITAL LETTER E WITH ACUTE
|
||||
+<U00E6> /x91 LATIN SMALL LETTER AE
|
||||
+<U00C6> /x92 LATIN CAPITAL LETTER AE
|
||||
+<U00F4> /x93 LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||
+<U00F6> /x94 LATIN SMALL LETTER O WITH DIAERESIS
|
||||
+<U00F2> /x95 LATIN SMALL LETTER O WITH GRAVE
|
||||
+<U00FB> /x96 LATIN SMALL LETTER U WITH CIRCUMFLEX
|
||||
+<U00F9> /x97 LATIN SMALL LETTER U WITH GRAVE
|
||||
+<U00FF> /x98 LATIN SMALL LETTER Y WITH DIAERESIS
|
||||
+<U00D6> /x99 LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
+<U00DC> /x9a LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||
+<U00F8> /x9b LATIN SMALL LETTER O WITH STROKE
|
||||
+<U00A3> /x9c POUND SIGN
|
||||
+<U00D8> /x9d LATIN CAPITAL LETTER O WITH STROKE
|
||||
+<U00D7> /x9e MULTIPLICATION SIGN
|
||||
+<U0192> /x9f LATIN SMALL LETTER F WITH HOOK
|
||||
+<U00E1> /xa0 LATIN SMALL LETTER A WITH ACUTE
|
||||
+<U00ED> /xa1 LATIN SMALL LETTER I WITH ACUTE
|
||||
+<U00F3> /xa2 LATIN SMALL LETTER O WITH ACUTE
|
||||
+<U00FA> /xa3 LATIN SMALL LETTER U WITH ACUTE
|
||||
+<U00F1> /xa4 LATIN SMALL LETTER N WITH TILDE
|
||||
+<U00D1> /xa5 LATIN CAPITAL LETTER N WITH TILDE
|
||||
+<U00AA> /xa6 FEMININE ORDINAL INDICATOR
|
||||
+<U00BA> /xa7 MASCULINE ORDINAL INDICATOR
|
||||
+<U00BF> /xa8 INVERTED QUESTION MARK
|
||||
+<U00AE> /xa9 REGISTERED SIGN
|
||||
+<U00AC> /xaa NOT SIGN
|
||||
+<U00BD> /xab VULGAR FRACTION ONE HALF
|
||||
+<U00BC> /xac VULGAR FRACTION ONE QUARTER
|
||||
+<U00A1> /xad INVERTED EXCLAMATION MARK
|
||||
+<U00AB> /xae LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
+<U00BB> /xaf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
+<U2591> /xb0 LIGHT SHADE
|
||||
+<U2592> /xb1 MEDIUM SHADE
|
||||
+<U2593> /xb2 DARK SHADE
|
||||
+<U2502> /xb3 BOX DRAWINGS LIGHT VERTICAL
|
||||
+<U2524> /xb4 BOX DRAWINGS LIGHT VERTICAL AND LEFT
|
||||
+<U00C1> /xb5 LATIN CAPITAL LETTER A WITH ACUTE
|
||||
+<U00C2> /xb6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||
+<U00C0> /xb7 LATIN CAPITAL LETTER A WITH GRAVE
|
||||
+<U00A9> /xb8 COPYRIGHT SIGN
|
||||
+<U2563> /xb9 BOX DRAWINGS DOUBLE VERTICAL AND LEFT
|
||||
+<U2551> /xba BOX DRAWINGS DOUBLE VERTICAL
|
||||
+<U2557> /xbb BOX DRAWINGS DOUBLE DOWN AND LEFT
|
||||
+<U255D> /xbc BOX DRAWINGS DOUBLE UP AND LEFT
|
||||
+<U00A2> /xbd CENT SIGN
|
||||
+<U00A5> /xbe YEN SIGN
|
||||
+<U2510> /xbf BOX DRAWINGS LIGHT DOWN AND LEFT
|
||||
+<U2514> /xc0 BOX DRAWINGS LIGHT UP AND RIGHT
|
||||
+<U2534> /xc1 BOX DRAWINGS LIGHT UP AND HORIZONTAL
|
||||
+<U252C> /xc2 BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
|
||||
+<U251C> /xc3 BOX DRAWINGS LIGHT VERTICAL AND RIGHT
|
||||
+<U2500> /xc4 BOX DRAWINGS LIGHT HORIZONTAL
|
||||
+<U253C> /xc5 BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
|
||||
+<U00E3> /xc6 LATIN SMALL LETTER A WITH TILDE
|
||||
+<U00C3> /xc7 LATIN CAPITAL LETTER A WITH TILDE
|
||||
+<U255A> /xc8 BOX DRAWINGS DOUBLE UP AND RIGHT
|
||||
+<U2554> /xc9 BOX DRAWINGS DOUBLE DOWN AND RIGHT
|
||||
+<U2569> /xca BOX DRAWINGS DOUBLE UP AND HORIZONTAL
|
||||
+<U2566> /xcb BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
|
||||
+<U2560> /xcc BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
|
||||
+<U2550> /xcd BOX DRAWINGS DOUBLE HORIZONTAL
|
||||
+<U256C> /xce BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
|
||||
+<U00A4> /xcf CURRENCY SIGN
|
||||
+<U00F0> /xd0 LATIN SMALL LETTER ETH (Icelandic)
|
||||
+<U00D0> /xd1 LATIN CAPITAL LETTER ETH (Icelandic)
|
||||
+<U00CA> /xd2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
||||
+<U00CB> /xd3 LATIN CAPITAL LETTER E WITH DIAERESIS
|
||||
+<U00C8> /xd4 LATIN CAPITAL LETTER E WITH GRAVE
|
||||
+<U20AC> /xd5 EURO SIGN
|
||||
+<U00CD> /xd6 LATIN CAPITAL LETTER I WITH ACUTE
|
||||
+<U00CE> /xd7 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||
+<U00CF> /xd8 LATIN CAPITAL LETTER I WITH DIAERESIS
|
||||
+<U2518> /xd9 BOX DRAWINGS LIGHT UP AND LEFT
|
||||
+<U250C> /xda BOX DRAWINGS LIGHT DOWN AND RIGHT
|
||||
+<U2588> /xdb FULL BLOCK
|
||||
+<U2584> /xdc LOWER HALF BLOCK
|
||||
+<U00A6> /xdd BROKEN BAR
|
||||
+<U00CC> /xde LATIN CAPITAL LETTER I WITH GRAVE
|
||||
+<U2580> /xdf UPPER HALF BLOCK
|
||||
+<U00D3> /xe0 LATIN CAPITAL LETTER O WITH ACUTE
|
||||
+<U00DF> /xe1 LATIN SMALL LETTER SHARP S (German)
|
||||
+<U00D4> /xe2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||
+<U00D2> /xe3 LATIN CAPITAL LETTER O WITH GRAVE
|
||||
+<U00F5> /xe4 LATIN SMALL LETTER O WITH TILDE
|
||||
+<U00D5> /xe5 LATIN CAPITAL LETTER O WITH TILDE
|
||||
+<U00B5> /xe6 MICRO SIGN
|
||||
+<U00FE> /xe7 LATIN SMALL LETTER THORN (Icelandic)
|
||||
+<U00DE> /xe8 LATIN CAPITAL LETTER THORN (Icelandic)
|
||||
+<U00DA> /xe9 LATIN CAPITAL LETTER U WITH ACUTE
|
||||
+<U00DB> /xea LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
||||
+<U00D9> /xeb LATIN CAPITAL LETTER U WITH GRAVE
|
||||
+<U00FD> /xec LATIN SMALL LETTER Y WITH ACUTE
|
||||
+<U00DD> /xed LATIN CAPITAL LETTER Y WITH ACUTE
|
||||
+<U00AF> /xee MACRON
|
||||
+<U00B4> /xef ACUTE ACCENT
|
||||
+<U00AD> /xf0 SOFT HYPHEN
|
||||
+<U00B1> /xf1 PLUS-MINUS SIGN
|
||||
+<U2017> /xf2 DOUBLE LOW LINE
|
||||
+<U00BE> /xf3 VULGAR FRACTION THREE QUARTERS
|
||||
+<U00B6> /xf4 PILCROW SIGN
|
||||
+<U00A7> /xf5 SECTION SIGN
|
||||
+<U00F7> /xf6 DIVISION SIGN
|
||||
+<U00B8> /xf7 CEDILLA
|
||||
+<U00B0> /xf8 DEGREE SIGN
|
||||
+<U00A8> /xf9 DIAERESIS
|
||||
+<U00B7> /xfa MIDDLE DOT
|
||||
+<U00B9> /xfb SUPERSCRIPT ONE
|
||||
+<U00B3> /xfc SUPERSCRIPT THREE
|
||||
+<U00B2> /xfd SUPERSCRIPT TWO
|
||||
+<U25A0> /xfe BLACK SQUARE
|
||||
+<U00A0> /xff NO-BREAK SPACE
|
||||
+END CHARMAP
|
|
@ -0,0 +1,54 @@
|
|||
Backporting changes to the support/ subdirectory.
|
||||
|
||||
This is kept separate from glibc-rh1418978-1.patch to simplify rebases
|
||||
of the support/ subdirectory. Changes here should be restricted to
|
||||
things that absolutely cannot be upstreamed at this point (such as
|
||||
support for older compilers).
|
||||
|
||||
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
|
||||
index 16c1e448b990e386..a2d5e0cbd736f998 100644
|
||||
--- a/support/blob_repeat.c
|
||||
+++ b/support/blob_repeat.c
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
|
||||
+/* For check_mul_overflow_size_t. */
|
||||
+#include <malloc/malloc-internal.h>
|
||||
+
|
||||
/* Small allocations should use malloc directly instead of the mmap
|
||||
optimization because mappings carry a lot of overhead. */
|
||||
static const size_t maximum_small_size = 4 * 1024 * 1024;
|
||||
@@ -118,8 +121,8 @@ minimum_stride_size (size_t page_size, size_t element_size)
|
||||
common multiple, it appears only once. Therefore, shift one
|
||||
factor. */
|
||||
size_t multiple;
|
||||
- if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
|
||||
- &multiple))
|
||||
+ if (check_mul_overflow_size_t (page_size >> common_zeros, element_size,
|
||||
+ &multiple))
|
||||
return 0;
|
||||
return multiple;
|
||||
}
|
||||
@@ -255,7 +258,7 @@ support_blob_repeat_allocate (const void *element, size_t element_size,
|
||||
size_t count)
|
||||
{
|
||||
size_t total_size;
|
||||
- if (__builtin_mul_overflow (element_size, count, &total_size))
|
||||
+ if (check_mul_overflow_size_t (element_size, count, &total_size))
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return (struct support_blob_repeat) { 0 };
|
||||
diff --git a/support/links-dso-program.cc b/support/links-dso-program.cc
|
||||
index dba6976c0609a332..8ff3155dd7fcd757 100644
|
||||
--- a/support/links-dso-program.cc
|
||||
+++ b/support/links-dso-program.cc
|
||||
@@ -1,3 +1,8 @@
|
||||
+/* Change for backporting: The build system does not define _ISOMAC
|
||||
+ for us because the tests-internal changes have not been
|
||||
+ backported. */
|
||||
+#define _ISOMAC 1
|
||||
+
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
|
@ -0,0 +1,318 @@
|
|||
The commit included in this patch only incidentally fixes the problem
|
||||
reported in bug 1427734: In each of the IBM9xx character sets referenced in
|
||||
this patch, the removal of the "break" statement means that the subsequent
|
||||
increment of "inptr" is executed instead of being skipped. This allows
|
||||
conversion to progress instead of hanging.
|
||||
|
||||
commit 692de4b3960dc90bdcfb871513ee4d81d314cf69
|
||||
Author: Martin Sebor <msebor@redhat.com>
|
||||
Date: Fri Jan 15 11:25:13 2016 -0700
|
||||
|
||||
Have iconv accept redundant escape sequences in IBM900, IBM903, IBM905,
|
||||
IBM907, and IBM909.
|
||||
|
||||
Patch for bug #17197 changes the encoder to avoid generating redundant
|
||||
shift sequences. However, those sequences may already be present in
|
||||
data encododed by prior versions of the encoder. This change modifies
|
||||
the decoder to also avoid rejecting redundant shift sequences.
|
||||
|
||||
[BZ #19432]
|
||||
* iconvdata/Makefile: Add bug-iconv11.
|
||||
* iconvdata/bug-iconv11.c: New test.
|
||||
* iconvdata/ibm930.c: Do not reject redundant shift sequences.
|
||||
* iconvdata/ibm933.c: Same.
|
||||
* iconvdata/ibm935.c: Same.
|
||||
* iconvdata/ibm937.c: Same.
|
||||
* iconvdata/ibm939.c: Same.
|
||||
|
||||
# Conflicts:
|
||||
# iconvdata/Makefile
|
||||
|
||||
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
|
||||
index 0ec67554ca4c29ea..c4e6c510d7abc055 100644
|
||||
--- a/iconvdata/Makefile
|
||||
+++ b/iconvdata/Makefile
|
||||
@@ -68,7 +68,7 @@ include ../Makeconfig
|
||||
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-iconv12
|
||||
+ bug-iconv10 bug-iconv11 bug-iconv12
|
||||
ifeq ($(have-thread-library),yes)
|
||||
tests += bug-iconv3
|
||||
endif
|
||||
diff --git a/iconvdata/bug-iconv11.c b/iconvdata/bug-iconv11.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6cdc07d79883454d
|
||||
--- /dev/null
|
||||
+++ b/iconvdata/bug-iconv11.c
|
||||
@@ -0,0 +1,114 @@
|
||||
+/* bug 19432: iconv rejects redundant escape sequences in IBM903,
|
||||
+ IBM905, IBM907, and IBM909
|
||||
+
|
||||
+ Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <iconv.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+// The longest test input sequence.
|
||||
+#define MAXINBYTES 8
|
||||
+#define MAXOUTBYTES (MAXINBYTES * MB_LEN_MAX)
|
||||
+
|
||||
+/* Verify that a conversion of the INPUT sequence consisting of
|
||||
+ INBYTESLEFT bytes in the encoding specified by the codeset
|
||||
+ named by FROM_SET is successful.
|
||||
+ Return 0 on success, non-zero on iconv() failure. */
|
||||
+
|
||||
+static int
|
||||
+test_ibm93x (const char *from_set, const char *input, size_t inbytesleft)
|
||||
+{
|
||||
+ const char to_set[] = "UTF-8";
|
||||
+ iconv_t cd = iconv_open (to_set, from_set);
|
||||
+ if (cd == (iconv_t) -1)
|
||||
+ {
|
||||
+ printf ("iconv_open(\"%s\", \"%s\"): %s\n",
|
||||
+ from_set, to_set, strerror (errno));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ char output [MAXOUTBYTES];
|
||||
+ size_t outbytesleft = sizeof output;
|
||||
+
|
||||
+ char *inbuf = (char*)input;
|
||||
+ char *outbuf = output;
|
||||
+
|
||||
+ printf ("iconv(cd, %p, %zu, %p, %zu)\n",
|
||||
+ inbuf, inbytesleft, outbuf, outbytesleft);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ size_t ret = iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
|
||||
+ printf (" ==> %td: %s\n"
|
||||
+ " inbuf%+td, inbytesleft=%zu, outbuf%+td, outbytesleft=%zu\n",
|
||||
+ ret, strerror (errno),
|
||||
+ inbuf - input, inbytesleft, outbuf - output, outbytesleft);
|
||||
+
|
||||
+ // Return 0 on success, non-zero on iconv() failure.
|
||||
+ return ret == (size_t)-1 || errno;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ // State-dependent encodings to exercise.
|
||||
+ static const char* const to_code[] = {
|
||||
+ "IBM930", "IBM933", "IBM935", "IBM937", "IBM939"
|
||||
+ };
|
||||
+
|
||||
+ static const size_t ncodesets = sizeof to_code / sizeof *to_code;
|
||||
+
|
||||
+ static const struct {
|
||||
+ char txt[MAXINBYTES];
|
||||
+ size_t len;
|
||||
+ } input[] = {
|
||||
+#define DATA(s) { s, sizeof s - 1 }
|
||||
+ /* <SI>: denotes the shift-in 1-byte escape sequence, changing
|
||||
+ the encoder from a sigle-byte encoding to multibyte
|
||||
+ <SO>: denotes the shift-out 1-byte escape sequence, switching
|
||||
+ the encoder from a multibyte to a single-byte state */
|
||||
+
|
||||
+ DATA ("\x0e"), // <SI> (not redundant)
|
||||
+ DATA ("\x0f"), // <S0> (redundant with initial state)
|
||||
+ DATA ("\x0e\x0e"), // <SI><SI>
|
||||
+ DATA ("\x0e\x0f\x0f"), // <SI><SO><SO>
|
||||
+ DATA ("\x0f\x0f"), // <SO><SO>
|
||||
+ DATA ("\x0f\x0e\x0e"), // <SO><SI><SI>
|
||||
+ DATA ("\x0e\x0f\xc7\x0f"), // <SI><SO><G><SO>
|
||||
+ DATA ("\xc7\x0f") // <G><SO> (redundant with initial state)
|
||||
+ };
|
||||
+
|
||||
+ static const size_t ninputs = sizeof input / sizeof *input;
|
||||
+
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ size_t i, j;
|
||||
+
|
||||
+ /* Iterate over the IBM93x codesets above and exercise each with
|
||||
+ the input sequences above. */
|
||||
+ for (i = 0; i != ncodesets; ++i)
|
||||
+ for (j = 0; j != ninputs; ++j)
|
||||
+ ret += test_ibm93x (to_code [i], input [i].txt, input [i].len);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
diff --git a/iconvdata/ibm930.c b/iconvdata/ibm930.c
|
||||
index 636141114f506985..88413ccfbabfdc35 100644
|
||||
--- a/iconvdata/ibm930.c
|
||||
+++ b/iconvdata/ibm930.c
|
||||
@@ -105,24 +105,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; \
|
||||
} \
|
||||
else 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 --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
|
||||
index 8b9e5780a36a454a..335d385551fee86e 100644
|
||||
--- a/iconvdata/ibm933.c
|
||||
+++ b/iconvdata/ibm933.c
|
||||
@@ -104,24 +104,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; \
|
||||
} \
|
||||
else 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 --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
|
||||
index 4e2d99ab56d7f0d2..520d28a4e9a690fc 100644
|
||||
--- a/iconvdata/ibm935.c
|
||||
+++ b/iconvdata/ibm935.c
|
||||
@@ -104,24 +104,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; \
|
||||
} \
|
||||
else 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 --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
|
||||
index 1e468871b783e78d..64563bb8bf0441ff 100644
|
||||
--- a/iconvdata/ibm937.c
|
||||
+++ b/iconvdata/ibm937.c
|
||||
@@ -104,24 +104,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; \
|
||||
} \
|
||||
else 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 --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
|
||||
index 2060b0c329df0c86..4f73e2e55c94972d 100644
|
||||
--- a/iconvdata/ibm939.c
|
||||
+++ b/iconvdata/ibm939.c
|
||||
@@ -104,24 +104,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; \
|
||||
} \
|
||||
else 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; \
|
|
@ -0,0 +1,34 @@
|
|||
commit ab9f6255ab4e7aa353ec1b61b4f332bf00cea4d0
|
||||
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
|
||||
Date: Wed Jan 20 08:32:37 2016 +0100
|
||||
|
||||
S390: Fix build error in iconvdata/bug-iconv11.c.
|
||||
|
||||
This fixes the following build error on S390 31bit while building the test
|
||||
iconvdata/bug-iconv11.c with gcc 5.3:
|
||||
bug-iconv11.c: In function ‘test_ibm93x’:
|
||||
bug-iconv11.c:59:11: error: format ‘%td’ expects argument of type ‘ptrdiff_t’, but argument 2 has type ‘size_t {aka long unsigned int}’ [-Werror=format=]
|
||||
printf (" ==> %td: %s\n"
|
||||
^
|
||||
cc1: all warnings being treated as errors
|
||||
|
||||
This patch uses %zu format specifier for argument size_t ret instead of %td.
|
||||
|
||||
ChangeLog:
|
||||
|
||||
* iconvdata/bug-iconv11.c (test_ibm93x):
|
||||
Use %zu printf format specifier for size_t argument.
|
||||
|
||||
diff --git a/iconvdata/bug-iconv11.c b/iconvdata/bug-iconv11.c
|
||||
index 6cdc07d79883454d..5b9d9a36af0b4bcf 100644
|
||||
--- a/iconvdata/bug-iconv11.c
|
||||
+++ b/iconvdata/bug-iconv11.c
|
||||
@@ -56,7 +56,7 @@ test_ibm93x (const char *from_set, const char *input, size_t inbytesleft)
|
||||
|
||||
errno = 0;
|
||||
size_t ret = iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
|
||||
- printf (" ==> %td: %s\n"
|
||||
+ printf (" ==> %zu: %s\n"
|
||||
" inbuf%+td, inbytesleft=%zu, outbuf%+td, outbytesleft=%zu\n",
|
||||
ret, strerror (errno),
|
||||
inbuf - input, inbytesleft, outbuf - output, outbytesleft);
|
|
@ -0,0 +1,40 @@
|
|||
Add missing newlines to __libc_fatal error messages. This was
|
||||
implemented upstream in commits a6e8926f8d49a213a9abb1a61f6af964f612ab7f
|
||||
("[BZ #20271] Add newlines in __libc_fatal calls.") and
|
||||
36f30c104fe3addd4d864e276202c6b934f825b7
|
||||
("__netlink_assert_response: Add more __libc_fatal newlines [BZ #20271]").
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||
index b570e93db840fec1..434b50d20b67d130 100644
|
||||
--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||
+++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||
@@ -73,12 +73,12 @@ __netlink_assert_response (int fd, ssize_t result)
|
||||
char message[200];
|
||||
if (family < 0)
|
||||
__snprintf (message, sizeof (message),
|
||||
- "Unexpected error %d on netlink descriptor %d",
|
||||
+ "Unexpected error %d on netlink descriptor %d\n",
|
||||
error_code, fd);
|
||||
else
|
||||
__snprintf (message, sizeof (message),
|
||||
"Unexpected error %d on netlink descriptor %d"
|
||||
- " (address family %d)",
|
||||
+ " (address family %d)\n",
|
||||
error_code, fd, family);
|
||||
__libc_fatal (message);
|
||||
}
|
||||
@@ -93,12 +93,12 @@ __netlink_assert_response (int fd, ssize_t result)
|
||||
if (family < 0)
|
||||
__snprintf (message, sizeof (message),
|
||||
"Unexpected netlink response of size %zd"
|
||||
- " on descriptor %d",
|
||||
+ " on descriptor %d\n",
|
||||
result, fd);
|
||||
else
|
||||
__snprintf (message, sizeof (message),
|
||||
"Unexpected netlink response of size %zd"
|
||||
- " on descriptor %d (address family %d)",
|
||||
+ " on descriptor %d (address family %d)\n",
|
||||
result, fd, family);
|
||||
__libc_fatal (message);
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
commit 2eecc8afd02d8c65cf098cbae4de87f332dc21bd
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 9 12:48:41 2015 +0100
|
||||
|
||||
Terminate process on invalid netlink response from kernel [BZ #12926]
|
||||
|
||||
The recvmsg system calls for netlink sockets have been particularly
|
||||
prone to picking up unrelated data after a file descriptor race
|
||||
(where the descriptor is closed and reopened concurrently in a
|
||||
multi-threaded process, as the result of a file descriptor
|
||||
management issue elsewhere). This commit adds additional error
|
||||
checking and aborts the process if a datagram of unexpected length
|
||||
(without the netlink header) is received, or an error code which
|
||||
cannot happen due to the way the netlink socket is used.
|
||||
|
||||
[BZ #12926]
|
||||
Terminate process on invalid netlink response.
|
||||
* sysdeps/unix/sysv/linux/netlinkaccess.h
|
||||
(__netlink_assert_response): Declare.
|
||||
* sysdeps/unix/sysv/linux/netlink_assert_response.c: New file.
|
||||
* sysdeps/unix/sysv/linux/Makefile [$(subdir) == inet]
|
||||
(sysdep_routines): Add netlink_assert_response.
|
||||
* sysdeps/unix/sysv/linux/check_native.c (__check_native): Call
|
||||
__netlink_assert_response.
|
||||
* sysdeps/unix/sysv/linux/check_pf.c (make_request): Likewise.
|
||||
* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Likewise.
|
||||
* sysdeps/unix/sysv/linux/Versions (GLIBC_PRIVATE): Add
|
||||
__netlink_assert_response.
|
||||
|
||||
Conflicts:
|
||||
sysdeps/unix/sysv/linux/check_pf.c
|
||||
Upstream commit fda389c8f0311dd5786be91a7b54b9f935fcafa1
|
||||
("Fix infinite loop in check_pf (BZ #12926)") was not backported
|
||||
before and is superseded by the upstream commit backported here.
|
||||
sysdeps/unix/sysv/linux/netlinkaccess.h
|
||||
Missing backport of e054f494306530720114b321b3d97ca2f397cbbb
|
||||
("Add #include <stdint.h> for uint[32|64]_t usage (except
|
||||
installed headers)").
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
||||
index 95cff0ef651e74a9..bb69b985e6df7fb1 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
||||
@@ -114,6 +114,7 @@ sysdep_headers += netinet/if_fddi.h netinet/if_tr.h \
|
||||
netipx/ipx.h netash/ash.h netax25/ax25.h netatalk/at.h \
|
||||
netrom/netrom.h netpacket/packet.h netrose/rose.h \
|
||||
neteconet/ec.h netiucv/iucv.h
|
||||
+sysdep_routines += netlink_assert_response
|
||||
endif
|
||||
|
||||
# Don't compile the ctype glue code, since there is no old non-GNU C library.
|
||||
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
|
||||
index 16bb28159099c5fa..202ffccc2908ddcc 100644
|
||||
--- a/sysdeps/unix/sysv/linux/Versions
|
||||
+++ b/sysdeps/unix/sysv/linux/Versions
|
||||
@@ -169,5 +169,7 @@ libc {
|
||||
GLIBC_PRIVATE {
|
||||
# functions used in other libraries
|
||||
__syscall_rt_sigqueueinfo;
|
||||
+ # functions used by nscd
|
||||
+ __netlink_assert_response;
|
||||
}
|
||||
}
|
||||
diff --git a/sysdeps/unix/sysv/linux/check_native.c b/sysdeps/unix/sysv/linux/check_native.c
|
||||
index 4968a07a0f8c7932..319b46762aeaf3b6 100644
|
||||
--- a/sysdeps/unix/sysv/linux/check_native.c
|
||||
+++ b/sysdeps/unix/sysv/linux/check_native.c
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include <not-cancel.h>
|
||||
|
||||
+#include "netlinkaccess.h"
|
||||
|
||||
void
|
||||
__check_native (uint32_t a1_index, int *a1_native,
|
||||
@@ -117,6 +118,7 @@ __check_native (uint32_t a1_index, int *a1_native,
|
||||
};
|
||||
|
||||
ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
|
||||
+ __netlink_assert_response (fd, read_len);
|
||||
if (read_len < 0)
|
||||
goto out_fail;
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
|
||||
index d33e1b497d8ba9c7..6b28a735a14f1498 100644
|
||||
--- a/sysdeps/unix/sysv/linux/check_pf.c
|
||||
+++ b/sysdeps/unix/sysv/linux/check_pf.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <atomic.h>
|
||||
#include <nscd/nscd-client.h>
|
||||
|
||||
+#include "netlinkaccess.h"
|
||||
|
||||
#ifndef IFA_F_HOMEADDRESS
|
||||
# define IFA_F_HOMEADDRESS 0
|
||||
@@ -178,6 +179,7 @@ make_request (int fd, pid_t pid)
|
||||
};
|
||||
|
||||
ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
|
||||
+ __netlink_assert_response (fd, read_len);
|
||||
if (read_len < 0)
|
||||
goto out_fail;
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
|
||||
index 179653103e057b79..c87e594e30a314fe 100644
|
||||
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
|
||||
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
|
||||
@@ -169,6 +169,7 @@ __netlink_request (struct netlink_handle *h, int type)
|
||||
};
|
||||
|
||||
read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
|
||||
+ __netlink_assert_response (h->fd, read_len);
|
||||
if (read_len < 0)
|
||||
goto out_fail;
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..b570e93db840fec1
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||
@@ -0,0 +1,106 @@
|
||||
+/* Check recvmsg results for netlink sockets.
|
||||
+ Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdio.h>
|
||||
+#include <sys/socket.h>
|
||||
+
|
||||
+#include "netlinkaccess.h"
|
||||
+
|
||||
+static int
|
||||
+get_address_family (int fd)
|
||||
+{
|
||||
+ struct sockaddr_storage sa;
|
||||
+ socklen_t sa_len = sizeof (sa);
|
||||
+ if (__getsockname (fd, (struct sockaddr *) &sa, &sa_len) < 0)
|
||||
+ return -1;
|
||||
+ /* Check that the socket family number is preserved despite in-band
|
||||
+ signaling. */
|
||||
+ _Static_assert (sizeof (sa.ss_family) < sizeof (int), "address family size");
|
||||
+ _Static_assert (0 < (__typeof__ (sa.ss_family)) -1,
|
||||
+ "address family unsigned");
|
||||
+ return sa.ss_family;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+internal_function
|
||||
+__netlink_assert_response (int fd, ssize_t result)
|
||||
+{
|
||||
+ if (result < 0)
|
||||
+ {
|
||||
+ /* Check if the error is unexpected. */
|
||||
+ bool terminate = false;
|
||||
+ int error_code = errno;
|
||||
+ int family = get_address_family (fd);
|
||||
+ if (family != AF_NETLINK)
|
||||
+ /* If the address family does not match (or getsockname
|
||||
+ failed), report the original error. */
|
||||
+ terminate = true;
|
||||
+ else if (error_code == EBADF
|
||||
+ || error_code == ENOTCONN
|
||||
+ || error_code == ENOTSOCK
|
||||
+ || error_code == ECONNREFUSED)
|
||||
+ /* These errors indicate that the descriptor is not a
|
||||
+ connected socket. */
|
||||
+ terminate = true;
|
||||
+ else if (error_code == EAGAIN || error_code == EWOULDBLOCK)
|
||||
+ {
|
||||
+ /* The kernel might return EAGAIN for other reasons than a
|
||||
+ non-blocking socket. But if the socket is not blocking,
|
||||
+ it is not ours, so report the error. */
|
||||
+ int mode = __fcntl (fd, F_GETFL, 0);
|
||||
+ if (mode < 0 || (mode & O_NONBLOCK) != 0)
|
||||
+ terminate = true;
|
||||
+ }
|
||||
+ if (terminate)
|
||||
+ {
|
||||
+ char message[200];
|
||||
+ if (family < 0)
|
||||
+ __snprintf (message, sizeof (message),
|
||||
+ "Unexpected error %d on netlink descriptor %d",
|
||||
+ error_code, fd);
|
||||
+ else
|
||||
+ __snprintf (message, sizeof (message),
|
||||
+ "Unexpected error %d on netlink descriptor %d"
|
||||
+ " (address family %d)",
|
||||
+ error_code, fd, family);
|
||||
+ __libc_fatal (message);
|
||||
+ }
|
||||
+ else
|
||||
+ /* Restore orignal errno value. */
|
||||
+ __set_errno (error_code);
|
||||
+ }
|
||||
+ else if (result < sizeof (struct nlmsghdr))
|
||||
+ {
|
||||
+ char message[200];
|
||||
+ int family = get_address_family (fd);
|
||||
+ if (family < 0)
|
||||
+ __snprintf (message, sizeof (message),
|
||||
+ "Unexpected netlink response of size %zd"
|
||||
+ " on descriptor %d",
|
||||
+ result, fd);
|
||||
+ else
|
||||
+ __snprintf (message, sizeof (message),
|
||||
+ "Unexpected netlink response of size %zd"
|
||||
+ " on descriptor %d (address family %d)",
|
||||
+ result, fd, family);
|
||||
+ __libc_fatal (message);
|
||||
+ }
|
||||
+}
|
||||
+libc_hidden_def (__netlink_assert_response)
|
||||
diff --git a/sysdeps/unix/sysv/linux/netlinkaccess.h b/sysdeps/unix/sysv/linux/netlinkaccess.h
|
||||
index 6cd8a882640d2486..33dc4e12cd464681 100644
|
||||
--- a/sysdeps/unix/sysv/linux/netlinkaccess.h
|
||||
+++ b/sysdeps/unix/sysv/linux/netlinkaccess.h
|
||||
@@ -18,6 +18,7 @@
|
||||
#ifndef _NETLINKACCESS_H
|
||||
#define _NETLINKACCESS_H 1
|
||||
|
||||
+#include <sys/types.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
@@ -49,5 +50,10 @@ extern void __netlink_close (struct netlink_handle *h);
|
||||
extern void __netlink_free_handle (struct netlink_handle *h);
|
||||
extern int __netlink_request (struct netlink_handle *h, int type);
|
||||
|
||||
+/* Terminate the process if RESULT is an invalid recvmsg result for
|
||||
+ the netlink socket FD. */
|
||||
+void __netlink_assert_response (int fd, ssize_t result)
|
||||
+ internal_function;
|
||||
+libc_hidden_proto (__netlink_assert_response)
|
||||
|
||||
#endif /* netlinkaccess.h */
|
|
@ -0,0 +1,41 @@
|
|||
commit d62aa75af1941fca6f07e107afc447b7b248e340
|
||||
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||
Date: Thu Jul 10 14:15:16 2014 +0530
|
||||
|
||||
Fix crash when system has no ipv6 address [BZ #17125]
|
||||
|
||||
Here's an updated patch to fix the crash in bug-ga2 when the system
|
||||
has no configured ipv6 address. I have taken a different approach of
|
||||
using libc_freeres_fn instead of the libc_freeres_ptr since the former
|
||||
gives better control over what is freed; we need that since cache may
|
||||
or may not be allocated using malloc.
|
||||
|
||||
Verified that bug-ga2 works correctly in both cases and does not have
|
||||
memory leaks in either of them.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
|
||||
index 6b28a735a14f1498..757853342d2af5f4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/check_pf.c
|
||||
+++ b/sysdeps/unix/sysv/linux/check_pf.c
|
||||
@@ -62,7 +62,7 @@ static struct cached_data noai6ai_cached =
|
||||
.in6ailen = 0
|
||||
};
|
||||
|
||||
-libc_freeres_ptr (static struct cached_data *cache);
|
||||
+static struct cached_data *cache;
|
||||
__libc_lock_define_initialized (static, lock);
|
||||
|
||||
|
||||
@@ -378,6 +378,12 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
|
||||
*seen_ipv6 = true;
|
||||
}
|
||||
|
||||
+/* Free the cache if it has been allocated. */
|
||||
+libc_freeres_fn (freecache)
|
||||
+{
|
||||
+ if (cache)
|
||||
+ __free_in6ai (cache->in6ai);
|
||||
+}
|
||||
|
||||
void
|
||||
__free_in6ai (struct in6addrinfo *ai)
|
|
@ -0,0 +1,38 @@
|
|||
commit c1f86a33ca32e26a9d6e29fc961e5ecb5e2e5eb4
|
||||
Author: Daniel Alvarez <dalvarez@redhat.com>
|
||||
Date: Fri Jun 29 09:44:55 2018 +0200
|
||||
|
||||
getifaddrs: Don't return ifa entries with NULL names [BZ #21812]
|
||||
|
||||
A lookup operation in map_newlink could turn into an insert because of
|
||||
holes in the interface part of the map. This leads to incorrectly set
|
||||
the name of the interface to NULL when the interface is not present
|
||||
for the address being processed (most likely because the interface was
|
||||
added between the RTM_GETLINK and RTM_GETADDR calls to the kernel).
|
||||
When such changes are detected by the kernel, it'll mark the dump as
|
||||
"inconsistent" by setting NLM_F_DUMP_INTR flag on the next netlink
|
||||
message.
|
||||
|
||||
This patch checks this condition and retries the whole operation.
|
||||
Hopes are that next time the interface corresponding to the address
|
||||
entry is present in the list and correct name is returned.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
|
||||
index c87e594e30a314fe..b1329dc4d4c63529 100644
|
||||
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
|
||||
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
|
||||
@@ -369,6 +369,14 @@ getifaddrs_internal (struct ifaddrs **ifap)
|
||||
if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
|
||||
continue;
|
||||
|
||||
+ /* If the dump got interrupted, we can't rely on the results
|
||||
+ so try again. */
|
||||
+ if (nlh->nlmsg_flags & NLM_F_DUMP_INTR)
|
||||
+ {
|
||||
+ result = -EAGAIN;
|
||||
+ goto exit_free;
|
||||
+ }
|
||||
+
|
||||
if (nlh->nlmsg_type == NLMSG_DONE)
|
||||
break; /* ok */
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
commit 273cdee86d86e107c0eecef5614f57e37567b54e
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Tue Jan 15 16:39:07 2013 +0100
|
||||
|
||||
Fix invalid free of memory allocated during rtld init
|
||||
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 013efdb3814700d3..6a0005da502c8f37 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -822,6 +822,9 @@ _dl_init_paths (const char *llp)
|
||||
(const void *) (D_PTR (l, l_info[DT_STRTAB])
|
||||
+ l->l_info[DT_RUNPATH]->d_un.d_val),
|
||||
l, "RUNPATH");
|
||||
+ /* During rtld init the memory is allocated by the stub malloc,
|
||||
+ prevent any attempt to free it by the normal malloc. */
|
||||
+ l->l_runpath_dirs.malloced = 0;
|
||||
|
||||
/* The RPATH is ignored. */
|
||||
l->l_rpath_dirs.dirs = (void *) -1;
|
||||
@@ -838,6 +841,9 @@ _dl_init_paths (const char *llp)
|
||||
(const void *) (D_PTR (l, l_info[DT_STRTAB])
|
||||
+ l->l_info[DT_RPATH]->d_un.d_val),
|
||||
l, "RPATH");
|
||||
+ /* During rtld init the memory is allocated by the stub
|
||||
+ malloc, prevent any attempt to free it by the normal
|
||||
+ malloc. */
|
||||
l->l_rpath_dirs.malloced = 0;
|
||||
}
|
||||
else
|
|
@ -0,0 +1,61 @@
|
|||
Partial backport of the following Fedora Rawhide patches:
|
||||
|
||||
commit a747c093bbee95a3bdf1d7ef052bd248c95fadc5
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jun 1 12:05:26 2018 +0200
|
||||
|
||||
Modernise nsswitch.conf defaults (#1581809)
|
||||
|
||||
(backported the line which adds sss description).
|
||||
|
||||
commit 82a97343d6405772541d754aeb4bab79612bd839
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu Feb 7 17:15:12 2019 -0500
|
||||
|
||||
Add warnings and notes to /etc/nsswitch.conf and /etc/nscd.conf.
|
||||
|
||||
(backported fully with adjustments for releng/nsswitch.conf).
|
||||
|
||||
diff --git a/nscd/nscd.conf b/nscd/nscd.conf
|
||||
index 3730835c50a349c4..d7c0ee590466b0d4 100644
|
||||
--- a/nscd/nscd.conf
|
||||
+++ b/nscd/nscd.conf
|
||||
@@ -3,6 +3,9 @@
|
||||
#
|
||||
# An example Name Service Cache config file. This file is needed by nscd.
|
||||
#
|
||||
+# WARNING: Running nscd with a secondary caching service like sssd may lead to
|
||||
+# unexpected behaviour, especially with how long entries are cached.
|
||||
+#
|
||||
# Legal entries are:
|
||||
#
|
||||
# logfile <file>
|
||||
@@ -22,7 +25,12 @@
|
||||
# suggested-size <service> <prime number>
|
||||
# check-files <service> <yes|no>
|
||||
# persistent <service> <yes|no>
|
||||
+#
|
||||
# shared <service> <yes|no>
|
||||
+# NOTE: Setting 'shared' to a value of 'yes' will accelerate the lookup
|
||||
+# with the help of the client, but these lookups will not be
|
||||
+# counted as cache hits i.e. 'nscd -g' may show '0%'.
|
||||
+#
|
||||
# max-db-size <service> <number bytes>
|
||||
# auto-propagate <service> <yes|no>
|
||||
#
|
||||
diff --git a/releng/nsswitch.conf b/releng/nsswitch.conf
|
||||
index 0a02e5717d906387..4b120bf9e6f94e5f 100644
|
||||
--- a/releng/nsswitch.conf
|
||||
+++ b/releng/nsswitch.conf
|
||||
@@ -19,8 +19,11 @@
|
||||
# db Use the local database (.db) files
|
||||
# compat Use NIS on compat mode
|
||||
# hesiod Use Hesiod for user lookups
|
||||
+# sss Use sssd (System Security Services Daemon)
|
||||
# [NOTFOUND=return] Stop searching if not found so far
|
||||
#
|
||||
+# WARNING: Running nscd with a secondary caching service like sssd may lead to
|
||||
+# unexpected behaviour, especially with how long entries are cached.
|
||||
|
||||
# To use db, put the "db" in front of "files" for entries you want to be
|
||||
# looked up first in the databases
|
|
@ -0,0 +1,35 @@
|
|||
This patch replaces the era block in ja_JP with the non-escaped
|
||||
version. It is a partial backport of commit
|
||||
a259f5d388d6195da958b2d147d17c2e2d16b857 ("Replaced unicode sequences
|
||||
in the ASCII printable range"), containing only the changes to this
|
||||
part of the localedata/locales/ja_JP file.
|
||||
|
||||
diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
|
||||
index 54e55b1b52e90f29..594df82f05a23719 100644
|
||||
--- a/localedata/locales/ja_JP
|
||||
+++ b/localedata/locales/ja_JP
|
||||
@@ -14942,15 +14942,15 @@ am_pm "<U5348><U524D>";"<U5348><U5F8C>"
|
||||
|
||||
t_fmt_ampm "<U0025><U0070><U0025><U0049><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
|
||||
|
||||
-era "<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
|
||||
- "<U002B><U003A><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0038><U003A><U0031><U0039><U0038><U0039><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U5143><U5E74>";/
|
||||
- "<U002B><U003A><U0032><U003A><U0031><U0039><U0032><U0037><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0037><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
|
||||
- "<U002B><U003A><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0035><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U5143><U5E74>";/
|
||||
- "<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0034><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
|
||||
- "<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0033><U0030><U003A><U0031><U0039><U0031><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U5143><U5E74>";/
|
||||
- "<U002B><U003A><U0036><U003A><U0031><U0038><U0037><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0032><U0039><U003A><U660E><U6CBB><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
|
||||
- "<U002B><U003A><U0031><U003A><U0030><U0030><U0030><U0031><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0038><U0037><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U897F><U66A6><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
|
||||
- "<U002B><U003A><U0031><U003A><U002D><U0030><U0030><U0030><U0031><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U002D><U002A><U003A><U7D00><U5143><U524D><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>"
|
||||
+era "+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
|
||||
+ "+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
|
||||
+ "+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
|
||||
+ "+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
|
||||
+ "+:2:1913//01//01:1926//12//24:<U5927><U6B63>:%EC%Ey<U5E74>";/
|
||||
+ "+:2:1912//07//30:1912//12//31:<U5927><U6B63>:%EC<U5143><U5E74>";/
|
||||
+ "+:6:1873//01//01:1912//07//29:<U660E><U6CBB>:%EC%Ey<U5E74>";/
|
||||
+ "+:1:0001//01//01:1872//12//31:<U897F><U66A6>:%EC%Ey<U5E74>";/
|
||||
+ "+:1:-0001//12//31:-*:<U7D00><U5143><U524D>:%EC%Ey<U5E74>"
|
||||
|
||||
era_d_fmt "<U0025><U0045><U0059><U0025><U006d><U6708><U0025><U0064><U65E5>"
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Patch by Hanataka Shinya <hanataka.shinya@gmail.com> from
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=24405>. Confirmed by TAMUKI
|
||||
Shoichi's patch in
|
||||
<https://sourceware.org/ml/libc-alpha/2019-04/msg00005.html>.
|
||||
|
||||
The official announcement by the Japanese Prime Minister in
|
||||
<https://www.kantei.go.jp/jp/tyoukanpress/201904/1_a.html> uses U+4EE4 U+548C
|
||||
as well.
|
||||
|
||||
diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
|
||||
index 594df82f05a23719..40cb5795fea730a5 100644
|
||||
--- a/localedata/locales/ja_JP
|
||||
+++ b/localedata/locales/ja_JP
|
||||
@@ -14942,7 +14942,9 @@ am_pm "<U5348><U524D>";"<U5348><U5F8C>"
|
||||
|
||||
t_fmt_ampm "<U0025><U0070><U0025><U0049><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
|
||||
|
||||
-era "+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
|
||||
+era "+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
|
||||
+ "+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
|
||||
+ "+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
|
||||
"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
|
||||
"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
|
||||
"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
|
|
@ -0,0 +1,57 @@
|
|||
commit 583a27d525ae189bdfaa6784021b92a9a1dae12e
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Apr 9 10:08:07 2018 +0200
|
||||
|
||||
resolv: Fully initialize struct mmsghdr in send_dg [BZ #23037]
|
||||
|
||||
diff --git a/resolv/res_send.c b/resolv/res_send.c
|
||||
index 478d542419566574..05c7ba511b0383c1 100644
|
||||
--- a/resolv/res_send.c
|
||||
+++ b/resolv/res_send.c
|
||||
@@ -1154,25 +1154,27 @@ send_dg(res_state statp,
|
||||
if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL
|
||||
&& !single_request)
|
||||
{
|
||||
- struct iovec iov[2];
|
||||
- struct mmsghdr reqs[2];
|
||||
- reqs[0].msg_hdr.msg_name = NULL;
|
||||
- reqs[0].msg_hdr.msg_namelen = 0;
|
||||
- reqs[0].msg_hdr.msg_iov = &iov[0];
|
||||
- reqs[0].msg_hdr.msg_iovlen = 1;
|
||||
- iov[0].iov_base = (void *) buf;
|
||||
- iov[0].iov_len = buflen;
|
||||
- reqs[0].msg_hdr.msg_control = NULL;
|
||||
- reqs[0].msg_hdr.msg_controllen = 0;
|
||||
-
|
||||
- reqs[1].msg_hdr.msg_name = NULL;
|
||||
- reqs[1].msg_hdr.msg_namelen = 0;
|
||||
- reqs[1].msg_hdr.msg_iov = &iov[1];
|
||||
- reqs[1].msg_hdr.msg_iovlen = 1;
|
||||
- iov[1].iov_base = (void *) buf2;
|
||||
- iov[1].iov_len = buflen2;
|
||||
- reqs[1].msg_hdr.msg_control = NULL;
|
||||
- reqs[1].msg_hdr.msg_controllen = 0;
|
||||
+ struct iovec iov =
|
||||
+ { .iov_base = (void *) buf, .iov_len = buflen };
|
||||
+ struct iovec iov2 =
|
||||
+ { .iov_base = (void *) buf2, .iov_len = buflen2 };
|
||||
+ struct mmsghdr reqs[2] =
|
||||
+ {
|
||||
+ {
|
||||
+ .msg_hdr =
|
||||
+ {
|
||||
+ .msg_iov = &iov,
|
||||
+ .msg_iovlen = 1,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .msg_hdr =
|
||||
+ {
|
||||
+ .msg_iov = &iov2,
|
||||
+ .msg_iovlen = 1,
|
||||
+ }
|
||||
+ },
|
||||
+ };
|
||||
|
||||
int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
|
||||
if (__glibc_likely (ndg == 2))
|
|
@ -0,0 +1,112 @@
|
|||
[RHBZ #1579451]
|
||||
This is a backport of the following two upstream patches:
|
||||
|
||||
commit 31545c23277cd54a1edd41c85d8255fb589158e3
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Jun 29 14:38:46 2015 +0000
|
||||
|
||||
Update headers for Linux 4.0, 4.1 definitions.
|
||||
|
||||
This patch updates installed glibc headers for new definitions from
|
||||
Linux 4.0 and 4.1 that seem relevant to glibc headers. In addition, I
|
||||
noticed that PF_IB / AF_IB, added in Linux 3.11, were missing for no
|
||||
obvious reason, so added those as well.
|
||||
|
||||
Tested for x86_64 (testsuite, and that installed stripped shared
|
||||
libraries are unchanged by the patch).
|
||||
|
||||
* sysdeps/unix/sysv/linux/bits/in.h (IP_CHECKSUM): New macro.
|
||||
* sysdeps/unix/sysv/linux/bits/socket.h (PF_IB): Likewise.
|
||||
(PF_MPLS): Likewise.
|
||||
(AF_IB): Likewise.
|
||||
(AF_MPLS): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sys/mount.h (MS_LAZYTIME): New enum
|
||||
value and macro.
|
||||
(MS_RMT_MASK): Include MS_LAZYTIME.
|
||||
|
||||
commit 04d9a38bafddb92ab79bc0015533689e15848522
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Tue Sep 1 13:47:25 2015 +0000
|
||||
|
||||
Add netinet/in.h values from Linux 4.2.
|
||||
|
||||
This patch adds new constants from Linux 4.2 to netinet/in.h:
|
||||
IPPROTO_MPLS and IP_BIND_ADDRESS_NO_PORT (both in
|
||||
include/uapi/linux/in.h in Linux; one directly in netinet/in.h, one in
|
||||
bits/in.h in glibc).
|
||||
|
||||
Tested for x86_64 (testsuite, and that installed stripped shared
|
||||
libraries are unchanged by the patch).
|
||||
|
||||
* inet/netinet/in.h (IPPROTO_MPLS): New enum value and macro.
|
||||
* sysdeps/unix/sysv/linux/bits/in.h (IP_BIND_ADDRESS_NO_PORT): New
|
||||
macro.
|
||||
|
||||
|
||||
diff -Nrup a/inet/netinet/in.h b/inet/netinet/in.h
|
||||
--- a/inet/netinet/in.h 2019-07-30 12:03:33.082066705 -0400
|
||||
+++ b/inet/netinet/in.h 2019-07-30 12:22:54.461572719 -0400
|
||||
@@ -86,6 +86,8 @@ enum
|
||||
#define IPPROTO_SCTP IPPROTO_SCTP
|
||||
IPPROTO_UDPLITE = 136, /* UDP-Lite protocol. */
|
||||
#define IPPROTO_UDPLITE IPPROTO_UDPLITE
|
||||
+ IPPROTO_MPLS = 137, /* MPLS in IP. */
|
||||
+#define IPPROTO_MPLS IPPROTO_MPLS
|
||||
IPPROTO_RAW = 255, /* Raw IP packets. */
|
||||
#define IPPROTO_RAW IPPROTO_RAW
|
||||
IPPROTO_MAX
|
||||
diff -Nrup a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
|
||||
--- a/sysdeps/unix/sysv/linux/bits/in.h 2019-07-30 12:03:35.863052019 -0400
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/in.h 2019-07-30 12:51:15.293703728 -0400
|
||||
@@ -99,6 +99,8 @@
|
||||
|
||||
#define IP_MINTTL 21
|
||||
#define IP_NODEFRAG 22
|
||||
+#define IP_CHECKSUM 23
|
||||
+#define IP_BIND_ADDRESS_NO_PORT 24
|
||||
|
||||
/* IP_MTU_DISCOVER arguments. */
|
||||
#define IP_PMTUDISC_DONT 0 /* Never send DF frames. */
|
||||
diff -Nrup a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
|
||||
--- a/sysdeps/unix/sysv/linux/bits/socket.h 2019-07-30 12:03:33.757063141 -0400
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/socket.h 2019-07-30 12:54:02.612870856 -0400
|
||||
@@ -69,6 +69,8 @@ typedef __socklen_t socklen_t;
|
||||
#define PF_PPPOX 24 /* PPPoX sockets. */
|
||||
#define PF_WANPIPE 25 /* Wanpipe API sockets. */
|
||||
#define PF_LLC 26 /* Linux LLC. */
|
||||
+#define PF_IB 27 /* Native InfiniBand address. */
|
||||
+#define PF_MPLS 28 /* MPLS. */
|
||||
#define PF_CAN 29 /* Controller Area Network. */
|
||||
#define PF_TIPC 30 /* TIPC sockets. */
|
||||
#define PF_BLUETOOTH 31 /* Bluetooth sockets. */
|
||||
@@ -114,6 +116,8 @@ typedef __socklen_t socklen_t;
|
||||
#define AF_PPPOX PF_PPPOX
|
||||
#define AF_WANPIPE PF_WANPIPE
|
||||
#define AF_LLC PF_LLC
|
||||
+#define AF_IB PF_IB
|
||||
+#define AF_MPLS PF_MPLS
|
||||
#define AF_CAN PF_CAN
|
||||
#define AF_TIPC PF_TIPC
|
||||
#define AF_BLUETOOTH PF_BLUETOOTH
|
||||
diff -Nrup a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
|
||||
--- a/sysdeps/unix/sysv/linux/sys/mount.h 2012-12-24 22:02:13.000000000 -0500
|
||||
+++ b/sysdeps/unix/sysv/linux/sys/mount.h 2019-07-30 12:58:23.595571750 -0400
|
||||
@@ -78,6 +78,8 @@ enum
|
||||
#define MS_I_VERSION MS_I_VERSION
|
||||
MS_STRICTATIME = 1 << 24, /* Always perform atime updates. */
|
||||
#define MS_STRICTATIME MS_STRICTATIME
|
||||
+ MS_LAZYTIME = 1 << 25, /* Update the on-disk [acm]times lazily. */
|
||||
+#define MS_LAZYTIME MS_LAZYTIME
|
||||
MS_ACTIVE = 1 << 30,
|
||||
#define MS_ACTIVE MS_ACTIVE
|
||||
MS_NOUSER = 1 << 31
|
||||
@@ -85,7 +87,8 @@ enum
|
||||
};
|
||||
|
||||
/* Flags that can be altered by MS_REMOUNT */
|
||||
-#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
|
||||
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION \
|
||||
+ |MS_LAZYTIME)
|
||||
|
||||
|
||||
/* Magic mount flag number. Has to be or-ed to the flag values. */
|
|
@ -0,0 +1,308 @@
|
|||
commit 68448be208ee06e76665918b37b0a57e3e00c8b4
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Fri Nov 17 16:04:29 2017 -0200
|
||||
|
||||
i386: Fix i386 sigaction sa_restorer initialization (BZ#21269)
|
||||
|
||||
This patch fixes the i386 sa_restorer field initialization for sigaction
|
||||
syscall for kernel with vDSO. As described in bug report, i386 Linux
|
||||
(and compat on x86_64) interprets SA_RESTORER clear with nonzero
|
||||
sa_restorer as a request for stack switching if the SS segment is 'funny'.
|
||||
This means that anything that tries to mix glibc's signal handling with
|
||||
segmentation (for instance through modify_ldt syscall) is randomly broken
|
||||
depending on what values lands in sa_restorer.
|
||||
|
||||
The testcase added is based on Linux test tools/testing/selftests/x86/ldt_gdt.c,
|
||||
more specifically in do_multicpu_tests function. The main changes are:
|
||||
|
||||
- C11 atomics instead of plain access.
|
||||
|
||||
- Remove x86_64 support which simplifies the syscall handling and fallbacks.
|
||||
|
||||
- Replicate only the test required to trigger the issue.
|
||||
|
||||
Checked on i686-linux-gnu.
|
||||
|
||||
[BZ #21269]
|
||||
* sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269.
|
||||
* sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear
|
||||
sa_restorer for vDSO case.
|
||||
* sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file.
|
||||
|
||||
(Adjusted for conflicted in sysdeps/unix/sysv/linux/i386/Makefile due
|
||||
different context around the addition of the new test.)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
|
||||
index acc30219e8dc965f..78e2101682d8d996 100644
|
||||
--- a/sysdeps/unix/sysv/linux/i386/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
|
||||
@@ -3,6 +3,9 @@ default-abi := 32
|
||||
|
||||
ifeq ($(subdir),misc)
|
||||
sysdep_routines += ioperm iopl vm86 call_pselect6 call_fallocate
|
||||
+
|
||||
+tests += tst-bz21269
|
||||
+$(objpfx)tst-bz21269: $(shared-thread-library)
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),elf)
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c
|
||||
index 414ef759a97363c4..f10e1363865c3d18 100644
|
||||
--- a/sysdeps/unix/sysv/linux/i386/sigaction.c
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/sigaction.c
|
||||
@@ -44,7 +44,6 @@ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
|
||||
#endif
|
||||
extern void restore (void) asm ("__restore") attribute_hidden;
|
||||
|
||||
-
|
||||
/* If ACT is not NULL, change the action for SIG to *ACT.
|
||||
If OACT is not NULL, put the old action for SIG in *OACT. */
|
||||
int
|
||||
@@ -67,6 +66,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
|
||||
kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
|
||||
? &restore_rt : &restore);
|
||||
}
|
||||
+ else
|
||||
+ kact.sa_restorer = NULL;
|
||||
}
|
||||
|
||||
/* XXX The size argument hopefully will have to be changed to the
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..353e36507dce92ea
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
@@ -0,0 +1,233 @@
|
||||
+/* Test for i386 sigaction sa_restorer handling (BZ#21269)
|
||||
+ Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This is based on Linux test tools/testing/selftests/x86/ldt_gdt.c,
|
||||
+ more specifically in do_multicpu_tests function. The main changes
|
||||
+ are:
|
||||
+
|
||||
+ - C11 atomics instead of plain access.
|
||||
+ - Remove x86_64 support which simplifies the syscall handling
|
||||
+ and fallbacks.
|
||||
+ - Replicate only the test required to trigger the issue for the
|
||||
+ BZ#21269. */
|
||||
+
|
||||
+#include <stdatomic.h>
|
||||
+
|
||||
+#include <asm/ldt.h>
|
||||
+#include <linux/futex.h>
|
||||
+
|
||||
+#include <setjmp.h>
|
||||
+#include <signal.h>
|
||||
+#include <errno.h>
|
||||
+#include <sys/syscall.h>
|
||||
+#include <sys/mman.h>
|
||||
+
|
||||
+#include <support/xunistd.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xthread.h>
|
||||
+
|
||||
+static int
|
||||
+xset_thread_area (struct user_desc *u_info)
|
||||
+{
|
||||
+ long ret = syscall (SYS_set_thread_area, u_info);
|
||||
+ TEST_VERIFY_EXIT (ret == 0);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xmodify_ldt (int func, const void *ptr, unsigned long bytecount)
|
||||
+{
|
||||
+ TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+futex (int *uaddr, int futex_op, int val, void *timeout, int *uaddr2,
|
||||
+ int val3)
|
||||
+{
|
||||
+ return syscall (SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xsethandler (int sig, void (*handler)(int, siginfo_t *, void *), int flags)
|
||||
+{
|
||||
+ struct sigaction sa = { 0 };
|
||||
+ sa.sa_sigaction = handler;
|
||||
+ sa.sa_flags = SA_SIGINFO | flags;
|
||||
+ TEST_VERIFY_EXIT (sigemptyset (&sa.sa_mask) == 0);
|
||||
+ TEST_VERIFY_EXIT (sigaction (sig, &sa, 0) == 0);
|
||||
+}
|
||||
+
|
||||
+static jmp_buf jmpbuf;
|
||||
+
|
||||
+static void
|
||||
+sigsegv_handler (int sig, siginfo_t *info, void *ctx_void)
|
||||
+{
|
||||
+ siglongjmp (jmpbuf, 1);
|
||||
+}
|
||||
+
|
||||
+/* Points to an array of 1024 ints, each holding its own index. */
|
||||
+static const unsigned int *counter_page;
|
||||
+static struct user_desc *low_user_desc;
|
||||
+static struct user_desc *low_user_desc_clear; /* Used to delete GDT entry. */
|
||||
+static int gdt_entry_num;
|
||||
+
|
||||
+static void
|
||||
+setup_counter_page (void)
|
||||
+{
|
||||
+ long page_size = sysconf (_SC_PAGE_SIZE);
|
||||
+ TEST_VERIFY_EXIT (page_size > 0);
|
||||
+ unsigned int *page = xmmap (NULL, page_size, PROT_READ | PROT_WRITE,
|
||||
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1);
|
||||
+ for (int i = 0; i < (page_size / sizeof (unsigned int)); i++)
|
||||
+ page[i] = i;
|
||||
+ counter_page = page;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+setup_low_user_desc (void)
|
||||
+{
|
||||
+ low_user_desc = xmmap (NULL, 2 * sizeof (struct user_desc),
|
||||
+ PROT_READ | PROT_WRITE,
|
||||
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1);
|
||||
+
|
||||
+ low_user_desc->entry_number = -1;
|
||||
+ low_user_desc->base_addr = (unsigned long) &counter_page[1];
|
||||
+ low_user_desc->limit = 0xffff;
|
||||
+ low_user_desc->seg_32bit = 1;
|
||||
+ low_user_desc->contents = 0;
|
||||
+ low_user_desc->read_exec_only = 0;
|
||||
+ low_user_desc->limit_in_pages = 1;
|
||||
+ low_user_desc->seg_not_present = 0;
|
||||
+ low_user_desc->useable = 0;
|
||||
+
|
||||
+ xset_thread_area (low_user_desc);
|
||||
+
|
||||
+ low_user_desc_clear = low_user_desc + 1;
|
||||
+ low_user_desc_clear->entry_number = gdt_entry_num;
|
||||
+ low_user_desc_clear->read_exec_only = 1;
|
||||
+ low_user_desc_clear->seg_not_present = 1;
|
||||
+}
|
||||
+
|
||||
+/* Possible values of futex:
|
||||
+ 0: thread is idle.
|
||||
+ 1: thread armed.
|
||||
+ 2: thread should clear LDT entry 0.
|
||||
+ 3: thread should exit. */
|
||||
+static atomic_uint ftx;
|
||||
+
|
||||
+static void *
|
||||
+threadproc (void *ctx)
|
||||
+{
|
||||
+ while (1)
|
||||
+ {
|
||||
+ futex ((int *) &ftx, FUTEX_WAIT, 1, NULL, NULL, 0);
|
||||
+ while (atomic_load (&ftx) != 2)
|
||||
+ {
|
||||
+ if (atomic_load (&ftx) >= 3)
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* clear LDT entry 0. */
|
||||
+ const struct user_desc desc = { 0 };
|
||||
+ xmodify_ldt (1, &desc, sizeof (desc));
|
||||
+
|
||||
+ /* If ftx == 2, set it to zero, If ftx == 100, quit. */
|
||||
+ if (atomic_fetch_add (&ftx, -2) != 2)
|
||||
+ return NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* As described in testcase, for historical reasons x86_32 Linux (and compat
|
||||
+ on x86_64) interprets SA_RESTORER clear with nonzero sa_restorer as a
|
||||
+ request for stack switching if the SS segment is 'funny' (this is default
|
||||
+ scenario for vDSO system). This means that anything that tries to mix
|
||||
+ signal handling with segmentation should explicit clear the sa_restorer.
|
||||
+
|
||||
+ This testcase check if sigaction in fact does it by changing the local
|
||||
+ descriptor table (LDT) through the modify_ldt syscall and triggering
|
||||
+ a synchronous segfault on iret fault by trying to install an invalid
|
||||
+ segment. With a correct zeroed sa_restorer it should not trigger an
|
||||
+ 'real' SEGSEGV and allows the siglongjmp in signal handler. */
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ setup_counter_page ();
|
||||
+ setup_low_user_desc ();
|
||||
+
|
||||
+ pthread_t thread;
|
||||
+ unsigned short orig_ss;
|
||||
+
|
||||
+ xsethandler (SIGSEGV, sigsegv_handler, 0);
|
||||
+ /* 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */
|
||||
+ xsethandler (SIGILL, sigsegv_handler, 0);
|
||||
+
|
||||
+ thread = xpthread_create (0, threadproc, 0);
|
||||
+
|
||||
+ asm volatile ("mov %%ss, %0" : "=rm" (orig_ss));
|
||||
+
|
||||
+ for (int i = 0; i < 5; i++)
|
||||
+ {
|
||||
+ if (sigsetjmp (jmpbuf, 1) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Make sure the thread is ready after the last test. */
|
||||
+ while (atomic_load (&ftx) != 0)
|
||||
+ ;
|
||||
+
|
||||
+ struct user_desc desc = {
|
||||
+ .entry_number = 0,
|
||||
+ .base_addr = 0,
|
||||
+ .limit = 0xffff,
|
||||
+ .seg_32bit = 1,
|
||||
+ .contents = 0,
|
||||
+ .read_exec_only = 0,
|
||||
+ .limit_in_pages = 1,
|
||||
+ .seg_not_present = 0,
|
||||
+ .useable = 0
|
||||
+ };
|
||||
+
|
||||
+ xmodify_ldt (0x11, &desc, sizeof (desc));
|
||||
+
|
||||
+ /* Arm the thread. */
|
||||
+ ftx = 1;
|
||||
+ futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
|
||||
+
|
||||
+ asm volatile ("mov %0, %%ss" : : "r" (0x7));
|
||||
+
|
||||
+ /* Fire up thread modify_ldt call. */
|
||||
+ atomic_store (&ftx, 2);
|
||||
+
|
||||
+ while (atomic_load (&ftx) != 0)
|
||||
+ ;
|
||||
+
|
||||
+ /* On success, modify_ldt will segfault us synchronously and we will
|
||||
+ escape via siglongjmp. */
|
||||
+ support_record_failure ();
|
||||
+ }
|
||||
+
|
||||
+ atomic_store (&ftx, 100);
|
||||
+ futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
|
||||
+
|
||||
+ xpthread_join (thread);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,22 @@
|
|||
commit 4d76d3e59d31aa690f148fc0c95cc0c581aed3e8
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Mar 29 11:42:24 2018 +0200
|
||||
|
||||
Linux i386: tst-bz21269 triggers SIGBUS on some kernels
|
||||
|
||||
In addition to SIGSEGV and SIGILL, SIGBUS is also a possible signal
|
||||
generated by the kernel.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
index 353e36507dce92ea..6ee3fc62be0d3312 100644
|
||||
--- a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
@@ -177,6 +177,8 @@ do_test (void)
|
||||
xsethandler (SIGSEGV, sigsegv_handler, 0);
|
||||
/* 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */
|
||||
xsethandler (SIGILL, sigsegv_handler, 0);
|
||||
+ /* Some kernels send SIGBUS instead. */
|
||||
+ xsethandler (SIGBUS, sigsegv_handler, 0);
|
||||
|
||||
thread = xpthread_create (0, threadproc, 0);
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
Port sysdeps/unix/sysv/linux/i386/tst-bz21269.c to __atomic builtins
|
||||
|
||||
The upstream test uses <stdatomic.h>, which is not supported in the
|
||||
Red Hat Enterprise Linux 7 system compiler.
|
||||
|
||||
The port uses __ATOMIC_SEQ_CST for consistency with the upstream test;
|
||||
such as trong memory ordering is not actually required here.
|
||||
|
||||
Furthermore, it is necessary to change the SYS_ system call constants
|
||||
to __NR_ constants. Downstream builts the test with internal headers,
|
||||
and those only have the __NR_ constants from the kernel.
|
||||
|
||||
The initializer of sa in xsethandler was replaced with a memset, to
|
||||
avoid a warning about missing braces in an initializer (something that
|
||||
later GCC versions do not warn about).
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
index 6ee3fc62be0d3312..f58395cedc6972c4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/tst-bz21269.c
|
||||
@@ -26,8 +26,6 @@
|
||||
- Replicate only the test required to trigger the issue for the
|
||||
BZ#21269. */
|
||||
|
||||
-#include <stdatomic.h>
|
||||
-
|
||||
#include <asm/ldt.h>
|
||||
#include <linux/futex.h>
|
||||
|
||||
@@ -36,6 +34,7 @@
|
||||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/mman.h>
|
||||
+#include <string.h>
|
||||
|
||||
#include <support/xunistd.h>
|
||||
#include <support/check.h>
|
||||
@@ -44,7 +43,7 @@
|
||||
static int
|
||||
xset_thread_area (struct user_desc *u_info)
|
||||
{
|
||||
- long ret = syscall (SYS_set_thread_area, u_info);
|
||||
+ long ret = syscall (__NR_set_thread_area, u_info);
|
||||
TEST_VERIFY_EXIT (ret == 0);
|
||||
return ret;
|
||||
}
|
||||
@@ -52,20 +51,21 @@ xset_thread_area (struct user_desc *u_info)
|
||||
static void
|
||||
xmodify_ldt (int func, const void *ptr, unsigned long bytecount)
|
||||
{
|
||||
- TEST_VERIFY_EXIT (syscall (SYS_modify_ldt, 1, ptr, bytecount) == 0);
|
||||
+ TEST_VERIFY_EXIT (syscall (__NR_modify_ldt, 1, ptr, bytecount) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
futex (int *uaddr, int futex_op, int val, void *timeout, int *uaddr2,
|
||||
int val3)
|
||||
{
|
||||
- return syscall (SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
||||
+ return syscall (__NR_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
|
||||
}
|
||||
|
||||
static void
|
||||
xsethandler (int sig, void (*handler)(int, siginfo_t *, void *), int flags)
|
||||
{
|
||||
- struct sigaction sa = { 0 };
|
||||
+ struct sigaction sa;
|
||||
+ memset (&sa, 0, sizeof (sa));
|
||||
sa.sa_sigaction = handler;
|
||||
sa.sa_flags = SA_SIGINFO | flags;
|
||||
TEST_VERIFY_EXIT (sigemptyset (&sa.sa_mask) == 0);
|
||||
@@ -128,7 +128,7 @@ setup_low_user_desc (void)
|
||||
1: thread armed.
|
||||
2: thread should clear LDT entry 0.
|
||||
3: thread should exit. */
|
||||
-static atomic_uint ftx;
|
||||
+static unsigned int ftx;
|
||||
|
||||
static void *
|
||||
threadproc (void *ctx)
|
||||
@@ -136,9 +136,9 @@ threadproc (void *ctx)
|
||||
while (1)
|
||||
{
|
||||
futex ((int *) &ftx, FUTEX_WAIT, 1, NULL, NULL, 0);
|
||||
- while (atomic_load (&ftx) != 2)
|
||||
+ while (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) != 2)
|
||||
{
|
||||
- if (atomic_load (&ftx) >= 3)
|
||||
+ if (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) >= 3)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ threadproc (void *ctx)
|
||||
xmodify_ldt (1, &desc, sizeof (desc));
|
||||
|
||||
/* If ftx == 2, set it to zero, If ftx == 100, quit. */
|
||||
- if (atomic_fetch_add (&ftx, -2) != 2)
|
||||
+ if (__atomic_fetch_add (&ftx, -2, __ATOMIC_SEQ_CST) != 2)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -190,7 +190,7 @@ do_test (void)
|
||||
continue;
|
||||
|
||||
/* Make sure the thread is ready after the last test. */
|
||||
- while (atomic_load (&ftx) != 0)
|
||||
+ while (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) != 0)
|
||||
;
|
||||
|
||||
struct user_desc desc = {
|
||||
@@ -214,9 +214,9 @@ do_test (void)
|
||||
asm volatile ("mov %0, %%ss" : : "r" (0x7));
|
||||
|
||||
/* Fire up thread modify_ldt call. */
|
||||
- atomic_store (&ftx, 2);
|
||||
+ __atomic_store_n (&ftx, 2, __ATOMIC_SEQ_CST);
|
||||
|
||||
- while (atomic_load (&ftx) != 0)
|
||||
+ while (__atomic_load_n (&ftx, __ATOMIC_SEQ_CST) != 0)
|
||||
;
|
||||
|
||||
/* On success, modify_ldt will segfault us synchronously and we will
|
||||
@@ -224,7 +224,7 @@ do_test (void)
|
||||
support_record_failure ();
|
||||
}
|
||||
|
||||
- atomic_store (&ftx, 100);
|
||||
+ __atomic_store_n (&ftx, 100, __ATOMIC_SEQ_CST);
|
||||
futex ((int*) &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
|
||||
|
||||
xpthread_join (thread);
|
|
@ -0,0 +1,66 @@
|
|||
commit c259196b5005812aa3294dbf4eeca29b266a4522
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Mar 1 18:53:03 2019 +0100
|
||||
|
||||
elf/tst-big-note: Improve accuracy of test [BZ #20419]
|
||||
|
||||
It is possible that the link editor injects an allocated ABI tag note
|
||||
before the artificial, allocated large note in the test. Note parsing
|
||||
in open_verify stops when the first ABI tag note is encountered, so if
|
||||
the ABI tag note comes first, the problematic code is not actually
|
||||
exercised.
|
||||
|
||||
Also tweak the artificial note so that it is a syntactically valid
|
||||
4-byte aligned note, in case the link editor tries to parse notes and
|
||||
process them.
|
||||
|
||||
Improves the testing part of commit 0065aaaaae51cd60210ec3a7e13.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
(Minor adjustment for Makefile conflict.)
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index b46b3a0e3542a06f..2b2662d5cf96c437 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -244,8 +244,8 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||
# We need this variable to be sure the test modules get the right CPPFLAGS.
|
||||
test-extras += $(modules-names)
|
||||
|
||||
-# filtmod1.so has a special rule
|
||||
-modules-names-nobuild := filtmod1
|
||||
+# filtmod1.so, tst-big-note-lib.so have special rules.
|
||||
+modules-names-nobuild := filtmod1 tst-big-note-lib
|
||||
|
||||
ifneq (no,$(multi-arch))
|
||||
tests-static += ifuncmain1static ifuncmain1picstatic \
|
||||
@@ -1239,3 +1239,8 @@ $(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
|
||||
LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
|
||||
|
||||
$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
|
||||
+# Avoid creating an ABI tag note, which may come before the
|
||||
+# artificial, large note in tst-big-note-lib.o and invalidate the
|
||||
+# test.
|
||||
+$(objpfx)tst-big-note-lib.so: $(objpfx)tst-big-note-lib.o
|
||||
+ $(LINK.o) -shared -o $@ $(LDFLAGS.so) $<
|
||||
diff --git a/elf/tst-big-note-lib.S b/elf/tst-big-note-lib.S
|
||||
index 6b514a03cc686141..c97590ccb05e9b2e 100644
|
||||
--- a/elf/tst-big-note-lib.S
|
||||
+++ b/elf/tst-big-note-lib.S
|
||||
@@ -20,7 +20,13 @@
|
||||
On a typical Linux system with 8MiB "ulimit -s", that was enough
|
||||
to trigger stack overflow in open_verify. */
|
||||
|
||||
+#define NOTE_SIZE 8*1024*1024
|
||||
+
|
||||
.pushsection .note.big,"a"
|
||||
-.balign 4
|
||||
-.fill 8*1024*1024, 1, 0
|
||||
+ .balign 4
|
||||
+ .long 5 /* n_namesz. Length of "GLIBC". */
|
||||
+ .long NOTE_SIZE /* n_descsz. */
|
||||
+ .long 0 /* n_type. */
|
||||
+ .ascii "GLIBC\0\0\0" /* Name and alignment to four bytes. */
|
||||
+ .fill NOTE_SIZE, 1, 0
|
||||
.popsection
|
|
@ -0,0 +1,162 @@
|
|||
commit 0065aaaaae51cd60210ec3a7e13dddd8e01ffe2c
|
||||
Author: Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||
Date: Sat May 5 18:08:27 2018 -0700
|
||||
|
||||
Fix BZ 20419. A PT_NOTE in a binary could be arbitratily large, so using
|
||||
alloca for it may cause stack overflow. If the note is larger than
|
||||
__MAX_ALLOCA_CUTOFF, use dynamically allocated memory to read it in.
|
||||
|
||||
2018-05-05 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||
|
||||
[BZ #20419]
|
||||
* elf/dl-load.c (open_verify): Fix stack overflow.
|
||||
* elf/Makefile (tst-big-note): New test.
|
||||
* elf/tst-big-note-lib.S: New.
|
||||
* elf/tst-big-note.c: New.
|
||||
|
||||
Minor textual conflicts and elf/Makefile due to continued upstream
|
||||
development.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index dea66ca1c12e5c29..b46b3a0e3542a06f 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -151,7 +151,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
|
||||
tst-stackguard1 tst-addr1 tst-thrlock \
|
||||
tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
|
||||
- tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1
|
||||
+ tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1 \
|
||||
+ tst-big-note
|
||||
# reldep9
|
||||
test-srcs = tst-pathopt
|
||||
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
|
||||
@@ -223,7 +224,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
|
||||
tst-array5dep \
|
||||
tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
|
||||
- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12
|
||||
+ tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
|
||||
+ tst-big-note-lib
|
||||
+
|
||||
ifeq (yesyes,$(have-fpie)$(build-shared))
|
||||
modules-names += tst-piemod1
|
||||
tests += tst-pie1
|
||||
@@ -1234,3 +1237,5 @@ $(objpfx)tst-audit12: $(libdl)
|
||||
tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so
|
||||
$(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
|
||||
LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
|
||||
+
|
||||
+$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 7466b686244e55b2..013efdb3814700d3 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1744,6 +1744,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
||||
ElfW(Ehdr) *ehdr;
|
||||
ElfW(Phdr) *phdr, *ph;
|
||||
ElfW(Word) *abi_note;
|
||||
+ ElfW(Word) *abi_note_malloced = NULL;
|
||||
unsigned int osversion;
|
||||
size_t maplength;
|
||||
|
||||
@@ -1889,10 +1890,25 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
||||
abi_note = (void *) (fbp->buf + ph->p_offset);
|
||||
else
|
||||
{
|
||||
- abi_note = alloca (size);
|
||||
+ /* Note: __libc_use_alloca is not usable here, because
|
||||
+ thread info may not have been set up yet. */
|
||||
+ if (size < __MAX_ALLOCA_CUTOFF)
|
||||
+ abi_note = alloca (size);
|
||||
+ else
|
||||
+ {
|
||||
+ /* There could be multiple PT_NOTEs. */
|
||||
+ abi_note_malloced = realloc (abi_note_malloced, size);
|
||||
+ if (abi_note_malloced == NULL)
|
||||
+ goto read_error;
|
||||
+
|
||||
+ abi_note = abi_note_malloced;
|
||||
+ }
|
||||
__lseek (fd, ph->p_offset, SEEK_SET);
|
||||
if (__libc_read (fd, (void *) abi_note, size) != size)
|
||||
- goto read_error;
|
||||
+ {
|
||||
+ free (abi_note_malloced);
|
||||
+ goto read_error;
|
||||
+ }
|
||||
}
|
||||
|
||||
while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
|
||||
@@ -1928,6 +1944,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
||||
|
||||
break;
|
||||
}
|
||||
+ free (abi_note_malloced);
|
||||
}
|
||||
|
||||
return fd;
|
||||
diff --git a/elf/tst-big-note-lib.S b/elf/tst-big-note-lib.S
|
||||
new file mode 100644
|
||||
index 0000000000000000..6b514a03cc686141
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-big-note-lib.S
|
||||
@@ -0,0 +1,26 @@
|
||||
+/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This creates a .so with 8MiB PT_NOTE segment.
|
||||
+ On a typical Linux system with 8MiB "ulimit -s", that was enough
|
||||
+ to trigger stack overflow in open_verify. */
|
||||
+
|
||||
+.pushsection .note.big,"a"
|
||||
+.balign 4
|
||||
+.fill 8*1024*1024, 1, 0
|
||||
+.popsection
|
||||
diff --git a/elf/tst-big-note.c b/elf/tst-big-note.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..fcd2b0ed82cc1667
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-big-note.c
|
||||
@@ -0,0 +1,26 @@
|
||||
+/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This file must be run from within a directory called "elf". */
|
||||
+
|
||||
+int main (int argc, char *argv[])
|
||||
+{
|
||||
+ /* Nothing to do here: merely linking against tst-big-note-lib.so triggers
|
||||
+ the bug. */
|
||||
+ return 0;
|
||||
+}
|
|
@ -0,0 +1,38 @@
|
|||
From 14beef7575099f6373f9a45b4656f1e3675f7372 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 14 Jun 2018 22:34:09 +0200
|
||||
Subject: [PATCH] localedata: Make IBM273 compatible with ISO-8859-1 [BZ
|
||||
#23290]
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
---
|
||||
ChangeLog | 8 ++++++++
|
||||
iconvdata/ibm273.c | 2 +-
|
||||
localedata/charmaps/IBM273 | 2 +-
|
||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: b/iconvdata/ibm273.c
|
||||
===================================================================
|
||||
--- a/iconvdata/ibm273.c
|
||||
+++ b/iconvdata/ibm273.c
|
||||
@@ -23,6 +23,6 @@
|
||||
#define TABLES <ibm273.h>
|
||||
|
||||
#define CHARSET_NAME "IBM273//"
|
||||
-#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
+#define HAS_HOLES 0
|
||||
|
||||
#include <8bit-gap.c>
|
||||
Index: b/localedata/charmaps/IBM273
|
||||
===================================================================
|
||||
--- a/localedata/charmaps/IBM273
|
||||
+++ b/localedata/charmaps/IBM273
|
||||
@@ -194,7 +194,7 @@ CHARMAP
|
||||
<U00BE> /xb9 VULGAR FRACTION THREE QUARTERS
|
||||
<U00AC> /xba NOT SIGN
|
||||
<U007C> /xbb VERTICAL LINE
|
||||
-<U203E> /xbc OVERLINE
|
||||
+<U00AF> /xbc MACRON
|
||||
<U00A8> /xbd DIAERESIS
|
||||
<U00B4> /xbe ACUTE ACCENT
|
||||
<U00D7> /xbf MULTIPLICATION SIGN
|
|
@ -0,0 +1,194 @@
|
|||
From f2857da7cdb65bfad75ee30981f5b2fde5bbb1dc Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon, 18 Jun 2018 13:37:57 +0000
|
||||
Subject: [PATCH] Add SHM_STAT_ANY from Linux 4.17 to bits/shm.h.
|
||||
|
||||
Linux 4.17 adds a SHM_STAT_ANY constant (ipcs command). This patch
|
||||
adds it to the relevant bits/shm.h headers.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): New macro.
|
||||
* sysdeps/unix/sysv/linux/arm/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/generic/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/hppa/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sh/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86/bits/shm.h [__USE_MISC]
|
||||
(SHM_STAT_ANY): Likewise.
|
||||
---
|
||||
ChangeLog | 25 ++++++++++++++++++++++
|
||||
sysdeps/unix/sysv/linux/alpha/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/arm/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/generic/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/hppa/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/ia64/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/mips/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/powerpc/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/s390/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/sh/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/sparc/bits/shm.h | 1 +
|
||||
sysdeps/unix/sysv/linux/x86/bits/shm.h | 1 +
|
||||
13 files changed, 37 insertions(+)
|
||||
|
||||
Index: b/sysdeps/unix/sysv/linux/alpha/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/alpha/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/alpha/bits/shm.h
|
||||
@@ -65,6 +65,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/arm/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/arm/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/arm/bits/shm.h
|
||||
@@ -69,6 +69,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/shm.h
|
||||
@@ -68,6 +68,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/generic/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/generic/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/generic/bits/shm.h
|
||||
@@ -76,6 +76,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
|
||||
@@ -73,6 +73,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/ia64/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/bits/shm.h
|
||||
@@ -61,6 +61,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/mips/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/mips/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/bits/shm.h
|
||||
@@ -62,6 +62,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/shm.h
|
||||
@@ -78,6 +78,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/s390/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/s390/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/bits/shm.h
|
||||
@@ -75,6 +75,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/sh/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/sh/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sh/bits/shm.h
|
||||
@@ -66,6 +66,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/sparc/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/bits/shm.h
|
||||
@@ -76,6 +76,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
||||
Index: b/sysdeps/unix/sysv/linux/x86/bits/shm.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/x86/bits/shm.h
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/bits/shm.h
|
||||
@@ -74,6 +74,7 @@ struct shmid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define SHM_STAT 13
|
||||
# define SHM_INFO 14
|
||||
+# define SHM_STAT_ANY 15
|
||||
|
||||
/* shm_mode upper byte flags */
|
||||
# define SHM_DEST 01000 /* segment will be destroyed on last detach */
|
|
@ -0,0 +1,164 @@
|
|||
From 176c7fee517c11f628aed4ef4b9457e47fa976a1 Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon, 18 Jun 2018 13:36:41 +0000
|
||||
Subject: [PATCH] Add SEM_STAT_ANY from Linux 4.17 to bits/sem.h.
|
||||
|
||||
Linux 4.17 adds a SEM_STAT_ANY constant (ipcs command). This patch
|
||||
adds it to the relevant bits/sem.h headers.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): New macro.
|
||||
* sysdeps/unix/sysv/linux/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/generic/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/hppa/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86/bits/sem.h [__USE_MISC]
|
||||
(SEM_STAT_ANY): Likewise.
|
||||
---
|
||||
ChangeLog | 21 +++++++++++++++++++++
|
||||
sysdeps/unix/sysv/linux/alpha/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/generic/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/hppa/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/ia64/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/mips/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/powerpc/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/s390/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/sparc/bits/sem.h | 1 +
|
||||
sysdeps/unix/sysv/linux/x86/bits/sem.h | 1 +
|
||||
11 files changed, 31 insertions(+)
|
||||
|
||||
Index: b/sysdeps/unix/sysv/linux/alpha/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/alpha/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/alpha/bits/sem.h
|
||||
@@ -66,6 +66,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/sem.h
|
||||
@@ -68,6 +68,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/generic/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/generic/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/generic/bits/sem.h
|
||||
@@ -74,6 +74,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/hppa/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/bits/sem.h
|
||||
@@ -73,6 +73,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/ia64/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/bits/sem.h
|
||||
@@ -68,6 +68,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/mips/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/mips/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/bits/sem.h
|
||||
@@ -66,6 +66,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/sem.h
|
||||
@@ -73,6 +73,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/s390/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/s390/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/bits/sem.h
|
||||
@@ -73,6 +73,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/sparc/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/bits/sem.h
|
||||
@@ -73,6 +73,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
||||
Index: b/sysdeps/unix/sysv/linux/x86/bits/sem.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/x86/bits/sem.h
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/bits/sem.h
|
||||
@@ -68,6 +68,7 @@ struct semid_ds
|
||||
/* ipcs ctl cmds */
|
||||
# define SEM_STAT 18
|
||||
# define SEM_INFO 19
|
||||
+# define SEM_STAT_ANY 20
|
||||
|
||||
struct seminfo
|
||||
{
|
|
@ -0,0 +1,164 @@
|
|||
From 86bf0019ed9c0d1e19916448454c3f7df0479ac6 Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon, 18 Jun 2018 13:34:52 +0000
|
||||
Subject: [PATCH] Add MSG_STAT_ANY from Linux 4.17 to bits/msq.h.
|
||||
|
||||
Linux 4.17 adds a MSG_STAT_ANY constant (ipcs command). This patch
|
||||
adds it to the relevant bits/msq.h headers.
|
||||
|
||||
Tested for x86_64.
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): New macro.
|
||||
* sysdeps/unix/sysv/linux/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/generic/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/hppa/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86/bits/msq.h [__USE_MISC]
|
||||
(MSG_STAT_ANY): Likewise.
|
||||
---
|
||||
ChangeLog | 21 +++++++++++++++++++++
|
||||
sysdeps/unix/sysv/linux/alpha/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/generic/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/hppa/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/ia64/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/mips/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/powerpc/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/s390/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/sparc/bits/msq.h | 1 +
|
||||
sysdeps/unix/sysv/linux/x86/bits/msq.h | 1 +
|
||||
11 files changed, 31 insertions(+)
|
||||
|
||||
Index: b/sysdeps/unix/sysv/linux/alpha/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/alpha/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/alpha/bits/msq.h
|
||||
@@ -56,6 +56,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/msq.h
|
||||
@@ -59,6 +59,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/generic/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/generic/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/generic/bits/msq.h
|
||||
@@ -66,6 +66,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/hppa/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/hppa/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/hppa/bits/msq.h
|
||||
@@ -66,6 +66,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/ia64/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/ia64/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/ia64/bits/msq.h
|
||||
@@ -51,6 +51,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/mips/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/mips/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/mips/bits/msq.h
|
||||
@@ -74,6 +74,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/msq.h
|
||||
@@ -65,6 +65,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/s390/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/s390/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/bits/msq.h
|
||||
@@ -66,6 +66,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/sparc/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/bits/msq.h
|
||||
@@ -66,6 +66,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
||||
Index: b/sysdeps/unix/sysv/linux/x86/bits/msq.h
|
||||
===================================================================
|
||||
--- a/sysdeps/unix/sysv/linux/x86/bits/msq.h
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/bits/msq.h
|
||||
@@ -64,6 +64,7 @@ struct msqid_ds
|
||||
/* ipcs ctl commands */
|
||||
# define MSG_STAT 11
|
||||
# define MSG_INFO 12
|
||||
+# define MSG_STAT_ANY 13
|
||||
|
||||
/* buffer for msgctl calls IPC_INFO, MSG_INFO */
|
||||
struct msginfo
|
|
@ -0,0 +1,230 @@
|
|||
commit 0262507918cfad7223bf81b8f162b7adc7a2af01
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jun 1 10:43:06 2018 +0200
|
||||
|
||||
libio: Avoid _allocate_buffer, _free_buffer function pointers [BZ #23236]
|
||||
|
||||
These unmangled function pointers reside on the heap and could
|
||||
be targeted by exploit writers, effectively bypassing libio vtable
|
||||
validation. Instead, we ignore these pointers and always call
|
||||
malloc or free.
|
||||
|
||||
In theory, this is a backwards-incompatible change, but using the
|
||||
global heap instead of the user-supplied callback functions should
|
||||
have little application impact. (The old libstdc++ implementation
|
||||
exposed this functionality via a public, undocumented constructor
|
||||
in its strstreambuf class.)
|
||||
|
||||
(cherry picked from commit 4e8a6346cd3da2d88bbad745a1769260d36f2783)
|
||||
|
||||
Backported from the upstream release/2.27/master branch.
|
||||
|
||||
diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c
|
||||
index a8ca32bad57b4d13..113354749ccf8d9a 100644
|
||||
--- a/debug/vasprintf_chk.c
|
||||
+++ b/debug/vasprintf_chk.c
|
||||
@@ -55,8 +55,8 @@ __vasprintf_chk (char **result_ptr, int flags, const char *format,
|
||||
_IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
|
||||
_IO_str_init_static_internal (&sf, string, init_string_size, string);
|
||||
sf._sbf._f._flags &= ~_IO_USER_BUF;
|
||||
- sf._s._allocate_buffer = (_IO_alloc_type) malloc;
|
||||
- sf._s._free_buffer = (_IO_free_type) free;
|
||||
+ sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
|
||||
+ sf._s._free_buffer_unused = (_IO_free_type) free;
|
||||
|
||||
/* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
|
||||
can only come from read-only format strings. */
|
||||
diff --git a/libio/memstream.c b/libio/memstream.c
|
||||
index e18a7756b297c9f4..9a51331e525c3468 100644
|
||||
--- a/libio/memstream.c
|
||||
+++ b/libio/memstream.c
|
||||
@@ -87,8 +87,8 @@ open_memstream (char **bufloc, _IO_size_t *sizeloc)
|
||||
_IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps;
|
||||
_IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
|
||||
new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
|
||||
- new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
|
||||
- new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
|
||||
+ new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
|
||||
+ new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
|
||||
|
||||
new_f->fp.bufloc = bufloc;
|
||||
new_f->fp.sizeloc = sizeloc;
|
||||
diff --git a/libio/strfile.h b/libio/strfile.h
|
||||
index 4ea7548f9fa92638..9cd8e7c466616b52 100644
|
||||
--- a/libio/strfile.h
|
||||
+++ b/libio/strfile.h
|
||||
@@ -34,8 +34,11 @@ typedef void (*_IO_free_type) (void*);
|
||||
|
||||
struct _IO_str_fields
|
||||
{
|
||||
- _IO_alloc_type _allocate_buffer;
|
||||
- _IO_free_type _free_buffer;
|
||||
+ /* These members are preserved for ABI compatibility. The glibc
|
||||
+ implementation always calls malloc/free for user buffers if
|
||||
+ _IO_USER_BUF or _IO_FLAGS2_USER_WBUF are not set. */
|
||||
+ _IO_alloc_type _allocate_buffer_unused;
|
||||
+ _IO_free_type _free_buffer_unused;
|
||||
};
|
||||
|
||||
/* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type,
|
||||
@@ -55,10 +58,6 @@ typedef struct _IO_strfile_
|
||||
struct _IO_str_fields _s;
|
||||
} _IO_strfile;
|
||||
|
||||
-/* dynamic: set when the array object is allocated (or reallocated) as
|
||||
- necessary to hold a character sequence that can change in length. */
|
||||
-#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0)
|
||||
-
|
||||
/* frozen: set when the program has requested that the array object not
|
||||
be altered, reallocated, or freed. */
|
||||
#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF)
|
||||
diff --git a/libio/strops.c b/libio/strops.c
|
||||
index fdd113a60811e593..129a0f6aeca818fd 100644
|
||||
--- a/libio/strops.c
|
||||
+++ b/libio/strops.c
|
||||
@@ -61,7 +61,7 @@ _IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size,
|
||||
fp->_IO_read_end = end;
|
||||
}
|
||||
/* A null _allocate_buffer function flags the strfile as being static. */
|
||||
- sf->_s._allocate_buffer = (_IO_alloc_type) 0;
|
||||
+ sf->_s._allocate_buffer_unused = (_IO_alloc_type) 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -103,8 +103,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
|
||||
_IO_size_t new_size = 2 * old_blen + 100;
|
||||
if (new_size < old_blen)
|
||||
return EOF;
|
||||
- new_buf
|
||||
- = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
|
||||
+ new_buf = malloc (new_size);
|
||||
if (new_buf == NULL)
|
||||
{
|
||||
/* __ferror(fp) = 1; */
|
||||
@@ -113,7 +112,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
|
||||
if (old_buf)
|
||||
{
|
||||
memcpy (new_buf, old_buf, old_blen);
|
||||
- (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
|
||||
+ free (old_buf);
|
||||
/* Make sure _IO_setb won't try to delete _IO_buf_base. */
|
||||
fp->_IO_buf_base = NULL;
|
||||
}
|
||||
@@ -182,15 +181,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
|
||||
|
||||
_IO_size_t newsize = offset + 100;
|
||||
char *oldbuf = fp->_IO_buf_base;
|
||||
- char *newbuf
|
||||
- = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize);
|
||||
+ char *newbuf = malloc (newsize);
|
||||
if (newbuf == NULL)
|
||||
return 1;
|
||||
|
||||
if (oldbuf != NULL)
|
||||
{
|
||||
memcpy (newbuf, oldbuf, _IO_blen (fp));
|
||||
- (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
|
||||
+ free (oldbuf);
|
||||
/* Make sure _IO_setb won't try to delete
|
||||
_IO_buf_base. */
|
||||
fp->_IO_buf_base = NULL;
|
||||
@@ -317,7 +315,7 @@ void
|
||||
_IO_str_finish (_IO_FILE *fp, int dummy)
|
||||
{
|
||||
if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
|
||||
- (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
|
||||
+ free (fp->_IO_buf_base);
|
||||
fp->_IO_buf_base = NULL;
|
||||
|
||||
_IO_default_finish (fp, 0);
|
||||
diff --git a/libio/vasprintf.c b/libio/vasprintf.c
|
||||
index 282c86fff0a7ae0e..867ef4fe4ca4ec56 100644
|
||||
--- a/libio/vasprintf.c
|
||||
+++ b/libio/vasprintf.c
|
||||
@@ -54,8 +54,8 @@ _IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args)
|
||||
_IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
|
||||
_IO_str_init_static_internal (&sf, string, init_string_size, string);
|
||||
sf._sbf._f._flags &= ~_IO_USER_BUF;
|
||||
- sf._s._allocate_buffer = (_IO_alloc_type) malloc;
|
||||
- sf._s._free_buffer = (_IO_free_type) free;
|
||||
+ sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
|
||||
+ sf._s._free_buffer_unused = (_IO_free_type) free;
|
||||
ret = _IO_vfprintf (&sf._sbf._f, format, args);
|
||||
if (ret < 0)
|
||||
{
|
||||
diff --git a/libio/wmemstream.c b/libio/wmemstream.c
|
||||
index bd6d1798b1685fe9..3a9a681c80a321a7 100644
|
||||
--- a/libio/wmemstream.c
|
||||
+++ b/libio/wmemstream.c
|
||||
@@ -90,8 +90,8 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc)
|
||||
_IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
|
||||
_IO_BUFSIZ / sizeof (wchar_t), buf);
|
||||
new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF;
|
||||
- new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
|
||||
- new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
|
||||
+ new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
|
||||
+ new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
|
||||
|
||||
new_f->fp.bufloc = bufloc;
|
||||
new_f->fp.sizeloc = sizeloc;
|
||||
diff --git a/libio/wstrops.c b/libio/wstrops.c
|
||||
index 7a9a33ab8763b8ff..a31d0e23341b2aad 100644
|
||||
--- a/libio/wstrops.c
|
||||
+++ b/libio/wstrops.c
|
||||
@@ -63,7 +63,7 @@ _IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size,
|
||||
fp->_wide_data->_IO_read_end = end;
|
||||
}
|
||||
/* A null _allocate_buffer function flags the strfile as being static. */
|
||||
- (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
|
||||
+ (((_IO_strfile *) fp)->_s._allocate_buffer_unused) = (_IO_alloc_type)0;
|
||||
}
|
||||
|
||||
_IO_wint_t
|
||||
@@ -95,9 +95,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
|
||||
|| __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
|
||||
return EOF;
|
||||
|
||||
- new_buf
|
||||
- = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
|
||||
- * sizeof (wchar_t));
|
||||
+ new_buf = malloc (new_size * sizeof (wchar_t));
|
||||
if (new_buf == NULL)
|
||||
{
|
||||
/* __ferror(fp) = 1; */
|
||||
@@ -106,7 +104,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
|
||||
if (old_buf)
|
||||
{
|
||||
__wmemcpy (new_buf, old_buf, old_wblen);
|
||||
- (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
|
||||
+ free (old_buf);
|
||||
/* Make sure _IO_setb won't try to delete _IO_buf_base. */
|
||||
fp->_wide_data->_IO_buf_base = NULL;
|
||||
}
|
||||
@@ -186,16 +184,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
|
||||
return 1;
|
||||
|
||||
wchar_t *oldbuf = wd->_IO_buf_base;
|
||||
- wchar_t *newbuf
|
||||
- = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
|
||||
- * sizeof (wchar_t));
|
||||
+ wchar_t *newbuf = malloc (newsize * sizeof (wchar_t));
|
||||
if (newbuf == NULL)
|
||||
return 1;
|
||||
|
||||
if (oldbuf != NULL)
|
||||
{
|
||||
__wmemcpy (newbuf, oldbuf, _IO_wblen (fp));
|
||||
- (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
|
||||
+ free (oldbuf);
|
||||
/* Make sure _IO_setb won't try to delete
|
||||
_IO_buf_base. */
|
||||
wd->_IO_buf_base = NULL;
|
||||
@@ -326,7 +322,7 @@ void
|
||||
_IO_wstr_finish (_IO_FILE *fp, int dummy)
|
||||
{
|
||||
if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
|
||||
- (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base);
|
||||
+ free (fp->_wide_data->_IO_buf_base);
|
||||
fp->_wide_data->_IO_buf_base = NULL;
|
||||
|
||||
_IO_wdefault_finish (fp, 0);
|
|
@ -0,0 +1,34 @@
|
|||
commit 3bb748257405e94e13de76573a4e9da1cfd961d0
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jul 3 15:54:49 2018 +0200
|
||||
|
||||
libio: Disable vtable validation in case of interposition [BZ #23313]
|
||||
|
||||
(cherry picked from commit c402355dfa7807b8e0adb27c009135a7e2b9f1b0)
|
||||
|
||||
Backported from the upstream release/2.27/master branch.
|
||||
|
||||
diff --git a/libio/vtables.c b/libio/vtables.c
|
||||
index e364ea03edbfa75b..d6478e4bab9050ce 100644
|
||||
--- a/libio/vtables.c
|
||||
+++ b/libio/vtables.c
|
||||
@@ -68,3 +68,19 @@ _IO_vtable_check (void)
|
||||
|
||||
__libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n");
|
||||
}
|
||||
+
|
||||
+/* Some variants of libstdc++ interpose _IO_2_1_stdin_ etc. and
|
||||
+ install their own vtables directly, without calling _IO_init or
|
||||
+ other functions. Detect this by looking at the vtables values
|
||||
+ during startup, and disable vtable validation in this case. */
|
||||
+#ifdef SHARED
|
||||
+__attribute__ ((constructor))
|
||||
+static void
|
||||
+check_stdfiles_vtables (void)
|
||||
+{
|
||||
+ if (_IO_2_1_stdin_.vtable != &_IO_file_jumps
|
||||
+ || _IO_2_1_stdout_.vtable != &_IO_file_jumps
|
||||
+ || _IO_2_1_stderr_.vtable != &_IO_file_jumps)
|
||||
+ IO_set_accept_foreign_vtables (&_IO_vtable_check);
|
||||
+}
|
||||
+#endif
|
|
@ -0,0 +1,624 @@
|
|||
commit 44927211651adde42bbd431ef5ebe568186125e5
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jul 3 17:57:14 2018 +0200
|
||||
|
||||
libio: Add tst-vtables, tst-vtables-interposed
|
||||
|
||||
(cherry picked from commit 29055464a03c72762969a2e8734d0d05d4d70e58)
|
||||
|
||||
Some adjustments were needed for a tricky multi-inclusion issue related
|
||||
to libioP.h.
|
||||
|
||||
Backported from the upsteam release/2.27/master branch, adjusted for
|
||||
lack of tests-internal support downstream.
|
||||
|
||||
diff --git a/libio/Makefile b/libio/Makefile
|
||||
index 0cef96141209fe99..1e923da42e45c492 100644
|
||||
--- a/libio/Makefile
|
||||
+++ b/libio/Makefile
|
||||
@@ -61,7 +61,9 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
|
||||
bug-memstream1 bug-wmemstream1 \
|
||||
tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
|
||||
tst-fwrite-error tst-ftell-active-handler \
|
||||
- tst-ftell-append
|
||||
+ tst-ftell-append \
|
||||
+ tst-vtables tst-vtables-interposed
|
||||
+
|
||||
ifeq (yes,$(build-shared))
|
||||
# Add test-fopenloc only if shared library is enabled since it depends on
|
||||
# shared localedata objects.
|
||||
diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..dc8d89c195b95b8d
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-vtables-common.c
|
||||
@@ -0,0 +1,511 @@
|
||||
+/* Test for libio vtables and their validation. Common code.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This test provides some coverage for how various stdio functions
|
||||
+ use the vtables in FILE * objects. The focus is mostly on which
|
||||
+ functions call which methods, not so much on validating data
|
||||
+ processing. An initial series of tests check that custom vtables
|
||||
+ do not work without activation through _IO_init.
|
||||
+
|
||||
+ Note: libio vtables are deprecated feature. Do not use this test
|
||||
+ as a documentation source for writing custom vtables. See
|
||||
+ fopencookie for a different way of creating custom stdio
|
||||
+ streams. */
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+#include <string.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/namespace.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/test-driver.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+/* Data shared between the test subprocess and the test driver in the
|
||||
+ parent. Note that *shared is reset at the start of the check_call
|
||||
+ function. */
|
||||
+struct shared
|
||||
+{
|
||||
+ /* Expected file pointer for method calls. */
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ /* If true, assume that a call to _IO_init is needed to enable
|
||||
+ custom vtables. */
|
||||
+ bool initially_disabled;
|
||||
+
|
||||
+ /* Requested return value for the methods which have one. */
|
||||
+ int return_value;
|
||||
+
|
||||
+ /* A value (usually a character) recorded by some of the methods
|
||||
+ below. */
|
||||
+ int value;
|
||||
+
|
||||
+ /* Likewise, for some data. */
|
||||
+ char buffer[16];
|
||||
+ size_t buffer_length;
|
||||
+
|
||||
+ /* Total number of method calls. */
|
||||
+ unsigned int calls;
|
||||
+
|
||||
+ /* Individual method call counts. */
|
||||
+ unsigned int calls_finish;
|
||||
+ unsigned int calls_overflow;
|
||||
+ unsigned int calls_underflow;
|
||||
+ unsigned int calls_uflow;
|
||||
+ unsigned int calls_pbackfail;
|
||||
+ unsigned int calls_xsputn;
|
||||
+ unsigned int calls_xsgetn;
|
||||
+ unsigned int calls_seekoff;
|
||||
+ unsigned int calls_seekpos;
|
||||
+ unsigned int calls_setbuf;
|
||||
+ unsigned int calls_sync;
|
||||
+ unsigned int calls_doallocate;
|
||||
+ unsigned int calls_read;
|
||||
+ unsigned int calls_write;
|
||||
+ unsigned int calls_seek;
|
||||
+ unsigned int calls_close;
|
||||
+ unsigned int calls_stat;
|
||||
+ unsigned int calls_showmanyc;
|
||||
+ unsigned int calls_imbue;
|
||||
+} *shared;
|
||||
+
|
||||
+/* Method implementations which increment the counters in *shared. */
|
||||
+
|
||||
+static void
|
||||
+log_method (FILE *fp, const char *name)
|
||||
+{
|
||||
+ if (test_verbose > 0)
|
||||
+ printf ("info: %s (%p) called\n", name, fp);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+method_finish (FILE *fp, int dummy)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_finish;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_overflow (FILE *fp, int ch)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_overflow;
|
||||
+ shared->value = ch;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_underflow (FILE *fp)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_underflow;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_uflow (FILE *fp)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_uflow;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_pbackfail (FILE *fp, int ch)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_pbackfail;
|
||||
+ shared->value = ch;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static size_t
|
||||
+method_xsputn (FILE *fp, const void *data, size_t n)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_xsputn;
|
||||
+
|
||||
+ size_t to_copy = n;
|
||||
+ if (n > sizeof (shared->buffer))
|
||||
+ to_copy = sizeof (shared->buffer);
|
||||
+ memcpy (shared->buffer, data, to_copy);
|
||||
+ shared->buffer_length = to_copy;
|
||||
+ return to_copy;
|
||||
+}
|
||||
+
|
||||
+static size_t
|
||||
+method_xsgetn (FILE *fp, void *data, size_t n)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_xsgetn;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static off64_t
|
||||
+method_seekoff (FILE *fp, off64_t offset, int dir, int mode)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_seekoff;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static off64_t
|
||||
+method_seekpos (FILE *fp, off64_t offset, int mode)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_seekpos;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static FILE *
|
||||
+method_setbuf (FILE *fp, char *buffer, ssize_t length)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_setbuf;
|
||||
+ return fp;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_sync (FILE *fp)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_sync;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_doallocate (FILE *fp)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_doallocate;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
+method_read (FILE *fp, void *data, ssize_t length)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_read;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static ssize_t
|
||||
+method_write (FILE *fp, const void *data, ssize_t length)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_write;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static off64_t
|
||||
+method_seek (FILE *fp, off64_t offset, int mode)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_seek;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_close (FILE *fp)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_close;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_stat (FILE *fp, void *buffer)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_stat;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+method_showmanyc (FILE *fp)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_showmanyc;
|
||||
+ return shared->return_value;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+method_imbue (FILE *fp, void *locale)
|
||||
+{
|
||||
+ log_method (fp, __func__);
|
||||
+ TEST_VERIFY (fp == shared->fp);
|
||||
+ ++shared->calls;
|
||||
+ ++shared->calls_imbue;
|
||||
+}
|
||||
+
|
||||
+/* Our custom vtable. */
|
||||
+
|
||||
+static const struct _IO_jump_t jumps =
|
||||
+{
|
||||
+ JUMP_INIT_DUMMY,
|
||||
+ JUMP_INIT (finish, method_finish),
|
||||
+ JUMP_INIT (overflow, method_overflow),
|
||||
+ JUMP_INIT (underflow, method_underflow),
|
||||
+ JUMP_INIT (uflow, method_uflow),
|
||||
+ JUMP_INIT (pbackfail, method_pbackfail),
|
||||
+ JUMP_INIT (xsputn, method_xsputn),
|
||||
+ JUMP_INIT (xsgetn, method_xsgetn),
|
||||
+ JUMP_INIT (seekoff, method_seekoff),
|
||||
+ JUMP_INIT (seekpos, method_seekpos),
|
||||
+ JUMP_INIT (setbuf, method_setbuf),
|
||||
+ JUMP_INIT (sync, method_sync),
|
||||
+ JUMP_INIT (doallocate, method_doallocate),
|
||||
+ JUMP_INIT (read, method_read),
|
||||
+ JUMP_INIT (write, method_write),
|
||||
+ JUMP_INIT (seek, method_seek),
|
||||
+ JUMP_INIT (close, method_close),
|
||||
+ JUMP_INIT (stat, method_stat),
|
||||
+ JUMP_INIT (showmanyc, method_showmanyc),
|
||||
+ JUMP_INIT (imbue, method_imbue)
|
||||
+};
|
||||
+
|
||||
+/* Our file implementation. */
|
||||
+
|
||||
+struct my_file
|
||||
+{
|
||||
+ FILE f;
|
||||
+ const struct _IO_jump_t *vtable;
|
||||
+};
|
||||
+
|
||||
+struct my_file
|
||||
+my_file_create (void)
|
||||
+{
|
||||
+ return (struct my_file)
|
||||
+ {
|
||||
+ /* Disable locking, so that we do not have to set up a lock
|
||||
+ pointer. */
|
||||
+ .f._flags = _IO_USER_LOCK,
|
||||
+
|
||||
+ /* Copy the offset from the an initialized handle, instead of
|
||||
+ figuring it out from scratch. */
|
||||
+ .f._vtable_offset = stdin->_vtable_offset,
|
||||
+
|
||||
+ .vtable = &jumps,
|
||||
+ };
|
||||
+}
|
||||
+
|
||||
+/* Initial tests which do not enable vtable compatibility. */
|
||||
+
|
||||
+/* Inhibit GCC optimization of fprintf. */
|
||||
+typedef int (*fprintf_type) (FILE *, const char *, ...);
|
||||
+static const volatile fprintf_type fprintf_ptr = &fprintf;
|
||||
+
|
||||
+static void
|
||||
+without_compatibility_fprintf (void *closure)
|
||||
+{
|
||||
+ /* This call should abort. */
|
||||
+ fprintf_ptr (shared->fp, " ");
|
||||
+ _exit (1);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+without_compatibility_fputc (void *closure)
|
||||
+{
|
||||
+ /* This call should abort. */
|
||||
+ fputc (' ', shared->fp);
|
||||
+ _exit (1);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+without_compatibility_fgetc (void *closure)
|
||||
+{
|
||||
+ /* This call should abort. */
|
||||
+ fgetc (shared->fp);
|
||||
+ _exit (1);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+without_compatibility_fflush (void *closure)
|
||||
+{
|
||||
+ /* This call should abort. */
|
||||
+ fflush (shared->fp);
|
||||
+ _exit (1);
|
||||
+}
|
||||
+
|
||||
+/* Exit status after abnormal termination. */
|
||||
+static int termination_status;
|
||||
+
|
||||
+static void
|
||||
+init_termination_status (void)
|
||||
+{
|
||||
+ pid_t pid = xfork ();
|
||||
+ if (pid == 0)
|
||||
+ abort ();
|
||||
+ xwaitpid (pid, &termination_status, 0);
|
||||
+
|
||||
+ TEST_VERIFY (WIFSIGNALED (termination_status));
|
||||
+ TEST_COMPARE (WTERMSIG (termination_status), SIGABRT);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check_for_termination (const char *name, void (*callback) (void *))
|
||||
+{
|
||||
+ struct my_file file = my_file_create ();
|
||||
+ shared->fp = &file.f;
|
||||
+ shared->return_value = -1;
|
||||
+ shared->calls = 0;
|
||||
+ struct support_capture_subprocess proc
|
||||
+ = support_capture_subprocess (callback, NULL);
|
||||
+ support_capture_subprocess_check (&proc, name, termination_status,
|
||||
+ sc_allow_stderr);
|
||||
+ const char *message
|
||||
+ = "Fatal error: glibc detected an invalid stdio handle\n";
|
||||
+ TEST_COMPARE_BLOB (proc.err.buffer, proc.err.length,
|
||||
+ message, strlen (message));
|
||||
+ TEST_COMPARE (shared->calls, 0);
|
||||
+ support_capture_subprocess_free (&proc);
|
||||
+}
|
||||
+
|
||||
+/* The test with vtable validation disabled. */
|
||||
+
|
||||
+/* This function does not have a prototype in libioP.h to prevent
|
||||
+ accidental use from within the library (which would disable vtable
|
||||
+ verification). */
|
||||
+void _IO_init (FILE *fp, int flags);
|
||||
+
|
||||
+static void
|
||||
+with_compatibility_fprintf (void *closure)
|
||||
+{
|
||||
+ TEST_COMPARE (fprintf_ptr (shared->fp, "A%sCD", "B"), 4);
|
||||
+ TEST_COMPARE (shared->calls, 3);
|
||||
+ TEST_COMPARE (shared->calls_xsputn, 3);
|
||||
+ TEST_COMPARE_BLOB (shared->buffer, shared->buffer_length,
|
||||
+ "CD", 2);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+with_compatibility_fputc (void *closure)
|
||||
+{
|
||||
+ shared->return_value = '@';
|
||||
+ TEST_COMPARE (fputc ('@', shared->fp), '@');
|
||||
+ TEST_COMPARE (shared->calls, 1);
|
||||
+ TEST_COMPARE (shared->calls_overflow, 1);
|
||||
+ TEST_COMPARE (shared->value, '@');
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+with_compatibility_fgetc (void *closure)
|
||||
+{
|
||||
+ shared->return_value = 'X';
|
||||
+ TEST_COMPARE (fgetc (shared->fp), 'X');
|
||||
+ TEST_COMPARE (shared->calls, 1);
|
||||
+ TEST_COMPARE (shared->calls_uflow, 1);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+with_compatibility_fflush (void *closure)
|
||||
+{
|
||||
+ TEST_COMPARE (fflush (shared->fp), 0);
|
||||
+ TEST_COMPARE (shared->calls, 1);
|
||||
+ TEST_COMPARE (shared->calls_sync, 1);
|
||||
+}
|
||||
+
|
||||
+/* Call CALLBACK in a subprocess, after setting up a custom file
|
||||
+ object and updating shared->fp. */
|
||||
+static void
|
||||
+check_call (const char *name, void (*callback) (void *),
|
||||
+ bool initially_disabled)
|
||||
+{
|
||||
+ *shared = (struct shared)
|
||||
+ {
|
||||
+ .initially_disabled = initially_disabled,
|
||||
+ };
|
||||
+
|
||||
+ /* Set up a custom file object. */
|
||||
+ struct my_file file = my_file_create ();
|
||||
+ shared->fp = &file.f;
|
||||
+ if (shared->initially_disabled)
|
||||
+ _IO_init (shared->fp, file.f._flags);
|
||||
+
|
||||
+ if (test_verbose > 0)
|
||||
+ printf ("info: calling test %s\n", name);
|
||||
+ support_isolate_in_subprocess (callback, NULL);
|
||||
+}
|
||||
+
|
||||
+/* Run the tests. INITIALLY_DISABLED indicates whether custom vtables
|
||||
+ are disabled when the test starts. */
|
||||
+static int
|
||||
+run_tests (bool initially_disabled)
|
||||
+{
|
||||
+ /* The test relies on fatal error messages being printed to standard
|
||||
+ error. */
|
||||
+ setenv ("LIBC_FATAL_STDERR_", "1", 1);
|
||||
+
|
||||
+ shared = support_shared_allocate (sizeof (*shared));
|
||||
+ shared->initially_disabled = initially_disabled;
|
||||
+ init_termination_status ();
|
||||
+
|
||||
+ if (initially_disabled)
|
||||
+ {
|
||||
+ check_for_termination ("fprintf", without_compatibility_fprintf);
|
||||
+ check_for_termination ("fputc", without_compatibility_fputc);
|
||||
+ check_for_termination ("fgetc", without_compatibility_fgetc);
|
||||
+ check_for_termination ("fflush", without_compatibility_fflush);
|
||||
+ }
|
||||
+
|
||||
+ check_call ("fprintf", with_compatibility_fprintf, initially_disabled);
|
||||
+ check_call ("fputc", with_compatibility_fputc, initially_disabled);
|
||||
+ check_call ("fgetc", with_compatibility_fgetc, initially_disabled);
|
||||
+ check_call ("fflush", with_compatibility_fflush, initially_disabled);
|
||||
+
|
||||
+ support_shared_free (shared);
|
||||
+ shared = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/libio/tst-vtables-interposed.c b/libio/tst-vtables-interposed.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c8f4e8c7c386af39
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-vtables-interposed.c
|
||||
@@ -0,0 +1,37 @@
|
||||
+/* Test for libio vtables and their validation. Enabled through interposition.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* Provide an interposed definition of the standard file handles with
|
||||
+ our own vtable. stdout/stdin/stderr will not work as a result, but
|
||||
+ a succesful test does not print anything, so this is fine. */
|
||||
+static const struct _IO_jump_t jumps;
|
||||
+#define _IO_file_jumps jumps
|
||||
+#include "stdfiles.c"
|
||||
+
|
||||
+#include "tst-vtables-common.c"
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ return run_tests (false);
|
||||
+}
|
||||
+
|
||||
+/* Calling setvbuf in the test driver is not supported with our
|
||||
+ interposed file handles. */
|
||||
+#define TEST_NO_SETVBUF
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/libio/tst-vtables.c b/libio/tst-vtables.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f16acf5d23b0fff6
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-vtables.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* Test for libio vtables and their validation. Initially disabled case.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "libioP.h"
|
||||
+
|
||||
+#include "tst-vtables-common.c"
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ return run_tests (true);
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,24 @@
|
|||
commit 2d1c89a5d7c872a1109768f50e2508cf9a4b0348
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Jun 20 09:45:19 2018 +0200
|
||||
|
||||
libio: Avoid ptrdiff_t overflow in IO_validate_vtable
|
||||
|
||||
If the candidate pointer is sufficiently far away from
|
||||
__start___libc_IO_vtables, the result might not fit into ptrdiff_t.
|
||||
|
||||
diff --git a/libio/libioP.h b/libio/libioP.h
|
||||
index b60244ac5fc3d908..f1576381500ffc85 100644
|
||||
--- a/libio/libioP.h
|
||||
+++ b/libio/libioP.h
|
||||
@@ -957,8 +957,8 @@ IO_validate_vtable (const struct _IO_jump_t *vtable)
|
||||
/* Fast path: The vtable pointer is within the __libc_IO_vtables
|
||||
section. */
|
||||
uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;
|
||||
- const char *ptr = (const char *) vtable;
|
||||
- uintptr_t offset = ptr - __start___libc_IO_vtables;
|
||||
+ uintptr_t ptr = (uintptr_t) vtable;
|
||||
+ uintptr_t offset = ptr - (uintptr_t) __start___libc_IO_vtables;
|
||||
if (__glibc_unlikely (offset >= section_length))
|
||||
/* The vtable pointer is not in the expected section. Use the
|
||||
slow path, which will terminate the process if necessary. */
|
|
@ -0,0 +1,65 @@
|
|||
commit b04acb2651e0aaf615de50e9138cddfd5c24021f
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Tue Jul 30 11:58:45 2013 +0200
|
||||
|
||||
Fix race conditions in pldd that may leave the process stopped after detaching
|
||||
|
||||
Fixes bug 15804
|
||||
|
||||
diff --git a/elf/pldd.c b/elf/pldd.c
|
||||
index 684aff4..75f7812 100644
|
||||
--- a/elf/pldd.c
|
||||
+++ b/elf/pldd.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <sys/wait.h>
|
||||
|
||||
#include <ldsodefs.h>
|
||||
#include <version.h>
|
||||
@@ -82,6 +83,7 @@ static char *exe;
|
||||
|
||||
/* Local functions. */
|
||||
static int get_process_info (int dfd, long int pid);
|
||||
+static void wait_for_ptrace_stop (long int pid);
|
||||
|
||||
|
||||
int
|
||||
@@ -170,6 +172,8 @@ main (int argc, char *argv[])
|
||||
tid);
|
||||
}
|
||||
|
||||
+ wait_for_ptrace_stop (tid);
|
||||
+
|
||||
struct thread_list *newp = alloca (sizeof (*newp));
|
||||
newp->tid = tid;
|
||||
newp->next = thread_list;
|
||||
@@ -194,6 +198,27 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
+/* Wait for PID to enter ptrace-stop state after being attached. */
|
||||
+static void
|
||||
+wait_for_ptrace_stop (long int pid)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ /* While waiting for SIGSTOP being delivered to the tracee we have to
|
||||
+ reinject any other pending signal. Ignore all other errors. */
|
||||
+ while (waitpid (pid, &status, __WALL) == pid && WIFSTOPPED (status))
|
||||
+ {
|
||||
+ /* The STOP signal should not be delivered to the tracee. */
|
||||
+ if (WSTOPSIG (status) == SIGSTOP)
|
||||
+ return;
|
||||
+ if (ptrace (PTRACE_CONT, pid, NULL,
|
||||
+ (void *) (uintptr_t) WSTOPSIG (status)))
|
||||
+ /* The only possible error is that the process died. */
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Handle program arguments. */
|
||||
static error_t
|
||||
parse_opt (int key, char *arg, struct argp_state *state)
|
|
@ -0,0 +1,486 @@
|
|||
commit e5d262effe3a87164308a3f37e61b32d0348692a
|
||||
Author: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
Date: Fri Nov 30 18:05:32 2018 -0200
|
||||
|
||||
Fix _dl_profile_fixup data-dependency issue (Bug 23690)
|
||||
|
||||
There is a data-dependency between the fields of struct l_reloc_result
|
||||
and the field used as the initialization guard. Users of the guard
|
||||
expect writes to the structure to be observable when they also observe
|
||||
the guard initialized. The solution for this problem is to use an acquire
|
||||
and release load and store to ensure previous writes to the structure are
|
||||
observable if the guard is initialized.
|
||||
|
||||
The previous implementation used DL_FIXUP_VALUE_ADDR (l_reloc_result->addr)
|
||||
as the initialization guard, making it impossible for some architectures
|
||||
to load and store it atomically, i.e. hppa and ia64, due to its larger size.
|
||||
|
||||
This commit adds an unsigned int to l_reloc_result to be used as the new
|
||||
initialization guard of the struct, making it possible to load and store
|
||||
it atomically in all architectures. The fix ensures that the values
|
||||
observed in l_reloc_result are consistent and do not lead to crashes.
|
||||
The algorithm is documented in the code in elf/dl-runtime.c
|
||||
(_dl_profile_fixup). Not all data races have been eliminated.
|
||||
|
||||
Tested with build-many-glibcs and on powerpc, powerpc64, and powerpc64le.
|
||||
|
||||
[BZ #23690]
|
||||
* elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
|
||||
modification order when accessing reloc_result->addr.
|
||||
* include/link.h (reloc_result): Add field init.
|
||||
* nptl/Makefile (tests): Add tst-audit-threads.
|
||||
(modules-names): Add tst-audit-threads-mod1 and
|
||||
tst-audit-threads-mod2.
|
||||
Add rules to build tst-audit-threads.
|
||||
* nptl/tst-audit-threads-mod1.c: New file.
|
||||
* nptl/tst-audit-threads-mod2.c: Likewise.
|
||||
* nptl/tst-audit-threads.c: Likewise.
|
||||
* nptl/tst-audit-threads.h: Likewise.
|
||||
|
||||
Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
(elf/dl-runtime.c adjusted here for lack of __builtin_expect cleanup,
|
||||
nptl/Makefile for the usual test-related conflicts.)
|
||||
|
||||
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||
index a42e3c4924e067ba..3678a98c98d726f3 100644
|
||||
--- a/elf/dl-runtime.c
|
||||
+++ b/elf/dl-runtime.c
|
||||
@@ -183,10 +183,36 @@ _dl_profile_fixup (
|
||||
/* This is the address in the array where we store the result of previous
|
||||
relocations. */
|
||||
struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
|
||||
- DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
|
||||
|
||||
- DL_FIXUP_VALUE_TYPE value = *resultp;
|
||||
- if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
|
||||
+ /* CONCURRENCY NOTES:
|
||||
+
|
||||
+ Multiple threads may be calling the same PLT sequence and with
|
||||
+ LD_AUDIT enabled they will be calling into _dl_profile_fixup to
|
||||
+ update the reloc_result with the result of the lazy resolution.
|
||||
+ The reloc_result guard variable is reloc_init, and we use
|
||||
+ acquire/release loads and store to it to ensure that the results of
|
||||
+ the structure are consistent with the loaded value of the guard.
|
||||
+ This does not fix all of the data races that occur when two or more
|
||||
+ threads read reloc_result->reloc_init with a value of zero and read
|
||||
+ and write to that reloc_result concurrently. The expectation is
|
||||
+ generally that while this is a data race it works because the
|
||||
+ threads write the same values. Until the data races are fixed
|
||||
+ there is a potential for problems to arise from these data races.
|
||||
+ The reloc result updates should happen in parallel but there should
|
||||
+ be an atomic RMW which does the final update to the real result
|
||||
+ entry (see bug 23790).
|
||||
+
|
||||
+ The following code uses reloc_result->init set to 0 to indicate if it is
|
||||
+ the first time this object is being relocated, otherwise 1 which
|
||||
+ indicates the object has already been relocated.
|
||||
+
|
||||
+ Reading/Writing from/to reloc_result->reloc_init must not happen
|
||||
+ before previous writes to reloc_result complete as they could
|
||||
+ end-up with an incomplete struct. */
|
||||
+ DL_FIXUP_VALUE_TYPE value;
|
||||
+ unsigned int init = atomic_load_acquire (&reloc_result->init);
|
||||
+
|
||||
+ if (init == 0)
|
||||
{
|
||||
/* This is the first time we have to relocate this object. */
|
||||
const ElfW(Sym) *const symtab
|
||||
@@ -347,20 +373,32 @@ _dl_profile_fixup (
|
||||
#endif
|
||||
|
||||
/* Store the result for later runs. */
|
||||
- if (__builtin_expect (! GLRO(dl_bind_not), 1))
|
||||
- *resultp = value;
|
||||
+ if (__glibc_likely (! GLRO(dl_bind_not)))
|
||||
+ {
|
||||
+ reloc_result->addr = value;
|
||||
+ /* Guarantee all previous writes complete before
|
||||
+ init is updated. See CONCURRENCY NOTES earlier */
|
||||
+ atomic_store_release (&reloc_result->init, 1);
|
||||
+ }
|
||||
+ init = 1;
|
||||
}
|
||||
+ else
|
||||
+ value = reloc_result->addr;
|
||||
|
||||
/* By default we do not call the pltexit function. */
|
||||
long int framesize = -1;
|
||||
|
||||
+
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: report the PLT entering and allow the
|
||||
auditors to change the value. */
|
||||
- if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
|
||||
+ if (GLRO(dl_naudit) > 0
|
||||
/* Don't do anything if no auditor wants to intercept this call. */
|
||||
&& (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
|
||||
{
|
||||
+ /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||
+ initialized earlier in this function or in another thread. */
|
||||
+ assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
|
||||
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||
l_info[DT_SYMTAB])
|
||||
+ reloc_result->boundndx);
|
||||
diff --git a/include/link.h b/include/link.h
|
||||
index d7590640aa9285e5..22d020d833ae3a7c 100644
|
||||
--- a/include/link.h
|
||||
+++ b/include/link.h
|
||||
@@ -206,6 +206,10 @@ struct link_map
|
||||
unsigned int boundndx;
|
||||
uint32_t enterexit;
|
||||
unsigned int flags;
|
||||
+ /* CONCURRENCY NOTE: This is used to guard the concurrent initialization
|
||||
+ of the relocation result across multiple threads. See the more
|
||||
+ detailed notes in elf/dl-runtime.c. */
|
||||
+ unsigned int init;
|
||||
} *l_reloc_result;
|
||||
|
||||
/* Pointer to the version information if available. */
|
||||
diff --git a/nptl/Makefile b/nptl/Makefile
|
||||
index cf47a6f097916766..1b9639f3566a63fd 100644
|
||||
--- a/nptl/Makefile
|
||||
+++ b/nptl/Makefile
|
||||
@@ -298,7 +298,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
|
||||
endif
|
||||
ifeq ($(build-shared),yes)
|
||||
tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1 tst-fini1 \
|
||||
- tst-stackguard1
|
||||
+ tst-stackguard1 tst-audit-threads
|
||||
tests-nolibpthread += tst-fini1
|
||||
ifeq ($(have-z-execstack),yes)
|
||||
tests += tst-execstack
|
||||
@@ -309,7 +309,7 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
|
||||
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
|
||||
tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
|
||||
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
|
||||
- tst-join7mod
|
||||
+ tst-join7mod tst-audit-threads-mod1 tst-audit-threads-mod2
|
||||
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
|
||||
test-extras += $(modules-names) tst-cleanup4aux
|
||||
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
|
||||
@@ -627,6 +627,14 @@ $(objpfx)tst-oddstacklimit.out: $(objpfx)tst-oddstacklimit $(objpfx)tst-basic1
|
||||
$(run-program-prefix) $< --command '$(host-built-program-cmd)' > $@
|
||||
endif
|
||||
|
||||
+# Protect against a build using -Wl,-z,now.
|
||||
+LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy
|
||||
+LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy
|
||||
+LDFLAGS-tst-audit-threads = -Wl,-z,lazy
|
||||
+$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so
|
||||
+$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so
|
||||
+tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so
|
||||
+
|
||||
# The tests here better do not run in parallel
|
||||
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
|
||||
.NOTPARALLEL:
|
||||
diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..615d5ee5121962df
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads-mod1.c
|
||||
@@ -0,0 +1,74 @@
|
||||
+/* Dummy audit library for test-audit-threads.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <elf.h>
|
||||
+#include <link.h>
|
||||
+#include <stdio.h>
|
||||
+#include <assert.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* We must use a dummy LD_AUDIT module to force the dynamic loader to
|
||||
+ *not* update the real PLT, and instead use a cached value for the
|
||||
+ lazy resolution result. It is the update of that cached value that
|
||||
+ we are testing for correctness by doing this. */
|
||||
+
|
||||
+/* Library to be audited. */
|
||||
+#define LIB "tst-audit-threads-mod2.so"
|
||||
+/* CALLNUM is the number of retNum functions. */
|
||||
+#define CALLNUM 7999
|
||||
+
|
||||
+#define CONCATX(a, b) __CONCAT (a, b)
|
||||
+
|
||||
+static int previous = 0;
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int ver)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||
+{
|
||||
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||
+}
|
||||
+
|
||||
+uintptr_t
|
||||
+CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym,
|
||||
+ unsigned int ndx,
|
||||
+ uintptr_t *refcook,
|
||||
+ uintptr_t *defcook,
|
||||
+ unsigned int *flags,
|
||||
+ const char *symname)
|
||||
+{
|
||||
+ const char * retnum = "retNum";
|
||||
+ char * num = strstr (symname, retnum);
|
||||
+ int n;
|
||||
+ /* Validate if the symbols are getting called in the correct order.
|
||||
+ This code is here to verify binutils does not optimize out the PLT
|
||||
+ entries that require the symbol binding. */
|
||||
+ if (num != NULL)
|
||||
+ {
|
||||
+ n = atoi (num);
|
||||
+ assert (n >= previous);
|
||||
+ assert (n <= CALLNUM);
|
||||
+ previous = n;
|
||||
+ }
|
||||
+ return sym->st_value;
|
||||
+}
|
||||
diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f9817dd3dc7f4910
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads-mod2.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* Shared object with a huge number of functions for test-audit-threads.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* Define all the retNumN functions in a library. */
|
||||
+#define definenum
|
||||
+#include "tst-audit-threads.h"
|
||||
diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..e4bf433bd85f3715
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads.c
|
||||
@@ -0,0 +1,97 @@
|
||||
+/* Test multi-threading using LD_AUDIT.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a
|
||||
+ library with a huge number of functions in order to validate lazy symbol
|
||||
+ binding with an audit library. We use one thread per CPU to test that
|
||||
+ concurrent lazy resolution does not have any defects which would cause
|
||||
+ the process to fail. We use an LD_AUDIT library to force the testing of
|
||||
+ the relocation resolution caching code in the dynamic loader i.e.
|
||||
+ _dl_runtime_profile and _dl_profile_fixup. */
|
||||
+
|
||||
+#include <support/xthread.h>
|
||||
+#include <strings.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <sys/sysinfo.h>
|
||||
+
|
||||
+static int do_test (void);
|
||||
+
|
||||
+/* This test usually takes less than 3s to run. However, there are cases that
|
||||
+ take up to 30s. */
|
||||
+#define TIMEOUT 60
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
+
|
||||
+/* Declare the functions we are going to call. */
|
||||
+#define externnum
|
||||
+#include "tst-audit-threads.h"
|
||||
+#undef externnum
|
||||
+
|
||||
+int num_threads;
|
||||
+pthread_barrier_t barrier;
|
||||
+
|
||||
+void
|
||||
+sync_all (int num)
|
||||
+{
|
||||
+ pthread_barrier_wait (&barrier);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+call_all_ret_nums (void)
|
||||
+{
|
||||
+ /* Call each function one at a time from all threads. */
|
||||
+#define callnum
|
||||
+#include "tst-audit-threads.h"
|
||||
+#undef callnum
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+thread_main (void *unused)
|
||||
+{
|
||||
+ call_all_ret_nums ();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+#define STR2(X) #X
|
||||
+#define STR(X) STR2(X)
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int i;
|
||||
+ pthread_t *threads;
|
||||
+
|
||||
+ num_threads = get_nprocs ();
|
||||
+ if (num_threads <= 1)
|
||||
+ num_threads = 2;
|
||||
+
|
||||
+ /* Used to synchronize all the threads after calling each retNumN. */
|
||||
+ xpthread_barrier_init (&barrier, NULL, num_threads);
|
||||
+
|
||||
+ threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
|
||||
+ for (i = 0; i < num_threads; i++)
|
||||
+ threads[i] = xpthread_create(NULL, thread_main, NULL);
|
||||
+
|
||||
+ for (i = 0; i < num_threads; i++)
|
||||
+ xpthread_join(threads[i]);
|
||||
+
|
||||
+ free (threads);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..1c9ecc08dfcd3e65
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads.h
|
||||
@@ -0,0 +1,92 @@
|
||||
+/* Helper header for test-audit-threads.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* We use this helper to create a large number of functions, all of
|
||||
+ which will be resolved lazily and thus have their PLT updated.
|
||||
+ This is done to provide enough functions that we can statistically
|
||||
+ observe a thread vs. PLT resolution failure if one exists. */
|
||||
+
|
||||
+#define CONCAT(a, b) a ## b
|
||||
+#define NUM(x, y) CONCAT (x, y)
|
||||
+
|
||||
+#define FUNC10(x) \
|
||||
+ FUNC (NUM (x, 0)); \
|
||||
+ FUNC (NUM (x, 1)); \
|
||||
+ FUNC (NUM (x, 2)); \
|
||||
+ FUNC (NUM (x, 3)); \
|
||||
+ FUNC (NUM (x, 4)); \
|
||||
+ FUNC (NUM (x, 5)); \
|
||||
+ FUNC (NUM (x, 6)); \
|
||||
+ FUNC (NUM (x, 7)); \
|
||||
+ FUNC (NUM (x, 8)); \
|
||||
+ FUNC (NUM (x, 9))
|
||||
+
|
||||
+#define FUNC100(x) \
|
||||
+ FUNC10 (NUM (x, 0)); \
|
||||
+ FUNC10 (NUM (x, 1)); \
|
||||
+ FUNC10 (NUM (x, 2)); \
|
||||
+ FUNC10 (NUM (x, 3)); \
|
||||
+ FUNC10 (NUM (x, 4)); \
|
||||
+ FUNC10 (NUM (x, 5)); \
|
||||
+ FUNC10 (NUM (x, 6)); \
|
||||
+ FUNC10 (NUM (x, 7)); \
|
||||
+ FUNC10 (NUM (x, 8)); \
|
||||
+ FUNC10 (NUM (x, 9))
|
||||
+
|
||||
+#define FUNC1000(x) \
|
||||
+ FUNC100 (NUM (x, 0)); \
|
||||
+ FUNC100 (NUM (x, 1)); \
|
||||
+ FUNC100 (NUM (x, 2)); \
|
||||
+ FUNC100 (NUM (x, 3)); \
|
||||
+ FUNC100 (NUM (x, 4)); \
|
||||
+ FUNC100 (NUM (x, 5)); \
|
||||
+ FUNC100 (NUM (x, 6)); \
|
||||
+ FUNC100 (NUM (x, 7)); \
|
||||
+ FUNC100 (NUM (x, 8)); \
|
||||
+ FUNC100 (NUM (x, 9))
|
||||
+
|
||||
+#define FUNC7000() \
|
||||
+ FUNC1000 (1); \
|
||||
+ FUNC1000 (2); \
|
||||
+ FUNC1000 (3); \
|
||||
+ FUNC1000 (4); \
|
||||
+ FUNC1000 (5); \
|
||||
+ FUNC1000 (6); \
|
||||
+ FUNC1000 (7);
|
||||
+
|
||||
+#ifdef FUNC
|
||||
+# undef FUNC
|
||||
+#endif
|
||||
+
|
||||
+#ifdef externnum
|
||||
+# define FUNC(x) extern int CONCAT (retNum, x) (void)
|
||||
+#endif
|
||||
+
|
||||
+#ifdef definenum
|
||||
+# define FUNC(x) int CONCAT (retNum, x) (void) { return x; }
|
||||
+#endif
|
||||
+
|
||||
+#ifdef callnum
|
||||
+# define FUNC(x) CONCAT (retNum, x) (); sync_all (x)
|
||||
+#endif
|
||||
+
|
||||
+/* A value of 7000 functions is chosen as an arbitrarily large
|
||||
+ number of functions that will allow us enough attempts to
|
||||
+ verify lazy resolution operation. */
|
||||
+FUNC7000 ();
|
|
@ -0,0 +1,48 @@
|
|||
nptl/tst-audit-threads: Switch to <support/test-driver.c>
|
||||
|
||||
The downstream version of test-skeleton.c does not include
|
||||
<support/support.h> for backwards compatibility reasons, leading to a
|
||||
compilation failure:
|
||||
|
||||
tst-audit-threads.c: In function 'do_test':
|
||||
tst-audit-threads.c:87:3: error: implicit declaration of function 'xcalloc' [-Werror=implicit-function-declaration]
|
||||
threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
|
||||
^
|
||||
tst-audit-threads.c:87:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
|
||||
threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
|
||||
^
|
||||
|
||||
diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
|
||||
index e4bf433bd85f3715..42742d51e4bc06a3 100644
|
||||
--- a/nptl/tst-audit-threads.c
|
||||
+++ b/nptl/tst-audit-threads.c
|
||||
@@ -25,19 +25,12 @@
|
||||
the relocation resolution caching code in the dynamic loader i.e.
|
||||
_dl_runtime_profile and _dl_profile_fixup. */
|
||||
|
||||
+#include <support/support.h>
|
||||
#include <support/xthread.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
-static int do_test (void);
|
||||
-
|
||||
-/* This test usually takes less than 3s to run. However, there are cases that
|
||||
- take up to 30s. */
|
||||
-#define TIMEOUT 60
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
-
|
||||
/* Declare the functions we are going to call. */
|
||||
#define externnum
|
||||
#include "tst-audit-threads.h"
|
||||
@@ -95,3 +88,8 @@ do_test (void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/* This test usually takes less than 3s to run. However, there are cases that
|
||||
+ take up to 30s. */
|
||||
+#define TIMEOUT 60
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,19 @@
|
|||
commit 8ec3f656d6edf6f16216105131fc8b0542216a5b
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Mon Nov 11 12:24:42 2013 +0100
|
||||
|
||||
Fix off-by-one in nscd getservbyport call
|
||||
|
||||
diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c
|
||||
index c9c890c..7728258 100644
|
||||
--- a/nscd/nscd_getserv_r.c
|
||||
+++ b/nscd/nscd_getserv_r.c
|
||||
@@ -54,7 +54,7 @@ __nscd_getservbyport_r (int port, const char *proto,
|
||||
portstr[sizeof (portstr) - 1] = '\0';
|
||||
char *cp = _itoa_word (port, portstr + sizeof (portstr) - 1, 10, 0);
|
||||
|
||||
- return nscd_getserv_r (cp, portstr + sizeof (portstr) - cp, proto,
|
||||
+ return nscd_getserv_r (cp, portstr + sizeof (portstr) - 1 - cp, proto,
|
||||
GETSERVBYPORT, result_buf, buf, buflen, result);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,196 @@
|
|||
commit a3fe6a20bf81ef6a97a761dac9050517e7fd7a1f
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Thu Aug 17 17:58:25 2017 -0400
|
||||
|
||||
Update nss tests to new skeleton
|
||||
|
||||
* bug17079.c: Update to new test harness.
|
||||
* test-digits-dots.c: Likewise.
|
||||
* test-netdb.c: Likewise.
|
||||
* tst-field.c: Likewise.
|
||||
* tst-nss-getpwent.c: Likewise.
|
||||
* tst-nss-static.c: Likewise.
|
||||
* tst-nss-test1.c: Likewise.
|
||||
* tst-nss-test2.c: Likewise.
|
||||
* tst-nss-test3.c: Likewise.
|
||||
* tst-nss-test4.c: Likewise.
|
||||
* tst-nss-test5.c: Likewise.
|
||||
|
||||
Partial port of this patch - tst-field.c changes not ported.
|
||||
|
||||
diff --git a/nss/bug17079.c b/nss/bug17079.c
|
||||
index 4171c7db55..09d33f018c 100644
|
||||
--- a/nss/bug17079.c
|
||||
+++ b/nss/bug17079.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include <support/support.h>
|
||||
+
|
||||
/* Check if two passwd structs contain the same data. */
|
||||
static bool
|
||||
equal (const struct passwd *a, const struct passwd *b)
|
||||
@@ -52,13 +54,13 @@ init_test_items (void)
|
||||
if (pwd == NULL)
|
||||
break;
|
||||
struct passwd *target = test_items + test_count;
|
||||
- target->pw_name = strdup (pwd->pw_name);
|
||||
- target->pw_passwd = strdup (pwd->pw_passwd);
|
||||
+ target->pw_name = xstrdup (pwd->pw_name);
|
||||
+ target->pw_passwd = xstrdup (pwd->pw_passwd);
|
||||
target->pw_uid = pwd->pw_uid;
|
||||
target->pw_gid = pwd->pw_gid;
|
||||
- target->pw_gecos = strdup (pwd->pw_gecos);
|
||||
- target->pw_dir = strdup (pwd->pw_dir);
|
||||
- target->pw_shell = strdup (pwd->pw_shell);
|
||||
+ target->pw_gecos = xstrdup (pwd->pw_gecos);
|
||||
+ target->pw_dir = xstrdup (pwd->pw_dir);
|
||||
+ target->pw_shell = xstrdup (pwd->pw_shell);
|
||||
}
|
||||
while (++test_count < MAX_TEST_ITEMS);
|
||||
endpwent ();
|
||||
@@ -108,13 +110,7 @@ static void
|
||||
test_one (const struct passwd *item, size_t buffer_size,
|
||||
char pad, size_t padding_size)
|
||||
{
|
||||
- char *buffer = malloc (buffer_size + padding_size);
|
||||
- if (buffer == NULL)
|
||||
- {
|
||||
- puts ("error: malloc failure");
|
||||
- errors = true;
|
||||
- return;
|
||||
- }
|
||||
+ char *buffer = xmalloc (buffer_size + padding_size);
|
||||
|
||||
struct passwd pwd;
|
||||
struct passwd *result;
|
||||
@@ -240,5 +236,4 @@ do_test (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/test-digits-dots.c b/nss/test-digits-dots.c
|
||||
index 2685161e65..5b898a932d 100644
|
||||
--- a/nss/test-digits-dots.c
|
||||
+++ b/nss/test-digits-dots.c
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
+#include <support/support.h>
|
||||
+
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
@@ -34,5 +36,4 @@ do_test (void)
|
||||
return err == ERANGE && h_err == NETDB_INTERNAL ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/tst-nss-static.c b/nss/tst-nss-static.c
|
||||
index 98cf073deb..6c3dc07622 100644
|
||||
--- a/nss/tst-nss-static.c
|
||||
+++ b/nss/tst-nss-static.c
|
||||
@@ -1,7 +1,8 @@
|
||||
/* glibc test for static NSS. */
|
||||
#include <stdio.h>
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
+#include <support/support.h>
|
||||
+
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
@@ -12,4 +13,4 @@ do_test (void)
|
||||
}
|
||||
|
||||
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/tst-nss-test2.c b/nss/tst-nss-test2.c
|
||||
index 11c2edf118..ac45d58c4b 100644
|
||||
--- a/nss/tst-nss-test2.c
|
||||
+++ b/nss/tst-nss-test2.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include <support/support.h>
|
||||
+
|
||||
#include "nss_test.h"
|
||||
|
||||
/* The data in these tables is arbitrary, but the merged data based on
|
||||
@@ -132,5 +134,4 @@ do_test (void)
|
||||
return retval;
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/tst-nss-test3.c b/nss/tst-nss-test3.c
|
||||
index 308708f387..5098aae67b 100644
|
||||
--- a/nss/tst-nss-test3.c
|
||||
+++ b/nss/tst-nss-test3.c
|
||||
@@ -20,7 +20,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
-#include <sys/signal.h>
|
||||
+
|
||||
+#include <support/support.h>
|
||||
|
||||
#include "nss_test.h"
|
||||
|
||||
@@ -146,5 +147,4 @@ do_test (void)
|
||||
}
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/tst-nss-test4.c b/nss/tst-nss-test4.c
|
||||
index 731e0ed10a..6e0ac84acc 100644
|
||||
--- a/nss/tst-nss-test4.c
|
||||
+++ b/nss/tst-nss-test4.c
|
||||
@@ -20,7 +20,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
-#include <sys/signal.h>
|
||||
+
|
||||
+#include <support/support.h>
|
||||
|
||||
#include "nss_test.h"
|
||||
|
||||
@@ -133,5 +134,4 @@ do_test (void)
|
||||
}
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/tst-nss-test5.c b/nss/tst-nss-test5.c
|
||||
index fef41f08df..8f02cb7779 100644
|
||||
--- a/nss/tst-nss-test5.c
|
||||
+++ b/nss/tst-nss-test5.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include <support/support.h>
|
||||
+
|
||||
#include "nss_test.h"
|
||||
|
||||
/* The specific values and names used here are arbitrary, other than
|
||||
@@ -104,5 +106,4 @@ do_test (void)
|
||||
}
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,294 @@
|
|||
This file contains the reworked/backported sections from these two
|
||||
upstream commits:
|
||||
|
||||
commit ae5c498d93d049d9574d3f8f18e62cac64cbdf5c
|
||||
Author: DJ Delorie <dj@delorie.com>
|
||||
Date: Mon Jul 17 15:50:43 2017 -0400
|
||||
|
||||
Extend NSS test suite
|
||||
|
||||
commit a3fe6a20bf81ef6a97a761dac9050517e7fd7a1f
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Thu Aug 17 17:58:25 2017 -0400
|
||||
|
||||
Update nss tests to new skeleton
|
||||
|
||||
diff -Nrup a/nss/Makefile b/nss/Makefile
|
||||
--- a/nss/Makefile 2019-07-29 22:25:16.482170120 -0400
|
||||
+++ b/nss/Makefile 2019-07-29 22:37:05.675342258 -0400
|
||||
@@ -38,8 +38,14 @@ install-bin := getent makedb
|
||||
makedb-modules = xmalloc hash-string
|
||||
extra-objs += $(makedb-modules:=.o)
|
||||
|
||||
-tests = test-netdb tst-nss-test1 bug17079 tst-nss-getpwent \
|
||||
- test-digits-dots tst-nss-files-hosts-erange
|
||||
+tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \
|
||||
+ tst-nss-files-hosts-erange \
|
||||
+ tst-nss-test1 \
|
||||
+ tst-nss-test2 \
|
||||
+ tst-nss-test3 \
|
||||
+ tst-nss-test4 \
|
||||
+ tst-nss-test5
|
||||
+
|
||||
xtests = bug-erange
|
||||
|
||||
include ../Makeconfig
|
||||
@@ -80,6 +86,8 @@ tests-static = tst-nss-static
|
||||
tests += $(tests-static)
|
||||
endif
|
||||
|
||||
+extra-test-objs += nss_test1.os nss_test2.os
|
||||
+
|
||||
include ../Rules
|
||||
|
||||
ifeq (yes,$(have-selinux))
|
||||
@@ -107,13 +115,28 @@ $(objpfx)makedb: $(makedb-modules:%=$(ob
|
||||
$(inst_vardbdir)/Makefile: db-Makefile $(+force)
|
||||
$(do-install)
|
||||
|
||||
+libnss_test1.so-no-z-defs = 1
|
||||
+libnss_test2.so-no-z-defs = 1
|
||||
+
|
||||
+rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
|
||||
+
|
||||
libof-nss_test1 = extramodules
|
||||
+libof-nss_test2 = extramodules
|
||||
$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps)
|
||||
$(build-module)
|
||||
+$(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps)
|
||||
+ $(build-module)
|
||||
+$(objpfx)nss_test2.os : nss_test1.c
|
||||
ifdef libnss_test1.so-version
|
||||
$(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so
|
||||
$(make-link)
|
||||
endif
|
||||
-$(objpfx)tst-nss-test1.out: $(objpfx)/libnss_test1.so$(libnss_test1.so-version)
|
||||
+ifdef libnss_test2.so-version
|
||||
+$(objpfx)/libnss_test2.so$(libnss_test2.so-version): $(objpfx)/libnss_test2.so
|
||||
+ $(make-link)
|
||||
+endif
|
||||
+$(patsubst %,$(objpfx)%.out,$(tests)) : \
|
||||
+ $(objpfx)/libnss_test1.so$(libnss_test1.so-version) \
|
||||
+ $(objpfx)/libnss_test2.so$(libnss_test2.so-version)
|
||||
|
||||
$(objpfx)tst-nss-files-hosts-erange: $(libdl)
|
||||
diff -Nrup a/nss/tst-nss-getpwent.c b/nss/tst-nss-getpwent.c
|
||||
--- a/nss/tst-nss-getpwent.c 2019-07-29 16:44:37.670904243 -0400
|
||||
+++ b/nss/tst-nss-getpwent.c 2019-07-29 16:49:58.538313946 -0400
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include <support/support.h>
|
||||
+
|
||||
int
|
||||
do_test (void)
|
||||
{
|
||||
@@ -37,22 +39,12 @@ do_test (void)
|
||||
{
|
||||
if (first_name == NULL)
|
||||
{
|
||||
- first_name = strdup (pw->pw_name);
|
||||
- if (first_name == NULL)
|
||||
- {
|
||||
- printf ("strdup: %m\n");
|
||||
- return 1;
|
||||
- }
|
||||
+ first_name = xstrdup (pw->pw_name);
|
||||
first_uid = pw->pw_uid;
|
||||
}
|
||||
|
||||
free (last_name);
|
||||
- last_name = strdup (pw->pw_name);
|
||||
- if (last_name == NULL)
|
||||
- {
|
||||
- printf ("strdup: %m\n");
|
||||
- return 1;
|
||||
- }
|
||||
+ last_name = xstrdup (pw->pw_name);
|
||||
last_uid = pw->pw_uid;
|
||||
++count;
|
||||
}
|
||||
@@ -112,5 +104,4 @@ do_test (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff -Nrup a/shlib-versions b/shlib-versions
|
||||
--- a/shlib-versions 2019-07-29 16:50:46.222077613 -0400
|
||||
+++ b/shlib-versions 2019-07-29 16:53:04.745391058 -0400
|
||||
@@ -87,6 +87,7 @@ sh.*-.*-linux.* ld=ld-linux.so.2 GLIBC_
|
||||
# Tests for NSS. They must have the same NSS_SHLIB_REVISION number as
|
||||
# the rest.
|
||||
.*-.*-.* libnss_test1=2
|
||||
+.*-.*-.* libnss_test2=2
|
||||
|
||||
# Version for libnsl with YP and NIS+ functions.
|
||||
.*-.*-.* libnsl=1
|
||||
diff -Nrup a/nss/tst-nss-test1.c b/nss/tst-nss-test1.c
|
||||
--- a/nss/tst-nss-test1.c 2019-07-29 16:54:05.824241220 -0400
|
||||
+++ b/nss/tst-nss-test1.c 2019-07-29 17:13:55.696765720 -0400
|
||||
@@ -1,9 +1,51 @@
|
||||
+/* Basic test of passwd database handling.
|
||||
+ Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
#include <nss.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+#include "nss_test.h"
|
||||
+
|
||||
+static int hook_called = 0;
|
||||
+
|
||||
+/* Note: the values chosen here are arbitrary; they need only be
|
||||
+ unique within the table. However, they do need to match the
|
||||
+ "pwdids" array further down. */
|
||||
+static struct passwd pwd_table[] = {
|
||||
+ PWD (100),
|
||||
+ PWD (30),
|
||||
+ PWD (200),
|
||||
+ PWD (60),
|
||||
+ PWD (20000),
|
||||
+ PWD_LAST ()
|
||||
+ };
|
||||
+
|
||||
+void
|
||||
+_nss_test1_init_hook(test_tables *t)
|
||||
+{
|
||||
+ hook_called = 1;
|
||||
+ t->pwd_table = pwd_table;
|
||||
+}
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
@@ -12,20 +54,26 @@ do_test (void)
|
||||
|
||||
__nss_configure_lookup ("passwd", "test1");
|
||||
|
||||
+ /* This must match the pwd_table above. */
|
||||
static const unsigned int pwdids[] = { 100, 30, 200, 60, 20000 };
|
||||
#define npwdids (sizeof (pwdids) / sizeof (pwdids[0]))
|
||||
+
|
||||
setpwent ();
|
||||
|
||||
const unsigned int *np = pwdids;
|
||||
for (struct passwd *p = getpwent (); p != NULL; ++np, p = getpwent ())
|
||||
- if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0
|
||||
- || atol (p->pw_name + 4) != *np)
|
||||
- {
|
||||
- printf ("passwd entry %td wrong (%s, %u)\n",
|
||||
- np - pwdids, p->pw_name, p->pw_uid);
|
||||
- retval = 1;
|
||||
- break;
|
||||
- }
|
||||
+ {
|
||||
+ retval += compare_passwds (np-pwdids, p, & pwd_table[np-pwdids]);
|
||||
+
|
||||
+ if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0
|
||||
+ || atol (p->pw_name + 4) != *np)
|
||||
+ {
|
||||
+ printf ("FAIL: passwd entry %td wrong (%s, %u)\n",
|
||||
+ np - pwdids, p->pw_name, p->pw_uid);
|
||||
+ retval = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
endpwent ();
|
||||
|
||||
@@ -37,14 +85,14 @@ do_test (void)
|
||||
struct passwd *p = getpwnam (buf);
|
||||
if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0)
|
||||
{
|
||||
- printf ("passwd entry \"%s\" wrong\n", buf);
|
||||
+ printf ("FAIL: passwd entry \"%s\" wrong\n", buf);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
p = getpwuid (pwdids[i]);
|
||||
if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0)
|
||||
{
|
||||
- printf ("passwd entry %u wrong\n", pwdids[i]);
|
||||
+ printf ("FAIL: passwd entry %u wrong\n", pwdids[i]);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
@@ -53,20 +101,25 @@ do_test (void)
|
||||
p = getpwnam (buf);
|
||||
if (p != NULL)
|
||||
{
|
||||
- printf ("passwd entry \"%s\" wrong\n", buf);
|
||||
+ printf ("FAIL: passwd entry \"%s\" wrong\n", buf);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
p = getpwuid (pwdids[i] + 1);
|
||||
if (p != NULL)
|
||||
{
|
||||
- printf ("passwd entry %u wrong\n", pwdids[i] + 1);
|
||||
+ printf ("FAIL: passwd entry %u wrong\n", pwdids[i] + 1);
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
+ if (!hook_called)
|
||||
+ {
|
||||
+ retval = 1;
|
||||
+ printf("FAIL: init hook never called\n");
|
||||
+ }
|
||||
+
|
||||
return retval;
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff -Nrup a/nss/test-netdb.c b/nss/test-netdb.c
|
||||
--- a/nss/test-netdb.c 2019-07-30 15:31:30.468602060 -0400
|
||||
+++ b/nss/test-netdb.c 2019-07-30 15:37:29.116601115 -0400
|
||||
@@ -42,6 +42,8 @@
|
||||
#include <errno.h>
|
||||
#include "nss.h"
|
||||
|
||||
+#include <support/support.h>
|
||||
+
|
||||
/*
|
||||
The following define is necessary for glibc 2.0.6
|
||||
*/
|
||||
@@ -179,7 +181,7 @@ test_hosts (void)
|
||||
while (gethostname (name, namelen) < 0 && errno == ENAMETOOLONG)
|
||||
{
|
||||
namelen += 2; /* tiny increments to test a lot */
|
||||
- name = realloc (name, namelen);
|
||||
+ name = xrealloc (name, namelen);
|
||||
}
|
||||
if (gethostname (name, namelen) == 0)
|
||||
{
|
||||
@@ -377,5 +379,4 @@ do_test (void)
|
||||
return (error_count != 0);
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,21 @@
|
|||
NOTE: This is a downstream patch that should not go upstream.
|
||||
|
||||
diff -Nrup a/nss/Makefile b/nss/Makefile
|
||||
--- a/nss/Makefile 2019-07-30 13:28:36.493476963 -0400
|
||||
+++ b/nss/Makefile 2019-07-30 13:33:14.536086456 -0400
|
||||
@@ -118,7 +118,14 @@ $(inst_vardbdir)/Makefile: db-Makefile $
|
||||
libnss_test1.so-no-z-defs = 1
|
||||
libnss_test2.so-no-z-defs = 1
|
||||
|
||||
-rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
|
||||
+# RHEL 7 glibc tree does not support rtld-tests-LDFLAGS.
|
||||
+# Instead we directly alter the way the tests are built.
|
||||
+# rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver
|
||||
+LDFLAGS-tst-nss-test1 += -Wl,-E
|
||||
+LDFLAGS-tst-nss-test2 += -Wl,-E
|
||||
+LDFLAGS-tst-nss-test3 += -Wl,-E
|
||||
+LDFLAGS-tst-nss-test4 += -Wl,-E
|
||||
+LDFLAGS-tst-nss-test5 += -Wl,-E
|
||||
|
||||
libof-nss_test1 = extramodules
|
||||
libof-nss_test2 = extramodules
|
|
@ -0,0 +1,74 @@
|
|||
Note: the context of this patch differs from upstream slightly,
|
||||
to accomodate the lack of ILP32 in RHEL.
|
||||
|
||||
commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67
|
||||
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
Date: Wed Sep 27 16:55:14 2017 +0100
|
||||
|
||||
aarch64: Disable lazy symbol binding of TLSDESC
|
||||
|
||||
Always do TLS descriptor initialization at load time during relocation
|
||||
processing to avoid barriers at every TLS access. In non-dlopened shared
|
||||
libraries the overhead of tls access vs static global access is > 3x
|
||||
bigger when lazy initialization is used (_dl_tlsdesc_return_lazy)
|
||||
compared to bind-now (_dl_tlsdesc_return) so the barriers dominate tls
|
||||
access performance.
|
||||
|
||||
TLSDESC relocs are in DT_JMPREL which are processed at load time using
|
||||
elf_machine_lazy_rel which is only supposed to do lightweight
|
||||
initialization using the DT_TLSDESC_PLT trampoline (the trampoline code
|
||||
jumps to the entry point in DT_TLSDESC_GOT which does the lazy tlsdesc
|
||||
initialization at runtime). This patch changes elf_machine_lazy_rel
|
||||
in aarch64 to do the symbol binding and initialization as if DF_BIND_NOW
|
||||
was set, so the non-lazy code path of elf/do-rel.h was replicated.
|
||||
|
||||
The static linker could be changed to emit TLSDESC relocs in DT_REL*,
|
||||
which are processed non-lazily, but the goal of this patch is to always
|
||||
guarantee bind-now semantics, even if the binary was produced with an
|
||||
old linker, so the barriers can be dropped in tls descriptor functions.
|
||||
|
||||
After this change the synchronizing ldar instructions can be dropped
|
||||
as well as the lazy initialization machinery including the DT_TLSDESC_GOT
|
||||
setup.
|
||||
|
||||
I believe this should be done on all targets, including ones where no
|
||||
barrier is needed for lazy initialization. There is very little gain in
|
||||
optimizing for large number of symbolic tlsdesc relocations which is an
|
||||
extremely uncommon case. And currently the tlsdesc entries are only
|
||||
readonly protected with -z now and some hardennings against writable
|
||||
JUMPSLOT relocs don't work for TLSDESC so they are a security hazard.
|
||||
(But to fix that the static linker has to be changed.)
|
||||
|
||||
* sysdeps/aarch64/dl-machine.h (elf_machine_lazy_rel): Do symbol
|
||||
binding and initialization non-lazily for R_AARCH64_TLSDESC.
|
||||
|
||||
diff -rup a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
|
||||
--- a/sysdeps/aarch64/dl-machine.h 2018-10-16 12:07:31.588149003 -0400
|
||||
+++ b/sysdeps/aarch64/dl-machine.h 2018-10-16 12:18:46.214078837 -0400
|
||||
@@ -376,12 +376,21 @@ elf_machine_lazy_rel (struct link_map *m
|
||||
}
|
||||
else if (__builtin_expect (r_type == R_AARCH64_TLSDESC, 1))
|
||||
{
|
||||
- struct tlsdesc volatile *td =
|
||||
- (struct tlsdesc volatile *)reloc_addr;
|
||||
+ const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
|
||||
+ const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]);
|
||||
+ const ElfW (Sym) *sym = &symtab[symndx];
|
||||
+ const struct r_found_version *version = NULL;
|
||||
|
||||
- td->arg = (void*)reloc;
|
||||
- td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
|
||||
- + map->l_addr);
|
||||
+ if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
+ {
|
||||
+ const ElfW (Half) *vernum =
|
||||
+ (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
|
||||
+ version = &map->l_versions[vernum[symndx] & 0x7fff];
|
||||
+ }
|
||||
+
|
||||
+ /* Always initialize TLS descriptors completely, because lazy
|
||||
+ initialization requires synchronization at every TLS access. */
|
||||
+ elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
|
||||
}
|
||||
else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE))
|
||||
{
|
|
@ -0,0 +1,41 @@
|
|||
commit c3d8dc45c9df199b8334599a6cbd98c9950dba62
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Oct 11 15:18:40 2018 -0300
|
||||
|
||||
x86: Fix Haswell strong flags (BZ#23709)
|
||||
|
||||
Th commit 'Disable TSX on some Haswell processors.' (2702856bf4) changed the
|
||||
default flags for Haswell models. Previously, new models were handled by the
|
||||
default switch path, which assumed a Core i3/i5/i7 if AVX is available. After
|
||||
the patch, Haswell models (0x3f, 0x3c, 0x45, 0x46) do not set the flags
|
||||
Fast_Rep_String, Fast_Unaligned_Load, Fast_Unaligned_Copy, and
|
||||
Prefer_PMINUB_for_stringop (only the TSX one).
|
||||
|
||||
This patch fixes it by disentangle the TSX flag handling from the memory
|
||||
optimization ones. The strstr case cited on patch now selects the
|
||||
__strstr_sse2_unaligned as expected for the Haswell cpu.
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
|
||||
[BZ #23709]
|
||||
* sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
|
||||
independently of other flags.
|
||||
|
||||
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||
index 0667e486959a8a91..d134ef3a92cbc83d 100644
|
||||
--- a/sysdeps/x86/cpu-features.c
|
||||
+++ b/sysdeps/x86/cpu-features.c
|
||||
@@ -133,7 +133,13 @@ init_cpu_features (struct cpu_features *cpu_features)
|
||||
| bit_Fast_Unaligned_Load
|
||||
| bit_Prefer_PMINUB_for_stringop);
|
||||
break;
|
||||
+ }
|
||||
|
||||
+ /* Disable TSX on some Haswell processors to avoid TSX on kernels that
|
||||
+ weren't updated with the latest microcode package (which disables
|
||||
+ broken feature by default). */
|
||||
+ switch (model)
|
||||
+ {
|
||||
case 0x3f:
|
||||
/* Xeon E7 v3 with stepping >= 4 has working TSX. */
|
||||
if (stepping >= 4)
|
|
@ -0,0 +1,32 @@
|
|||
commit bd3b0fbae33a9a4cc5e2daf049443d5cf03d4251
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Mon Nov 5 12:47:30 2018 +0100
|
||||
|
||||
libanl: properly cleanup if first helper thread creation failed (bug 22927)
|
||||
|
||||
2018-11-05 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
[BZ #22927]
|
||||
* resolv/gai_misc.c (__gai_enqueue_request): Don't crash if
|
||||
creating the first helper thread failed.
|
||||
|
||||
[Note from DJ - hard to test; must force second calloc() call in
|
||||
getaddrinfo_a() to return NULL/ENOMEM]
|
||||
|
||||
diff -rup a/resolv/gai_misc.c b/resolv/gai_misc.c
|
||||
--- a/resolv/gai_misc.c 2012-12-24 22:02:13.000000000 -0500
|
||||
+++ b/resolv/gai_misc.c 2019-01-22 16:19:30.514199534 -0500
|
||||
@@ -264,8 +264,11 @@ __gai_enqueue_request (struct gaicb *gai
|
||||
/* We cannot create a thread in the moment and there is
|
||||
also no thread running. This is a problem. `errno' is
|
||||
set to EAGAIN if this is only a temporary problem. */
|
||||
- assert (lastp->next == newp);
|
||||
- lastp->next = NULL;
|
||||
+ assert (requests == newp || lastp->next == newp);
|
||||
+ if (lastp != NULL)
|
||||
+ lastp->next = NULL;
|
||||
+ else
|
||||
+ requests = NULL;
|
||||
requests_tail = lastp;
|
||||
|
||||
newp->next = freelist;
|
|
@ -0,0 +1,80 @@
|
|||
commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523
|
||||
Author: Paul Pluzhnikov <ppluzhnikov@kazbek.mtv.corp.google.com>
|
||||
Date: Fri Aug 24 18:08:51 2018 -0700
|
||||
|
||||
Fix BZ#23400 (creating temporary files in source tree), and undefined behavior in test.
|
||||
|
||||
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||
index e7837f98c19fc4bf..d1aa69106ccf6ac5 100644
|
||||
--- a/stdlib/test-bz22786.c
|
||||
+++ b/stdlib/test-bz22786.c
|
||||
@@ -26,28 +26,20 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
#include <support/test-driver.h>
|
||||
#include <libc-diag.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- const char dir[] = "bz22786";
|
||||
- const char lnk[] = "bz22786/symlink";
|
||||
+ const char *dir = support_create_temp_directory ("bz22786.");
|
||||
+ const char *lnk = xasprintf ("%s/symlink", dir);
|
||||
+ const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||
|
||||
- rmdir (dir);
|
||||
- if (mkdir (dir, 0755) != 0 && errno != EEXIST)
|
||||
- {
|
||||
- printf ("mkdir %s: %m\n", dir);
|
||||
- return EXIT_FAILURE;
|
||||
- }
|
||||
- if (symlink (".", lnk) != 0 && errno != EEXIST)
|
||||
- {
|
||||
- printf ("symlink (%s, %s): %m\n", dir, lnk);
|
||||
- return EXIT_FAILURE;
|
||||
- }
|
||||
-
|
||||
- const size_t path_len = (size_t) INT_MAX + 1;
|
||||
+ TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
|
||||
|
||||
DIAG_PUSH_NEEDS_COMMENT;
|
||||
#if __GNUC_PREREQ (7, 0)
|
||||
@@ -55,20 +47,14 @@ do_test (void)
|
||||
allocation to succeed for the test to work. */
|
||||
DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
|
||||
#endif
|
||||
- char *path = malloc (path_len);
|
||||
+ char *path = xmalloc (path_len);
|
||||
DIAG_POP_NEEDS_COMMENT;
|
||||
|
||||
- if (path == NULL)
|
||||
- {
|
||||
- printf ("malloc (%zu): %m\n", path_len);
|
||||
- return EXIT_UNSUPPORTED;
|
||||
- }
|
||||
-
|
||||
- /* Construct very long path = "bz22786/symlink/aaaa....." */
|
||||
- char *p = mempcpy (path, lnk, sizeof (lnk) - 1);
|
||||
+ /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
|
||||
+ char *p = mempcpy (path, lnk, strlen (lnk));
|
||||
*(p++) = '/';
|
||||
- memset (p, 'a', path_len - (path - p) - 2);
|
||||
- p[path_len - (path - p) - 1] = '\0';
|
||||
+ memset (p, 'a', path_len - (p - path) - 2);
|
||||
+ p[path_len - (p - path) - 1] = '\0';
|
||||
|
||||
/* This call crashes before the fix for bz22786 on 32-bit platforms. */
|
||||
p = realpath (path, NULL);
|
||||
@@ -81,7 +67,6 @@ do_test (void)
|
||||
|
||||
/* Cleanup. */
|
||||
unlink (lnk);
|
||||
- rmdir (dir);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
commit 3bad2358d67d371497079bba4f8eca9c0096f4e2
|
||||
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||
Date: Thu Aug 30 08:44:32 2018 +0200
|
||||
|
||||
Test stdlib/test-bz22786 exits now with unsupported if malloc fails.
|
||||
|
||||
The test tries to allocate more than 2^31 bytes which will always fail on s390
|
||||
as it has maximum 2^31bit of memory.
|
||||
Before commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523, this test returned
|
||||
unsupported if malloc fails. This patch re enables this behaviour.
|
||||
|
||||
Furthermore support_delete_temp_files() failed to remove the temp directory
|
||||
in this case as it is not empty due to the created symlink.
|
||||
Thus the creation of the symlink is moved behind malloc.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
ChangeLog:
|
||||
|
||||
* stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
|
||||
if malloc fails.
|
||||
|
||||
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||
index d1aa69106ccf6ac5..777bf9180f4b5022 100644
|
||||
--- a/stdlib/test-bz22786.c
|
||||
+++ b/stdlib/test-bz22786.c
|
||||
@@ -39,16 +39,25 @@ do_test (void)
|
||||
const char *lnk = xasprintf ("%s/symlink", dir);
|
||||
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||
|
||||
- TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
|
||||
-
|
||||
DIAG_PUSH_NEEDS_COMMENT;
|
||||
#if __GNUC_PREREQ (7, 0)
|
||||
/* GCC 7 warns about too-large allocations; here we need such
|
||||
allocation to succeed for the test to work. */
|
||||
DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
|
||||
#endif
|
||||
- char *path = xmalloc (path_len);
|
||||
+ char *path = malloc (path_len);
|
||||
DIAG_POP_NEEDS_COMMENT;
|
||||
+ if (path == NULL)
|
||||
+ {
|
||||
+ printf ("malloc (%zu): %m\n", path_len);
|
||||
+ /* On 31-bit s390 the malloc will always fail as we do not have
|
||||
+ so much memory, and we want to mark the test unsupported.
|
||||
+ Likewise on systems with little physical memory the test will
|
||||
+ fail and should be unsupported. */
|
||||
+ return EXIT_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
|
||||
|
||||
/* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
|
||||
char *p = mempcpy (path, lnk, strlen (lnk));
|
|
@ -0,0 +1,64 @@
|
|||
commit f5e7e95921847bd83186bfe621fc2b48c4de5477
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Oct 30 13:11:47 2018 +0100
|
||||
|
||||
stdlib/test-bz22786: Avoid spurious test failures using alias mappings
|
||||
|
||||
On systems without enough random-access memory, stdlib/test-bz22786
|
||||
will go deeply into swap and time out, even with a substantial
|
||||
TIMEOUTFACTOR. This commit adds a facility to construct repeating
|
||||
strings with alias mappings, so that the requirement for physical
|
||||
memory, and uses it in stdlib/test-bz22786.
|
||||
|
||||
Adjusted here for the support/ backport in glibc-rh1418978-1.patch.
|
||||
|
||||
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||
index 777bf9180f4b5022..bb1e04f2debe9042 100644
|
||||
--- a/stdlib/test-bz22786.c
|
||||
+++ b/stdlib/test-bz22786.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
+#include <support/blob_repeat.h>
|
||||
#include <support/check.h>
|
||||
#include <support/support.h>
|
||||
#include <support/temp_file.h>
|
||||
@@ -39,17 +40,12 @@ do_test (void)
|
||||
const char *lnk = xasprintf ("%s/symlink", dir);
|
||||
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||
|
||||
- DIAG_PUSH_NEEDS_COMMENT;
|
||||
-#if __GNUC_PREREQ (7, 0)
|
||||
- /* GCC 7 warns about too-large allocations; here we need such
|
||||
- allocation to succeed for the test to work. */
|
||||
- DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
|
||||
-#endif
|
||||
- char *path = malloc (path_len);
|
||||
- DIAG_POP_NEEDS_COMMENT;
|
||||
+ struct support_blob_repeat repeat
|
||||
+ = support_blob_repeat_allocate ("a", 1, path_len);
|
||||
+ char *path = repeat.start;
|
||||
if (path == NULL)
|
||||
{
|
||||
- printf ("malloc (%zu): %m\n", path_len);
|
||||
+ printf ("Repeated allocation (%zu bytes): %m\n", path_len);
|
||||
/* On 31-bit s390 the malloc will always fail as we do not have
|
||||
so much memory, and we want to mark the test unsupported.
|
||||
Likewise on systems with little physical memory the test will
|
||||
@@ -62,7 +58,6 @@ do_test (void)
|
||||
/* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
|
||||
char *p = mempcpy (path, lnk, strlen (lnk));
|
||||
*(p++) = '/';
|
||||
- memset (p, 'a', path_len - (p - path) - 2);
|
||||
p[path_len - (p - path) - 1] = '\0';
|
||||
|
||||
/* This call crashes before the fix for bz22786 on 32-bit platforms. */
|
||||
@@ -76,6 +71,7 @@ do_test (void)
|
||||
|
||||
/* Cleanup. */
|
||||
unlink (lnk);
|
||||
+ support_blob_repeat_free (&repeat);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
commit 07da99aad93c9364acb7efdab47c27ba698f6313
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Oct 30 13:55:01 2018 +0100
|
||||
|
||||
stdlib/tst-strtod-overflow: Switch to support_blob_repeat
|
||||
|
||||
This is another test with an avoidable large memory allocation.
|
||||
|
||||
diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
|
||||
index 6c5b2828551dd580..fd1be79f3f58c64b 100644
|
||||
--- a/stdlib/tst-strtod-overflow.c
|
||||
+++ b/stdlib/tst-strtod-overflow.c
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <support/blob_repeat.h>
|
||||
+#include <support/test-driver.h>
|
||||
|
||||
#define EXPONENT "e-2147483649"
|
||||
#define SIZE 214748364
|
||||
@@ -26,21 +28,23 @@
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- char *p = malloc (1 + SIZE + sizeof (EXPONENT));
|
||||
- if (p == NULL)
|
||||
+ struct support_blob_repeat repeat = support_blob_repeat_allocate
|
||||
+ ("0", 1, 1 + SIZE + sizeof (EXPONENT));
|
||||
+ if (repeat.size == 0)
|
||||
{
|
||||
- puts ("malloc failed, cannot test for overflow");
|
||||
- return 0;
|
||||
+ puts ("warning: memory allocation failed, cannot test for overflow");
|
||||
+ return EXIT_UNSUPPORTED;
|
||||
}
|
||||
+ char *p = repeat.start;
|
||||
p[0] = '1';
|
||||
- memset (p + 1, '0', SIZE);
|
||||
memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT));
|
||||
double d = strtod (p, NULL);
|
||||
if (d != 0)
|
||||
{
|
||||
- printf ("strtod returned wrong value: %a\n", d);
|
||||
+ printf ("error: strtod returned wrong value: %a\n", d);
|
||||
return 1;
|
||||
}
|
||||
+ support_blob_repeat_free (&repeat);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
commit 60708030536df82616c16aa2f14f533c4362b969
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Oct 30 13:56:40 2018 +0100
|
||||
|
||||
stdlib/test-bz22786: Avoid memory leaks in the test itself
|
||||
|
||||
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||
index bb1e04f2debe9042..8035e8a394e7d034 100644
|
||||
--- a/stdlib/test-bz22786.c
|
||||
+++ b/stdlib/test-bz22786.c
|
||||
@@ -36,8 +36,8 @@
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
- const char *dir = support_create_temp_directory ("bz22786.");
|
||||
- const char *lnk = xasprintf ("%s/symlink", dir);
|
||||
+ char *dir = support_create_temp_directory ("bz22786.");
|
||||
+ char *lnk = xasprintf ("%s/symlink", dir);
|
||||
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||
|
||||
struct support_blob_repeat repeat
|
||||
@@ -72,6 +72,8 @@ do_test (void)
|
||||
/* Cleanup. */
|
||||
unlink (lnk);
|
||||
support_blob_repeat_free (&repeat);
|
||||
+ free (lnk);
|
||||
+ free (dir);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
Use <support/test-driver.c> in stdlib/tst-strtod-overflow.c
|
||||
|
||||
This downstream-only patch is needed because test-skeleton.c contains
|
||||
a copy of the old test skeleton (unlike upstream), resulting in the
|
||||
following error:
|
||||
|
||||
In file included from tst-strtod-overflow.c:53:0:
|
||||
../test-skeleton.c:65:20: error: static declaration of 'test_dir' follows non-static declaration
|
||||
static const char *test_dir;
|
||||
^
|
||||
In file included from tst-strtod-overflow.c:23:0:
|
||||
../support/test-driver.h:65:20: note: previous declaration of 'test_dir' was here
|
||||
extern const char *test_dir;
|
||||
^
|
||||
|
||||
diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
|
||||
index fd1be79f3f58c64b..2b30947d9a9fa03a 100644
|
||||
--- a/stdlib/tst-strtod-overflow.c
|
||||
+++ b/stdlib/tst-strtod-overflow.c
|
||||
@@ -48,6 +48,4 @@ do_test (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#define TIMEOUT 5
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,41 @@
|
|||
Update kernel version in syscall-names.list to 4.17.
|
||||
|
||||
As far as I can tell, Linux 4.17 does not add any new syscalls; this
|
||||
patch updates the version number in syscall-names.list to reflect that
|
||||
it's still current for 4.17.
|
||||
|
||||
Tested for x86_64-linux-gnu with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
version to 4.17.
|
||||
|
||||
(cherry picked from commit 0e0577c93fcdd8922ca83763400f74ca10e46019)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 77c3dae5b015ecad..77aa2a8cf78e568f 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,8 @@
|
||||
+2018-06-05 Joseph Myers <joseph@codesourcery.com>
|
||||
+
|
||||
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
+ version to 4.17.
|
||||
+
|
||||
2012-12-21 David S. Miller <davem@davemloft.net>
|
||||
|
||||
* po/hr.po: Update from translation team.
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index fab3ff2328373a1f..5306d538e6448163 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,8 +22,8 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 4.16.
|
||||
-kernel 4.16
|
||||
+# The list of system calls is current as of Linux 4.17.
|
||||
+kernel 4.17
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
|
@ -0,0 +1,61 @@
|
|||
Update syscall-names.list for Linux 4.18.
|
||||
|
||||
This patch updates sysdeps/unix/sysv/linux/syscall-names.list for
|
||||
Linux 4.18. The io_pgetevents and rseq syscalls are added to the
|
||||
kernel on various architectures, so need to be mentioned in this file.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
version to 4.18.
|
||||
(io_pgetevents): New syscall.
|
||||
(rseq): Likewise.
|
||||
|
||||
(cherry picked from commit 17b26500f9bb926d85e86821d014f7c1bb88043c)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 77aa2a8cf78e568f..3ccca34563e5b71f 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,10 @@
|
||||
+2018-08-13 Joseph Myers <joseph@codesourcery.com>
|
||||
+
|
||||
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
+ version to 4.18.
|
||||
+ (io_pgetevents): New syscall.
|
||||
+ (rseq): Likewise.
|
||||
+
|
||||
2018-06-05 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index 5306d538e6448163..9982a6334d46ae62 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,8 +22,8 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 4.17.
|
||||
-kernel 4.17
|
||||
+# The list of system calls is current as of Linux 4.18.
|
||||
+kernel 4.18
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
||||
@@ -186,6 +186,7 @@ inotify_rm_watch
|
||||
io_cancel
|
||||
io_destroy
|
||||
io_getevents
|
||||
+io_pgetevents
|
||||
io_setup
|
||||
io_submit
|
||||
ioctl
|
||||
@@ -431,6 +432,7 @@ renameat2
|
||||
request_key
|
||||
restart_syscall
|
||||
rmdir
|
||||
+rseq
|
||||
rt_sigaction
|
||||
rt_sigpending
|
||||
rt_sigprocmask
|
|
@ -0,0 +1,41 @@
|
|||
Update kernel version in syscall-names.list to 4.19.
|
||||
|
||||
Linux 4.19 does not add any new syscalls (some existing ones are added
|
||||
to more architectures); this patch updates the version number in
|
||||
syscall-names.list to reflect that it's still current for 4.19.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
version to 4.19.
|
||||
|
||||
(cherry picked from commit 029ad711b8ad4cf0e5d98e0c138a35a23a376a74)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 3ccca34563e5b71f..30a5bed6b09efcef 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,8 @@
|
||||
+2018-10-22 Joseph Myers <joseph@codesourcery.com>
|
||||
+
|
||||
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
+ version to 4.19.
|
||||
+
|
||||
2018-08-13 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index 9982a6334d46ae62..f88001c9c38d5fc7 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,8 +22,8 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 4.18.
|
||||
-kernel 4.18
|
||||
+# The list of system calls is current as of Linux 4.19.
|
||||
+kernel 4.19
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
|
@ -0,0 +1,52 @@
|
|||
Update syscall-names.list for Linux 4.20.
|
||||
|
||||
This patch updates sysdeps/unix/sysv/linux/syscall-names.list for
|
||||
Linux 4.20. Although there are no new syscalls, the
|
||||
riscv_flush_icache syscall has moved to asm/unistd.h (previously in
|
||||
asm/syscalls.h) and so now needs to be added to the list.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
version to 4.20.
|
||||
(riscv_flush_icache): New syscall.
|
||||
|
||||
(cherry picked from commit 47ad5e1a2a3ab8eeda491454cbef3b1c5239dc02)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 30a5bed6b09efcef..0f4f95193ff07d45 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,9 @@
|
||||
+2019-01-01 Joseph Myers <joseph@codesourcery.com>
|
||||
+
|
||||
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
+ version to 4.20.
|
||||
+ (riscv_flush_icache): New syscall.
|
||||
+
|
||||
2018-10-22 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index f88001c9c38d5fc7..d623dc1d9af027be 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,8 +22,8 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 4.19.
|
||||
-kernel 4.19
|
||||
+# The list of system calls is current as of Linux 4.20.
|
||||
+kernel 4.20
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
||||
@@ -431,6 +431,7 @@ renameat
|
||||
renameat2
|
||||
request_key
|
||||
restart_syscall
|
||||
+riscv_flush_icache
|
||||
rmdir
|
||||
rseq
|
||||
rt_sigaction
|
|
@ -0,0 +1,68 @@
|
|||
commit b50dd3bc8cbb1efe85399b03d7e6c0310c2ead84
|
||||
Author: Florian Weimer <fw@deneb.enyo.de>
|
||||
Date: Mon Dec 31 22:04:36 2018 +0100
|
||||
|
||||
malloc: Always call memcpy in _int_realloc [BZ #24027]
|
||||
|
||||
This commit removes the custom memcpy implementation from _int_realloc
|
||||
for small chunk sizes. The ncopies variable has the wrong type, and
|
||||
an integer wraparound could cause the existing code to copy too few
|
||||
elements (leaving the new memory region mostly uninitialized).
|
||||
Therefore, removing this code fixes bug 24027.
|
||||
|
||||
diff -rup a/malloc/malloc.c b/malloc/malloc.c
|
||||
--- a/malloc/malloc.c 2019-03-26 14:12:59.364333388 -0400
|
||||
+++ b/malloc/malloc.c 2019-03-26 14:17:17.373475418 -0400
|
||||
@@ -4214,11 +4214,6 @@ _int_realloc(mstate av, mchunkptr oldp,
|
||||
mchunkptr bck; /* misc temp for linking */
|
||||
mchunkptr fwd; /* misc temp for linking */
|
||||
|
||||
- unsigned long copysize; /* bytes to copy */
|
||||
- unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */
|
||||
- INTERNAL_SIZE_T* s; /* copy source */
|
||||
- INTERNAL_SIZE_T* d; /* copy destination */
|
||||
-
|
||||
const char *errstr = NULL;
|
||||
|
||||
/* oldmem size */
|
||||
@@ -4291,39 +4286,7 @@ _int_realloc(mstate av, mchunkptr oldp,
|
||||
newp = oldp;
|
||||
}
|
||||
else {
|
||||
- /*
|
||||
- Unroll copy of <= 36 bytes (72 if 8byte sizes)
|
||||
- We know that contents have an odd number of
|
||||
- INTERNAL_SIZE_T-sized words; minimally 3.
|
||||
- */
|
||||
-
|
||||
- copysize = oldsize - SIZE_SZ;
|
||||
- s = (INTERNAL_SIZE_T*)(chunk2mem(oldp));
|
||||
- d = (INTERNAL_SIZE_T*)(newmem);
|
||||
- ncopies = copysize / sizeof(INTERNAL_SIZE_T);
|
||||
- assert(ncopies >= 3);
|
||||
-
|
||||
- if (ncopies > 9)
|
||||
- MALLOC_COPY(d, s, copysize);
|
||||
-
|
||||
- else {
|
||||
- *(d+0) = *(s+0);
|
||||
- *(d+1) = *(s+1);
|
||||
- *(d+2) = *(s+2);
|
||||
- if (ncopies > 4) {
|
||||
- *(d+3) = *(s+3);
|
||||
- *(d+4) = *(s+4);
|
||||
- if (ncopies > 6) {
|
||||
- *(d+5) = *(s+5);
|
||||
- *(d+6) = *(s+6);
|
||||
- if (ncopies > 8) {
|
||||
- *(d+7) = *(s+7);
|
||||
- *(d+8) = *(s+8);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
+ memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ);
|
||||
_int_free(av, oldp, 1);
|
||||
check_inuse_chunk(av, newp);
|
||||
return chunk2mem(newp);
|
|
@ -0,0 +1,104 @@
|
|||
commit 08504de71813ddbd447bfbca4a325cbe8ce8bcda
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Mar 12 11:40:47 2019 +0100
|
||||
|
||||
resolv: Enable full ICMP errors for UDP DNS sockets [BZ #24047]
|
||||
|
||||
The Linux kernel suppresses some ICMP error messages by default for
|
||||
UDP sockets. This commit enables full ICMP error reporting,
|
||||
hopefully resulting in faster failover to working name servers.
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index 033c3c651f0deb1b..133fe5885c5b65b5 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -92,7 +92,7 @@ libresolv-routines := res_comp res_debug \
|
||||
res_data res_mkquery res_query res_send \
|
||||
inet_net_ntop inet_net_pton inet_neta base64 \
|
||||
ns_parse ns_name ns_netint ns_ttl ns_print \
|
||||
- ns_samedomain ns_date \
|
||||
+ ns_samedomain ns_date res_enable_icmp \
|
||||
compat-hooks compat-gethnamaddr
|
||||
|
||||
libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \
|
||||
diff --git a/resolv/res_enable_icmp.c b/resolv/res_enable_icmp.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..bdc9220f08cef71d
|
||||
--- /dev/null
|
||||
+++ b/resolv/res_enable_icmp.c
|
||||
@@ -0,0 +1,37 @@
|
||||
+/* Enable full ICMP errors on a socket.
|
||||
+ Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <netinet/in.h>
|
||||
+#include <sys/socket.h>
|
||||
+
|
||||
+int
|
||||
+__res_enable_icmp (int family, int fd)
|
||||
+{
|
||||
+ int one = 1;
|
||||
+ switch (family)
|
||||
+ {
|
||||
+ case AF_INET:
|
||||
+ return setsockopt (fd, SOL_IP, IP_RECVERR, &one, sizeof (one));
|
||||
+ case AF_INET6:
|
||||
+ return setsockopt (fd, SOL_IPV6, IPV6_RECVERR, &one, sizeof (one));
|
||||
+ default:
|
||||
+ __set_errno (EAFNOSUPPORT);
|
||||
+ return -1;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/resolv/res_send.c b/resolv/res_send.c
|
||||
index 05c7ba511b0383c1..e57bb12a66b087e4 100644
|
||||
--- a/resolv/res_send.c
|
||||
+++ b/resolv/res_send.c
|
||||
@@ -943,6 +943,18 @@ reopen (res_state statp, int *terrno, int ns)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
+ /* Enable full ICMP error reporting for this
|
||||
+ socket. */
|
||||
+ if (__res_enable_icmp (nsap->sa_family,
|
||||
+ EXT (statp).nssocks[ns]) < 0)
|
||||
+ {
|
||||
+ int saved_errno = errno;
|
||||
+ __res_iclose (statp, false);
|
||||
+ __set_errno (saved_errno);
|
||||
+ *terrno = saved_errno;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* On a 4.3BSD+ machine (client and server,
|
||||
* actually), sending to a nameserver datagram
|
||||
diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h
|
||||
index 32dc44777e311849..d73a2c1b944bcbbe 100644
|
||||
--- a/resolv/resolv-internal.h
|
||||
+++ b/resolv/resolv-internal.h
|
||||
@@ -97,4 +97,10 @@ int __res_nopt (struct resolv_context *, int n0,
|
||||
int __inet_pton_length (int af, const char *src, size_t srclen, void *);
|
||||
libc_hidden_proto (__inet_pton_length)
|
||||
|
||||
+/* The Linux kernel does not enable all ICMP messages on a UDP socket
|
||||
+ by default. A call this function enables full error reporting for
|
||||
+ the socket FD. FAMILY must be AF_INET or AF_INET6. Returns 0 on
|
||||
+ success, -1 on failure. */
|
||||
+int __res_enable_icmp (int family, int fd) attribute_hidden;
|
||||
+
|
||||
#endif /* _RESOLV_INTERNAL_H */
|
|
@ -0,0 +1,200 @@
|
|||
commit 823624bdc47f1f80109c9c52dee7939b9386d708
|
||||
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||
Date: Thu Feb 7 15:18:36 2019 +0100
|
||||
|
||||
Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock. [BZ #24180]
|
||||
|
||||
While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and
|
||||
Heiko Carstens found a bug in pthread_mutex_trylock due to misordered
|
||||
instructions:
|
||||
140: a5 1b 00 01 oill %r1,1
|
||||
144: e5 48 a0 f0 00 00 mvghi 240(%r10),0 <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
14a: e3 10 a0 e0 00 24 stg %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI
|
||||
|
||||
vs (with compiler barriers):
|
||||
140: a5 1b 00 01 oill %r1,1
|
||||
144: e3 10 a0 e0 00 24 stg %r1,224(%r10)
|
||||
14a: e5 48 a0 f0 00 00 mvghi 240(%r10),0
|
||||
|
||||
Please have a look at the discussion:
|
||||
"Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede"
|
||||
(https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/)
|
||||
|
||||
This patch is introducing the same compiler barriers and comments
|
||||
for pthread_mutex_trylock as introduced for pthread_mutex_lock and
|
||||
pthread_mutex_timedlock by commit 8f9450a0b7a9e78267e8ae1ab1000ebca08e473e
|
||||
"Add compiler barriers around modifications of the robust mutex list."
|
||||
|
||||
ChangeLog:
|
||||
|
||||
[BZ #24180]
|
||||
* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock):
|
||||
|
||||
|
||||
diff -Nrup a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
|
||||
--- a/nptl/pthread_mutex_trylock.c 2019-07-26 16:43:11.028271897 -0400
|
||||
+++ b/nptl/pthread_mutex_trylock.c 2019-07-26 17:06:48.708748979 -0400
|
||||
@@ -95,6 +95,9 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
|
||||
&mutex->__data.__list.__next);
|
||||
+ /* We need to set op_pending before starting the operation. Also
|
||||
+ see comments at ENQUEUE_MUTEX. */
|
||||
+ __asm ("" ::: "memory");
|
||||
|
||||
oldval = mutex->__data.__lock;
|
||||
do
|
||||
@@ -120,7 +123,12 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
/* But it is inconsistent unless marked otherwise. */
|
||||
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
|
||||
|
||||
+ /* We must not enqueue the mutex before we have acquired it.
|
||||
+ Also see comments at ENQUEUE_MUTEX. */
|
||||
+ __asm ("" ::: "memory");
|
||||
ENQUEUE_MUTEX (mutex);
|
||||
+ /* We need to clear op_pending after we enqueue the mutex. */
|
||||
+ __asm ("" ::: "memory");
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
/* Note that we deliberately exist here. If we fall
|
||||
@@ -136,6 +144,8 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
int kind = PTHREAD_MUTEX_TYPE (mutex);
|
||||
if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
|
||||
{
|
||||
+ /* We do not need to ensure ordering wrt another memory
|
||||
+ access. Also see comments at ENQUEUE_MUTEX. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
|
||||
NULL);
|
||||
return EDEADLK;
|
||||
@@ -143,6 +153,8 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
|
||||
if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
|
||||
{
|
||||
+ /* We do not need to ensure ordering wrt another memory
|
||||
+ access. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
|
||||
NULL);
|
||||
|
||||
@@ -160,6 +172,10 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
oldval = lll_robust_trylock (mutex->__data.__lock, id);
|
||||
if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
|
||||
{
|
||||
+ /* We haven't acquired the lock as it is already acquired by
|
||||
+ another owner. We do not need to ensure ordering wrt another
|
||||
+ memory access. */
|
||||
+
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
return EBUSY;
|
||||
@@ -173,13 +189,20 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
if (oldval == id)
|
||||
lll_unlock (mutex->__data.__lock,
|
||||
PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
|
||||
+ /* FIXME This violates the mutex destruction requirements. See
|
||||
+ __pthread_mutex_unlock_full. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
return ENOTRECOVERABLE;
|
||||
}
|
||||
}
|
||||
while ((oldval & FUTEX_OWNER_DIED) != 0);
|
||||
|
||||
+ /* We must not enqueue the mutex before we have acquired it.
|
||||
+ Also see comments at ENQUEUE_MUTEX. */
|
||||
+ __asm ("" ::: "memory");
|
||||
ENQUEUE_MUTEX (mutex);
|
||||
+ /* We need to clear op_pending after we enqueue the mutex. */
|
||||
+ __asm ("" ::: "memory");
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
mutex->__data.__owner = id;
|
||||
@@ -201,10 +224,15 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
|
||||
|
||||
if (robust)
|
||||
- /* Note: robust PI futexes are signaled by setting bit 0. */
|
||||
- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
|
||||
- (void *) (((uintptr_t) &mutex->__data.__list.__next)
|
||||
- | 1));
|
||||
+ {
|
||||
+ /* Note: robust PI futexes are signaled by setting bit 0. */
|
||||
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
|
||||
+ (void *) (((uintptr_t) &mutex->__data.__list.__next)
|
||||
+ | 1));
|
||||
+ /* We need to set op_pending before starting the operation. Also
|
||||
+ see comments at ENQUEUE_MUTEX. */
|
||||
+ __asm ("" ::: "memory");
|
||||
+ }
|
||||
|
||||
oldval = mutex->__data.__lock;
|
||||
|
||||
@@ -213,12 +241,16 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
{
|
||||
if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
|
||||
{
|
||||
+ /* We do not need to ensure ordering wrt another memory
|
||||
+ access. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
return EDEADLK;
|
||||
}
|
||||
|
||||
if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
|
||||
{
|
||||
+ /* We do not need to ensure ordering wrt another memory
|
||||
+ access. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
/* Just bump the counter. */
|
||||
@@ -240,6 +272,9 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
{
|
||||
if ((oldval & FUTEX_OWNER_DIED) == 0)
|
||||
{
|
||||
+ /* We haven't acquired the lock as it is already acquired by
|
||||
+ another owner. We do not need to ensure ordering wrt another
|
||||
+ memory access. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
return EBUSY;
|
||||
@@ -260,6 +295,9 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
|
||||
&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
|
||||
{
|
||||
+ /* The kernel has not yet finished the mutex owner death.
|
||||
+ We do not need to ensure ordering wrt another memory
|
||||
+ access. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
return EBUSY;
|
||||
@@ -277,7 +315,12 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
/* But it is inconsistent unless marked otherwise. */
|
||||
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
|
||||
|
||||
+ /* We must not enqueue the mutex before we have acquired it.
|
||||
+ Also see comments at ENQUEUE_MUTEX. */
|
||||
+ __asm ("" ::: "memory");
|
||||
ENQUEUE_MUTEX (mutex);
|
||||
+ /* We need to clear op_pending after we enqueue the mutex. */
|
||||
+ __asm ("" ::: "memory");
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
/* Note that we deliberately exit here. If we fall
|
||||
@@ -300,13 +343,20 @@ __pthread_mutex_trylock (pthread_mutex_t
|
||||
PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
|
||||
0, 0);
|
||||
|
||||
+ /* To the kernel, this will be visible after the kernel has
|
||||
+ acquired the mutex in the syscall. */
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
return ENOTRECOVERABLE;
|
||||
}
|
||||
|
||||
if (robust)
|
||||
{
|
||||
+ /* We must not enqueue the mutex before we have acquired it.
|
||||
+ Also see comments at ENQUEUE_MUTEX. */
|
||||
+ __asm ("" ::: "memory");
|
||||
ENQUEUE_MUTEX_PI (mutex);
|
||||
+ /* We need to clear op_pending after we enqueue the mutex. */
|
||||
+ __asm ("" ::: "memory");
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
commit c94a5688fb1228a862b2d4a3f1239cdc0e3349e5
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Nov 2 12:14:01 2017 +0100
|
||||
|
||||
<array_length.h>: New array_length and array_end macros
|
||||
|
||||
diff --git a/include/array_length.h b/include/array_length.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..cb4a8b2a56bca3ad
|
||||
--- /dev/null
|
||||
+++ b/include/array_length.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+/* The array_length and array_end macros.
|
||||
+ Copyright (C) 2017 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef _ARRAY_LENGTH_H
|
||||
+#define _ARRAY_LENGTH_H
|
||||
+
|
||||
+/* array_length (VAR) is the number of elements in the array VAR. VAR
|
||||
+ must evaluate to an array, not a pointer. */
|
||||
+#define array_length(var) \
|
||||
+ __extension__ ({ \
|
||||
+ _Static_assert (!__builtin_types_compatible_p \
|
||||
+ (__typeof (var), __typeof (&(var)[0])), \
|
||||
+ "argument must be an array"); \
|
||||
+ sizeof (var) / sizeof ((var)[0]); \
|
||||
+ })
|
||||
+
|
||||
+/* array_end (VAR) is a pointer one past the end of the array VAR.
|
||||
+ VAR must evaluate to an array, not a pointer. */
|
||||
+#define array_end(var) (&(var)[array_length (var)])
|
||||
+
|
||||
+#endif /* _ARRAY_LENGTH_H */
|
|
@ -0,0 +1,34 @@
|
|||
commit 8311c83f91a3127ccd2fe684e25bc60c5178d23b
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Feb 7 09:03:02 2019 +0100
|
||||
|
||||
array_length: Make usable as a constant expression
|
||||
|
||||
Do not use a statement expression in array_length, so that
|
||||
array_length can be used at file scope and as a constant expression.
|
||||
Instead, put the _Static_assert into a struct (as a declaration),
|
||||
and nest this in the expression using a sizeof expression.
|
||||
|
||||
diff --git a/include/array_length.h b/include/array_length.h
|
||||
index cb4a8b2a56bca3ad..ccb253c1dc1641cf 100644
|
||||
--- a/include/array_length.h
|
||||
+++ b/include/array_length.h
|
||||
@@ -22,12 +22,12 @@
|
||||
/* array_length (VAR) is the number of elements in the array VAR. VAR
|
||||
must evaluate to an array, not a pointer. */
|
||||
#define array_length(var) \
|
||||
- __extension__ ({ \
|
||||
- _Static_assert (!__builtin_types_compatible_p \
|
||||
- (__typeof (var), __typeof (&(var)[0])), \
|
||||
- "argument must be an array"); \
|
||||
- sizeof (var) / sizeof ((var)[0]); \
|
||||
- })
|
||||
+ (sizeof (var) / sizeof ((var)[0]) \
|
||||
+ + 0 * sizeof (struct { \
|
||||
+ _Static_assert (!__builtin_types_compatible_p \
|
||||
+ (__typeof (var), __typeof (&(var)[0])), \
|
||||
+ "argument must be an array"); \
|
||||
+ }))
|
||||
|
||||
/* array_end (VAR) is a pointer one past the end of the array VAR.
|
||||
VAR must evaluate to an array, not a pointer. */
|
|
@ -0,0 +1,142 @@
|
|||
commit c74a91deaa5de416237c02bbb3e41bda76ca4c7b
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Nov 27 21:35:56 2018 +0100
|
||||
|
||||
support: Implement support_quote_string
|
||||
|
||||
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 2b663fbbfa334ea2..a2536980d1d5a89b 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -58,6 +58,7 @@ libsupport-routines = \
|
||||
support_openpty \
|
||||
support_paths \
|
||||
support_quote_blob \
|
||||
+ support_quote_string \
|
||||
support_record_failure \
|
||||
support_run_diff \
|
||||
support_shared_allocate \
|
||||
@@ -196,6 +197,7 @@ tests = \
|
||||
tst-support_capture_subprocess \
|
||||
tst-support_format_dns_packet \
|
||||
tst-support_quote_blob \
|
||||
+ tst-support_quote_string \
|
||||
tst-support_record_failure \
|
||||
tst-test_compare \
|
||||
tst-test_compare_blob \
|
||||
diff --git a/support/support.h b/support/support.h
|
||||
index 9418cd11ef6e684d..835e7173eb566355 100644
|
||||
--- a/support/support.h
|
||||
+++ b/support/support.h
|
||||
@@ -69,6 +69,11 @@ void support_write_file_string (const char *path, const char *contents);
|
||||
the result). */
|
||||
char *support_quote_blob (const void *blob, size_t length);
|
||||
|
||||
+/* Quote the contents of the at STR, in such a way that the result
|
||||
+ string can be included in a C literal (in single/double quotes,
|
||||
+ without putting the quotes into the result). */
|
||||
+char *support_quote_string (const char *str);
|
||||
+
|
||||
/* Returns non-zero if the file descriptor is a regular file on a file
|
||||
system which supports holes (that is, seeking and writing does not
|
||||
allocate storage for the range of zeros). FD must refer to a
|
||||
diff --git a/support/support_quote_string.c b/support/support_quote_string.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..d324371b133a4d66
|
||||
--- /dev/null
|
||||
+++ b/support/support_quote_string.c
|
||||
@@ -0,0 +1,26 @@
|
||||
+/* Quote a string so that it can be used in C literals.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <string.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+char *
|
||||
+support_quote_string (const char *str)
|
||||
+{
|
||||
+ return support_quote_blob (str, strlen (str));
|
||||
+}
|
||||
diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3c004759b76e21d7
|
||||
--- /dev/null
|
||||
+++ b/support/tst-support_quote_string.c
|
||||
@@ -0,0 +1,60 @@
|
||||
+/* Test the support_quote_string function.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *p = support_quote_string ("");
|
||||
+ TEST_COMPARE (strlen (p), 0);
|
||||
+ free (p);
|
||||
+ p = support_quote_string ("X");
|
||||
+ TEST_COMPARE (strlen (p), 1);
|
||||
+ TEST_COMPARE (p[0], 'X');
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check escaping of backslash-escaped characters, and lack of
|
||||
+ escaping for other shell meta-characters. */
|
||||
+ p = support_quote_string ("$()*?`@[]{}~\'\"X");
|
||||
+ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check lack of escaping for letters and digits. */
|
||||
+#define LETTERS_AND_DIGTS \
|
||||
+ "abcdefghijklmnopqrstuvwxyz" \
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||
+ "0123456789"
|
||||
+ p = support_quote_string (LETTERS_AND_DIGTS "@");
|
||||
+ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check escaping of control characters and other non-printable
|
||||
+ characters. */
|
||||
+ p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@");
|
||||
+ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
|
||||
+ "\\177\\200\\377@"), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,221 @@
|
|||
commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Jan 21 08:59:42 2019 +0100
|
||||
|
||||
resolv: Reformat inet_addr, inet_aton to GNU style
|
||||
|
||||
diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
|
||||
index 022f7ea0841b6bae..32f58b0e13598b32 100644
|
||||
--- a/resolv/inet_addr.c
|
||||
+++ b/resolv/inet_addr.c
|
||||
@@ -1,3 +1,21 @@
|
||||
+/* Legacy IPv4 text-to-address functions.
|
||||
+ Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
/*
|
||||
* Copyright (c) 1983, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -78,105 +96,97 @@
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
-/*
|
||||
- * Ascii internet address interpretation routine.
|
||||
- * The value returned is in network order.
|
||||
- */
|
||||
+/* ASCII IPv4 Internet address interpretation routine. The value
|
||||
+ returned is in network order. */
|
||||
in_addr_t
|
||||
-__inet_addr(const char *cp) {
|
||||
- struct in_addr val;
|
||||
+__inet_addr (const char *cp)
|
||||
+{
|
||||
+ struct in_addr val;
|
||||
|
||||
- if (__inet_aton(cp, &val))
|
||||
- return (val.s_addr);
|
||||
- return (INADDR_NONE);
|
||||
+ if (__inet_aton (cp, &val))
|
||||
+ return val.s_addr;
|
||||
+ return INADDR_NONE;
|
||||
}
|
||||
weak_alias (__inet_addr, inet_addr)
|
||||
|
||||
-/*
|
||||
- * Check whether "cp" is a valid ascii representation
|
||||
- * of an Internet address and convert to a binary address.
|
||||
- * Returns 1 if the address is valid, 0 if not.
|
||||
- * This replaces inet_addr, the return value from which
|
||||
- * cannot distinguish between failure and a local broadcast address.
|
||||
- */
|
||||
+/* Check whether "cp" is a valid ASCII representation of an IPv4
|
||||
+ Internet address and convert it to a binary address. Returns 1 if
|
||||
+ the address is valid, 0 if not. This replaces inet_addr, the
|
||||
+ return value from which cannot distinguish between failure and a
|
||||
+ local broadcast address. */
|
||||
int
|
||||
-__inet_aton(const char *cp, struct in_addr *addr)
|
||||
+__inet_aton (const char *cp, struct in_addr *addr)
|
||||
{
|
||||
- static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
|
||||
- in_addr_t val;
|
||||
- char c;
|
||||
- union iaddr {
|
||||
- uint8_t bytes[4];
|
||||
- uint32_t word;
|
||||
- } res;
|
||||
- uint8_t *pp = res.bytes;
|
||||
- int digit;
|
||||
-
|
||||
- int saved_errno = errno;
|
||||
- __set_errno (0);
|
||||
-
|
||||
- res.word = 0;
|
||||
-
|
||||
- c = *cp;
|
||||
- for (;;) {
|
||||
- /*
|
||||
- * Collect number up to ``.''.
|
||||
- * Values are specified as for C:
|
||||
- * 0x=hex, 0=octal, isdigit=decimal.
|
||||
- */
|
||||
- if (!isdigit(c))
|
||||
- goto ret_0;
|
||||
- {
|
||||
- char *endp;
|
||||
- unsigned long ul = strtoul (cp, (char **) &endp, 0);
|
||||
- if (ul == ULONG_MAX && errno == ERANGE)
|
||||
- goto ret_0;
|
||||
- if (ul > 0xfffffffful)
|
||||
- goto ret_0;
|
||||
- val = ul;
|
||||
- digit = cp != endp;
|
||||
- cp = endp;
|
||||
- }
|
||||
- c = *cp;
|
||||
- if (c == '.') {
|
||||
- /*
|
||||
- * Internet format:
|
||||
- * a.b.c.d
|
||||
- * a.b.c (with c treated as 16 bits)
|
||||
- * a.b (with b treated as 24 bits)
|
||||
- */
|
||||
- if (pp > res.bytes + 2 || val > 0xff)
|
||||
- goto ret_0;
|
||||
- *pp++ = val;
|
||||
- c = *++cp;
|
||||
- } else
|
||||
- break;
|
||||
- }
|
||||
- /*
|
||||
- * Check for trailing characters.
|
||||
- */
|
||||
- if (c != '\0' && (!isascii(c) || !isspace(c)))
|
||||
- goto ret_0;
|
||||
- /*
|
||||
- * Did we get a valid digit?
|
||||
- */
|
||||
- if (!digit)
|
||||
- goto ret_0;
|
||||
-
|
||||
- /* Check whether the last part is in its limits depending on
|
||||
- the number of parts in total. */
|
||||
- if (val > max[pp - res.bytes])
|
||||
+ static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
|
||||
+ in_addr_t val;
|
||||
+ char c;
|
||||
+ union iaddr
|
||||
+ {
|
||||
+ uint8_t bytes[4];
|
||||
+ uint32_t word;
|
||||
+ } res;
|
||||
+ uint8_t *pp = res.bytes;
|
||||
+ int digit;
|
||||
+
|
||||
+ int saved_errno = errno;
|
||||
+ __set_errno (0);
|
||||
+
|
||||
+ res.word = 0;
|
||||
+
|
||||
+ c = *cp;
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ /* Collect number up to ``.''. Values are specified as for C:
|
||||
+ 0x=hex, 0=octal, isdigit=decimal. */
|
||||
+ if (!isdigit (c))
|
||||
+ goto ret_0;
|
||||
+ {
|
||||
+ char *endp;
|
||||
+ unsigned long ul = strtoul (cp, &endp, 0);
|
||||
+ if (ul == ULONG_MAX && errno == ERANGE)
|
||||
goto ret_0;
|
||||
-
|
||||
- if (addr != NULL)
|
||||
- addr->s_addr = res.word | htonl (val);
|
||||
-
|
||||
- __set_errno (saved_errno);
|
||||
- return (1);
|
||||
-
|
||||
-ret_0:
|
||||
- __set_errno (saved_errno);
|
||||
- return (0);
|
||||
+ if (ul > 0xfffffffful)
|
||||
+ goto ret_0;
|
||||
+ val = ul;
|
||||
+ digit = cp != endp;
|
||||
+ cp = endp;
|
||||
+ }
|
||||
+ c = *cp;
|
||||
+ if (c == '.')
|
||||
+ {
|
||||
+ /* Internet format:
|
||||
+ a.b.c.d
|
||||
+ a.b.c (with c treated as 16 bits)
|
||||
+ a.b (with b treated as 24 bits). */
|
||||
+ if (pp > res.bytes + 2 || val > 0xff)
|
||||
+ goto ret_0;
|
||||
+ *pp++ = val;
|
||||
+ c = *++cp;
|
||||
+ }
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+ /* Check for trailing characters. */
|
||||
+ if (c != '\0' && (!isascii (c) || !isspace (c)))
|
||||
+ goto ret_0;
|
||||
+ /* Did we get a valid digit? */
|
||||
+ if (!digit)
|
||||
+ goto ret_0;
|
||||
+
|
||||
+ /* Check whether the last part is in its limits depending on the
|
||||
+ number of parts in total. */
|
||||
+ if (val > max[pp - res.bytes])
|
||||
+ goto ret_0;
|
||||
+
|
||||
+ if (addr != NULL)
|
||||
+ addr->s_addr = res.word | htonl (val);
|
||||
+
|
||||
+ __set_errno (saved_errno);
|
||||
+ return 1;
|
||||
+
|
||||
+ ret_0:
|
||||
+ __set_errno (saved_errno);
|
||||
+ return 0;
|
||||
}
|
||||
weak_alias (__inet_aton, inet_aton)
|
||||
libc_hidden_def (__inet_aton)
|
|
@ -0,0 +1,80 @@
|
|||
commit 6ca53a2453598804a2559a548a08424fca96434a
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Jan 21 09:26:41 2019 +0100
|
||||
|
||||
resolv: Do not send queries for non-host-names in nss_dns [BZ #24112]
|
||||
|
||||
Before this commit, nss_dns would send a query which did not contain a
|
||||
host name as the query name (such as invalid\032name.example.com) and
|
||||
then reject the answer in getanswer_r and gaih_getanswer_slice, using
|
||||
a check based on res_hnok. With this commit, no query is sent, and a
|
||||
host-not-found error is returned to NSS without network interaction.
|
||||
|
||||
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
|
||||
index 1e85e4f08ffc8600..e697d9103797341b 100644
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -273,11 +273,26 @@ gethostbyname3_context (struct resolv_context *ctx,
|
||||
return status;
|
||||
}
|
||||
|
||||
+/* Verify that the name looks like a host name. There is no point in
|
||||
+ sending a query which will not produce a usable name in the
|
||||
+ response. */
|
||||
+static enum nss_status
|
||||
+check_name (const char *name, int *h_errnop)
|
||||
+{
|
||||
+ if (res_hnok (name))
|
||||
+ return NSS_STATUS_SUCCESS;
|
||||
+ *h_errnop = HOST_NOT_FOUND;
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+}
|
||||
+
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *errnop,
|
||||
int *h_errnop)
|
||||
{
|
||||
+ enum nss_status status = check_name (name, h_errnop);
|
||||
+ if (status != NSS_STATUS_SUCCESS)
|
||||
+ return status;
|
||||
return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop,
|
||||
h_errnop, NULL, NULL);
|
||||
}
|
||||
@@ -288,6 +303,9 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *errnop,
|
||||
int *h_errnop)
|
||||
{
|
||||
+ enum nss_status status = check_name (name, h_errnop);
|
||||
+ if (status != NSS_STATUS_SUCCESS)
|
||||
+ return status;
|
||||
struct resolv_context *ctx = __resolv_context_get ();
|
||||
if (ctx == NULL)
|
||||
{
|
||||
@@ -295,7 +313,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
- enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
+ status = NSS_STATUS_NOTFOUND;
|
||||
if (res_use_inet6 ())
|
||||
status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer,
|
||||
buflen, errnop, h_errnop, NULL, NULL);
|
||||
@@ -312,6 +330,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
char *buffer, size_t buflen, int *errnop,
|
||||
int *herrnop, int32_t *ttlp)
|
||||
{
|
||||
+ enum nss_status status = check_name (name, herrnop);
|
||||
+ if (status != NSS_STATUS_SUCCESS)
|
||||
+ return status;
|
||||
struct resolv_context *ctx = __resolv_context_get ();
|
||||
if (ctx == NULL)
|
||||
{
|
||||
@@ -346,7 +367,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
|
||||
int ans2p_malloced = 0;
|
||||
|
||||
int olderr = errno;
|
||||
- enum nss_status status;
|
||||
int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
|
||||
host_buffer.buf->buf, 2048, &host_buffer.ptr,
|
||||
&ans2p, &nans2p, &resplen2, &ans2p_malloced);
|
|
@ -0,0 +1,698 @@
|
|||
commit 108bc4049f8ae82710aec26a92ffdb4b439c83fd
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Jan 21 21:26:03 2019 +0100
|
||||
|
||||
CVE-2016-10739: getaddrinfo: Fully parse IPv4 address strings [BZ #20018]
|
||||
|
||||
The IPv4 address parser in the getaddrinfo function is changed so that
|
||||
it does not ignore trailing whitespace and all characters after it.
|
||||
For backwards compatibility, the getaddrinfo function still recognizes
|
||||
legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8
|
||||
(octal).
|
||||
|
||||
This commit does not change the behavior of inet_addr and inet_aton.
|
||||
gethostbyname already had additional sanity checks (but is switched
|
||||
over to the new __inet_aton_exact function for completeness as well).
|
||||
|
||||
To avoid sending the problematic query names over DNS, commit
|
||||
6ca53a2453598804a2559a548a08424fca96434a ("resolv: Do not send queries
|
||||
for non-host-names in nss_dns [BZ #24112]") is needed.
|
||||
|
||||
diff --git a/include/arpa/inet.h b/include/arpa/inet.h
|
||||
index c3f28f2baaa2ed66..19aec74275069a45 100644
|
||||
--- a/include/arpa/inet.h
|
||||
+++ b/include/arpa/inet.h
|
||||
@@ -1,10 +1,10 @@
|
||||
#include <inet/arpa/inet.h>
|
||||
|
||||
#ifndef _ISOMAC
|
||||
-extern int __inet_aton (const char *__cp, struct in_addr *__inp);
|
||||
-libc_hidden_proto (__inet_aton)
|
||||
+/* Variant of inet_aton which rejects trailing garbage. */
|
||||
+extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp);
|
||||
+libc_hidden_proto (__inet_aton_exact)
|
||||
|
||||
-libc_hidden_proto (inet_aton)
|
||||
libc_hidden_proto (inet_ntop)
|
||||
libc_hidden_proto (inet_pton)
|
||||
extern __typeof (inet_pton) __inet_pton;
|
||||
diff --git a/nscd/gai.c b/nscd/gai.c
|
||||
index 018b449339813df5..dbe878fcf699dbc1 100644
|
||||
--- a/nscd/gai.c
|
||||
+++ b/nscd/gai.c
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
/* This file uses the getaddrinfo code but it compiles it without NSCD
|
||||
support. We just need a few symbol renames. */
|
||||
-#define __inet_aton inet_aton
|
||||
#define __ioctl ioctl
|
||||
#define __getsockname getsockname
|
||||
#define __socket socket
|
||||
diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c
|
||||
index 2ab75e469eca1589..958a12d063f1e3e6 100644
|
||||
--- a/nscd/gethstbynm3_r.c
|
||||
+++ b/nscd/gethstbynm3_r.c
|
||||
@@ -38,8 +38,6 @@
|
||||
#define HAVE_LOOKUP_BUFFER 1
|
||||
#define HAVE_AF 1
|
||||
|
||||
-#define __inet_aton inet_aton
|
||||
-
|
||||
/* We are nscd, so we don't want to be talking to ourselves. */
|
||||
#undef USE_NSCD
|
||||
|
||||
diff --git a/nss/digits_dots.c b/nss/digits_dots.c
|
||||
index 0c1fa97e3977a81e..5f7e5b5fb120c387 100644
|
||||
--- a/nss/digits_dots.c
|
||||
+++ b/nss/digits_dots.c
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "nsswitch.h"
|
||||
|
||||
#ifdef USE_NSCD
|
||||
-# define inet_aton __inet_aton
|
||||
# include <nscd/nscd_proto.h>
|
||||
#endif
|
||||
|
||||
@@ -160,7 +159,7 @@ __nss_hostname_digits_dots_context (struct resolv_context *ctx,
|
||||
255.255.255.255? The test below will succeed
|
||||
spuriously... ??? */
|
||||
if (af == AF_INET)
|
||||
- ok = __inet_aton (name, (struct in_addr *) host_addr);
|
||||
+ ok = __inet_aton_exact (name, (struct in_addr *) host_addr);
|
||||
else
|
||||
{
|
||||
assert (af == AF_INET6);
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index 1124897ce5f9610b..988871086a70b291 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -34,6 +34,9 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
|
||||
tests = tst-aton tst-leaks tst-inet_ntop
|
||||
xtests = tst-leaks2
|
||||
|
||||
+tests-internal += tst-inet_aton_exact
|
||||
+
|
||||
+
|
||||
generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
|
||||
|
||||
extra-libs := libresolv libnss_dns
|
||||
@@ -51,8 +54,10 @@ tests += \
|
||||
tst-resolv-basic \
|
||||
tst-resolv-edns \
|
||||
tst-resolv-network \
|
||||
+ tst-resolv-nondecimal \
|
||||
tst-resolv-res_init-multi \
|
||||
tst-resolv-search \
|
||||
+ tst-resolv-trailing \
|
||||
|
||||
# These tests need libdl.
|
||||
ifeq (yes,$(build-shared))
|
||||
@@ -164,9 +169,11 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
|
||||
$(shared-thread-library)
|
||||
$(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \
|
||||
$(shared-thread-library)
|
||||
+$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
+$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-threads: \
|
||||
$(libdl) $(objpfx)libresolv.so $(shared-thread-library)
|
||||
$(objpfx)tst-resolv-canonname: \
|
||||
diff --git a/resolv/Versions b/resolv/Versions
|
||||
index b05778d9654aa0f2..9a82704af75f789b 100644
|
||||
--- a/resolv/Versions
|
||||
+++ b/resolv/Versions
|
||||
@@ -27,6 +27,7 @@ libc {
|
||||
__h_errno; __resp;
|
||||
|
||||
__res_iclose;
|
||||
+ __inet_aton_exact;
|
||||
__inet_pton_length;
|
||||
__resolv_context_get;
|
||||
__resolv_context_get_preinit;
|
||||
diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
|
||||
index 32f58b0e13598b32..41b6166a5bd5a44b 100644
|
||||
--- a/resolv/inet_addr.c
|
||||
+++ b/resolv/inet_addr.c
|
||||
@@ -96,26 +96,14 @@
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
-/* ASCII IPv4 Internet address interpretation routine. The value
|
||||
- returned is in network order. */
|
||||
-in_addr_t
|
||||
-__inet_addr (const char *cp)
|
||||
-{
|
||||
- struct in_addr val;
|
||||
-
|
||||
- if (__inet_aton (cp, &val))
|
||||
- return val.s_addr;
|
||||
- return INADDR_NONE;
|
||||
-}
|
||||
-weak_alias (__inet_addr, inet_addr)
|
||||
-
|
||||
/* Check whether "cp" is a valid ASCII representation of an IPv4
|
||||
Internet address and convert it to a binary address. Returns 1 if
|
||||
the address is valid, 0 if not. This replaces inet_addr, the
|
||||
return value from which cannot distinguish between failure and a
|
||||
- local broadcast address. */
|
||||
-int
|
||||
-__inet_aton (const char *cp, struct in_addr *addr)
|
||||
+ local broadcast address. Write a pointer to the first
|
||||
+ non-converted character to *endp. */
|
||||
+static int
|
||||
+inet_aton_end (const char *cp, struct in_addr *addr, const char **endp)
|
||||
{
|
||||
static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
|
||||
in_addr_t val;
|
||||
@@ -180,6 +168,7 @@ __inet_aton (const char *cp, struct in_addr *addr)
|
||||
|
||||
if (addr != NULL)
|
||||
addr->s_addr = res.word | htonl (val);
|
||||
+ *endp = cp;
|
||||
|
||||
__set_errno (saved_errno);
|
||||
return 1;
|
||||
@@ -188,6 +177,41 @@ __inet_aton (const char *cp, struct in_addr *addr)
|
||||
__set_errno (saved_errno);
|
||||
return 0;
|
||||
}
|
||||
-weak_alias (__inet_aton, inet_aton)
|
||||
-libc_hidden_def (__inet_aton)
|
||||
-libc_hidden_weak (inet_aton)
|
||||
+
|
||||
+int
|
||||
+__inet_aton_exact (const char *cp, struct in_addr *addr)
|
||||
+{
|
||||
+ struct in_addr val;
|
||||
+ const char *endp;
|
||||
+ /* Check that inet_aton_end parsed the entire string. */
|
||||
+ if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0)
|
||||
+ {
|
||||
+ *addr = val;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+libc_hidden_def (__inet_aton_exact)
|
||||
+
|
||||
+/* inet_aton ignores trailing garbage. */
|
||||
+int
|
||||
+__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr)
|
||||
+{
|
||||
+ const char *endp;
|
||||
+ return inet_aton_end (cp, addr, &endp);
|
||||
+}
|
||||
+weak_alias (__inet_aton_ignore_trailing, inet_aton)
|
||||
+
|
||||
+/* ASCII IPv4 Internet address interpretation routine. The value
|
||||
+ returned is in network order. */
|
||||
+in_addr_t
|
||||
+__inet_addr (const char *cp)
|
||||
+{
|
||||
+ struct in_addr val;
|
||||
+ const char *endp;
|
||||
+ if (inet_aton_end (cp, &val, &endp))
|
||||
+ return val.s_addr;
|
||||
+ return INADDR_NONE;
|
||||
+}
|
||||
+weak_alias (__inet_addr, inet_addr)
|
||||
diff --git a/resolv/res_init.c b/resolv/res_init.c
|
||||
index c29bc4e9b99b6bee..9ea9c01d1029ba5f 100644
|
||||
--- a/resolv/res_init.c
|
||||
+++ b/resolv/res_init.c
|
||||
@@ -399,8 +399,16 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
|
||||
cp = parser->buffer + sizeof ("nameserver") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
+
|
||||
+ /* Ignore trailing contents on the name server line. */
|
||||
+ {
|
||||
+ char *el;
|
||||
+ if ((el = strpbrk (cp, " \t\n")) != NULL)
|
||||
+ *el = '\0';
|
||||
+ }
|
||||
+
|
||||
struct sockaddr *sa;
|
||||
- if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a))
|
||||
+ if ((*cp != '\0') && (*cp != '\n') && __inet_aton_exact (cp, &a))
|
||||
{
|
||||
sa = allocate_address_v4 (a, NAMESERVER_PORT);
|
||||
if (sa == NULL)
|
||||
@@ -410,9 +418,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
|
||||
{
|
||||
struct in6_addr a6;
|
||||
char *el;
|
||||
-
|
||||
- if ((el = strpbrk (cp, " \t\n")) != NULL)
|
||||
- *el = '\0';
|
||||
if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL)
|
||||
*el = '\0';
|
||||
if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0))
|
||||
@@ -472,7 +477,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
|
||||
char separator = *cp;
|
||||
*cp = 0;
|
||||
struct resolv_sortlist_entry e;
|
||||
- if (__inet_aton (net, &a))
|
||||
+ if (__inet_aton_exact (net, &a))
|
||||
{
|
||||
e.addr = a;
|
||||
if (is_sort_mask (separator))
|
||||
@@ -484,7 +489,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
|
||||
cp++;
|
||||
separator = *cp;
|
||||
*cp = 0;
|
||||
- if (__inet_aton (net, &a))
|
||||
+ if (__inet_aton_exact (net, &a))
|
||||
e.mask = a.s_addr;
|
||||
else
|
||||
e.mask = net_mask (e.addr);
|
||||
diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c
|
||||
index 08110a007af909ff..eb734d7758d6ed87 100644
|
||||
--- a/resolv/tst-aton.c
|
||||
+++ b/resolv/tst-aton.c
|
||||
@@ -1,11 +1,29 @@
|
||||
+/* Test legacy IPv4 text-to-address function inet_aton.
|
||||
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
-
|
||||
-static struct tests
|
||||
+static const struct tests
|
||||
{
|
||||
const char *input;
|
||||
int valid;
|
||||
@@ -16,6 +34,7 @@ static struct tests
|
||||
{ "-1", 0, 0 },
|
||||
{ "256", 1, 0x00000100 },
|
||||
{ "256.", 0, 0 },
|
||||
+ { "255a", 0, 0 },
|
||||
{ "256a", 0, 0 },
|
||||
{ "0x100", 1, 0x00000100 },
|
||||
{ "0200.0x123456", 1, 0x80123456 },
|
||||
@@ -40,7 +59,12 @@ static struct tests
|
||||
{ "1.2.256.4", 0, 0 },
|
||||
{ "1.2.3.0x100", 0, 0 },
|
||||
{ "323543357756889", 0, 0 },
|
||||
- { "10.1.2.3.4", 0, 0},
|
||||
+ { "10.1.2.3.4", 0, 0 },
|
||||
+ { "192.0.2.1", 1, 0xc0000201 },
|
||||
+ { "192.0.2.2\nX", 1, 0xc0000202 },
|
||||
+ { "192.0.2.3 Y", 1, 0xc0000203 },
|
||||
+ { "192.0.2.3Z", 0, 0 },
|
||||
+ { "192.000.002.010", 1, 0xc0000208 },
|
||||
};
|
||||
|
||||
|
||||
@@ -50,7 +74,7 @@ do_test (void)
|
||||
int result = 0;
|
||||
size_t cnt;
|
||||
|
||||
- for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt)
|
||||
+ for (cnt = 0; cnt < array_length (tests); ++cnt)
|
||||
{
|
||||
struct in_addr addr;
|
||||
|
||||
@@ -73,5 +97,4 @@ do_test (void)
|
||||
return result;
|
||||
}
|
||||
|
||||
-#define TEST_FUNCTION do_test ()
|
||||
-#include "../test-skeleton.c"
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0fdfa3d6aa9aef91
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-inet_aton_exact.c
|
||||
@@ -0,0 +1,47 @@
|
||||
+/* Test internal legacy IPv4 text-to-address function __inet_aton_exact.
|
||||
+ Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <arpa/inet.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct in_addr addr = { };
|
||||
+
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.1", &addr), 1);
|
||||
+ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000201);
|
||||
+
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.000.002.010", &addr), 1);
|
||||
+ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000208);
|
||||
+ TEST_COMPARE (__inet_aton_exact ("0xC0000234", &addr), 1);
|
||||
+ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000234);
|
||||
+
|
||||
+ /* Trailing content is not accepted. */
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.2X", &addr), 0);
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.3 Y", &addr), 0);
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.4\nZ", &addr), 0);
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.5\tT", &addr), 0);
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.6 Y", &addr), 0);
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.7\n", &addr), 0);
|
||||
+ TEST_COMPARE (__inet_aton_exact ("192.0.2.8\t", &addr), 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/resolv/tst-resolv-nondecimal.c b/resolv/tst-resolv-nondecimal.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..a0df6f332ae8faf7
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-resolv-nondecimal.c
|
||||
@@ -0,0 +1,139 @@
|
||||
+/* Test name resolution behavior for octal, hexadecimal IPv4 addresses.
|
||||
+ Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <netdb.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/check_nss.h>
|
||||
+#include <support/resolv_test.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static void
|
||||
+response (const struct resolv_response_context *ctx,
|
||||
+ struct resolv_response_builder *b,
|
||||
+ const char *qname, uint16_t qclass, uint16_t qtype)
|
||||
+{
|
||||
+ /* The tests are not supposed send any DNS queries. */
|
||||
+ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+run_query_addrinfo (const char *query, const char *address)
|
||||
+{
|
||||
+ char *quoted_query = support_quote_string (query);
|
||||
+
|
||||
+ struct addrinfo *ai;
|
||||
+ struct addrinfo hints =
|
||||
+ {
|
||||
+ .ai_socktype = SOCK_STREAM,
|
||||
+ .ai_protocol = IPPROTO_TCP,
|
||||
+ };
|
||||
+
|
||||
+ char *context = xasprintf ("getaddrinfo \"%s\" AF_INET", quoted_query);
|
||||
+ char *expected = xasprintf ("address: STREAM/TCP %s 80\n", address);
|
||||
+ hints.ai_family = AF_INET;
|
||||
+ int ret = getaddrinfo (query, "80", &hints, &ai);
|
||||
+ check_addrinfo (context, ai, ret, expected);
|
||||
+ if (ret == 0)
|
||||
+ freeaddrinfo (ai);
|
||||
+ free (context);
|
||||
+
|
||||
+ context = xasprintf ("getaddrinfo \"%s\" AF_UNSPEC", quoted_query);
|
||||
+ hints.ai_family = AF_UNSPEC;
|
||||
+ ret = getaddrinfo (query, "80", &hints, &ai);
|
||||
+ check_addrinfo (context, ai, ret, expected);
|
||||
+ if (ret == 0)
|
||||
+ freeaddrinfo (ai);
|
||||
+ free (expected);
|
||||
+ free (context);
|
||||
+
|
||||
+ context = xasprintf ("getaddrinfo \"%s\" AF_INET6", quoted_query);
|
||||
+ expected = xasprintf ("flags: AI_V4MAPPED\n"
|
||||
+ "address: STREAM/TCP ::ffff:%s 80\n",
|
||||
+ address);
|
||||
+ hints.ai_family = AF_INET6;
|
||||
+ hints.ai_flags = AI_V4MAPPED;
|
||||
+ ret = getaddrinfo (query, "80", &hints, &ai);
|
||||
+ check_addrinfo (context, ai, ret, expected);
|
||||
+ if (ret == 0)
|
||||
+ freeaddrinfo (ai);
|
||||
+ free (expected);
|
||||
+ free (context);
|
||||
+
|
||||
+ free (quoted_query);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+run_query (const char *query, const char *address)
|
||||
+{
|
||||
+ char *quoted_query = support_quote_string (query);
|
||||
+ char *context = xasprintf ("gethostbyname (\"%s\")", quoted_query);
|
||||
+ char *expected = xasprintf ("name: %s\n"
|
||||
+ "address: %s\n", query, address);
|
||||
+ check_hostent (context, gethostbyname (query), expected);
|
||||
+ free (context);
|
||||
+
|
||||
+ context = xasprintf ("gethostbyname_r \"%s\"", quoted_query);
|
||||
+ struct hostent storage;
|
||||
+ char buf[4096];
|
||||
+ struct hostent *e = NULL;
|
||||
+ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
|
||||
+ &e, &h_errno), 0);
|
||||
+ check_hostent (context, e, expected);
|
||||
+ free (context);
|
||||
+
|
||||
+ context = xasprintf ("gethostbyname2 (\"%s\", AF_INET)", quoted_query);
|
||||
+ check_hostent (context, gethostbyname2 (query, AF_INET), expected);
|
||||
+ free (context);
|
||||
+
|
||||
+ context = xasprintf ("gethostbyname2_r \"%s\" AF_INET", quoted_query);
|
||||
+ e = NULL;
|
||||
+ TEST_COMPARE (gethostbyname2_r (query, AF_INET, &storage, buf, sizeof (buf),
|
||||
+ &e, &h_errno), 0);
|
||||
+ check_hostent (context, e, expected);
|
||||
+ free (context);
|
||||
+ free (expected);
|
||||
+
|
||||
+ free (quoted_query);
|
||||
+
|
||||
+ /* The gethostbyname tests are always valid for getaddrinfo, but not
|
||||
+ vice versa. */
|
||||
+ run_query_addrinfo (query, address);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct resolv_test *aux = resolv_test_start
|
||||
+ ((struct resolv_redirect_config)
|
||||
+ {
|
||||
+ .response_callback = response,
|
||||
+ });
|
||||
+
|
||||
+ run_query ("192.000.002.010", "192.0.2.8");
|
||||
+
|
||||
+ /* Hexadecimal numbers are not accepted by gethostbyname. */
|
||||
+ run_query_addrinfo ("0xc0000210", "192.0.2.16");
|
||||
+ run_query_addrinfo ("192.0x234", "192.0.2.52");
|
||||
+
|
||||
+ resolv_test_end (aux);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/resolv/tst-resolv-trailing.c b/resolv/tst-resolv-trailing.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..7504bdae572ed8d0
|
||||
--- /dev/null
|
||||
+++ b/resolv/tst-resolv-trailing.c
|
||||
@@ -0,0 +1,136 @@
|
||||
+/* Test name resolution behavior with trailing characters.
|
||||
+ Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <netdb.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/check_nss.h>
|
||||
+#include <support/resolv_test.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static void
|
||||
+response (const struct resolv_response_context *ctx,
|
||||
+ struct resolv_response_builder *b,
|
||||
+ const char *qname, uint16_t qclass, uint16_t qtype)
|
||||
+{
|
||||
+ /* The tests are not supposed send any DNS queries. */
|
||||
+ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct resolv_test *aux = resolv_test_start
|
||||
+ ((struct resolv_redirect_config)
|
||||
+ {
|
||||
+ .response_callback = response,
|
||||
+ });
|
||||
+
|
||||
+ static const char *const queries[] =
|
||||
+ {
|
||||
+ "192.0.2.1 ",
|
||||
+ "192.0.2.2\t",
|
||||
+ "192.0.2.3\n",
|
||||
+ "192.0.2.4 X",
|
||||
+ "192.0.2.5\tY",
|
||||
+ "192.0.2.6\nZ",
|
||||
+ "192.0.2. ",
|
||||
+ "192.0.2.\t",
|
||||
+ "192.0.2.\n",
|
||||
+ "192.0.2. X",
|
||||
+ "192.0.2.\tY",
|
||||
+ "192.0.2.\nZ",
|
||||
+ "2001:db8::1 ",
|
||||
+ "2001:db8::2\t",
|
||||
+ "2001:db8::3\n",
|
||||
+ "2001:db8::4 X",
|
||||
+ "2001:db8::5\tY",
|
||||
+ "2001:db8::6\nZ",
|
||||
+ };
|
||||
+ for (size_t query_idx = 0; query_idx < array_length (queries); ++query_idx)
|
||||
+ {
|
||||
+ const char *query = queries[query_idx];
|
||||
+ struct hostent storage;
|
||||
+ char buf[4096];
|
||||
+ struct hostent *e;
|
||||
+
|
||||
+ h_errno = 0;
|
||||
+ TEST_VERIFY (gethostbyname (query) == NULL);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+
|
||||
+ h_errno = 0;
|
||||
+ e = NULL;
|
||||
+ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
|
||||
+ &e, &h_errno), 0);
|
||||
+ TEST_VERIFY (e == NULL);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+
|
||||
+ h_errno = 0;
|
||||
+ TEST_VERIFY (gethostbyname2 (query, AF_INET) == NULL);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+
|
||||
+ h_errno = 0;
|
||||
+ e = NULL;
|
||||
+ TEST_COMPARE (gethostbyname2_r (query, AF_INET,
|
||||
+ &storage, buf, sizeof (buf),
|
||||
+ &e, &h_errno), 0);
|
||||
+ TEST_VERIFY (e == NULL);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+
|
||||
+ h_errno = 0;
|
||||
+ TEST_VERIFY (gethostbyname2 (query, AF_INET6) == NULL);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+
|
||||
+ h_errno = 0;
|
||||
+ e = NULL;
|
||||
+ TEST_COMPARE (gethostbyname2_r (query, AF_INET6,
|
||||
+ &storage, buf, sizeof (buf),
|
||||
+ &e, &h_errno), 0);
|
||||
+ TEST_VERIFY (e == NULL);
|
||||
+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
|
||||
+
|
||||
+ static const int gai_flags[] =
|
||||
+ {
|
||||
+ 0,
|
||||
+ AI_ADDRCONFIG,
|
||||
+ AI_NUMERICHOST,
|
||||
+ AI_IDN,
|
||||
+ AI_IDN | AI_NUMERICHOST,
|
||||
+ AI_V4MAPPED,
|
||||
+ AI_V4MAPPED | AI_NUMERICHOST,
|
||||
+ };
|
||||
+ for (size_t gai_flags_idx; gai_flags_idx < array_length (gai_flags);
|
||||
+ ++gai_flags_idx)
|
||||
+ {
|
||||
+ struct addrinfo hints = { .ai_flags = gai_flags[gai_flags_idx], };
|
||||
+ struct addrinfo *ai;
|
||||
+ hints.ai_family = AF_INET;
|
||||
+ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
|
||||
+ hints.ai_family = AF_INET6;
|
||||
+ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
|
||||
+ hints.ai_family = AF_UNSPEC;
|
||||
+ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ resolv_test_end (aux);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||
index 2c4b6d6793a4c3a9..52f1b590f00c518e 100644
|
||||
--- a/sysdeps/posix/getaddrinfo.c
|
||||
+++ b/sysdeps/posix/getaddrinfo.c
|
||||
@@ -508,7 +508,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
|
||||
+ if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
|
||||
{
|
||||
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
|
||||
at->family = AF_INET;
|
|
@ -0,0 +1,81 @@
|
|||
commit c533244b8e00ae701583ec50aeb43377d292452d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Feb 4 20:07:18 2019 +0100
|
||||
|
||||
nscd: Do not use __inet_aton_exact@GLIBC_PRIVATE [BZ #20018]
|
||||
|
||||
This commit avoids referencing the __inet_aton_exact@GLIBC_PRIVATE
|
||||
symbol from nscd. In master, the separately-compiled getaddrinfo
|
||||
implementation in nscd needs it, however such an internal ABI change
|
||||
is not desirable on a release branch if it can be avoided.
|
||||
|
||||
(Note: This commit was backported from the release/2.28/master branch.)
|
||||
|
||||
diff --git a/nscd/Makefile b/nscd/Makefile
|
||||
index 2dc98d3a3347f998..62f38fa824527e0a 100644
|
||||
--- a/nscd/Makefile
|
||||
+++ b/nscd/Makefile
|
||||
@@ -36,7 +36,7 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
|
||||
getsrvbynm_r getsrvbypt_r servicescache \
|
||||
dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
|
||||
xmalloc xstrdup aicache initgrcache gai res_hconf \
|
||||
- netgroupcache
|
||||
+ netgroupcache nscd-inet_addr
|
||||
|
||||
ifeq ($(build-nscd)$(have-thread-library),yesyes)
|
||||
|
||||
diff --git a/nscd/gai.c b/nscd/gai.c
|
||||
index dbe878fcf699dbc1..e7443904b4514836 100644
|
||||
--- a/nscd/gai.c
|
||||
+++ b/nscd/gai.c
|
||||
@@ -32,6 +32,12 @@
|
||||
/* nscd uses 1MB or 2MB thread stacks. */
|
||||
#define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF)
|
||||
|
||||
+/* We do not want to export __inet_aton_exact. Get the prototype and
|
||||
+ change its visibility to hidden. */
|
||||
+#include <arpa/inet.h>
|
||||
+__typeof__ (__inet_aton_exact) __inet_aton_exact
|
||||
+ __attribute__ ((visibility ("hidden")));
|
||||
+
|
||||
/* We are nscd, so we don't want to be talking to ourselves. */
|
||||
#undef USE_NSCD
|
||||
|
||||
diff --git a/nscd/nscd-inet_addr.c b/nscd/nscd-inet_addr.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..f366b9567d914f99
|
||||
--- /dev/null
|
||||
+++ b/nscd/nscd-inet_addr.c
|
||||
@@ -0,0 +1,32 @@
|
||||
+/* Legacy IPv4 text-to-address functions. Version for nscd.
|
||||
+ Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <arpa/inet.h>
|
||||
+
|
||||
+/* We do not want to export __inet_aton_exact. Get the prototype and
|
||||
+ change the visibility to hidden. */
|
||||
+#include <arpa/inet.h>
|
||||
+__typeof__ (__inet_aton_exact) __inet_aton_exact
|
||||
+ __attribute__ ((visibility ("hidden")));
|
||||
+
|
||||
+/* Do not provide definitions of the public symbols exported from
|
||||
+ libc. */
|
||||
+#undef weak_alias
|
||||
+#define weak_alias(from, to)
|
||||
+
|
||||
+#include <resolv/inet_addr.c>
|
|
@ -0,0 +1,16 @@
|
|||
Adjust resolv/tst-inet_aton_exact to use tests instead of tests-internal.
|
||||
Downstream, tests-internal is currently ignored.
|
||||
|
||||
diff --git a/resolv/Makefile b/resolv/Makefile
|
||||
index 0130a09db2d69451..033c3c651f0deb1b 100644
|
||||
--- a/resolv/Makefile
|
||||
+++ b/resolv/Makefile
|
||||
@@ -34,7 +34,7 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
|
||||
tests = tst-aton tst-leaks tst-inet_ntop
|
||||
xtests = tst-leaks2
|
||||
|
||||
-tests-internal += tst-inet_aton_exact
|
||||
+tests += tst-inet_aton_exact
|
||||
|
||||
|
||||
generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
|
|
@ -0,0 +1,54 @@
|
|||
commit 7c70f2272edd4efcc4525f1bbb50e92de1a27a57
|
||||
Author: Mike Frysinger <vapier@gentoo.org>
|
||||
Date: Thu Jan 30 18:56:56 2014 -0500
|
||||
|
||||
linux: bits/in.h: sync with latest kernel headers
|
||||
|
||||
This pulls in the latest defines for {g,s}etsockopt.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
|
||||
index 022082da1c0ca9f7..ac07d17d0e9dc9c9 100644
|
||||
--- a/sysdeps/unix/sysv/linux/bits/in.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/in.h
|
||||
@@ -98,13 +98,37 @@
|
||||
#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
|
||||
|
||||
#define IP_MINTTL 21
|
||||
-
|
||||
+#define IP_NODEFRAG 22
|
||||
|
||||
/* IP_MTU_DISCOVER arguments. */
|
||||
#define IP_PMTUDISC_DONT 0 /* Never send DF frames. */
|
||||
#define IP_PMTUDISC_WANT 1 /* Use per route hints. */
|
||||
#define IP_PMTUDISC_DO 2 /* Always DF. */
|
||||
#define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu. */
|
||||
+/* Always use interface mtu (ignores dst pmtu) but don't set DF flag.
|
||||
+ Also incoming ICMP frag_needed notifications will be ignored on
|
||||
+ this socket to prevent accepting spoofed ones. */
|
||||
+#define IP_PMTUDISC_INTERFACE 4
|
||||
+
|
||||
+#define IP_MULTICAST_IF 32
|
||||
+#define IP_MULTICAST_TTL 33
|
||||
+#define IP_MULTICAST_LOOP 34
|
||||
+#define IP_ADD_MEMBERSHIP 35
|
||||
+#define IP_DROP_MEMBERSHIP 36
|
||||
+#define IP_UNBLOCK_SOURCE 37
|
||||
+#define IP_BLOCK_SOURCE 38
|
||||
+#define IP_ADD_SOURCE_MEMBERSHIP 39
|
||||
+#define IP_DROP_SOURCE_MEMBERSHIP 40
|
||||
+#define IP_MSFILTER 41
|
||||
+#define MCAST_JOIN_GROUP 42
|
||||
+#define MCAST_BLOCK_SOURCE 43
|
||||
+#define MCAST_UNBLOCK_SOURCE 44
|
||||
+#define MCAST_LEAVE_GROUP 45
|
||||
+#define MCAST_JOIN_SOURCE_GROUP 46
|
||||
+#define MCAST_LEAVE_SOURCE_GROUP 47
|
||||
+#define MCAST_MSFILTER 48
|
||||
+#define IP_MULTICAST_ALL 49
|
||||
+#define IP_UNICAST_IF 50
|
||||
|
||||
/* To select the IP level. */
|
||||
#define SOL_IP 0
|
|
@ -0,0 +1,49 @@
|
|||
commit 76e5216e317f39da2bc5bf905721cd9554ee6d09
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Mon Jun 23 15:48:42 2014 +0000
|
||||
|
||||
Update headers for Linux 3.15.
|
||||
|
||||
This patch updates glibc headers for changes / new definitions in
|
||||
Linux 3.15. In the course of my review I noticed that
|
||||
IPV6_PMTUDISC_INTERFACE was absent from glibc despite the inclusion of
|
||||
IP_PMTUDISC_INTERFACE; I added it along with IP_PMTUDISC_OMIT and
|
||||
IPV6_PMTUDISC_OMIT. I did not add FALLOC_FL_NO_HIDE_STALE given the
|
||||
kernel header comment that it is reserved.
|
||||
|
||||
Tested x86_64.
|
||||
|
||||
* sysdeps/unix/sysv/linux/bits/fcntl-linux.h [__USE_GNU]
|
||||
(FALLOC_FL_COLLAPSE_RANGE): New macro.
|
||||
[__USE_GNU] (FALLOC_FL_ZERO_RANGE): Likewise.
|
||||
* sysdeps/unix/sysv/linux/bits/in.h (IP_PMTUDISC_OMIT): Likewise.
|
||||
(IPV6_PMTUDISC_INTERFACE): Likewise.
|
||||
(IPV6_PMTUDISC_OMIT): Likewise.
|
||||
|
||||
Only the sysdeps/unix/sysv/linux/bits/in.h part is backported in this
|
||||
patch. The sysdeps/unix/sysv/linux/bits/fcntl-linux.h part was
|
||||
completely superseded by glibc-rh1476120.patch, which uses
|
||||
<linux/falloc.h> in favor of duplicated constants.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
|
||||
index ac07d17d0e9dc9c9..23046d3b5a6b0d91 100644
|
||||
--- a/sysdeps/unix/sysv/linux/bits/in.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/in.h
|
||||
@@ -109,6 +109,8 @@
|
||||
Also incoming ICMP frag_needed notifications will be ignored on
|
||||
this socket to prevent accepting spoofed ones. */
|
||||
#define IP_PMTUDISC_INTERFACE 4
|
||||
+/* Like IP_PMTUDISC_INTERFACE but allow packets to be fragmented. */
|
||||
+#define IP_PMTUDISC_OMIT 5
|
||||
|
||||
#define IP_MULTICAST_IF 32
|
||||
#define IP_MULTICAST_TTL 33
|
||||
@@ -224,6 +226,8 @@ struct in_pktinfo
|
||||
#define IPV6_PMTUDISC_WANT 1 /* Use per route hints. */
|
||||
#define IPV6_PMTUDISC_DO 2 /* Always DF. */
|
||||
#define IPV6_PMTUDISC_PROBE 3 /* Ignore dst pmtu. */
|
||||
+#define IPV6_PMTUDISC_INTERFACE 4 /* See IP_PMTUDISC_INTERFACE. */
|
||||
+#define IPV6_PMTUDISC_OMIT 5 /* See IP_PMTUDISC_OMIT. */
|
||||
|
||||
/* Socket level values for IPv6. */
|
||||
#define SOL_IPV6 41
|
|
@ -0,0 +1,46 @@
|
|||
commit ac64195ccd4f320659fd0058bc7524c6fd0b37b4
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Wed Mar 20 23:56:59 2019 -0400
|
||||
|
||||
iconv, localedef: avoid floating point rounding differences [BZ #24372]
|
||||
|
||||
Two cases of "int * 1.4" may result in imprecise results, which
|
||||
in at least one case resulted in i686 and x86-64 producing
|
||||
different locale files. This replaced that floating point multiply
|
||||
with integer operations. While the hash table margin is increased
|
||||
from 40% to 50%, testing shows only 2% increase in overall size
|
||||
of the locale archive.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1311954
|
||||
|
||||
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
|
||||
index 0201450..1e6066c 100644
|
||||
--- a/iconv/iconvconfig.c
|
||||
+++ b/iconv/iconvconfig.c
|
||||
@@ -1079,9 +1079,9 @@ write_output (void)
|
||||
|
||||
/* Create the hashing table. We know how many strings we have.
|
||||
Creating a perfect hash table is not reasonable here. Therefore
|
||||
- we use open hashing and a table size which is the next prime 40%
|
||||
+ we use open hashing and a table size which is the next prime 50%
|
||||
larger than the number of strings. */
|
||||
- hash_size = next_prime (nnames * 1.4);
|
||||
+ hash_size = next_prime (nnames + nnames >> 1);
|
||||
hash_table = (struct hash_entry *) xcalloc (hash_size,
|
||||
sizeof (struct hash_entry));
|
||||
/* Fill the hash table. */
|
||||
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
|
||||
index bb4e2c5..19b23c2 100644
|
||||
--- a/locale/programs/ld-collate.c
|
||||
+++ b/locale/programs/ld-collate.c
|
||||
@@ -2401,8 +2401,8 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
|
||||
runp = runp->next;
|
||||
}
|
||||
- /* Add 40% and find the next prime number. */
|
||||
- elem_size = next_prime (elem_size * 1.4);
|
||||
+ /* Add 50% and find the next prime number. */
|
||||
+ elem_size = next_prime (elem_size + elem_size >> 1);
|
||||
|
||||
/* Allocate the table. Each entry consists of two words: the hash
|
||||
value and an index in a secondary table which provides the index
|
|
@ -0,0 +1,47 @@
|
|||
commit 5abcddd7949270998c6e8d99fdbbba821b664f8b
|
||||
Author: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
|
||||
Date: Thu Mar 21 17:24:30 2019 -0300
|
||||
|
||||
Fix parentheses error in iconvconfig.c and ld-collate.c [BZ #24372]
|
||||
|
||||
When -Werror=parentheses is in use, iconvconfig.c builds fail with:
|
||||
|
||||
iconvconfig.c: In function ‘write_output’:
|
||||
iconvconfig.c:1084:34: error: suggest parentheses around ‘+’ inside ‘>>’ [-Werror=parentheses]
|
||||
hash_size = next_prime (nnames + nnames >> 1);
|
||||
~~~~~~~^~~~~~~~
|
||||
|
||||
This patch adds parentheses to the expression. Not where suggested by
|
||||
the compiler warning, but where it produces the expected result, i.e.:
|
||||
where it has the effect of multiplying nnames by 1.5.
|
||||
|
||||
Likewise for elem_size in ld-collate.c.
|
||||
|
||||
Tested for powerpc64le.
|
||||
|
||||
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
|
||||
index 1e6066c..f75e46d 100644
|
||||
--- a/iconv/iconvconfig.c
|
||||
+++ b/iconv/iconvconfig.c
|
||||
@@ -1081,7 +1081,7 @@ write_output (void)
|
||||
Creating a perfect hash table is not reasonable here. Therefore
|
||||
we use open hashing and a table size which is the next prime 50%
|
||||
larger than the number of strings. */
|
||||
- hash_size = next_prime (nnames + nnames >> 1);
|
||||
+ hash_size = next_prime (nnames + (nnames >> 1));
|
||||
hash_table = (struct hash_entry *) xcalloc (hash_size,
|
||||
sizeof (struct hash_entry));
|
||||
/* Fill the hash table. */
|
||||
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
|
||||
index 19b23c2..6baab6c 100644
|
||||
--- a/locale/programs/ld-collate.c
|
||||
+++ b/locale/programs/ld-collate.c
|
||||
@@ -2402,7 +2402,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
|
||||
runp = runp->next;
|
||||
}
|
||||
/* Add 50% and find the next prime number. */
|
||||
- elem_size = next_prime (elem_size + elem_size >> 1);
|
||||
+ elem_size = next_prime (elem_size + (elem_size >> 1));
|
||||
|
||||
/* Allocate the table. Each entry consists of two words: the hash
|
||||
value and an index in a secondary table which provides the index
|
|
@ -0,0 +1,32 @@
|
|||
commit 99135114ba23c3110b7e4e650fabdc5e639746b7
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Fri Jun 28 18:30:00 2019 -0500
|
||||
|
||||
nss_db: fix endent wrt NULL mappings [BZ #24695] [BZ #24696]
|
||||
|
||||
nss_db allows for getpwent et al to be called without a set*ent,
|
||||
but it only works once. After the last get*ent a set*ent is
|
||||
required to restart, because the end*ent did not properly reset
|
||||
the module. Resetting it to NULL allows for a proper restart.
|
||||
|
||||
If the database doesn't exist, however, end*ent erroniously called
|
||||
munmap which set errno.
|
||||
|
||||
Note: the test case has not been included in this backport as the
|
||||
required test harness infrastructure does not exist.
|
||||
|
||||
diff --git a/nss/nss_db/db-open.c b/nss/nss_db/db-open.c
|
||||
index 8a83d6b..3fa11e9 100644
|
||||
--- a/nss/nss_db/db-open.c
|
||||
+++ b/nss/nss_db/db-open.c
|
||||
@@ -63,5 +63,9 @@ internal_setent (const char *file, struct nss_db_map *mapping)
|
||||
void
|
||||
internal_endent (struct nss_db_map *mapping)
|
||||
{
|
||||
- munmap (mapping->header, mapping->len);
|
||||
+ if (mapping->header != NULL)
|
||||
+ {
|
||||
+ munmap (mapping->header, mapping->len);
|
||||
+ mapping->header = NULL;
|
||||
+ }
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
commit 08b7e9988272113ca5640cf5e115ea51449fb392
|
||||
Author: Ian Kent <ikent@redhat.com>
|
||||
Date: Mon Sep 2 13:26:14 2019 +0200
|
||||
|
||||
Use autofs "ignore" mount hint in getmntent_r/getmntent
|
||||
|
||||
Historically autofs mounts were not included in mount table
|
||||
listings. This is the case in other SysV autofs implementations
|
||||
and was also the case with Linux autofs.
|
||||
|
||||
But now that /etc/mtab is a symlink to the proc filesystem
|
||||
mount table the autofs mount entries appear in the mount table
|
||||
on Linux.
|
||||
|
||||
Prior to the symlinking of /etc/mtab mount table it was
|
||||
sufficient to call mount(2) and simply not update /etc/mtab
|
||||
to exclude autofs mounts from mount listings.
|
||||
|
||||
Also, with the symlinking of /etc/mtab we have seen a shift in
|
||||
usage toward using the proc mount tables directly.
|
||||
|
||||
But the autofs mount entries need to be retained when coming
|
||||
from the proc file system for applications that need them
|
||||
(largely autofs file system users themselves) so filtering out
|
||||
these entries within the kernel itself can't be done. So it
|
||||
needs be done in user space.
|
||||
|
||||
There are three reasons to omit the autofs mount entries.
|
||||
|
||||
One is that certain types of auto-mounts have an autofs mount
|
||||
for every entry in their autofs mount map and these maps can
|
||||
be quite large. This leads to mount table listings containing
|
||||
a lot of unnecessary entries.
|
||||
|
||||
Also, this change in behaviour between autofs implementations
|
||||
can cause problems for applications that use getmntent(3) in
|
||||
other OS implementations as well as Linux.
|
||||
|
||||
Lastly, there's very little that user space can do with autofs
|
||||
mount entries since this must be left to the autofs mount owner,
|
||||
typically the automount daemon. But it can also lead to attempts
|
||||
to access automount managed paths resulting mounts being triggered
|
||||
when they aren't needed or mounts staying mounted for much longer
|
||||
thay they need be. While the point of this change ins't to help
|
||||
with these problems (and it can be quite a problem) it may be
|
||||
a welcome side effect.
|
||||
|
||||
So the Linux autofs file system has been modified to accept a
|
||||
pseudo mount option of "ignore" (as is used in other OS
|
||||
implementations) so that user space can use this as a hint to
|
||||
skip autofs entries on reading the mount table.
|
||||
|
||||
The Linux autofs automount daemon used getmntent(3) itself and
|
||||
has been modified to use the proc file system directly so that
|
||||
it can "ignore" mount option.
|
||||
|
||||
The use of this mount option is opt-in and a configuration
|
||||
option has been added which defaults to not use this option
|
||||
so if there are applications that need these entries, other
|
||||
than autofs itself, they can be retained. Also, since this
|
||||
filtering is based on an added mount option earlier versions
|
||||
of Linux autofs iand other autofs file system users will not
|
||||
use the option and so won't be affected by the change.
|
||||
|
||||
diff -rup a/misc/mntent_r.c b/misc/mntent_r.c
|
||||
--- a/misc/mntent_r.c 2012-12-24 22:02:13.000000000 -0500
|
||||
+++ b/misc/mntent_r.c 2020-01-20 15:55:23.417838854 -0500
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <alloca.h>
|
||||
#include <mntent.h>
|
||||
+#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <string.h>
|
||||
@@ -112,26 +113,18 @@ decode_name (char *buf)
|
||||
return buf;
|
||||
}
|
||||
|
||||
-
|
||||
-/* Read one mount table entry from STREAM. Returns a pointer to storage
|
||||
- reused on the next call, or null for EOF or error (use feof/ferror to
|
||||
- check). */
|
||||
-struct mntent *
|
||||
-__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
|
||||
+static bool
|
||||
+get_mnt_entry (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
|
||||
{
|
||||
char *cp;
|
||||
char *head;
|
||||
|
||||
- flockfile (stream);
|
||||
do
|
||||
{
|
||||
char *end_ptr;
|
||||
|
||||
if (fgets_unlocked (buffer, bufsiz, stream) == NULL)
|
||||
- {
|
||||
- funlockfile (stream);
|
||||
- return NULL;
|
||||
- }
|
||||
+ return false;
|
||||
|
||||
end_ptr = strchr (buffer, '\n');
|
||||
if (end_ptr != NULL) /* chop newline */
|
||||
@@ -173,9 +166,40 @@ __getmntent_r (FILE *stream, struct mnte
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/* Read one mount table entry from STREAM. Returns a pointer to storage
|
||||
+ reused on the next call, or null for EOF or error (use feof/ferror to
|
||||
+ check). */
|
||||
+struct mntent *
|
||||
+__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
|
||||
+{
|
||||
+ struct mntent *result;
|
||||
+
|
||||
+ flockfile (stream);
|
||||
+ while (true)
|
||||
+ if (get_mnt_entry (stream, mp, buffer, bufsiz))
|
||||
+ {
|
||||
+ /* If the file system is autofs look for a mount option hint
|
||||
+ ("ignore") to skip the entry. */
|
||||
+ if (strcmp (mp->mnt_type, "autofs") == 0 && __hasmntopt (mp, "ignore"))
|
||||
+ memset (mp, 0, sizeof (*mp));
|
||||
+ else
|
||||
+ {
|
||||
+ result = mp;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ result = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
funlockfile (stream);
|
||||
|
||||
- return mp;
|
||||
+ return result;
|
||||
}
|
||||
libc_hidden_def (__getmntent_r)
|
||||
weak_alias (__getmntent_r, getmntent_r)
|
|
@ -0,0 +1,164 @@
|
|||
commit 9a1e7257a4292d3aea45c8317df3956f4331d8ce
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Sep 2 12:40:38 2019 +0200
|
||||
|
||||
Add misc/tst-mntent-autofs, testing autofs "ignore" filtering
|
||||
|
||||
diff -rupN a/misc/Makefile b/misc/Makefile
|
||||
--- a/misc/Makefile 2020-01-20 15:48:16.472243494 -0500
|
||||
+++ b/misc/Makefile 2020-01-20 16:03:01.291550472 -0500
|
||||
@@ -76,7 +76,8 @@ install-lib := libbsd-compat.a libg.a
|
||||
gpl2lgpl := error.c error.h
|
||||
|
||||
tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
|
||||
- tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 bug18240
|
||||
+ tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 bug18240 \
|
||||
+ tst-mntent-autofs
|
||||
ifeq ($(run-built-tests),yes)
|
||||
tests: $(objpfx)tst-error1-mem
|
||||
endif
|
||||
diff -rupN a/misc/tst-mntent-autofs.c b/misc/tst-mntent-autofs.c
|
||||
--- a/misc/tst-mntent-autofs.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ b/misc/tst-mntent-autofs.c 2020-01-20 16:01:37.233483270 -0500
|
||||
@@ -0,0 +1,141 @@
|
||||
+/* Test autofs "ignore" filtering for getment_r.
|
||||
+ Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <errno.h>
|
||||
+#include <mntent.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/temp_file.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+struct test_case
|
||||
+{
|
||||
+ const char *line;
|
||||
+ struct
|
||||
+ {
|
||||
+ /* Like struct mntent, but with const pointers. */
|
||||
+ const char *mnt_fsname;
|
||||
+ const char *mnt_dir;
|
||||
+ const char *mnt_type;
|
||||
+ const char *mnt_opts;
|
||||
+ int mnt_freq;
|
||||
+ int mnt_passno;
|
||||
+ } expected;
|
||||
+};
|
||||
+
|
||||
+static struct test_case test_cases[] =
|
||||
+ {
|
||||
+ { "/etc/auto.direct /mnt/auto/1 autofs defaults 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/1", "autofs", "defaults", 0, 0 } },
|
||||
+
|
||||
+ /* These entries are filtered out. */
|
||||
+ { "/etc/auto.2 /mnt/auto/2 autofs ignore 0 0", { NULL, } },
|
||||
+ { "/etc/auto.3 /mnt/auto/3 autofs ignore,other 1 2", { NULL, } },
|
||||
+ { "/etc/auto.4 /mnt/auto/4 autofs other,ignore 3 4", { NULL, } },
|
||||
+ { "/etc/auto.5 /mnt/auto/5 autofs opt1,ignore,opt2 5 6", { NULL, } },
|
||||
+
|
||||
+ /* Dummy entry to make the desynchronization more obvious. */
|
||||
+ { "/dev/sda1 / xfs defaults 0 0",
|
||||
+ { "/dev/sda1", "/", "xfs", "defaults", 0, 0 } },
|
||||
+
|
||||
+ /* These are not filtered because the file system is not autofs. */
|
||||
+ { "/etc/auto.direct /mnt/auto/6 autofs1 ignore 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/6", "autofs1", "ignore", 0, 0 } },
|
||||
+ { "/etc/auto.direct /mnt/auto/7 autofs1 ignore,other 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/7", "autofs1", "ignore,other", 0, 0 } },
|
||||
+ { "/etc/auto.direct /mnt/auto/8 autofs1 other,ignore 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/8", "autofs1", "other,ignore", 0, 0 } },
|
||||
+ { "/etc/auto.direct /mnt/auto/9 autofs1 opt1,ignore,opt2 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/9", "autofs1", "opt1,ignore,opt2", } },
|
||||
+
|
||||
+ /* These are not filtered because the string "ignore" is not an
|
||||
+ option name. */
|
||||
+ { "/etc/auto.direct /mnt/auto/10 autofs noignore 1 2",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/10", "autofs", "noignore", 1, 2 } },
|
||||
+ { "/etc/auto.direct /mnt/auto/11 autofs noignore,other 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/11", "autofs", "noignore,other", } },
|
||||
+ { "/etc/auto.direct /mnt/auto/12 autofs other,noignore 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/12", "autofs", "other,noignore", } },
|
||||
+ { "/etc/auto.direct /mnt/auto/13 autofs errors=ignore 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/13", "autofs", "errors=ignore", } },
|
||||
+ { "/etc/auto.direct /mnt/auto/14 autofs errors=ignore,other 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/14", "autofs",
|
||||
+ "errors=ignore,other", } },
|
||||
+ { "/etc/auto.direct /mnt/auto/15 autofs other,errors=ignore 0 0",
|
||||
+ { "/etc/auto.direct", "/mnt/auto/15", "autofs",
|
||||
+ "other,errors=ignore", } },
|
||||
+
|
||||
+ /* These are not filtered because the string is escaped. '\151'
|
||||
+ is 'i', but it is not actually decoded by the parser. */
|
||||
+ { "/etc/auto.\\151gnore /mnt/auto/16 autofs \\151gnore 0 0",
|
||||
+ { "/etc/auto.\\151gnore", "/mnt/auto/16", "autofs",
|
||||
+ "\\151gnore", } },
|
||||
+ };
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *path;
|
||||
+ xclose (create_temp_file ("tst-mntent-autofs-", &path));
|
||||
+
|
||||
+ /* Write the test file. */
|
||||
+ FILE *fp = xfopen (path, "w");
|
||||
+ for (size_t i = 0; i < array_length (test_cases); ++i)
|
||||
+ fprintf (fp, "%s\n", test_cases[i].line);
|
||||
+ xfclose (fp);
|
||||
+
|
||||
+ /* Open the test file again, this time for parsing. */
|
||||
+ fp = setmntent (path, "r");
|
||||
+ TEST_VERIFY_EXIT (fp != NULL);
|
||||
+ char buffer[512];
|
||||
+ struct mntent me;
|
||||
+
|
||||
+ for (size_t i = 0; i < array_length (test_cases); ++i)
|
||||
+ {
|
||||
+ if (test_cases[i].expected.mnt_type == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ memset (buffer, 0xcc, sizeof (buffer));
|
||||
+ memset (&me, 0xcc, sizeof (me));
|
||||
+ struct mntent *pme = getmntent_r (fp, &me, buffer, sizeof (buffer));
|
||||
+ TEST_VERIFY_EXIT (pme != NULL);
|
||||
+ TEST_VERIFY (pme == &me);
|
||||
+ TEST_COMPARE_STRING (test_cases[i].expected.mnt_fsname, me.mnt_fsname);
|
||||
+ TEST_COMPARE_STRING (test_cases[i].expected.mnt_dir, me.mnt_dir);
|
||||
+ TEST_COMPARE_STRING (test_cases[i].expected.mnt_type, me.mnt_type);
|
||||
+ TEST_COMPARE_STRING (test_cases[i].expected.mnt_opts, me.mnt_opts);
|
||||
+ TEST_COMPARE (test_cases[i].expected.mnt_freq, me.mnt_freq);
|
||||
+ TEST_COMPARE (test_cases[i].expected.mnt_passno, me.mnt_passno);
|
||||
+ }
|
||||
+
|
||||
+ TEST_VERIFY (getmntent_r (fp, &me, buffer, sizeof (buffer)) == NULL);
|
||||
+
|
||||
+ TEST_COMPARE (feof (fp), 1);
|
||||
+ TEST_COMPARE (ferror (fp), 0);
|
||||
+ errno = 0;
|
||||
+ TEST_COMPARE (endmntent (fp), 1);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ free (path);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,160 @@
|
|||
Partial backport of:
|
||||
|
||||
commit a42faf59d6d9f82e5293a9ebcc26d9c9e562b12b
|
||||
Author: Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||
Date: Mon Mar 24 10:58:26 2014 -0700
|
||||
|
||||
Fix BZ #16634.
|
||||
|
||||
An application that erroneously tries to repeatedly dlopen("a.out", ...)
|
||||
may hit assertion failure:
|
||||
|
||||
Inconsistency detected by ld.so: dl-tls.c: 474: _dl_allocate_tls_init:
|
||||
Assertion `listp != ((void *)0)' failed!
|
||||
|
||||
dlopen() actually fails with "./a.out: cannot dynamically load executable",
|
||||
but it does so after incrementing dl_tls_max_dtv_idx.
|
||||
|
||||
Once we run out of TLS_SLOTINFO_SURPLUS (62), we exit with above assertion
|
||||
failure.
|
||||
|
||||
2014-03-24 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||
|
||||
[BZ #16634]
|
||||
|
||||
* elf/dl-load.c (open_verify): Add mode parameter.
|
||||
Error early when ET_EXEC and mode does not have __RTLD_OPENEXEC.
|
||||
(open_path): Change from boolean 'secure' to complete flag 'mode'
|
||||
(_dl_map_object): Adjust.
|
||||
* elf/Makefile (tests): Add tst-dlopen-aout.
|
||||
* elf/tst-dlopen-aout.c: New test.
|
||||
|
||||
Only the change to elf/dl-load.c is included here. The upstream test
|
||||
does not work because it depends on --enable-hardcoded-path-in-tests
|
||||
(which is not available in this tree, despite being documented in the
|
||||
manual).
|
||||
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 6a0005da502c8f37..0ba0712aa5201fa0 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1686,7 +1686,7 @@ print_search_path (struct r_search_path_elem **list,
|
||||
user might want to know about this. */
|
||||
static int
|
||||
open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
||||
- int whatcode, bool *found_other_class, bool free_name)
|
||||
+ int whatcode, int mode, bool *found_other_class, bool free_name)
|
||||
{
|
||||
/* This is the expected ELF header. */
|
||||
#define ELF32_CLASS ELFCLASS32
|
||||
@@ -1863,6 +1863,17 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
||||
errstring = N_("only ET_DYN and ET_EXEC can be loaded");
|
||||
goto call_lose;
|
||||
}
|
||||
+ else if (__glibc_unlikely (ehdr->e_type == ET_EXEC
|
||||
+ && (mode & __RTLD_OPENEXEC) == 0))
|
||||
+ {
|
||||
+ /* BZ #16634. It is an error to dlopen ET_EXEC (unless
|
||||
+ __RTLD_OPENEXEC is explicitly set). We return error here
|
||||
+ so that code in _dl_map_object_from_fd does not try to set
|
||||
+ l_tls_modid for this module. */
|
||||
+
|
||||
+ errstring = N_("cannot dynamically load executable");
|
||||
+ goto call_lose;
|
||||
+ }
|
||||
else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr)))
|
||||
!= sizeof (ElfW(Phdr)))
|
||||
{
|
||||
@@ -1964,7 +1975,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
||||
if MAY_FREE_DIRS is true. */
|
||||
|
||||
static int
|
||||
-open_path (const char *name, size_t namelen, int secure,
|
||||
+open_path (const char *name, size_t namelen, int mode,
|
||||
struct r_search_path_struct *sps, char **realname,
|
||||
struct filebuf *fbp, struct link_map *loader, int whatcode,
|
||||
bool *found_other_class)
|
||||
@@ -2016,8 +2027,8 @@ open_path (const char *name, size_t namelen, int secure,
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
|
||||
_dl_debug_printf (" trying file=%s\n", buf);
|
||||
|
||||
- fd = open_verify (buf, fbp, loader, whatcode, found_other_class,
|
||||
- false);
|
||||
+ fd = open_verify (buf, fbp, loader, whatcode, mode,
|
||||
+ found_other_class, false);
|
||||
if (this_dir->status[cnt] == unknown)
|
||||
{
|
||||
if (fd != -1)
|
||||
@@ -2046,7 +2057,7 @@ open_path (const char *name, size_t namelen, int secure,
|
||||
/* Remember whether we found any existing directory. */
|
||||
here_any |= this_dir->status[cnt] != nonexisting;
|
||||
|
||||
- if (fd != -1 && __builtin_expect (secure, 0)
|
||||
+ if (fd != -1 && __builtin_expect (mode & __RTLD_SECURE, 0)
|
||||
&& INTUSE(__libc_enable_secure))
|
||||
{
|
||||
/* This is an extra security effort to make sure nobody can
|
||||
@@ -2236,7 +2247,7 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
for (l = loader; l; l = l->l_loader)
|
||||
if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
|
||||
{
|
||||
- fd = open_path (name, namelen, mode & __RTLD_SECURE,
|
||||
+ fd = open_path (name, namelen, mode,
|
||||
&l->l_rpath_dirs,
|
||||
&realname, &fb, loader, LA_SER_RUNPATH,
|
||||
&found_other_class);
|
||||
@@ -2252,7 +2263,7 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
&& main_map != NULL && main_map->l_type != lt_loaded
|
||||
&& cache_rpath (main_map, &main_map->l_rpath_dirs, DT_RPATH,
|
||||
"RPATH"))
|
||||
- fd = open_path (name, namelen, mode & __RTLD_SECURE,
|
||||
+ fd = open_path (name, namelen, mode,
|
||||
&main_map->l_rpath_dirs,
|
||||
&realname, &fb, loader ?: main_map, LA_SER_RUNPATH,
|
||||
&found_other_class);
|
||||
@@ -2260,7 +2271,7 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
|
||||
/* Try the LD_LIBRARY_PATH environment variable. */
|
||||
if (fd == -1 && env_path_list.dirs != (void *) -1)
|
||||
- fd = open_path (name, namelen, mode & __RTLD_SECURE, &env_path_list,
|
||||
+ fd = open_path (name, namelen, mode, &env_path_list,
|
||||
&realname, &fb,
|
||||
loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded,
|
||||
LA_SER_LIBPATH, &found_other_class);
|
||||
@@ -2269,7 +2280,7 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
if (fd == -1 && loader != NULL
|
||||
&& cache_rpath (loader, &loader->l_runpath_dirs,
|
||||
DT_RUNPATH, "RUNPATH"))
|
||||
- fd = open_path (name, namelen, mode & __RTLD_SECURE,
|
||||
+ fd = open_path (name, namelen, mode,
|
||||
&loader->l_runpath_dirs, &realname, &fb, loader,
|
||||
LA_SER_RUNPATH, &found_other_class);
|
||||
|
||||
@@ -2326,7 +2337,8 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
{
|
||||
fd = open_verify (cached,
|
||||
&fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
|
||||
- LA_SER_CONFIG, &found_other_class, false);
|
||||
+ LA_SER_CONFIG, mode, &found_other_class,
|
||||
+ false);
|
||||
if (__builtin_expect (fd != -1, 1))
|
||||
realname = cached;
|
||||
else
|
||||
@@ -2341,7 +2353,7 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
&& ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
|
||||
|| __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
|
||||
&& rtld_search_dirs.dirs != (void *) -1)
|
||||
- fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs,
|
||||
+ fd = open_path (name, namelen, mode, &rtld_search_dirs,
|
||||
&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
|
||||
|
||||
/* Add another newline when we are tracing the library loading. */
|
||||
@@ -2359,7 +2371,7 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||
else
|
||||
{
|
||||
fd = open_verify (realname, &fb,
|
||||
- loader ?: GL(dl_ns)[nsid]._ns_loaded, 0,
|
||||
+ loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode,
|
||||
&found_other_class, true);
|
||||
if (__builtin_expect (fd, 0) == -1)
|
||||
free (realname);
|
|
@ -0,0 +1,174 @@
|
|||
Partial backport of:
|
||||
|
||||
commit 7d3db434f910c23591f748a6d0ac3548af1048bb
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Oct 17 08:51:21 2019 +0200
|
||||
|
||||
Rename and split elf/tst-dlopen-aout collection of tests
|
||||
|
||||
From the beginning, elf/tst-dlopen-aout has exercised two different
|
||||
bugs: (a) failure to report errors for a dlopen of the executable
|
||||
itself in some cases (bug 24900) and (b) incorrect rollback of the
|
||||
TLS modid allocation in case of a dlopen failure (bug 16634).
|
||||
|
||||
This commit replaces the test with elf/tst-dlopen-self for (a) and
|
||||
elf/tst-dlopen-tlsmodid for (b). The latter tests use the
|
||||
elf/tst-dlopen-self binaries (or iconv) with dlopen, so they are
|
||||
no longer self-dlopen tests.
|
||||
|
||||
Tested on x86_64-linux-gnu and i686-linux-gnu, with a toolchain that
|
||||
does not default to PIE.
|
||||
|
||||
Only the non-PIE, non-container test elf/tst-dlopen-tlsmodid is
|
||||
included. The reason is that the self-dlopen fixes and the PIE TLS
|
||||
modid fix have not been backported, and that container testing support
|
||||
is missing downstream. The test binary is adjusted to tst-tls10
|
||||
because tst-dlopen-self does not exist in the backport.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index cfd039fc9dfb0be7..c22008b54afc91f5 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -153,7 +153,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
tst-stackguard1 tst-addr1 tst-thrlock \
|
||||
tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
|
||||
tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1 \
|
||||
- tst-big-note
|
||||
+ tst-big-note tst-dlopen-tlsmodid
|
||||
# reldep9
|
||||
test-srcs = tst-pathopt
|
||||
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
|
||||
@@ -1101,6 +1101,9 @@ $(objpfx)tst-addr1: $(libdl)
|
||||
|
||||
$(objpfx)tst-thrlock: $(libdl) $(shared-thread-library)
|
||||
|
||||
+$(objpfx)tst-dlopen-tlsmodid: $(libdl) $(shared-thread-library)
|
||||
+$(objpfx)tst-dlopen-tlsmodid.out: $(objpfx)tst-tls10
|
||||
+
|
||||
CFLAGS-ifuncmain1pic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain1picstatic.c += $(pic-ccflag)
|
||||
CFLAGS-ifuncmain1staticpic.c += $(pic-ccflag)
|
||||
diff --git a/elf/tst-dlopen-tlsmodid.c b/elf/tst-dlopen-tlsmodid.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..c5b1c39369aa610c
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-dlopen-tlsmodid.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Test case for BZ #16634. Non-PIE version.
|
||||
+
|
||||
+ Verify that incorrectly dlopen()ing an executable without
|
||||
+ __RTLD_OPENEXEC does not cause assertion in ld.so, and that it
|
||||
+ actually results in an error.
|
||||
+
|
||||
+ Copyright (C) 2014-2019 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/>. */
|
||||
+
|
||||
+#define TST_DLOPEN_TLSMODID_PATH "tst-tls10"
|
||||
+#include "tst-dlopen-tlsmodid.h"
|
||||
diff --git a/elf/tst-dlopen-tlsmodid.h b/elf/tst-dlopen-tlsmodid.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..c747cb14911c72fa
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-dlopen-tlsmodid.h
|
||||
@@ -0,0 +1,87 @@
|
||||
+/* Common code for tst-dlopen-tlsmodid, tst-dlopen-tlsmodid-pie,
|
||||
+ tst-dlopen-tlsmodid-container.
|
||||
+
|
||||
+ Verify that incorrectly dlopen()ing an executable without
|
||||
+ __RTLD_OPENEXEC does not cause assertion in ld.so, and that it
|
||||
+ actually results in an error.
|
||||
+
|
||||
+ Copyright (C) 2014-2019 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/>. */
|
||||
+
|
||||
+/* Before including this file, the macro TST_DLOPEN_TLSMODID_PATH must
|
||||
+ be defined, to specify the path used for the open operation. */
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+#include <pthread.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xthread.h>
|
||||
+
|
||||
+__thread int x;
|
||||
+
|
||||
+void *
|
||||
+fn (void *p)
|
||||
+{
|
||||
+ return p;
|
||||
+}
|
||||
+
|
||||
+/* Call dlopen and check that fails with an error message indicating
|
||||
+ an attempt to open an ET_EXEC or PIE object. */
|
||||
+static void
|
||||
+check_dlopen_failure (void)
|
||||
+{
|
||||
+ void *handle = dlopen (TST_DLOPEN_TLSMODID_PATH, RTLD_LAZY);
|
||||
+ if (handle != NULL)
|
||||
+ FAIL_EXIT1 ("dlopen succeeded unexpectedly: %s", TST_DLOPEN_TLSMODID_PATH);
|
||||
+
|
||||
+ const char *message = dlerror ();
|
||||
+ TEST_VERIFY_EXIT (message != NULL);
|
||||
+ if ((strstr (message,
|
||||
+ "cannot dynamically load position-independent executable")
|
||||
+ == NULL)
|
||||
+ && strstr (message, "cannot dynamically load executable") == NULL)
|
||||
+ FAIL_EXIT1 ("invalid dlopen error message: \"%s\"", message);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (int argc, char *argv[])
|
||||
+{
|
||||
+ int j;
|
||||
+
|
||||
+ for (j = 0; j < 100; ++j)
|
||||
+ {
|
||||
+ pthread_t thr;
|
||||
+
|
||||
+ check_dlopen_failure ();
|
||||
+
|
||||
+ /* We create threads to force TLS allocation, which triggers
|
||||
+ the original bug i.e. running out of surplus slotinfo entries
|
||||
+ for TLS. */
|
||||
+ thr = xpthread_create (NULL, fn, NULL);
|
||||
+ xpthread_join (thr);
|
||||
+ }
|
||||
+
|
||||
+ check_dlopen_failure ();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION_ARGV do_test
|
||||
+#include <support/test-driver.c>
|
|
@ -0,0 +1,43 @@
|
|||
commit 477e739b324349df854209117047779ac3142130
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Fri Mar 15 18:18:40 2019 +0000
|
||||
|
||||
Update syscall-names.list for Linux 5.0.
|
||||
|
||||
This patch updates sysdeps/unix/sysv/linux/syscall-names.list for
|
||||
Linux 5.0. Based on testing with build-many-glibcs.py, the only new
|
||||
entry needed is for old_getpagesize (a newly added __NR_* name for an
|
||||
old syscall on ia64). (Because 5.0 changes how syscall tables are
|
||||
handled in the kernel, checking diffs wasn't a useful way of looking
|
||||
for new syscalls in 5.0 as most of the syscall tables were moved to
|
||||
the new representation without actually adding any syscalls to them.)
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
version to 5.0.
|
||||
(old_getpagesize): New syscall.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index b650dc07cc..0227e52a5f 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,8 +22,8 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 4.20.
|
||||
-kernel 4.20
|
||||
+# The list of system calls is current as of Linux 5.0.
|
||||
+kernel 5.0
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
||||
@@ -261,6 +261,7 @@ nfsservctl
|
||||
ni_syscall
|
||||
nice
|
||||
old_adjtimex
|
||||
+old_getpagesize
|
||||
oldfstat
|
||||
oldlstat
|
||||
oldolduname
|
|
@ -0,0 +1,181 @@
|
|||
commit 7621676f7a5130c030f7fff1cab72dbf2993b837
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Tue May 7 23:57:26 2019 +0000
|
||||
|
||||
Update syscall-names.list for Linux 5.1.
|
||||
|
||||
This patch updates syscall-names.list for Linux 5.1 (which has many
|
||||
new syscalls, mainly but not entirely ones for 64-bit time).
|
||||
|
||||
Tested with build-many-glibcs.py (before the revert of the move to
|
||||
Linux 5.1 there; verified there were no tst-syscall-list failures).
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
version to 5.1.
|
||||
(clock_adjtime64) New syscall.
|
||||
(clock_getres_time64) Likewise.
|
||||
(clock_gettime64) Likewise.
|
||||
(clock_nanosleep_time64) Likewise.
|
||||
(clock_settime64) Likewise.
|
||||
(futex_time64) Likewise.
|
||||
(io_pgetevents_time64) Likewise.
|
||||
(io_uring_enter) Likewise.
|
||||
(io_uring_register) Likewise.
|
||||
(io_uring_setup) Likewise.
|
||||
(mq_timedreceive_time64) Likewise.
|
||||
(mq_timedsend_time64) Likewise.
|
||||
(pidfd_send_signal) Likewise.
|
||||
(ppoll_time64) Likewise.
|
||||
(pselect6_time64) Likewise.
|
||||
(recvmmsg_time64) Likewise.
|
||||
(rt_sigtimedwait_time64) Likewise.
|
||||
(sched_rr_get_interval_time64) Likewise.
|
||||
(semtimedop_time64) Likewise.
|
||||
(timer_gettime64) Likewise.
|
||||
(timer_settime64) Likewise.
|
||||
(timerfd_gettime64) Likewise.
|
||||
(timerfd_settime64) Likewise.
|
||||
(utimensat_time64) Likewise.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index 0227e52a5f..2d0354b8b3 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,8 +22,8 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 5.0.
|
||||
-kernel 5.0
|
||||
+# The list of system calls is current as of Linux 5.1.
|
||||
+kernel 5.1
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
||||
@@ -63,10 +63,15 @@ chown
|
||||
chown32
|
||||
chroot
|
||||
clock_adjtime
|
||||
+clock_adjtime64
|
||||
clock_getres
|
||||
+clock_getres_time64
|
||||
clock_gettime
|
||||
+clock_gettime64
|
||||
clock_nanosleep
|
||||
+clock_nanosleep_time64
|
||||
clock_settime
|
||||
+clock_settime64
|
||||
clone
|
||||
clone2
|
||||
close
|
||||
@@ -128,6 +133,7 @@ ftime
|
||||
ftruncate
|
||||
ftruncate64
|
||||
futex
|
||||
+futex_time64
|
||||
futimesat
|
||||
get_kernel_syms
|
||||
get_mempolicy
|
||||
@@ -187,8 +193,12 @@ io_cancel
|
||||
io_destroy
|
||||
io_getevents
|
||||
io_pgetevents
|
||||
+io_pgetevents_time64
|
||||
io_setup
|
||||
io_submit
|
||||
+io_uring_enter
|
||||
+io_uring_register
|
||||
+io_uring_setup
|
||||
ioctl
|
||||
ioperm
|
||||
iopl
|
||||
@@ -242,7 +252,9 @@ mq_getsetattr
|
||||
mq_notify
|
||||
mq_open
|
||||
mq_timedreceive
|
||||
+mq_timedreceive_time64
|
||||
mq_timedsend
|
||||
+mq_timedsend_time64
|
||||
mq_unlink
|
||||
mremap
|
||||
msgctl
|
||||
@@ -389,6 +401,7 @@ perf_event_open
|
||||
perfctr
|
||||
perfmonctl
|
||||
personality
|
||||
+pidfd_send_signal
|
||||
pipe
|
||||
pipe2
|
||||
pivot_root
|
||||
@@ -397,6 +410,7 @@ pkey_free
|
||||
pkey_mprotect
|
||||
poll
|
||||
ppoll
|
||||
+ppoll_time64
|
||||
prctl
|
||||
pread64
|
||||
preadv
|
||||
@@ -407,6 +421,7 @@ process_vm_writev
|
||||
prof
|
||||
profil
|
||||
pselect6
|
||||
+pselect6_time64
|
||||
ptrace
|
||||
putpmsg
|
||||
pwrite64
|
||||
@@ -424,6 +439,7 @@ reboot
|
||||
recv
|
||||
recvfrom
|
||||
recvmmsg
|
||||
+recvmmsg_time64
|
||||
recvmsg
|
||||
remap_file_pages
|
||||
removexattr
|
||||
@@ -442,6 +458,7 @@ rt_sigqueueinfo
|
||||
rt_sigreturn
|
||||
rt_sigsuspend
|
||||
rt_sigtimedwait
|
||||
+rt_sigtimedwait_time64
|
||||
rt_tgsigqueueinfo
|
||||
rtas
|
||||
s390_guarded_storage
|
||||
@@ -457,6 +474,7 @@ sched_getattr
|
||||
sched_getparam
|
||||
sched_getscheduler
|
||||
sched_rr_get_interval
|
||||
+sched_rr_get_interval_time64
|
||||
sched_set_affinity
|
||||
sched_setaffinity
|
||||
sched_setattr
|
||||
@@ -470,6 +488,7 @@ semctl
|
||||
semget
|
||||
semop
|
||||
semtimedop
|
||||
+semtimedop_time64
|
||||
send
|
||||
sendfile
|
||||
sendfile64
|
||||
@@ -567,11 +586,15 @@ timer_create
|
||||
timer_delete
|
||||
timer_getoverrun
|
||||
timer_gettime
|
||||
+timer_gettime64
|
||||
timer_settime
|
||||
+timer_settime64
|
||||
timerfd
|
||||
timerfd_create
|
||||
timerfd_gettime
|
||||
+timerfd_gettime64
|
||||
timerfd_settime
|
||||
+timerfd_settime64
|
||||
times
|
||||
tkill
|
||||
truncate
|
||||
@@ -591,6 +614,7 @@ userfaultfd
|
||||
ustat
|
||||
utime
|
||||
utimensat
|
||||
+utimensat_time64
|
||||
utimes
|
||||
utrap_install
|
||||
vfork
|
|
@ -0,0 +1,58 @@
|
|||
commit 0bb8f8c791862a4ff38a584af23bbb5bf3f90acd
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri May 31 13:52:16 2019 +0200
|
||||
|
||||
Linux: Add oddly-named arm syscalls to syscall-names.list
|
||||
|
||||
<asm/unistd.h> on arm defines the following macros:
|
||||
|
||||
#define __ARM_NR_breakpoint (__ARM_NR_BASE+1)
|
||||
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
|
||||
#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
|
||||
#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
|
||||
#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
|
||||
#define __ARM_NR_get_tls (__ARM_NR_BASE+6)
|
||||
|
||||
These do not follow the regular __NR_* naming convention and
|
||||
have so far been ignored by the syscall-names.list consistency
|
||||
checks. This commit adds these names to the file, preparing
|
||||
for the availability of these names in the regular __NR_*
|
||||
namespace.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index 2d0354b8b3..ae8adabb70 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -52,6 +52,7 @@ bdflush
|
||||
bind
|
||||
bpf
|
||||
break
|
||||
+breakpoint
|
||||
brk
|
||||
cachectl
|
||||
cacheflush
|
||||
@@ -139,6 +140,7 @@ get_kernel_syms
|
||||
get_mempolicy
|
||||
get_robust_list
|
||||
get_thread_area
|
||||
+get_tls
|
||||
getcpu
|
||||
getcwd
|
||||
getdents
|
||||
@@ -499,6 +501,7 @@ set_mempolicy
|
||||
set_robust_list
|
||||
set_thread_area
|
||||
set_tid_address
|
||||
+set_tls
|
||||
setdomainname
|
||||
setfsgid
|
||||
setfsgid32
|
||||
@@ -611,6 +614,8 @@ unlinkat
|
||||
unshare
|
||||
uselib
|
||||
userfaultfd
|
||||
+usr26
|
||||
+usr32
|
||||
ustat
|
||||
utime
|
||||
utimensat
|
|
@ -0,0 +1,30 @@
|
|||
commit a63b96fbddbf97feaa068a9efed3b5623a1a1e78
|
||||
Author: Vincent Chen <vincentc@andestech.com>
|
||||
Date: Wed Jun 26 17:30:11 2019 +0800
|
||||
|
||||
Linux: Add nds32 specific syscalls to syscall-names.list
|
||||
|
||||
The nds32 creates two specific syscalls, udftrap and fp_udfiex_crtl, in
|
||||
kernel v5.0 and v5.2, respectively. Add these two syscalls to
|
||||
syscall-names.list.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index ae8adabb70..95aa3ec7a5 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -121,6 +121,7 @@ finit_module
|
||||
flistxattr
|
||||
flock
|
||||
fork
|
||||
+fp_udfiex_crtl
|
||||
free_hugepages
|
||||
fremovexattr
|
||||
fsetxattr
|
||||
@@ -603,6 +604,7 @@ tkill
|
||||
truncate
|
||||
truncate64
|
||||
tuxcall
|
||||
+udftrap
|
||||
ugetrlimit
|
||||
ulimit
|
||||
umask
|
|
@ -0,0 +1,52 @@
|
|||
commit 1f7097d09ce628878107ed30341cfc1eb3649a81
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Jul 19 08:53:04 2019 +0200
|
||||
|
||||
Linux: Update syscall-names.list to Linux 5.2
|
||||
|
||||
This adds the system call names fsconfig, fsmount, fsopen, fspick,
|
||||
move_mount, open_tree.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index 95aa3ec7a5..21bf37c627 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -23,7 +23,7 @@
|
||||
# them.
|
||||
|
||||
# The list of system calls is current as of Linux 5.1.
|
||||
-kernel 5.1
|
||||
+kernel 5.2
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
||||
@@ -124,7 +124,11 @@ fork
|
||||
fp_udfiex_crtl
|
||||
free_hugepages
|
||||
fremovexattr
|
||||
+fsconfig
|
||||
fsetxattr
|
||||
+fsmount
|
||||
+fsopen
|
||||
+fspick
|
||||
fstat
|
||||
fstat64
|
||||
fstatat64
|
||||
@@ -248,6 +252,7 @@ mmap
|
||||
mmap2
|
||||
modify_ldt
|
||||
mount
|
||||
+move_mount
|
||||
move_pages
|
||||
mprotect
|
||||
mpx
|
||||
@@ -285,6 +290,7 @@ oldumount
|
||||
olduname
|
||||
open
|
||||
open_by_handle_at
|
||||
+open_tree
|
||||
openat
|
||||
osf_adjtime
|
||||
osf_afs_syscall
|
|
@ -0,0 +1,24 @@
|
|||
commit 9c37bde5a2067e5b4dc878bac0291d6b207b8add
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Fri Aug 2 15:08:02 2019 +0000
|
||||
|
||||
Update kernel version in comment in syscall-names.list.
|
||||
|
||||
This patch updates the Linux kernel version in a comment in
|
||||
syscall-names.list to agree with the following "kernel" line.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update comment.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index 21bf37c627..9dcdd293d3 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,7 +22,7 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 5.1.
|
||||
+# The list of system calls is current as of Linux 5.2.
|
||||
kernel 5.2
|
||||
|
||||
FAST_atomic_update
|
|
@ -0,0 +1,47 @@
|
|||
commit 0f02b6cfc44af73d4d4363c46b3cbb18b8ff9171
|
||||
Author: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Wed Sep 18 22:57:46 2019 +0000
|
||||
|
||||
Update syscall-names.list for Linux 5.3.
|
||||
|
||||
This patch updates syscall-names.list for Linux 5.3, adding two new
|
||||
syscalls.
|
||||
|
||||
Tested with build-many-glibcs.py.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||
version to 5.3.
|
||||
(clone3): New syscall.
|
||||
(pidfd_open): Likewise.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
index e2382d3414..b55ffbc2a0 100644
|
||||
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||
@@ -22,8 +22,8 @@
|
||||
# names are only used if the installed kernel headers also provide
|
||||
# them.
|
||||
|
||||
-# The list of system calls is current as of Linux 5.2.
|
||||
-kernel 5.2
|
||||
+# The list of system calls is current as of Linux 5.3.
|
||||
+kernel 5.3
|
||||
|
||||
FAST_atomic_update
|
||||
FAST_cmpxchg
|
||||
@@ -75,6 +75,7 @@ clock_settime
|
||||
clock_settime64
|
||||
clone
|
||||
clone2
|
||||
+clone3
|
||||
close
|
||||
cmpxchg_badaddr
|
||||
connect
|
||||
@@ -410,6 +411,7 @@ perf_event_open
|
||||
perfctr
|
||||
perfmonctl
|
||||
personality
|
||||
+pidfd_open
|
||||
pidfd_send_signal
|
||||
pipe
|
||||
pipe2
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue