glibc: sync patches with upstream

This commit is contained in:
maxice8 2018-11-30 01:02:18 -02:00 committed by maxice8
parent 64e2ffff52
commit c1eb92be12
26 changed files with 3068 additions and 1 deletions

View file

@ -137,3 +137,4 @@ index 7449f8c7d5..945d5cdf28 100644
.weak __powf_compat
.set __powf_compat,__powf
.symver __powf_compat,powf@GLIBC_2.2

View file

@ -0,0 +1,114 @@
From df11de91931597ab4adccb74d9d55c9ddd029a22 Mon Sep 17 00:00:00 2001
From: Paul Pluzhnikov <ppluzhnikov@kazbek.mtv.corp.google.com>
Date: Fri, 2 Nov 2018 10:47:07 +0100
Subject: [PATCH 27] Fix BZ#23400 (creating temporary files in source tree),
and undefined behavior in test.
(cherry picked from commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523)
---
ChangeLog | 6 ++++++
NEWS | 1 +
stdlib/test-bz22786.c | 39 ++++++++++++---------------------------
3 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 73d5c57f0d..43cc1fbc32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-08-24 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ [BZ #23400]
+ * stdlib/test-bz22786.c (do_test): Fix undefined behavior, don't
+ create temporary files in source tree.
+
2018-10-26 Szabolcs Nagy <szabolcs.nagy@arm.com>
[BZ #23822]
diff --git a/NEWS b/NEWS
index f4d9885819..79b028008d 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.28.1
The following bugs are resolved with this release:
[20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
+ [23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index e7837f98c1..d1aa69106c 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;
}

View file

@ -0,0 +1,75 @@
From d0b6db4acfba1f48b24da2c9b2a1530f6dd71503 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.ibm.com>
Date: Thu, 30 Aug 2018 08:44:32 +0200
Subject: [PATCH 28] 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.
(cherry picked from commit 3bad2358d67d371497079bba4f8eca9c0096f4e2)
---
ChangeLog | 5 +++++
stdlib/test-bz22786.c | 15 ++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 43cc1fbc32..645e6607b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-30 Stefan Liebler <stli@linux.ibm.com>
+
+ * stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
+ if malloc fails.
+
2018-08-24 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #23400]
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index d1aa69106c..777bf9180f 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));

View file

@ -0,0 +1,540 @@
From dcd52b94bf50f337dc4cfffa24ed86d7dfe03dc0 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:11:47 +0100
Subject: [PATCH 29] 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.
(cherry picked from commit f5e7e95921847bd83186bfe621fc2b48c4de5477)
---
ChangeLog | 11 ++
stdlib/test-bz22786.c | 16 +-
support/Makefile | 2 +
support/blob_repeat.c | 278 ++++++++++++++++++++++++++++++
support/blob_repeat.h | 44 +++++
support/tst-support_blob_repeat.c | 85 +++++++++
6 files changed, 426 insertions(+), 10 deletions(-)
create mode 100644 support/blob_repeat.c
create mode 100644 support/blob_repeat.h
create mode 100644 support/tst-support_blob_repeat.c
diff --git a/ChangeLog b/ChangeLog
index 645e6607b2..2043b21dde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ Avoid spurious test failures in stdlib/test-bz22786.
+ * support/Makefile (libsupport-routines): Add blob_repeat.
+ (tests): Add tst-support_blob_repeat.
+ * support/blob_repeat.h: New file.
+ * support/blob_repeat.c: Likewise.
+ * support/tst-support_blob_repeat.c: Likewise.
+ * stdlib/test-bz22786.c (do_test): Replace malloc and memset with
+ support_blob_repeat_allocate.
+
2018-08-30 Stefan Liebler <stli@linux.ibm.com>
* stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index 777bf9180f..bb1e04f2de 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;
}
diff --git a/support/Makefile b/support/Makefile
index 652d2cdf69..50470fb749 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -25,6 +25,7 @@ extra-libs-others = $(extra-libs)
extra-libs-noinstall := $(extra-libs)
libsupport-routines = \
+ blob_repeat \
check \
check_addrinfo \
check_dns_packet \
@@ -154,6 +155,7 @@ endif
tests = \
README-testing \
tst-support-namespace \
+ tst-support_blob_repeat \
tst-support_capture_subprocess \
tst-support_format_dns_packet \
tst-support_quote_blob \
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
new file mode 100644
index 0000000000..da4ca83043
--- /dev/null
+++ b/support/blob_repeat.c
@@ -0,0 +1,278 @@
+/* Repeating a memory blob, with alias mapping optimization.
+ 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 <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/blob_repeat.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <wchar.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;
+
+/* Internal helper for fill. */
+static void
+fill0 (char *target, const char *element, size_t element_size,
+ size_t count)
+{
+ while (count > 0)
+ {
+ memcpy (target, element, element_size);
+ target += element_size;
+ --count;
+ }
+}
+
+/* Fill the buffer at TARGET with COUNT copies of the ELEMENT_SIZE
+ bytes starting at ELEMENT. */
+static void
+fill (char *target, const char *element, size_t element_size,
+ size_t count)
+{
+ if (element_size == 0 || count == 0)
+ return;
+ else if (element_size == 1)
+ memset (target, element[0], count);
+ else if (element_size == sizeof (wchar_t))
+ {
+ wchar_t wc;
+ memcpy (&wc, element, sizeof (wc));
+ wmemset ((wchar_t *) target, wc, count);
+ }
+ else if (element_size < 1024 && count > 4096)
+ {
+ /* Use larger copies for really small element sizes. */
+ char buffer[8192];
+ size_t buffer_count = sizeof (buffer) / element_size;
+ fill0 (buffer, element, element_size, buffer_count);
+ while (count > 0)
+ {
+ size_t copy_count = buffer_count;
+ if (copy_count > count)
+ copy_count = count;
+ size_t copy_bytes = copy_count * element_size;
+ memcpy (target, buffer, copy_bytes);
+ target += copy_bytes;
+ count -= copy_count;
+ }
+ }
+ else
+ fill0 (target, element, element_size, count);
+}
+
+/* Use malloc instead of mmap for small allocations and unusual size
+ combinations. */
+static struct support_blob_repeat
+allocate_malloc (size_t total_size, const void *element, size_t element_size,
+ size_t count)
+{
+ void *buffer = malloc (total_size);
+ if (buffer == NULL)
+ return (struct support_blob_repeat) { 0 };
+ fill (buffer, element, element_size, count);
+ return (struct support_blob_repeat)
+ {
+ .start = buffer,
+ .size = total_size,
+ .use_malloc = true
+ };
+}
+
+/* Return the least common multiple of PAGE_SIZE and ELEMENT_SIZE,
+ avoiding overflow. This assumes that PAGE_SIZE is a power of
+ two. */
+static size_t
+minimum_stride_size (size_t page_size, size_t element_size)
+{
+ TEST_VERIFY_EXIT (page_size > 0);
+ TEST_VERIFY_EXIT (element_size > 0);
+
+ /* Compute the number of trailing zeros common to both sizes. */
+ unsigned int common_zeros = __builtin_ctzll (page_size | element_size);
+
+ /* In the product, this power of two appears twice, but in the least
+ common multiple, it appears only once. Therefore, shift one
+ factor. */
+ size_t multiple;
+ if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
+ &multiple))
+ return 0;
+ return multiple;
+}
+
+/* Allocations larger than maximum_small_size potentially use mmap
+ with alias mappings. */
+static struct support_blob_repeat
+allocate_big (size_t total_size, const void *element, size_t element_size,
+ size_t count)
+{
+ unsigned long page_size = xsysconf (_SC_PAGESIZE);
+ size_t stride_size = minimum_stride_size (page_size, element_size);
+ if (stride_size == 0)
+ {
+ errno = EOVERFLOW;
+ return (struct support_blob_repeat) { 0 };
+ }
+
+ /* Ensure that the stride size is at least maximum_small_size. This
+ is necessary to reduce the number of distinct mappings. */
+ if (stride_size < maximum_small_size)
+ stride_size
+ = ((maximum_small_size + stride_size - 1) / stride_size) * stride_size;
+
+ if (stride_size > total_size)
+ /* The mmap optimization would not save anything. */
+ return allocate_malloc (total_size, element, element_size, count);
+
+ /* Reserve the memory region. If we cannot create the mapping,
+ there is no reason to set up the backing file. */
+ void *target = mmap (NULL, total_size, PROT_NONE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (target == MAP_FAILED)
+ return (struct support_blob_repeat) { 0 };
+
+ /* Create the backing file for the repeated mapping. */
+ int fd;
+ {
+ char *temppath;
+ fd = create_temp_file ("support_blob_repeat-", &temppath);
+ if (fd < 0)
+ FAIL_EXIT1 ("create_temp_file: %m");
+ xunlink (temppath);
+ free (temppath);
+ }
+
+ /* Make sure that there is backing storage, so that the fill
+ operation will not fault. */
+ if (posix_fallocate (fd, 0, stride_size) != 0)
+ FAIL_EXIT1 ("posix_fallocate (%zu): %m", stride_size);
+
+ /* The stride size must still be a multiple of the page size and
+ element size. */
+ TEST_VERIFY_EXIT ((stride_size % page_size) == 0);
+ TEST_VERIFY_EXIT ((stride_size % element_size) == 0);
+
+ /* Fill the backing store. */
+ {
+ void *ptr = mmap (target, stride_size, PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_FILE | MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED)
+ {
+ int saved_errno = errno;
+ xmunmap (target, total_size);
+ xclose (fd);
+ errno = saved_errno;
+ return (struct support_blob_repeat) { 0 };
+ }
+ if (ptr != target)
+ FAIL_EXIT1 ("mapping of %zu bytes moved from %p to %p",
+ stride_size, target, ptr);
+
+ /* Write the repeating data. */
+ fill (target, element, element_size, stride_size / element_size);
+
+ /* Return to a PROT_NONE mapping, just to be on the safe side. */
+ ptr = mmap (target, stride_size, PROT_NONE,
+ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (ptr == MAP_FAILED)
+ FAIL_EXIT1 ("Failed to reinstate PROT_NONE mapping: %m");
+ if (ptr != target)
+ FAIL_EXIT1 ("PROT_NONE mapping of %zu bytes moved from %p to %p",
+ stride_size, target, ptr);
+ }
+
+ /* Create the alias mappings. */
+ {
+ size_t remaining_size = total_size;
+ char *current = target;
+ int flags = MAP_FIXED | MAP_FILE | MAP_PRIVATE;
+#ifdef MAP_NORESERVE
+ flags |= MAP_NORESERVE;
+#endif
+ while (remaining_size > 0)
+ {
+ size_t to_map = stride_size;
+ if (to_map > remaining_size)
+ to_map = remaining_size;
+ void *ptr = mmap (current, to_map, PROT_READ | PROT_WRITE,
+ flags, fd, 0);
+ if (ptr == MAP_FAILED)
+ {
+ int saved_errno = errno;
+ xmunmap (target, total_size);
+ xclose (fd);
+ errno = saved_errno;
+ return (struct support_blob_repeat) { 0 };
+ }
+ if (ptr != current)
+ FAIL_EXIT1 ("MAP_PRIVATE mapping of %zu bytes moved from %p to %p",
+ to_map, target, ptr);
+ remaining_size -= to_map;
+ current += to_map;
+ }
+ }
+
+ xclose (fd);
+
+ return (struct support_blob_repeat)
+ {
+ .start = target,
+ .size = total_size,
+ .use_malloc = false
+ };
+}
+
+struct support_blob_repeat
+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))
+ {
+ errno = EOVERFLOW;
+ return (struct support_blob_repeat) { 0 };
+ }
+ if (total_size <= maximum_small_size)
+ return allocate_malloc (total_size, element, element_size, count);
+ else
+ return allocate_big (total_size, element, element_size, count);
+}
+
+void
+support_blob_repeat_free (struct support_blob_repeat *blob)
+{
+ if (blob->size > 0)
+ {
+ int saved_errno = errno;
+ if (blob->use_malloc)
+ free (blob->start);
+ else
+ xmunmap (blob->start, blob->size);
+ errno = saved_errno;
+ }
+ *blob = (struct support_blob_repeat) { 0 };
+}
diff --git a/support/blob_repeat.h b/support/blob_repeat.h
new file mode 100644
index 0000000000..8e9d7ff5f1
--- /dev/null
+++ b/support/blob_repeat.h
@@ -0,0 +1,44 @@
+/* Repeating a memory blob, with alias mapping optimization.
+ 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/>. */
+
+#ifndef SUPPORT_BLOB_REPEAT_H
+#define SUPPORT_BLOB_REPEAT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+struct support_blob_repeat
+{
+ void *start;
+ size_t size;
+ bool use_malloc;
+};
+
+/* Return an allocation of COUNT elements, each of ELEMENT_SIZE bytes,
+ initialized with the bytes starting at ELEMENT. The memory is
+ writable (and thus counts towards the commit charge). In case of
+ on error, all members of the return struct are zero-initialized,
+ and errno is set accordingly. */
+struct support_blob_repeat support_blob_repeat_allocate (const void *element,
+ size_t element_size,
+ size_t count);
+
+/* Deallocate the blob created by support_blob_repeat_allocate. */
+void support_blob_repeat_free (struct support_blob_repeat *);
+
+#endif /* SUPPORT_BLOB_REPEAT_H */
diff --git a/support/tst-support_blob_repeat.c b/support/tst-support_blob_repeat.c
new file mode 100644
index 0000000000..1978c14488
--- /dev/null
+++ b/support/tst-support_blob_repeat.c
@@ -0,0 +1,85 @@
+/* Tests for <support/blob_repeat.h>
+ 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 <stdio.h>
+#include <support/blob_repeat.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ struct support_blob_repeat repeat
+ = support_blob_repeat_allocate ("5", 1, 5);
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "55555", 5);
+ support_blob_repeat_free (&repeat);
+
+ repeat = support_blob_repeat_allocate ("ABC", 3, 3);
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "ABCABCABC", 9);
+ support_blob_repeat_free (&repeat);
+
+ repeat = support_blob_repeat_allocate ("abc", 4, 3);
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "abc\0abc\0abc", 12);
+ support_blob_repeat_free (&repeat);
+
+ size_t gigabyte = 1U << 30;
+ repeat = support_blob_repeat_allocate ("X", 1, gigabyte + 1);
+ if (repeat.start == NULL)
+ puts ("warning: not enough memory for 1 GiB mapping");
+ else
+ {
+ TEST_COMPARE (repeat.size, gigabyte + 1);
+ {
+ unsigned char *p = repeat.start;
+ for (size_t i = 0; i < gigabyte + 1; ++i)
+ if (p[i] != 'X')
+ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
+
+ /* Check that there is no sharing across the mapping. */
+ p[0] = 'Y';
+ p[1U << 24] = 'Z';
+ for (size_t i = 0; i < gigabyte + 1; ++i)
+ if (i == 0)
+ TEST_COMPARE (p[i], 'Y');
+ else if (i == 1U << 24)
+ TEST_COMPARE (p[i], 'Z');
+ else if (p[i] != 'X')
+ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
+ }
+ }
+ support_blob_repeat_free (&repeat);
+
+ repeat = support_blob_repeat_allocate ("012345678", 9, 10 * 1000 * 1000);
+ if (repeat.start == NULL)
+ puts ("warning: not enough memory for large mapping");
+ else
+ {
+ unsigned char *p = repeat.start;
+ for (int i = 0; i < 10 * 1000 * 1000; ++i)
+ for (int j = 0; j <= 8; ++j)
+ if (p[i * 9 + j] != '0' + j)
+ {
+ printf ("error: element %d index %d\n", i, j);
+ TEST_COMPARE (p[i * 9 + j], '0' + j);
+ }
+ }
+ support_blob_repeat_free (&repeat);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -0,0 +1,50 @@
From 69dcd992a0efdb53bc2ea4948cfc6b13416b9636 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:56:40 +0100
Subject: [PATCH 30] stdlib/test-bz22786: Avoid memory leaks in the test
itself
(cherry picked from commit 60708030536df82616c16aa2f14f533c4362b969)
---
ChangeLog | 5 +++++
stdlib/test-bz22786.c | 6 ++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2043b21dde..a2a9fc3cc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ * stdlib/test-bz22786.c (do_test): Additional free calls to avoid
+ memory leaks.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
Avoid spurious test failures in stdlib/test-bz22786.
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index bb1e04f2de..8035e8a394 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;
}

View file

@ -0,0 +1,63 @@
From 6c2b6e9e2758b7491ce89920a8711c1b41100269 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:55:50 +0100
Subject: [PATCH 31] support_blob_repeat: Call mkstemp directory for the
backing file
This avoids a warning during post-test cleanup.
(cherry picked from commit a91e9301c47bb688f4e496a19cfc68261ff18293)
---
ChangeLog | 4 ++++
support/blob_repeat.c | 14 +++++++++-----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a2a9fc3cc9..b4c48644ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ * support/blob_repeat.c (allocate_big): Call mkstemp directly.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
* stdlib/test-bz22786.c (do_test): Additional free calls to avoid
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
index da4ca83043..16c1e448b9 100644
--- a/support/blob_repeat.c
+++ b/support/blob_repeat.c
@@ -23,8 +23,8 @@
#include <string.h>
#include <support/blob_repeat.h>
#include <support/check.h>
+#include <support/test-driver.h>
#include <support/support.h>
-#include <support/temp_file.h>
#include <support/xunistd.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -155,13 +155,17 @@ allocate_big (size_t total_size, const void *element, size_t element_size,
if (target == MAP_FAILED)
return (struct support_blob_repeat) { 0 };
- /* Create the backing file for the repeated mapping. */
+ /* Create the backing file for the repeated mapping. Call mkstemp
+ directly to remove the resources backing the temporary file
+ immediately, once support_blob_repeat_free is called. Using
+ create_temp_file would result in a warning during post-test
+ cleanup. */
int fd;
{
- char *temppath;
- fd = create_temp_file ("support_blob_repeat-", &temppath);
+ char *temppath = xasprintf ("%s/support_blob_repeat-XXXXXX", test_dir);
+ fd = mkstemp (temppath);
if (fd < 0)
- FAIL_EXIT1 ("create_temp_file: %m");
+ FAIL_EXIT1 ("mkstemp (\"%s\"): %m", temppath);
xunlink (temppath);
free (temppath);
}

View file

@ -0,0 +1,71 @@
From e1af1df694603c0dcd5118c30eea2cdeb01a1a0b Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:55:01 +0100
Subject: [PATCH 32] stdlib/tst-strtod-overflow: Switch to
support_blob_repeat
This is another test with an avoidable large memory allocation.
(cherry picked from commit 07da99aad93c9364acb7efdab47c27ba698f6313)
---
ChangeLog | 5 +++++
stdlib/tst-strtod-overflow.c | 16 ++++++++++------
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b4c48644ae..51a8f488d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ * stdlib/tst-strtod-overflow.c (do_test): Switch to
+ support_blob_repeat.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
* support/blob_repeat.c (allocate_big): Call mkstemp directly.
diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
index d14638d68e..dc53c1e521 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;
}

View file

@ -0,0 +1,74 @@
From 65010329f2c596bdd1204c1c9c9baac0193637af Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Fri, 2 Nov 2018 10:56:00 +0100
Subject: [PATCH 33] x86: Fix Haswell CPU string 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.
(cherry picked from commit c3d8dc45c9df199b8334599a6cbd98c9950dba62)
---
ChangeLog | 6 ++++++
NEWS | 1 +
sysdeps/x86/cpu-features.c | 6 ++++++
3 files changed, 13 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 51a8f488d9..d558df58af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-10-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #23709]
+ * sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
+ independently of other flags.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
* stdlib/tst-strtod-overflow.c (do_test): Switch to
diff --git a/NEWS b/NEWS
index 79b028008d..f3004915f2 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ The following bugs are resolved with this release:
[23579] libc: Errors misreported in preadv2
[23606] Missing ENDBR32 in sysdeps/i386/start.S
[23679] gethostid: Missing NULL check for gethostbyname_r result
+ [23709] Fix CPU string flags for Haswell-type CPUs
[23717] Fix stack overflow in stdlib/tst-setcontext9
[23821] si_band in siginfo_t has wrong type long int on sparc64
[23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index ea0b64fdb9..4695ac80d4 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -316,7 +316,13 @@ init_cpu_features (struct cpu_features *cpu_features)
| bit_arch_Fast_Unaligned_Copy
| bit_arch_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)

View file

@ -0,0 +1,58 @@
From fc0e3393ff775aa795b523083bb0db7f18d3b91e Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Tue, 6 Nov 2018 16:12:07 +0100
Subject: [PATCH 34] libanl: properly cleanup if first helper thread
creation failed (bug 22927)
(cherry picked from commit bd3b0fbae33a9a4cc5e2daf049443d5cf03d4251)
---
ChangeLog | 6 ++++++
NEWS | 1 +
resolv/gai_misc.c | 7 +++++--
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d558df58af..db4ac3b76a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2018-10-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #23709]
diff --git a/NEWS b/NEWS
index f3004915f2..b85be4a9c1 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.28.1
The following bugs are resolved with this release:
[20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
+ [22927] libanl: properly cleanup if first helper thread creation failed
[23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
index e7c3b63cc5..80a2cff835 100644
--- a/resolv/gai_misc.c
+++ b/resolv/gai_misc.c
@@ -261,8 +261,11 @@ __gai_enqueue_request (struct gaicb *gaicbp)
/* 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;

View file

@ -0,0 +1,192 @@
From 3e8d8dd5afba18a847ff7a80f473336f777cc329 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 8 Nov 2018 10:06:58 -0800
Subject: [PATCH 35] Check multiple NT_GNU_PROPERTY_TYPE_0 notes [BZ #23509]
Linkers group input note sections with the same name into one output
note section with the same name. One output note section is placed in
one PT_NOTE segment. Since new linkers merge input .note.gnu.property
sections into one output .note.gnu.property section, there is only
one NT_GNU_PROPERTY_TYPE_0 note in one PT_NOTE segment with new linkers.
Since older linkers treat input .note.gnu.property section as a generic
note section and just concatenate all input .note.gnu.property sections
into one output .note.gnu.property section without merging them, we may
see multiple NT_GNU_PROPERTY_TYPE_0 notes in one PT_NOTE segment with
older linkers.
When an older linker is used to created the program on CET-enabled OS,
the linker output has a single .note.gnu.property section with multiple
NT_GNU_PROPERTY_TYPE_0 notes, some of which have IBT and SHSTK enable
bits set even if the program isn't CET enabled. Such programs will
crash on CET-enabled machines. This patch updates the note parser:
1. Skip note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
2. Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
[BZ #23509]
* sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip
note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note.
Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
* sysdeps/x86/link_map.h (l_cet): Expand to 3 bits, Add
lc_unknown.
(cherry picked from commit d524fa6c35e675eedbd8fe6cdf4db0b49c658026)
---
ChangeLog | 10 +++++++++
NEWS | 1 +
sysdeps/x86/dl-prop.h | 51 +++++++++++++++++++++++++++++++++---------
sysdeps/x86/link_map.h | 9 ++++----
4 files changed, 57 insertions(+), 14 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index db4ac3b76a..86bdf17989 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-11-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #23509]
+ * sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip
+ note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
+ Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note.
+ Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
+ * sysdeps/x86/link_map.h (l_cet): Expand to 3 bits, Add
+ lc_unknown.
+
2018-11-05 Andreas Schwab <schwab@suse.de>
[BZ #22927]
diff --git a/NEWS b/NEWS
index b85be4a9c1..e5ca5903ec 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
[22927] libanl: properly cleanup if first helper thread creation failed
[23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
+ [23509] CET enabled glibc is incompatible with the older linker
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
[23562] signal: Use correct type for si_band in siginfo_t
diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
index 26c3131ac5..9ab890d12b 100644
--- a/sysdeps/x86/dl-prop.h
+++ b/sysdeps/x86/dl-prop.h
@@ -49,6 +49,10 @@ _dl_process_cet_property_note (struct link_map *l,
const ElfW(Addr) align)
{
#if CET_ENABLED
+ /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before. */
+ if (l->l_cet != lc_unknown)
+ return;
+
/* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in
32-bit objects and to 8 bytes in 64-bit objects. Skip notes
with incorrect alignment. */
@@ -57,6 +61,9 @@ _dl_process_cet_property_note (struct link_map *l,
const ElfW(Addr) start = (ElfW(Addr)) note;
+ unsigned int feature_1 = 0;
+ unsigned int last_type = 0;
+
while ((ElfW(Addr)) (note + 1) - start < size)
{
/* Find the NT_GNU_PROPERTY_TYPE_0 note. */
@@ -64,10 +71,18 @@ _dl_process_cet_property_note (struct link_map *l,
&& note->n_type == NT_GNU_PROPERTY_TYPE_0
&& memcmp (note + 1, "GNU", 4) == 0)
{
+ /* Stop if we see more than one GNU property note which may
+ be generated by the older linker. */
+ if (l->l_cet != lc_unknown)
+ return;
+
+ /* Check CET status now. */
+ l->l_cet = lc_none;
+
/* Check for invalid property. */
if (note->n_descsz < 8
|| (note->n_descsz % sizeof (ElfW(Addr))) != 0)
- break;
+ return;
/* Start and end of property array. */
unsigned char *ptr = (unsigned char *) (note + 1) + 4;
@@ -78,9 +93,15 @@ _dl_process_cet_property_note (struct link_map *l,
unsigned int type = *(unsigned int *) ptr;
unsigned int datasz = *(unsigned int *) (ptr + 4);
+ /* Property type must be in ascending order. */
+ if (type < last_type)
+ return;
+
ptr += 8;
if ((ptr + datasz) > ptr_end)
- break;
+ return;
+
+ last_type = type;
if (type == GNU_PROPERTY_X86_FEATURE_1_AND)
{
@@ -89,14 +110,18 @@ _dl_process_cet_property_note (struct link_map *l,
we stop the search regardless if its size is correct
or not. There is no point to continue if this note
is ill-formed. */
- if (datasz == 4)
- {
- unsigned int feature_1 = *(unsigned int *) ptr;
- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
- l->l_cet |= lc_ibt;
- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
- l->l_cet |= lc_shstk;
- }
+ if (datasz != 4)
+ return;
+
+ feature_1 = *(unsigned int *) ptr;
+
+ /* Keep searching for the next GNU property note
+ generated by the older linker. */
+ break;
+ }
+ else if (type > GNU_PROPERTY_X86_FEATURE_1_AND)
+ {
+ /* Stop since property type is in ascending order. */
return;
}
@@ -112,6 +137,12 @@ _dl_process_cet_property_note (struct link_map *l,
+ ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz,
align));
}
+
+ /* We get here only if there is one or no GNU property note. */
+ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
+ l->l_cet |= lc_ibt;
+ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
+ l->l_cet |= lc_shstk;
#endif
}
diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h
index ef1206a9d2..9367ed0889 100644
--- a/sysdeps/x86/link_map.h
+++ b/sysdeps/x86/link_map.h
@@ -19,8 +19,9 @@
/* If this object is enabled with CET. */
enum
{
- lc_none = 0, /* Not enabled with CET. */
- lc_ibt = 1 << 0, /* Enabled with IBT. */
- lc_shstk = 1 << 1, /* Enabled with STSHK. */
+ lc_unknown = 0, /* Unknown CET status. */
+ lc_none = 1 << 0, /* Not enabled with CET. */
+ lc_ibt = 1 << 1, /* Enabled with IBT. */
+ lc_shstk = 1 << 2, /* Enabled with STSHK. */
lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both. */
- } l_cet:2;
+ } l_cet:3;

View file

@ -0,0 +1,51 @@
From b21abc069f58da3f8e556ec730f0a387cfc91f5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
Date: Fri, 19 Oct 2018 13:30:44 +0200
Subject: [PATCH 36] Add an additional test to resolv/tst-resolv-network.c
Test for the infinite loop in getnetbyname, bug #17630.
(cherry picked from commit ac8060265bcaca61568ef3a20b9a0140a270af54)
---
ChangeLog | 5 +++++
resolv/tst-resolv-network.c | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 86bdf17989..d020aff979 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-08 Alexandra Hájková <ahajkova@redhat.com>
+
+ [BZ #17630]
+ * resolv/tst-resolv-network.c: Add test for getnetbyname.
+
2018-11-08 H.J. Lu <hongjiu.lu@intel.com>
[BZ #23509]
diff --git a/resolv/tst-resolv-network.c b/resolv/tst-resolv-network.c
index 4b862d57e6..735e38d0f8 100644
--- a/resolv/tst-resolv-network.c
+++ b/resolv/tst-resolv-network.c
@@ -149,6 +149,9 @@ handle_code (const struct resolv_response_context *ctx,
resolv_response_add_data (b, &rrtype, sizeof (rrtype));
}
break;
+ case 104:
+ send_ptr (b, qname, qclass, qtype, "host.example");
+ break;
default:
FAIL_EXIT1 ("invalid QNAME: %s (code %d)", qname, code);
}
@@ -257,6 +260,9 @@ do_test (void)
"error: TRY_AGAIN\n");
check_netent ("code103.example", getnetbyname ("code103.example"),
"error: NO_RECOVERY\n");
+ /* Test bug #17630. */
+ check_netent ("code104.example", getnetbyname ("code104.example"),
+ "error: TRY_AGAIN\n");
/* Lookup by address, success cases. */
check_reverse (1,

View file

@ -0,0 +1,69 @@
From 168035056eab9db4ee0e5d7f62060e111b86a0a4 Mon Sep 17 00:00:00 2001
From: Joseph Myers <joseph@codesourcery.com>
Date: Mon, 13 Aug 2018 21:35:27 +0000
Subject: [PATCH 37] 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)
---
ChangeLog | 7 +++++++
sysdeps/unix/sysv/linux/syscall-names.list | 6 ++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d020aff979..88814e6947 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-11-08 Alexandra Hájková <ahajkova@redhat.com>
[BZ #17630]
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 5306d538e6..9982a6334d 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

View file

@ -0,0 +1,48 @@
From 510a25f2d208e3b0c86f54b053f61c5b647e4b9b Mon Sep 17 00:00:00 2001
From: Pochang Chen <johnchen902@gmail.com>
Date: Thu, 16 Aug 2018 15:24:24 -0400
Subject: [PATCH 38] malloc: Verify size of top chunk.
The House of Force is a well-known technique to exploit heap
overflow. In essence, this exploit takes three steps:
1. Overwrite the size of top chunk with very large value (e.g. -1).
2. Request x bytes from top chunk. As the size of top chunk
is corrupted, x can be arbitrarily large and top chunk will
still be offset by x.
3. The next allocation from top chunk will thus be controllable.
If we verify the size of top chunk at step 2, we can stop such attack.
(cherry picked from commit 30a17d8c95fbfb15c52d1115803b63aaa73a285c)
---
ChangeLog | 4 ++++
malloc/malloc.c | 3 +++
2 files changed, 7 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 88814e6947..44795b2e61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-08-16 Pochang Chen <johnchen902@gmail.com>
+
+ * malloc/malloc.c (_int_malloc.c): Verify size of top chunk.
+
2018-08-13 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
diff --git a/malloc/malloc.c b/malloc/malloc.c
index e247c77b7d..9431108626 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -4076,6 +4076,9 @@ _int_malloc (mstate av, size_t bytes)
victim = av->top;
size = chunksize (victim);
+ if (__glibc_unlikely (size > av->system_mem))
+ malloc_printerr ("malloc(): corrupted top size");
+
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
{
remainder_size = size - nb;

View file

@ -0,0 +1,50 @@
From 7e40c3f804b5d5dbbc0519565b16101ab22fb899 Mon Sep 17 00:00:00 2001
From: Moritz Eckert <m.eckert@cs.ucsb.edu>
Date: Thu, 16 Aug 2018 21:08:36 -0400
Subject: [PATCH 39] malloc: Mitigate null-byte overflow attacks
* malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
(malloc_consolidate): Likewise.
(cherry picked from commit d6db68e66dff25d12c3bc5641b60cbd7fb6ab44f)
---
ChangeLog | 5 +++++
malloc/malloc.c | 4 ++++
2 files changed, 9 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 44795b2e61..e81991066e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-16 DJ Delorie <dj@delorie.com>
+
+ * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
+ (malloc_consolidate): Likewise.
+
2018-08-16 Pochang Chen <johnchen902@gmail.com>
* malloc/malloc.c (_int_malloc.c): Verify size of top chunk.
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 9431108626..7c8bf8413c 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -4281,6 +4281,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
+ if (__glibc_unlikely (chunksize(p) != prevsize))
+ malloc_printerr ("corrupted size vs. prev_size while consolidating");
unlink(av, p, bck, fwd);
}
@@ -4442,6 +4444,8 @@ static void malloc_consolidate(mstate av)
prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
+ if (__glibc_unlikely (chunksize(p) != prevsize))
+ malloc_printerr ("corrupted size vs. prev_size in fastbins");
unlink(av, p, bck, fwd);
}

View file

@ -0,0 +1,52 @@
From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001
From: Istvan Kurucsai <pistukem@gmail.com>
Date: Tue, 16 Jan 2018 14:48:16 +0100
Subject: [PATCH v2 1] malloc: Additional checks for unsorted bin integrity
I.
Ensure the following properties of chunks encountered during binning:
- victim chunk has reasonable size
- next chunk has reasonable size
- next->prev_size == victim->size
- valid double linked list
- PREV_INUSE of next chunk is unset
* malloc/malloc.c (_int_malloc): Additional binning code checks.
(cherry picked from commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)
---
malloc/malloc.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 7c8bf8413c..47795601c8 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3716,11 +3716,22 @@ _int_malloc (mstate av, size_t bytes)
while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
{
bck = victim->bk;
- if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
- || __builtin_expect (chunksize_nomask (victim)
- > av->system_mem, 0))
- malloc_printerr ("malloc(): memory corruption");
size = chunksize (victim);
+ mchunkptr next = chunk_at_offset (victim, size);
+
+ if (__glibc_unlikely (size <= 2 * SIZE_SZ)
+ || __glibc_unlikely (size > av->system_mem))
+ malloc_printerr ("malloc(): invalid size (unsorted)");
+ if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ)
+ || __glibc_unlikely (chunksize_nomask (next) > av->system_mem))
+ malloc_printerr ("malloc(): invalid next size (unsorted)");
+ if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size))
+ malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)");
+ if (__glibc_unlikely (bck->fd != victim)
+ || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
+ malloc_printerr ("malloc(): unsorted double linked list corrupted");
+ if (__glibc_unlikely (prev_inuse(next)))
+ malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");
/*
If a small request, try to use last remainder if it is the

View file

@ -0,0 +1,153 @@
From 7d174f53539bfbfa9cdfa41ead605573d3f219eb Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 28 Aug 2018 13:19:27 +0200
Subject: [PATCH 41] nscd: Fix use-after-free in addgetnetgrentX [BZ #23520]
addinnetgrX may use the heap-allocated buffer, so free the buffer
in this function.
(cherry picked from commit 745664bd798ec8fd50438605948eea594179fba1)
---
ChangeLog | 12 ++++++++++++
nscd/netgroupcache.c | 42 +++++++++++++++++++++++++++++-------------
2 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e81991066e..79d303e7b6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-08-28 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23520]
+ nscd: Fix use-after-free in addgetnetgrentX and its callers.
+ * nscd/netgroupcache.c
+ (addgetnetgrentX): Add tofreep parameter. Do not free
+ heap-allocated buffer.
+ (addinnetgrX): Free buffer allocated bt addgetnetgrentX.
+ (addgetnetgrentX_ignore): New function.
+ (addgetnetgrent): Call it.
+ (readdgetnetgrent): Likewise.
+
2018-08-16 DJ Delorie <dj@delorie.com>
* malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 2b35389cc8..87059fb280 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -113,7 +113,8 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *key, uid_t uid, struct hashentry *he,
- struct datahead *dh, struct dataset **resultp)
+ struct datahead *dh, struct dataset **resultp,
+ void **tofreep)
{
if (__glibc_unlikely (debug_level > 0))
{
@@ -139,6 +140,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
size_t group_len = strlen (key) + 1;
struct name_list *first_needed
= alloca (sizeof (struct name_list) + group_len);
+ *tofreep = NULL;
if (netgroup_database == NULL
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
@@ -151,6 +153,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
memset (&data, '\0', sizeof (data));
buffer = xmalloc (buflen);
+ *tofreep = buffer;
first_needed->next = first_needed;
memcpy (first_needed->name, key, group_len);
data.needed_groups = first_needed;
@@ -439,8 +442,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
out:
- free (buffer);
-
*resultp = dataset;
return timeout;
@@ -477,8 +478,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
group, group_len,
db, uid);
time_t timeout;
+ void *tofree;
if (result != NULL)
- timeout = result->head.timeout;
+ {
+ timeout = result->head.timeout;
+ tofree = NULL;
+ }
else
{
request_header req_get =
@@ -487,7 +492,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
.key_len = group_len
};
timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
- &result);
+ &result, &tofree);
}
struct indataset
@@ -560,7 +565,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
++dh->nreloads;
if (cacheable)
pthread_rwlock_unlock (&db->lock);
- return timeout;
+ goto out;
}
if (he == NULL)
@@ -596,17 +601,30 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
dh->usable = false;
}
+ out:
+ free (tofree);
return timeout;
}
+static time_t
+addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
+ const char *key, uid_t uid, struct hashentry *he,
+ struct datahead *dh)
+{
+ struct dataset *ignore;
+ void *tofree;
+ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
+ &ignore, &tofree);
+ free (tofree);
+ return timeout;
+}
+
void
addgetnetgrent (struct database_dyn *db, int fd, request_header *req,
void *key, uid_t uid)
{
- struct dataset *ignore;
-
- addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore);
+ addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL);
}
@@ -619,10 +637,8 @@ readdgetnetgrent (struct database_dyn *db, struct hashentry *he,
.type = GETNETGRENT,
.key_len = he->len
};
- struct dataset *ignore;
-
- return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh,
- &ignore);
+ return addgetnetgrentX_ignore
+ (db, -1, &req, db->data + he->key, he->owner, he, dh);
}

View file

@ -0,0 +1,286 @@
From 9071be6b3f78da905ab2b6403933fe14d4482e47 Mon Sep 17 00:00:00 2001
From: Paul Pluzhnikov <ppluzhnikov@google.com>
Date: Fri, 31 Aug 2018 18:04:32 -0700
Subject: [PATCH 42] [BZ #20271] Add newlines in __libc_fatal calls.
(cherry picked from commit a6e8926f8d49a213a9abb1a61f6af964f612ab7f)
---
ChangeLog | 22 +++++++++++++++++++
grp/initgroups.c | 2 +-
include/stdio.h | 3 ++-
nptl/pthread_cond_wait.c | 2 +-
nscd/initgrcache.c | 2 +-
nss/nsswitch.c | 2 +-
sysdeps/aarch64/dl-irel.h | 2 +-
sysdeps/arm/dl-irel.h | 2 +-
sysdeps/generic/unwind-dw2.c | 2 +-
sysdeps/i386/dl-irel.h | 2 +-
sysdeps/nptl/futex-internal.h | 2 +-
sysdeps/powerpc/powerpc32/dl-irel.h | 2 +-
sysdeps/powerpc/powerpc64/dl-irel.h | 2 +-
sysdeps/s390/dl-irel.h | 2 +-
sysdeps/sparc/sparc32/dl-irel.h | 2 +-
sysdeps/sparc/sparc64/dl-irel.h | 2 +-
.../unix/sysv/linux/netlink_assert_response.c | 4 ++--
sysdeps/x86_64/dl-irel.h | 2 +-
18 files changed, 41 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 79d303e7b6..5145768a45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2018-08-31 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ [BZ #20271]
+ * include/stdio.h (__libc_fatal): Mention newline in comment.
+ * grp/initgroups.c (internal_getgrouplist): Add missing newline.
+ * nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Likewise.
+ * nscd/initgrcache.c (addinitgroupsX): Likewise.
+ * nss/nsswitch.c (__nss_next2): Likewise.
+ * sysdeps/aarch64/dl-irel.h (elf_irela): Likewise.
+ * sysdeps/arm/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/generic/unwind-dw2.c (execute_cfa_program): Likewise.
+ * sysdeps/i386/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/powerpc/powerpc32/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/powerpc/powerpc64/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/s390/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/sparc/sparc32/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/sparc/sparc64/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/x86_64/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/nptl/futex-internal.h (futex_wake): Likewise.
+ * sysdeps/unix/sysv/linux/netlink_assert_response.c
+ (__netlink_assert_response): Likewise.
+
2018-08-28 Florian Weimer <fweimer@redhat.com>
[BZ #23520]
diff --git a/grp/initgroups.c b/grp/initgroups.c
index f056fbf5aa..93e7f5814d 100644
--- a/grp/initgroups.c
+++ b/grp/initgroups.c
@@ -128,7 +128,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
/* This is really only for debugging. */
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
- __libc_fatal ("illegal status in internal_getgrouplist");
+ __libc_fatal ("Illegal status in internal_getgrouplist.\n");
/* For compatibility reason we will continue to look for more
entries using the next service even though data has already
diff --git a/include/stdio.h b/include/stdio.h
index 9162d4e247..7a5c09089f 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -98,7 +98,8 @@ enum __libc_message_action
do_backtrace = 1 << 1 /* Backtrace. */
};
-/* Print out MESSAGE on the error output and abort. */
+/* Print out MESSAGE (which should end with a newline) on the error output
+ and abort. */
extern void __libc_fatal (const char *__message)
__attribute__ ((__noreturn__));
extern void __libc_message (enum __libc_message_action action,
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index 3e11054182..ebf07ca82d 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -516,7 +516,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec rt;
if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0)
__libc_fatal ("clock_gettime does not support "
- "CLOCK_MONOTONIC");
+ "CLOCK_MONOTONIC\n");
/* Convert the absolute timeout value to a relative
timeout. */
rt.tv_sec = abstime->tv_sec - rt.tv_sec;
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index 2c74951f57..4764f14a45 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -159,7 +159,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
/* This is really only for debugging. */
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
- __libc_fatal ("illegal status in internal_getgrouplist");
+ __libc_fatal ("Illegal status in internal_getgrouplist.\n");
any_success |= status == NSS_STATUS_SUCCESS;
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index ee46f24424..3c48b4b85e 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -235,7 +235,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name,
/* This is really only for debugging. */
if (__builtin_expect (NSS_STATUS_TRYAGAIN > status
|| status > NSS_STATUS_RETURN, 0))
- __libc_fatal ("illegal status in __nss_next");
+ __libc_fatal ("Illegal status in __nss_next.\n");
if (nss_next_action (*ni, status) == NSS_ACTION_RETURN)
return 1;
diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h
index 5889ee187b..bef71ed0f3 100644
--- a/sysdeps/aarch64/dl-irel.h
+++ b/sysdeps/aarch64/dl-irel.h
@@ -47,7 +47,7 @@ elf_irela (const ElfW(Rela) *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif
diff --git a/sysdeps/arm/dl-irel.h b/sysdeps/arm/dl-irel.h
index a7b6456075..be6eb7743e 100644
--- a/sysdeps/arm/dl-irel.h
+++ b/sysdeps/arm/dl-irel.h
@@ -46,7 +46,7 @@ elf_irel (const Elf32_Rel *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c
index 082609b34a..724c16a7f0 100644
--- a/sysdeps/generic/unwind-dw2.c
+++ b/sysdeps/generic/unwind-dw2.c
@@ -843,7 +843,7 @@ execute_cfa_program (const unsigned char *insn_ptr,
struct frame_state_reg_info *old_rs = fs->regs.prev;
#ifdef _LIBC
if (old_rs == NULL)
- __libc_fatal ("invalid DWARF unwind data");
+ __libc_fatal ("Invalid DWARF unwind data.\n");
else
#endif
{
diff --git a/sysdeps/i386/dl-irel.h b/sysdeps/i386/dl-irel.h
index 55303180c7..bcaf0668ac 100644
--- a/sysdeps/i386/dl-irel.h
+++ b/sysdeps/i386/dl-irel.h
@@ -45,7 +45,7 @@ elf_irel (const Elf32_Rel *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index 1a5624789d..6fd27f0df6 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -197,7 +197,7 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private);
static __always_inline __attribute__ ((__noreturn__)) void
futex_fatal_error (void)
{
- __libc_fatal ("The futex facility returned an unexpected error code.");
+ __libc_fatal ("The futex facility returned an unexpected error code.\n");
}
#endif /* futex-internal.h */
diff --git a/sysdeps/powerpc/powerpc32/dl-irel.h b/sysdeps/powerpc/powerpc32/dl-irel.h
index a7368b2582..61d0e4cf61 100644
--- a/sysdeps/powerpc/powerpc32/dl-irel.h
+++ b/sysdeps/powerpc/powerpc32/dl-irel.h
@@ -46,7 +46,7 @@ elf_irela (const Elf32_Rela *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h
index ab13c04358..2fd0ee8a86 100644
--- a/sysdeps/powerpc/powerpc64/dl-irel.h
+++ b/sysdeps/powerpc/powerpc64/dl-irel.h
@@ -57,7 +57,7 @@ elf_irela (const Elf64_Rela *reloc)
#endif
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h
index d8ba7ba427..ecb24f0a9b 100644
--- a/sysdeps/s390/dl-irel.h
+++ b/sysdeps/s390/dl-irel.h
@@ -46,7 +46,7 @@ elf_irela (const ElfW(Rela) *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/sparc/sparc32/dl-irel.h b/sysdeps/sparc/sparc32/dl-irel.h
index ffca36864f..cf47cda834 100644
--- a/sysdeps/sparc/sparc32/dl-irel.h
+++ b/sysdeps/sparc/sparc32/dl-irel.h
@@ -56,7 +56,7 @@ elf_irela (const Elf32_Rela *reloc)
else if (r_type == R_SPARC_NONE)
;
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/sparc/sparc64/dl-irel.h b/sysdeps/sparc/sparc64/dl-irel.h
index c5cd3057ac..446fed1836 100644
--- a/sysdeps/sparc/sparc64/dl-irel.h
+++ b/sysdeps/sparc/sparc64/dl-irel.h
@@ -59,7 +59,7 @@ elf_irela (const Elf64_Rela *reloc)
else if (r_type == R_SPARC_NONE)
;
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
index f31ccb52ff..6afc3a17ce 100644
--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
+++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
@@ -72,12 +72,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);
}
diff --git a/sysdeps/x86_64/dl-irel.h b/sysdeps/x86_64/dl-irel.h
index 6ecc50fb42..33f100d8b1 100644
--- a/sysdeps/x86_64/dl-irel.h
+++ b/sysdeps/x86_64/dl-irel.h
@@ -45,7 +45,7 @@ elf_irela (const ElfW(Rela) *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */

View file

@ -0,0 +1,45 @@
From e7388e5134471ef965bd48bafc71ba71eb8bf017 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 18 Sep 2018 15:02:10 -0700
Subject: [PATCH 43] Fix tzfile low-memory assertion failure
[BZ #21716]
* time/tzfile.c (__tzfile_read): Check for memory exhaustion
when registering time zone abbreviations.
(cherry picked from commit e4e4fde51a309801af5eed72d3494cbf4b7737aa)
---
ChangeLog | 7 +++++++
time/tzfile.c | 3 ++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 5145768a45..788f3f41be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-09-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix tzfile low-memory assertion failure
+ [BZ #21716]
+ * time/tzfile.c (__tzfile_read): Check for memory exhaustion
+ when registering time zone abbreviations.
+
2018-08-31 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #20271]
diff --git a/time/tzfile.c b/time/tzfile.c
index 2a385b92bc..ea6e940303 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -410,7 +410,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
/* First "register" all timezone names. */
for (i = 0; i < num_types; ++i)
- (void) __tzstring (&zone_names[types[i].idx]);
+ if (__tzstring (&zone_names[types[i].idx]) == NULL)
+ goto ret_free_transitions;
/* Find the standard and daylight time offsets used by the rule file.
We choose the offsets in the types of each flavor that are

View file

@ -0,0 +1,49 @@
From f44c2ca5eacd2df76fc38be75f9ebb8f0ff555eb Mon Sep 17 00:00:00 2001
From: Joseph Myers <joseph@codesourcery.com>
Date: Mon, 22 Oct 2018 23:26:37 +0000
Subject: [PATCH 44] 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)
---
ChangeLog | 5 +++++
sysdeps/unix/sysv/linux/syscall-names.list | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 788f3f41be..f2e0f1ffd7 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-09-18 Paul Eggert <eggert@cs.ucla.edu>
Fix tzfile low-memory assertion failure
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 9982a6334d..f88001c9c3 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

View file

@ -0,0 +1,53 @@
From 10f1519f6a0acdc1fc45e962fa5c13312cc7b624 Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Tue, 9 Oct 2018 14:31:28 +0100
Subject: [PATCH 45] Increase timeout of libio/tst-readline
Increase timeout from the default 20s to 100s. This test makes close to
20 million syscalls with distribution:
12327675 read
4143204 lseek
929475 close
929471 openat
92817 fstat
1431 write
...
The default timeout assumes each can finish in 1us on average which
is not true on slow machines.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* libio/tst-readline.c (TIMEOUT): Define.
(cherry picked from commit ed643089cd3251038863d32e67ec47b94cd557f3)
---
ChangeLog | 4 ++++
libio/tst-readline.c | 1 +
2 files changed, 5 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index f2e0f1ffd7..99462fa3d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-09 Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+ * libio/tst-readline.c (TIMEOUT): Define.
+
2018-10-22 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
diff --git a/libio/tst-readline.c b/libio/tst-readline.c
index 9322ef68da..63f5227760 100644
--- a/libio/tst-readline.c
+++ b/libio/tst-readline.c
@@ -232,5 +232,6 @@ do_test (void)
return 0;
}
+#define TIMEOUT 100
#define PREPARE prepare
#include <support/test-driver.c>

View file

@ -0,0 +1,91 @@
From 2c7078bfb9cc426433ac08d951e24c29c01b5f7d Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 19 Nov 2018 15:35:03 +0100
Subject: [PATCH 46] support: Print timestamps in timeout handler
This is sometimes useful to determine if a test truly got stuck, or if
it was making progress (logging information to standard output) and
was merely slow to finish.
(cherry picked from commit 35e3fbc4512c880fccb35b8e3abd132d4be18480)
---
ChangeLog | 7 +++++++
support/support_test_main.c | 28 ++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 99462fa3d4..8c92ee7764 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-19 Florian Weimer <fweimer@redhat.com>
+
+ support: Print timestamps in timeout handler.
+ * support/support_test_main.c (print_timestamp): New function.
+ (signal_handler): Use it to print the termination time and the
+ time of the last write to standard output.
+
2018-10-09 Szabolcs Nagy <szabolcs.nagy@arm.com>
* libio/tst-readline.c (TIMEOUT): Define.
diff --git a/support/support_test_main.c b/support/support_test_main.c
index 23429779ac..fa3c2e06de 100644
--- a/support/support_test_main.c
+++ b/support/support_test_main.c
@@ -30,6 +30,7 @@
#include <string.h>
#include <sys/param.h>
#include <sys/resource.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
@@ -86,6 +87,19 @@ static pid_t test_pid;
/* The cleanup handler passed to test_main. */
static void (*cleanup_function) (void);
+static void
+print_timestamp (const char *what, struct timeval tv)
+{
+ struct tm tm;
+ if (gmtime_r (&tv.tv_sec, &tm) == NULL)
+ printf ("%s: %lld.%06d\n",
+ what, (long long int) tv.tv_sec, (int) tv.tv_usec);
+ else
+ printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
+ what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
+}
+
/* Timeout handler. We kill the child and exit with an error. */
static void
__attribute__ ((noreturn))
@@ -94,6 +108,13 @@ signal_handler (int sig)
int killed;
int status;
+ /* Do this first to avoid further interference from the
+ subprocess. */
+ struct timeval now;
+ bool now_available = gettimeofday (&now, NULL) == 0;
+ struct stat64 st;
+ bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0;
+
assert (test_pid > 1);
/* Kill the whole process group. */
kill (-test_pid, SIGKILL);
@@ -144,6 +165,13 @@ signal_handler (int sig)
printf ("Timed out: killed the child process but it exited %d\n",
WEXITSTATUS (status));
+ if (now_available)
+ print_timestamp ("Termination time", now);
+ if (st_available)
+ print_timestamp ("Last write to standard output",
+ (struct timeval) { st.st_mtim.tv_sec,
+ st.st_mtim.tv_nsec / 1000 });
+
/* Exit with an error. */
exit (1);
}

View file

@ -0,0 +1,261 @@
From 481a6cf0c24f02f251d7cd0b776c12d00e6b144f Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@delorie.com>
Date: Tue, 20 Nov 2018 13:24:09 -0500
Subject: [PATCH 47] malloc: tcache double free check
* malloc/malloc.c (tcache_entry): Add key field.
(tcache_put): Set it.
(tcache_get): Likewise.
(_int_free): Check for double free in tcache.
* malloc/tst-tcfree1.c: New.
* malloc/tst-tcfree2.c: New.
* malloc/Makefile: Run the new tests.
* manual/probes.texi: Document memory_tcache_double_free probe.
* dlfcn/dlerror.c (check_free): Prevent double frees.
---
ChangeLog | 12 +++++++++++
dlfcn/dlerror.c | 5 ++++-
malloc/Makefile | 1 +
malloc/malloc.c | 28 ++++++++++++++++++++++++++
malloc/tst-tcfree1.c | 42 ++++++++++++++++++++++++++++++++++++++
malloc/tst-tcfree2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
manual/probes.texi | 12 +++++++++++
7 files changed, 147 insertions(+), 1 deletion(-)
create mode 100644 malloc/tst-tcfree1.c
create mode 100644 malloc/tst-tcfree2.c
diff --git a/ChangeLog b/ChangeLog
index 8c92ee7764..1ef4b4abe0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-11-20 DJ Delorie <dj@redhat.com>
+
+ * malloc/malloc.c (tcache_entry): Add key field.
+ (tcache_put): Set it.
+ (tcache_get): Likewise.
+ (_int_free): Check for double free in tcache.
+ * malloc/tst-tcfree1.c: New.
+ * malloc/tst-tcfree2.c: New.
+ * malloc/Makefile: Run the new tests.
+ * manual/probes.texi: Document memory_tcache_double_free probe.
+
+ * dlfcn/dlerror.c (check_free): Prevent double frees.
2018-11-19 Florian Weimer <fweimer@redhat.com>
support: Print timestamps in timeout handler.
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 33574faab6..96bf925333 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec)
Dl_info info;
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
#endif
- free ((char *) rec->errstring);
+ {
+ free ((char *) rec->errstring);
+ rec->errstring = NULL;
+ }
}
}
diff --git a/malloc/Makefile b/malloc/Makefile
index 7d54bad866..e6dfbfc14c 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc_info \
tst-malloc-too-large \
tst-malloc-stats-cancellation \
+ tst-tcfree1 tst-tcfree2 \
tests-static := \
tst-interpose-static-nothread \
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 47795601c8..6be2573868 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size)
typedef struct tcache_entry
{
struct tcache_entry *next;
+ /* This field exists to detect double frees. */
+ struct tcache_perthread_struct *key;
} tcache_entry;
/* There is one of these for each thread, which contains the
@@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);
+
+ /* Mark this chunk as "in the tcache" so the test in _int_free will
+ detect a double free. */
+ e->key = tcache;
+
e->next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
@@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx)
assert (tcache->entries[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
+ e->key = NULL;
return (void *) e;
}
@@ -4166,6 +4174,26 @@ _int_free (mstate av, mchunkptr p, int have_lock)
{
size_t tc_idx = csize2tidx (size);
+ /* Check to see if it's already in the tcache. */
+ tcache_entry *e = (tcache_entry *) chunk2mem (p);
+
+ /* This test succeeds on double free. However, we don't 100%
+ trust it (it also matches random payload data at a 1 in
+ 2^<size_t> chance), so verify it's not an unlikely coincidence
+ before aborting. */
+ if (__glibc_unlikely (e->key == tcache && tcache))
+ {
+ tcache_entry *tmp;
+ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
+ for (tmp = tcache->entries[tc_idx];
+ tmp;
+ tmp = tmp->next)
+ if (tmp == e)
+ malloc_printerr ("free(): double free detected in tcache 2");
+ /* If we get here, it was a coincidence. We've wasted a few
+ cycles, but don't abort. */
+ }
+
if (tcache
&& tc_idx < mp_.tcache_bins
&& tcache->counts[tc_idx] < mp_.tcache_count)
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
new file mode 100644
index 0000000000..bc29375ce7
--- /dev/null
+++ b/malloc/tst-tcfree1.c
@@ -0,0 +1,42 @@
+/* Test that malloc tcache catches double free.
+ 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 <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ /* Do one allocation of any size that fits in tcache. */
+ char * volatile x = malloc (32);
+
+ free (x); // puts in tcache
+ free (x); // should abort
+
+ printf("FAIL: tcache double free not detected\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
new file mode 100644
index 0000000000..17f06bacd4
--- /dev/null
+++ b/malloc/tst-tcfree2.c
@@ -0,0 +1,48 @@
+/* Test that malloc tcache catches double free.
+ 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 <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ char * volatile ptrs[20];
+ int i;
+
+ /* Allocate enough small chunks so that when we free them all, the tcache
+ is full, and the first one we freed is at the end of its linked list. */
+#define COUNT 20
+ for (i=0; i<COUNT; i++)
+ ptrs[i] = malloc (20);
+ for (i=0; i<COUNT; i++)
+ free (ptrs[i]);
+ free (ptrs[0]);
+
+ printf("FAIL: tcache double free\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/manual/probes.texi b/manual/probes.texi
index ab2a3102bb..0ea560ed78 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -243,6 +243,18 @@ This probe is triggered when the
value of this tunable.
@end deftp
+@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
+This probe is triggered when @code{free} determines that the memory
+being freed has probably already been freed, and resides in the
+per-thread cache. Note that there is an extremely unlikely chance
+that this probe will trigger due to random payload data remaining in
+the allocated memory matching the key used to detect double frees.
+This probe actually indicates that an expensive linear search of the
+tcache, looking for a double free, has happened. Argument @var{$arg1}
+is the memory location as passed to @code{free}, Argument @var{$arg2}
+is the tcache bin it resides in.
+@end deftp
+
@node Mathematical Function Probes
@section Mathematical Function Probes

View file

@ -0,0 +1,254 @@
From f5cc21eaeea6afbdfd543c63d2a552f141a91781 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Thu, 22 Nov 2018 22:05:57 +0100
Subject: [PATCH 48] Revert "malloc: tcache double free check" [BZ #23907]
This reverts commit 481a6cf0c24f02f251d7cd0b776c12d00e6b144f, the
backport of commit bcdaad21d4635931d1bd3b54a7894276925d081d on the
master branch.
---
ChangeLog | 12 -----------
dlfcn/dlerror.c | 5 +----
malloc/Makefile | 1 -
malloc/malloc.c | 28 --------------------------
malloc/tst-tcfree1.c | 42 --------------------------------------
malloc/tst-tcfree2.c | 48 --------------------------------------------
manual/probes.texi | 12 -----------
7 files changed, 1 insertion(+), 147 deletions(-)
delete mode 100644 malloc/tst-tcfree1.c
delete mode 100644 malloc/tst-tcfree2.c
diff --git a/ChangeLog b/ChangeLog
index 1ef4b4abe0..8c92ee7764 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,15 +1,3 @@
-2018-11-20 DJ Delorie <dj@redhat.com>
-
- * malloc/malloc.c (tcache_entry): Add key field.
- (tcache_put): Set it.
- (tcache_get): Likewise.
- (_int_free): Check for double free in tcache.
- * malloc/tst-tcfree1.c: New.
- * malloc/tst-tcfree2.c: New.
- * malloc/Makefile: Run the new tests.
- * manual/probes.texi: Document memory_tcache_double_free probe.
-
- * dlfcn/dlerror.c (check_free): Prevent double frees.
2018-11-19 Florian Weimer <fweimer@redhat.com>
support: Print timestamps in timeout handler.
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 96bf925333..33574faab6 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -198,10 +198,7 @@ check_free (struct dl_action_result *rec)
Dl_info info;
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
#endif
- {
- free ((char *) rec->errstring);
- rec->errstring = NULL;
- }
+ free ((char *) rec->errstring);
}
}
diff --git a/malloc/Makefile b/malloc/Makefile
index e6dfbfc14c..7d54bad866 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -38,7 +38,6 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc_info \
tst-malloc-too-large \
tst-malloc-stats-cancellation \
- tst-tcfree1 tst-tcfree2 \
tests-static := \
tst-interpose-static-nothread \
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 6be2573868..47795601c8 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2888,8 +2888,6 @@ mremap_chunk (mchunkptr p, size_t new_size)
typedef struct tcache_entry
{
struct tcache_entry *next;
- /* This field exists to detect double frees. */
- struct tcache_perthread_struct *key;
} tcache_entry;
/* There is one of these for each thread, which contains the
@@ -2913,11 +2911,6 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);
-
- /* Mark this chunk as "in the tcache" so the test in _int_free will
- detect a double free. */
- e->key = tcache;
-
e->next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
@@ -2933,7 +2926,6 @@ tcache_get (size_t tc_idx)
assert (tcache->entries[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
- e->key = NULL;
return (void *) e;
}
@@ -4174,26 +4166,6 @@ _int_free (mstate av, mchunkptr p, int have_lock)
{
size_t tc_idx = csize2tidx (size);
- /* Check to see if it's already in the tcache. */
- tcache_entry *e = (tcache_entry *) chunk2mem (p);
-
- /* This test succeeds on double free. However, we don't 100%
- trust it (it also matches random payload data at a 1 in
- 2^<size_t> chance), so verify it's not an unlikely coincidence
- before aborting. */
- if (__glibc_unlikely (e->key == tcache && tcache))
- {
- tcache_entry *tmp;
- LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
- for (tmp = tcache->entries[tc_idx];
- tmp;
- tmp = tmp->next)
- if (tmp == e)
- malloc_printerr ("free(): double free detected in tcache 2");
- /* If we get here, it was a coincidence. We've wasted a few
- cycles, but don't abort. */
- }
-
if (tcache
&& tc_idx < mp_.tcache_bins
&& tcache->counts[tc_idx] < mp_.tcache_count)
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
deleted file mode 100644
index bc29375ce7..0000000000
--- a/malloc/tst-tcfree1.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Test that malloc tcache catches double free.
- 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 <errno.h>
-#include <error.h>
-#include <limits.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/signal.h>
-
-static int
-do_test (void)
-{
- /* Do one allocation of any size that fits in tcache. */
- char * volatile x = malloc (32);
-
- free (x); // puts in tcache
- free (x); // should abort
-
- printf("FAIL: tcache double free not detected\n");
- return 1;
-}
-
-#define TEST_FUNCTION do_test
-#define EXPECTED_SIGNAL SIGABRT
-#include <support/test-driver.c>
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
deleted file mode 100644
index 17f06bacd4..0000000000
--- a/malloc/tst-tcfree2.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Test that malloc tcache catches double free.
- 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 <errno.h>
-#include <error.h>
-#include <limits.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/signal.h>
-
-static int
-do_test (void)
-{
- char * volatile ptrs[20];
- int i;
-
- /* Allocate enough small chunks so that when we free them all, the tcache
- is full, and the first one we freed is at the end of its linked list. */
-#define COUNT 20
- for (i=0; i<COUNT; i++)
- ptrs[i] = malloc (20);
- for (i=0; i<COUNT; i++)
- free (ptrs[i]);
- free (ptrs[0]);
-
- printf("FAIL: tcache double free\n");
- return 1;
-}
-
-#define TEST_FUNCTION do_test
-#define EXPECTED_SIGNAL SIGABRT
-#include <support/test-driver.c>
diff --git a/manual/probes.texi b/manual/probes.texi
index 0ea560ed78..ab2a3102bb 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -243,18 +243,6 @@ This probe is triggered when the
value of this tunable.
@end deftp
-@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
-This probe is triggered when @code{free} determines that the memory
-being freed has probably already been freed, and resides in the
-per-thread cache. Note that there is an extremely unlikely chance
-that this probe will trigger due to random payload data remaining in
-the allocated memory matching the key used to detect double frees.
-This probe actually indicates that an expensive linear search of the
-tcache, looking for a double free, has happened. Argument @var{$arg1}
-is the memory location as passed to @code{free}, Argument @var{$arg2}
-is the tcache bin it resides in.
-@end deftp
-
@node Mathematical Function Probes
@section Mathematical Function Probes

View file

@ -0,0 +1,76 @@
From ce6ba630dbc96f49eb1f30366aa62261df4792f9 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 27 Nov 2018 16:12:43 +0100
Subject: [PATCH 49] CVE-2018-19591: if_nametoindex: Fix descriptor for
overlong name [BZ #23927]
(cherry picked from commit d527c860f5a3f0ed687bd03f0cb464612dc23408)
---
ChangeLog | 7 +++++++
NEWS | 6 ++++++
sysdeps/unix/sysv/linux/if_index.c | 11 ++++++-----
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8c92ee7764..a997003664 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-27 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23927]
+ CVE-2018-19591
+ * sysdeps/unix/sysv/linux/if_index.c (__if_nametoindex): Avoid
+ descriptor leak in case of ENODEV error.
+
2018-11-19 Florian Weimer <fweimer@redhat.com>
support: Print timestamps in timeout handler.
diff --git a/NEWS b/NEWS
index e5ca5903ec..5290e21da9 100644
--- a/NEWS
+++ b/NEWS
@@ -25,7 +25,13 @@ The following bugs are resolved with this release:
[23717] Fix stack overflow in stdlib/tst-setcontext9
[23821] si_band in siginfo_t has wrong type long int on sparc64
[23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
+ [23927] Linux if_nametoindex() does not close descriptor (CVE-2018-19591)
+Security related changes:
+
+ CVE-2018-19591: A file descriptor leak in if_nametoindex can lead to a
+ denial of service due to resource exhaustion when processing getaddrinfo
+ calls with crafted host names. Reported by Guido Vranken.
Version 2.28
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index e3d08982d9..782fc5e175 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -38,11 +38,6 @@ __if_nametoindex (const char *ifname)
return 0;
#else
struct ifreq ifr;
- int fd = __opensock ();
-
- if (fd < 0)
- return 0;
-
if (strlen (ifname) >= IFNAMSIZ)
{
__set_errno (ENODEV);
@@ -50,6 +45,12 @@ __if_nametoindex (const char *ifname)
}
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return 0;
+
if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
{
int saved_errno = errno;

View file

@ -0,0 +1,291 @@
From b8dd0f42780a3133c02f064a2c0c5c4e7ab61aaa Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@delorie.com>
Date: Tue, 20 Nov 2018 13:24:09 -0500
Subject: [PATCH 50] malloc: tcache double free check
* malloc/malloc.c (tcache_entry): Add key field.
(tcache_put): Set it.
(tcache_get): Likewise.
(_int_free): Check for double free in tcache.
* malloc/tst-tcfree1.c: New.
* malloc/tst-tcfree2.c: New.
* malloc/Makefile: Run the new tests.
* manual/probes.texi: Document memory_tcache_double_free probe.
* dlfcn/dlerror.c (check_free): Prevent double frees.
(cherry picked from commit bcdaad21d4635931d1bd3b54a7894276925d081d)
malloc: tcache: Validate tc_idx before checking for double-frees [BZ #23907]
The previous check could read beyond the end of the tcache entry
array. If the e->key == tcache cookie check happened to pass, this
would result in crashes.
(cherry picked from commit affec03b713c82c43a5b025dddc21bde3334f41e)
---
ChangeLog | 20 ++++++++++++++++++
dlfcn/dlerror.c | 5 ++++-
malloc/Makefile | 1 +
malloc/malloc.c | 40 ++++++++++++++++++++++++++++++------
malloc/tst-tcfree1.c | 42 ++++++++++++++++++++++++++++++++++++++
malloc/tst-tcfree2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
manual/probes.texi | 12 +++++++++++
7 files changed, 161 insertions(+), 7 deletions(-)
create mode 100644 malloc/tst-tcfree1.c
create mode 100644 malloc/tst-tcfree2.c
diff --git a/ChangeLog b/ChangeLog
index a997003664..bc62a59c2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2018-11-26 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23907]
+ * malloc/malloc.c (_int_free): Validate tc_idx before checking for
+ double-frees.
+
+
+2018-11-20 DJ Delorie <dj@redhat.com>
+
+ * malloc/malloc.c (tcache_entry): Add key field.
+ (tcache_put): Set it.
+ (tcache_get): Likewise.
+ (_int_free): Check for double free in tcache.
+ * malloc/tst-tcfree1.c: New.
+ * malloc/tst-tcfree2.c: New.
+ * malloc/Makefile: Run the new tests.
+ * manual/probes.texi: Document memory_tcache_double_free probe.
+
+ * dlfcn/dlerror.c (check_free): Prevent double frees.
+
2018-11-27 Florian Weimer <fweimer@redhat.com>
[BZ #23927]
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 33574faab6..96bf925333 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec)
Dl_info info;
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
#endif
- free ((char *) rec->errstring);
+ {
+ free ((char *) rec->errstring);
+ rec->errstring = NULL;
+ }
}
}
diff --git a/malloc/Makefile b/malloc/Makefile
index 7d54bad866..e6dfbfc14c 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc_info \
tst-malloc-too-large \
tst-malloc-stats-cancellation \
+ tst-tcfree1 tst-tcfree2 \
tests-static := \
tst-interpose-static-nothread \
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 47795601c8..dad0e73735 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size)
typedef struct tcache_entry
{
struct tcache_entry *next;
+ /* This field exists to detect double frees. */
+ struct tcache_perthread_struct *key;
} tcache_entry;
/* There is one of these for each thread, which contains the
@@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);
+
+ /* Mark this chunk as "in the tcache" so the test in _int_free will
+ detect a double free. */
+ e->key = tcache;
+
e->next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
@@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx)
assert (tcache->entries[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
+ e->key = NULL;
return (void *) e;
}
@@ -4165,13 +4173,33 @@ _int_free (mstate av, mchunkptr p, int have_lock)
#if USE_TCACHE
{
size_t tc_idx = csize2tidx (size);
-
- if (tcache
- && tc_idx < mp_.tcache_bins
- && tcache->counts[tc_idx] < mp_.tcache_count)
+ if (tcache != NULL && tc_idx < mp_.tcache_bins)
{
- tcache_put (p, tc_idx);
- return;
+ /* Check to see if it's already in the tcache. */
+ tcache_entry *e = (tcache_entry *) chunk2mem (p);
+
+ /* This test succeeds on double free. However, we don't 100%
+ trust it (it also matches random payload data at a 1 in
+ 2^<size_t> chance), so verify it's not an unlikely
+ coincidence before aborting. */
+ if (__glibc_unlikely (e->key == tcache))
+ {
+ tcache_entry *tmp;
+ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
+ for (tmp = tcache->entries[tc_idx];
+ tmp;
+ tmp = tmp->next)
+ if (tmp == e)
+ malloc_printerr ("free(): double free detected in tcache 2");
+ /* If we get here, it was a coincidence. We've wasted a
+ few cycles, but don't abort. */
+ }
+
+ if (tcache->counts[tc_idx] < mp_.tcache_count)
+ {
+ tcache_put (p, tc_idx);
+ return;
+ }
}
}
#endif
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
new file mode 100644
index 0000000000..bc29375ce7
--- /dev/null
+++ b/malloc/tst-tcfree1.c
@@ -0,0 +1,42 @@
+/* Test that malloc tcache catches double free.
+ 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 <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ /* Do one allocation of any size that fits in tcache. */
+ char * volatile x = malloc (32);
+
+ free (x); // puts in tcache
+ free (x); // should abort
+
+ printf("FAIL: tcache double free not detected\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
new file mode 100644
index 0000000000..17f06bacd4
--- /dev/null
+++ b/malloc/tst-tcfree2.c
@@ -0,0 +1,48 @@
+/* Test that malloc tcache catches double free.
+ 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 <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ char * volatile ptrs[20];
+ int i;
+
+ /* Allocate enough small chunks so that when we free them all, the tcache
+ is full, and the first one we freed is at the end of its linked list. */
+#define COUNT 20
+ for (i=0; i<COUNT; i++)
+ ptrs[i] = malloc (20);
+ for (i=0; i<COUNT; i++)
+ free (ptrs[i]);
+ free (ptrs[0]);
+
+ printf("FAIL: tcache double free\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/manual/probes.texi b/manual/probes.texi
index ab2a3102bb..0ea560ed78 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -243,6 +243,18 @@ This probe is triggered when the
value of this tunable.
@end deftp
+@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
+This probe is triggered when @code{free} determines that the memory
+being freed has probably already been freed, and resides in the
+per-thread cache. Note that there is an extremely unlikely chance
+that this probe will trigger due to random payload data remaining in
+the allocated memory matching the key used to detect double frees.
+This probe actually indicates that an expensive linear search of the
+tcache, looking for a double free, has happened. Argument @var{$arg1}
+is the memory location as passed to @code{free}, Argument @var{$arg2}
+is the tcache bin it resides in.
+@end deftp
+
@node Mathematical Function Probes
@section Mathematical Function Probes

View file

@ -1,7 +1,7 @@
# Template file for 'glibc'
pkgname=glibc
version=2.28
revision=3
revision=4
bootstrap=yes
short_desc="The GNU C library"
maintainer="Juan RP <xtraeme@voidlinux.eu>"