diff --git a/srcpkgs/glibc/patches/glibc-upstream-26.patch b/srcpkgs/glibc/patches/glibc-upstream-26.patch index f4f096b3a67..385b5b83e8a 100644 --- a/srcpkgs/glibc/patches/glibc-upstream-26.patch +++ b/srcpkgs/glibc/patches/glibc-upstream-26.patch @@ -137,3 +137,4 @@ index 7449f8c7d5..945d5cdf28 100644 .weak __powf_compat .set __powf_compat,__powf .symver __powf_compat,powf@GLIBC_2.2 + diff --git a/srcpkgs/glibc/patches/glibc-upstream-27.patch b/srcpkgs/glibc/patches/glibc-upstream-27.patch new file mode 100644 index 00000000000..7e04413c7d1 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-27.patch @@ -0,0 +1,114 @@ +From df11de91931597ab4adccb74d9d55c9ddd029a22 Mon Sep 17 00:00:00 2001 +From: Paul Pluzhnikov +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 ++ ++ [BZ #23400] ++ * stdlib/test-bz22786.c (do_test): Fix undefined behavior, don't ++ create temporary files in source tree. ++ + 2018-10-26 Szabolcs Nagy + + [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 + #include + #include ++#include ++#include ++#include + #include + #include + + 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; + } + diff --git a/srcpkgs/glibc/patches/glibc-upstream-28.patch b/srcpkgs/glibc/patches/glibc-upstream-28.patch new file mode 100644 index 00000000000..d497195c927 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-28.patch @@ -0,0 +1,75 @@ +From d0b6db4acfba1f48b24da2c9b2a1530f6dd71503 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +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 + +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 ++ ++ * stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED ++ if malloc fails. ++ + 2018-08-24 Paul Pluzhnikov + + [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)); + diff --git a/srcpkgs/glibc/patches/glibc-upstream-29.patch b/srcpkgs/glibc/patches/glibc-upstream-29.patch new file mode 100644 index 00000000000..340274acce7 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-29.patch @@ -0,0 +1,540 @@ +From dcd52b94bf50f337dc4cfffa24ed86d7dfe03dc0 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 ++ ++ 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 + + * 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 + #include + #include ++#include + #include + #include + #include +@@ -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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 ++ . */ ++ ++#ifndef SUPPORT_BLOB_REPEAT_H ++#define SUPPORT_BLOB_REPEAT_H ++ ++#include ++#include ++ ++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 ++ 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 ++ . */ ++ ++#include ++#include ++#include ++ ++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 + diff --git a/srcpkgs/glibc/patches/glibc-upstream-30.patch b/srcpkgs/glibc/patches/glibc-upstream-30.patch new file mode 100644 index 00000000000..2f93e8aa77c --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-30.patch @@ -0,0 +1,50 @@ +From 69dcd992a0efdb53bc2ea4948cfc6b13416b9636 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 ++ ++ * stdlib/test-bz22786.c (do_test): Additional free calls to avoid ++ memory leaks. ++ + 2018-10-30 Florian Weimer + + 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; + } + diff --git a/srcpkgs/glibc/patches/glibc-upstream-31.patch b/srcpkgs/glibc/patches/glibc-upstream-31.patch new file mode 100644 index 00000000000..868c8f796f2 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-31.patch @@ -0,0 +1,63 @@ +From 6c2b6e9e2758b7491ce89920a8711c1b41100269 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 ++ ++ * support/blob_repeat.c (allocate_big): Call mkstemp directly. ++ + 2018-10-30 Florian Weimer + + * 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 + #include + #include ++#include + #include +-#include + #include + #include + #include +@@ -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); + } + diff --git a/srcpkgs/glibc/patches/glibc-upstream-32.patch b/srcpkgs/glibc/patches/glibc-upstream-32.patch new file mode 100644 index 00000000000..3403f583a68 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-32.patch @@ -0,0 +1,71 @@ +From e1af1df694603c0dcd5118c30eea2cdeb01a1a0b Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 ++ ++ * stdlib/tst-strtod-overflow.c (do_test): Switch to ++ support_blob_repeat. ++ + 2018-10-30 Florian Weimer + + * 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 + #include + #include ++#include ++#include + + #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; + } + + diff --git a/srcpkgs/glibc/patches/glibc-upstream-33.patch b/srcpkgs/glibc/patches/glibc-upstream-33.patch new file mode 100644 index 00000000000..0abaecea61f --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-33.patch @@ -0,0 +1,74 @@ +From 65010329f2c596bdd1204c1c9c9baac0193637af Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +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 ++ ++ [BZ #23709] ++ * sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits ++ independently of other flags. ++ + 2018-10-30 Florian Weimer + + * 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) + diff --git a/srcpkgs/glibc/patches/glibc-upstream-34.patch b/srcpkgs/glibc/patches/glibc-upstream-34.patch new file mode 100644 index 00000000000..44ae72e80bf --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-34.patch @@ -0,0 +1,58 @@ +From fc0e3393ff775aa795b523083bb0db7f18d3b91e Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +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 ++ ++ [BZ #22927] ++ * resolv/gai_misc.c (__gai_enqueue_request): Don't crash if ++ creating the first helper thread failed. ++ + 2018-10-23 Adhemerval Zanella + + [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; + diff --git a/srcpkgs/glibc/patches/glibc-upstream-35.patch b/srcpkgs/glibc/patches/glibc-upstream-35.patch new file mode 100644 index 00000000000..43f675dd6dd --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-35.patch @@ -0,0 +1,192 @@ +From 3e8d8dd5afba18a847ff7a80f473336f777cc329 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +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 ++ ++ [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 + + [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; + diff --git a/srcpkgs/glibc/patches/glibc-upstream-36.patch b/srcpkgs/glibc/patches/glibc-upstream-36.patch new file mode 100644 index 00000000000..32e736ee7fb --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-36.patch @@ -0,0 +1,51 @@ +From b21abc069f58da3f8e556ec730f0a387cfc91f5f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= +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á ++ ++ [BZ #17630] ++ * resolv/tst-resolv-network.c: Add test for getnetbyname. ++ + 2018-11-08 H.J. Lu + + [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, + diff --git a/srcpkgs/glibc/patches/glibc-upstream-37.patch b/srcpkgs/glibc/patches/glibc-upstream-37.patch new file mode 100644 index 00000000000..efac40ca15e --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-37.patch @@ -0,0 +1,69 @@ +From 168035056eab9db4ee0e5d7f62060e111b86a0a4 Mon Sep 17 00:00:00 2001 +From: Joseph Myers +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 ++ ++ * 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á + + [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 + diff --git a/srcpkgs/glibc/patches/glibc-upstream-38.patch b/srcpkgs/glibc/patches/glibc-upstream-38.patch new file mode 100644 index 00000000000..3ceaf45f581 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-38.patch @@ -0,0 +1,48 @@ +From 510a25f2d208e3b0c86f54b053f61c5b647e4b9b Mon Sep 17 00:00:00 2001 +From: Pochang Chen +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 ++ ++ * malloc/malloc.c (_int_malloc.c): Verify size of top chunk. ++ + 2018-08-13 Joseph Myers + + * 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; + diff --git a/srcpkgs/glibc/patches/glibc-upstream-39.patch b/srcpkgs/glibc/patches/glibc-upstream-39.patch new file mode 100644 index 00000000000..a0e110955b0 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-39.patch @@ -0,0 +1,50 @@ +From 7e40c3f804b5d5dbbc0519565b16101ab22fb899 Mon Sep 17 00:00:00 2001 +From: Moritz Eckert +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 ++ ++ * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size. ++ (malloc_consolidate): Likewise. ++ + 2018-08-16 Pochang Chen + + * 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); + } + + diff --git a/srcpkgs/glibc/patches/glibc-upstream-41.patch b/srcpkgs/glibc/patches/glibc-upstream-41.patch new file mode 100644 index 00000000000..8ce6fa0712d --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-41.patch @@ -0,0 +1,52 @@ +From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001 +From: Istvan Kurucsai +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 + diff --git a/srcpkgs/glibc/patches/glibc-upstream-42.patch b/srcpkgs/glibc/patches/glibc-upstream-42.patch new file mode 100644 index 00000000000..fd7c225e092 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-42.patch @@ -0,0 +1,153 @@ +From 7d174f53539bfbfa9cdfa41ead605573d3f219eb Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 ++ ++ [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 + + * 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); + } + + + diff --git a/srcpkgs/glibc/patches/glibc-upstream-43.patch b/srcpkgs/glibc/patches/glibc-upstream-43.patch new file mode 100644 index 00000000000..4c5274b5033 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-43.patch @@ -0,0 +1,286 @@ +From 9071be6b3f78da905ab2b6403933fe14d4482e47 Mon Sep 17 00:00:00 2001 +From: Paul Pluzhnikov +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 ++ ++ [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 + + [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 */ + diff --git a/srcpkgs/glibc/patches/glibc-upstream-44.patch b/srcpkgs/glibc/patches/glibc-upstream-44.patch new file mode 100644 index 00000000000..c7303c09ebf --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-44.patch @@ -0,0 +1,45 @@ +From e7388e5134471ef965bd48bafc71ba71eb8bf017 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +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 ++ ++ 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 + + [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 + diff --git a/srcpkgs/glibc/patches/glibc-upstream-45.patch b/srcpkgs/glibc/patches/glibc-upstream-45.patch new file mode 100644 index 00000000000..ef110cfcb54 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-45.patch @@ -0,0 +1,49 @@ +From f44c2ca5eacd2df76fc38be75f9ebb8f0ff555eb Mon Sep 17 00:00:00 2001 +From: Joseph Myers +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 ++ ++ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel ++ version to 4.19. ++ + 2018-09-18 Paul Eggert + + 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 + diff --git a/srcpkgs/glibc/patches/glibc-upstream-46.patch b/srcpkgs/glibc/patches/glibc-upstream-46.patch new file mode 100644 index 00000000000..c0b8564081a --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-46.patch @@ -0,0 +1,53 @@ +From 10f1519f6a0acdc1fc45e962fa5c13312cc7b624 Mon Sep 17 00:00:00 2001 +From: Szabolcs Nagy +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 + + * 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 ++ ++ * libio/tst-readline.c (TIMEOUT): Define. ++ + 2018-10-22 Joseph Myers + + * 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 + diff --git a/srcpkgs/glibc/patches/glibc-upstream-47.patch b/srcpkgs/glibc/patches/glibc-upstream-47.patch new file mode 100644 index 00000000000..af0b9e524d9 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-47.patch @@ -0,0 +1,91 @@ +From 2c7078bfb9cc426433ac08d951e24c29c01b5f7d Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 ++ ++ 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 + + * 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 + #include + #include ++#include + #include + #include + #include +@@ -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); + } + diff --git a/srcpkgs/glibc/patches/glibc-upstream-48.patch b/srcpkgs/glibc/patches/glibc-upstream-48.patch new file mode 100644 index 00000000000..901f2adf986 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-48.patch @@ -0,0 +1,261 @@ +From 481a6cf0c24f02f251d7cd0b776c12d00e6b144f Mon Sep 17 00:00:00 2001 +From: DJ Delorie +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 ++ ++ * 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 + + 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^ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 +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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 +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 + + diff --git a/srcpkgs/glibc/patches/glibc-upstream-49.patch b/srcpkgs/glibc/patches/glibc-upstream-49.patch new file mode 100644 index 00000000000..0582bb04372 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-49.patch @@ -0,0 +1,254 @@ +From f5cc21eaeea6afbdfd543c63d2a552f141a91781 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 +- +- * 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 + + 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^ 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 +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-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 +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 +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-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 +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 + + diff --git a/srcpkgs/glibc/patches/glibc-upstream-50.patch b/srcpkgs/glibc/patches/glibc-upstream-50.patch new file mode 100644 index 00000000000..7e6c23f9e42 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-50.patch @@ -0,0 +1,76 @@ +From ce6ba630dbc96f49eb1f30366aa62261df4792f9 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +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 ++ ++ [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 + + 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; + diff --git a/srcpkgs/glibc/patches/glibc-upstream-51.patch b/srcpkgs/glibc/patches/glibc-upstream-51.patch new file mode 100644 index 00000000000..cf416b86e88 --- /dev/null +++ b/srcpkgs/glibc/patches/glibc-upstream-51.patch @@ -0,0 +1,291 @@ +From b8dd0f42780a3133c02f064a2c0c5c4e7ab61aaa Mon Sep 17 00:00:00 2001 +From: DJ Delorie +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 ++ ++ [BZ #23907] ++ * malloc/malloc.c (_int_free): Validate tc_idx before checking for ++ double-frees. ++ ++ ++2018-11-20 DJ Delorie ++ ++ * 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 + + [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^ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 +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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 +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 + diff --git a/srcpkgs/glibc/template b/srcpkgs/glibc/template index e97a13077f9..89f6e88257c 100644 --- a/srcpkgs/glibc/template +++ b/srcpkgs/glibc/template @@ -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 "