basebuilder_pel7x64builder0
4 years ago
106 changed files with 14681 additions and 0 deletions
@ -0,0 +1,36 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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