Browse Source

add missing glibc patches

Signed-off-by: basebuilder_pel7x64builder0 <basebuilder@powerel.org>
master
basebuilder_pel7x64builder0 4 years ago
parent
commit
418e78b115
  1. 36
      SOURCES/glibc-armhfp-ELF_MACHINE_NO_REL-undefined.patch
  2. 185
      SOURCES/glibc-rh1039304-1.patch
  3. 235
      SOURCES/glibc-rh1039304-2.patch
  4. 40
      SOURCES/glibc-rh1039304-3.patch
  5. 322
      SOURCES/glibc-rh1039304-4.patch
  6. 38
      SOURCES/glibc-rh1065574-1.patch
  7. 236
      SOURCES/glibc-rh1065574-2.patch
  8. 276
      SOURCES/glibc-rh1065574-3.patch
  9. 38
      SOURCES/glibc-rh1065574-4.patch
  10. 31
      SOURCES/glibc-rh1065574-5.patch
  11. 175
      SOURCES/glibc-rh1065574-6.patch
  12. 24
      SOURCES/glibc-rh1065574-7.patch
  13. 834
      SOURCES/glibc-rh1163509-1.patch
  14. 294
      SOURCES/glibc-rh1163509-2.patch
  15. 108
      SOURCES/glibc-rh1163509-3.patch
  16. 443
      SOURCES/glibc-rh1163509-4.patch
  17. 720
      SOURCES/glibc-rh1163509-5.patch
  18. 60
      SOURCES/glibc-rh1235112.patch
  19. 11
      SOURCES/glibc-rh1256317-armhfp-build-issue.patch
  20. 98
      SOURCES/glibc-rh1406732-1.patch
  21. 96
      SOURCES/glibc-rh1406732-2.patch
  22. 44
      SOURCES/glibc-rh1406732-3.patch
  23. 25
      SOURCES/glibc-rh1406732-4.patch
  24. 26
      SOURCES/glibc-rh1406732-5.patch
  25. 43
      SOURCES/glibc-rh1406732-6.patch
  26. 423
      SOURCES/glibc-rh1414263.patch
  27. 54
      SOURCES/glibc-rh1418978-1a.patch
  28. 318
      SOURCES/glibc-rh1427734-1.patch
  29. 34
      SOURCES/glibc-rh1427734-2.patch
  30. 40
      SOURCES/glibc-rh1443872-2.patch
  31. 250
      SOURCES/glibc-rh1443872.patch
  32. 41
      SOURCES/glibc-rh1451308.patch
  33. 38
      SOURCES/glibc-rh1472832.patch
  34. 30
      SOURCES/glibc-rh1484832.patch
  35. 61
      SOURCES/glibc-rh1488370.patch
  36. 35
      SOURCES/glibc-rh1555189-1.patch
  37. 24
      SOURCES/glibc-rh1555189-2.patch
  38. 57
      SOURCES/glibc-rh1579354.patch
  39. 112
      SOURCES/glibc-rh1579451.patch
  40. 308
      SOURCES/glibc-rh1579730-1.patch
  41. 22
      SOURCES/glibc-rh1579730-2.patch
  42. 131
      SOURCES/glibc-rh1579730-3.patch
  43. 66
      SOURCES/glibc-rh1579739-2.patch
  44. 162
      SOURCES/glibc-rh1579739.patch
  45. 38
      SOURCES/glibc-rh1591268.patch
  46. 194
      SOURCES/glibc-rh1592475-1.patch
  47. 164
      SOURCES/glibc-rh1592475-2.patch
  48. 164
      SOURCES/glibc-rh1592475-3.patch
  49. 230
      SOURCES/glibc-rh1595191-1.patch
  50. 34
      SOURCES/glibc-rh1595191-2.patch
  51. 624
      SOURCES/glibc-rh1595191-3.patch
  52. 24
      SOURCES/glibc-rh1595191-4.patch
  53. 65
      SOURCES/glibc-rh1609067.patch
  54. 486
      SOURCES/glibc-rh1630440-1.patch
  55. 48
      SOURCES/glibc-rh1630440-2.patch
  56. 19
      SOURCES/glibc-rh1634021.patch
  57. 1316
      SOURCES/glibc-rh1636229-1.patch
  58. 196
      SOURCES/glibc-rh1636229-2.patch
  59. 294
      SOURCES/glibc-rh1636229-3.patch
  60. 21
      SOURCES/glibc-rh1636229-4.patch
  61. 74
      SOURCES/glibc-rh1639524.patch
  62. 41
      SOURCES/glibc-rh1641981.patch
  63. 32
      SOURCES/glibc-rh1646373.patch
  64. 80
      SOURCES/glibc-rh1647490-1.patch
  65. 55
      SOURCES/glibc-rh1647490-2.patch
  66. 64
      SOURCES/glibc-rh1647490-3.patch
  67. 51
      SOURCES/glibc-rh1647490-4.patch
  68. 30
      SOURCES/glibc-rh1647490-5.patch
  69. 27
      SOURCES/glibc-rh1647490-6.patch
  70. 41
      SOURCES/glibc-rh1657015-1.patch
  71. 61
      SOURCES/glibc-rh1657015-2.patch
  72. 41
      SOURCES/glibc-rh1657015-3.patch
  73. 52
      SOURCES/glibc-rh1657015-4.patch
  74. 68
      SOURCES/glibc-rh1662842.patch
  75. 104
      SOURCES/glibc-rh1670041.patch
  76. 200
      SOURCES/glibc-rh1672771.patch
  77. 48
      SOURCES/glibc-rh1673465-1.patch
  78. 34
      SOURCES/glibc-rh1673465-2.patch
  79. 142
      SOURCES/glibc-rh1673465-3.patch
  80. 221
      SOURCES/glibc-rh1673465-4.patch
  81. 80
      SOURCES/glibc-rh1673465-5.patch
  82. 698
      SOURCES/glibc-rh1673465-6.patch
  83. 81
      SOURCES/glibc-rh1673465-7.patch
  84. 16
      SOURCES/glibc-rh1673465-8.patch
  85. 54
      SOURCES/glibc-rh1684874-1.patch
  86. 49
      SOURCES/glibc-rh1684874-2.patch
  87. 46
      SOURCES/glibc-rh1691534-1.patch
  88. 47
      SOURCES/glibc-rh1691534-2.patch
  89. 32
      SOURCES/glibc-rh1698015.patch
  90. 147
      SOURCES/glibc-rh1728915-1.patch
  91. 164
      SOURCES/glibc-rh1728915-2.patch
  92. 160
      SOURCES/glibc-rh1740039-1.patch
  93. 174
      SOURCES/glibc-rh1740039-2.patch
  94. 43
      SOURCES/glibc-rh1747465-1.patch
  95. 181
      SOURCES/glibc-rh1747465-2.patch
  96. 58
      SOURCES/glibc-rh1747465-3.patch
  97. 30
      SOURCES/glibc-rh1747465-4.patch
  98. 52
      SOURCES/glibc-rh1747465-5.patch
  99. 24
      SOURCES/glibc-rh1747465-6.patch
  100. 47
      SOURCES/glibc-rh1747465-7.patch
  101. Some files were not shown because too many files have changed in this diff Show More

36
SOURCES/glibc-armhfp-ELF_MACHINE_NO_REL-undefined.patch

@ -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

185
SOURCES/glibc-rh1039304-1.patch

@ -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>

235
SOURCES/glibc-rh1039304-2.patch

@ -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>

40
SOURCES/glibc-rh1039304-3.patch

@ -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

322
SOURCES/glibc-rh1039304-4.patch

@ -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;

38
SOURCES/glibc-rh1065574-1.patch

@ -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;

236
SOURCES/glibc-rh1065574-2.patch

@ -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;
}

276
SOURCES/glibc-rh1065574-3.patch

@ -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);

38
SOURCES/glibc-rh1065574-4.patch

@ -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)

31
SOURCES/glibc-rh1065574-5.patch

@ -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;

175
SOURCES/glibc-rh1065574-6.patch

@ -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>

24
SOURCES/glibc-rh1065574-7.patch

@ -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);

834
SOURCES/glibc-rh1163509-1.patch

@ -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)

294
SOURCES/glibc-rh1163509-2.patch

@ -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)

108
SOURCES/glibc-rh1163509-3.patch

@ -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));

443
SOURCES/glibc-rh1163509-4.patch

@ -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

720
SOURCES/glibc-rh1163509-5.patch

@ -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)

60
SOURCES/glibc-rh1235112.patch

@ -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)

11
SOURCES/glibc-rh1256317-armhfp-build-issue.patch

@ -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

98
SOURCES/glibc-rh1406732-1.patch

@ -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

96
SOURCES/glibc-rh1406732-2.patch

@ -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

44
SOURCES/glibc-rh1406732-3.patch

@ -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); \

25
SOURCES/glibc-rh1406732-4.patch

@ -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 \

26
SOURCES/glibc-rh1406732-5.patch

@ -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

43
SOURCES/glibc-rh1406732-6.patch

@ -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

423
SOURCES/glibc-rh1414263.patch

@ -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

54
SOURCES/glibc-rh1418978-1a.patch

@ -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;

318
SOURCES/glibc-rh1427734-1.patch

@ -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; \

34
SOURCES/glibc-rh1427734-2.patch

@ -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);

40
SOURCES/glibc-rh1443872-2.patch

@ -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);
}

250
SOURCES/glibc-rh1443872.patch

@ -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 */

41
SOURCES/glibc-rh1451308.patch

@ -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)

38
SOURCES/glibc-rh1472832.patch

@ -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 */

30
SOURCES/glibc-rh1484832.patch

@ -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

61
SOURCES/glibc-rh1488370.patch

@ -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

35
SOURCES/glibc-rh1555189-1.patch

@ -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>"

24
SOURCES/glibc-rh1555189-2.patch

@ -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>";/

57
SOURCES/glibc-rh1579354.patch

@ -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))

112
SOURCES/glibc-rh1579451.patch

@ -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. */

308
SOURCES/glibc-rh1579730-1.patch

@ -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>

22
SOURCES/glibc-rh1579730-2.patch

@ -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);

131
SOURCES/glibc-rh1579730-3.patch

@ -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);

66
SOURCES/glibc-rh1579739-2.patch

@ -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

162
SOURCES/glibc-rh1579739.patch

@ -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;
+}

38
SOURCES/glibc-rh1591268.patch

@ -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

194
SOURCES/glibc-rh1592475-1.patch

@ -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 */

164
SOURCES/glibc-rh1592475-2.patch

@ -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
{

164
SOURCES/glibc-rh1592475-3.patch

@ -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

230
SOURCES/glibc-rh1595191-1.patch

@ -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);

34
SOURCES/glibc-rh1595191-2.patch

@ -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

624
SOURCES/glibc-rh1595191-3.patch

@ -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>

24
SOURCES/glibc-rh1595191-4.patch

@ -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. */

65
SOURCES/glibc-rh1609067.patch

@ -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)

486
SOURCES/glibc-rh1630440-1.patch

@ -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 ();

48
SOURCES/glibc-rh1630440-2.patch

@ -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>

19
SOURCES/glibc-rh1634021.patch

@ -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);
}

1316
SOURCES/glibc-rh1636229-1.patch

File diff suppressed because it is too large Load Diff

196
SOURCES/glibc-rh1636229-2.patch

@ -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>

294
SOURCES/glibc-rh1636229-3.patch

@ -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>

21
SOURCES/glibc-rh1636229-4.patch

@ -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

74
SOURCES/glibc-rh1639524.patch

@ -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))
{

41
SOURCES/glibc-rh1641981.patch

@ -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)

32
SOURCES/glibc-rh1646373.patch

@ -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;

80
SOURCES/glibc-rh1647490-1.patch

@ -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;
}

55
SOURCES/glibc-rh1647490-2.patch

@ -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));

64
SOURCES/glibc-rh1647490-3.patch

@ -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;
}

51
SOURCES/glibc-rh1647490-4.patch

@ -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;
}

30
SOURCES/glibc-rh1647490-5.patch

@ -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;
}

27
SOURCES/glibc-rh1647490-6.patch

@ -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>

41
SOURCES/glibc-rh1657015-1.patch

@ -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

61
SOURCES/glibc-rh1657015-2.patch

@ -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

41
SOURCES/glibc-rh1657015-3.patch

@ -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

52
SOURCES/glibc-rh1657015-4.patch

@ -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

68
SOURCES/glibc-rh1662842.patch

@ -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);

104
SOURCES/glibc-rh1670041.patch

@ -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 */

200
SOURCES/glibc-rh1672771.patch

@ -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);
}

48
SOURCES/glibc-rh1673465-1.patch

@ -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 */

34
SOURCES/glibc-rh1673465-2.patch

@ -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. */

142
SOURCES/glibc-rh1673465-3.patch

@ -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>

221
SOURCES/glibc-rh1673465-4.patch

@ -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)

80
SOURCES/glibc-rh1673465-5.patch

@ -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);

698
SOURCES/glibc-rh1673465-6.patch

@ -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;

81
SOURCES/glibc-rh1673465-7.patch

@ -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>

16
SOURCES/glibc-rh1673465-8.patch

@ -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

54
SOURCES/glibc-rh1684874-1.patch

@ -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

49
SOURCES/glibc-rh1684874-2.patch

@ -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

46
SOURCES/glibc-rh1691534-1.patch

@ -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

47
SOURCES/glibc-rh1691534-2.patch

@ -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

32
SOURCES/glibc-rh1698015.patch

@ -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;
+ }
}

147
SOURCES/glibc-rh1728915-1.patch

@ -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)

164
SOURCES/glibc-rh1728915-2.patch

@ -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>

160
SOURCES/glibc-rh1740039-1.patch

@ -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);

174
SOURCES/glibc-rh1740039-2.patch

@ -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>

43
SOURCES/glibc-rh1747465-1.patch

@ -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

181
SOURCES/glibc-rh1747465-2.patch

@ -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

58
SOURCES/glibc-rh1747465-3.patch

@ -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

30
SOURCES/glibc-rh1747465-4.patch

@ -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

52
SOURCES/glibc-rh1747465-5.patch

@ -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

24
SOURCES/glibc-rh1747465-6.patch

@ -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

47
SOURCES/glibc-rh1747465-7.patch

@ -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…
Cancel
Save