glibc: sync patches with upstream
This commit is contained in:
parent
64e2ffff52
commit
c1eb92be12
|
@ -137,3 +137,4 @@ index 7449f8c7d5..945d5cdf28 100644
|
||||||
.weak __powf_compat
|
.weak __powf_compat
|
||||||
.set __powf_compat,__powf
|
.set __powf_compat,__powf
|
||||||
.symver __powf_compat,powf@GLIBC_2.2
|
.symver __powf_compat,powf@GLIBC_2.2
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
From df11de91931597ab4adccb74d9d55c9ddd029a22 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Pluzhnikov <ppluzhnikov@kazbek.mtv.corp.google.com>
|
||||||
|
Date: Fri, 2 Nov 2018 10:47:07 +0100
|
||||||
|
Subject: [PATCH 27] Fix BZ#23400 (creating temporary files in source tree),
|
||||||
|
and undefined behavior in test.
|
||||||
|
|
||||||
|
(cherry picked from commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523)
|
||||||
|
---
|
||||||
|
ChangeLog | 6 ++++++
|
||||||
|
NEWS | 1 +
|
||||||
|
stdlib/test-bz22786.c | 39 ++++++++++++---------------------------
|
||||||
|
3 files changed, 19 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 73d5c57f0d..43cc1fbc32 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,9 @@
|
||||||
|
+2018-08-24 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
+
|
||||||
|
+ [BZ #23400]
|
||||||
|
+ * stdlib/test-bz22786.c (do_test): Fix undefined behavior, don't
|
||||||
|
+ create temporary files in source tree.
|
||||||
|
+
|
||||||
|
2018-10-26 Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
[BZ #23822]
|
||||||
|
diff --git a/NEWS b/NEWS
|
||||||
|
index f4d9885819..79b028008d 100644
|
||||||
|
--- a/NEWS
|
||||||
|
+++ b/NEWS
|
||||||
|
@@ -10,6 +10,7 @@ Version 2.28.1
|
||||||
|
The following bugs are resolved with this release:
|
||||||
|
|
||||||
|
[20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
|
||||||
|
+ [23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
|
||||||
|
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
|
||||||
|
[23521] nss_files aliases database file stream leak
|
||||||
|
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
|
||||||
|
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||||
|
index e7837f98c1..d1aa69106c 100644
|
||||||
|
--- a/stdlib/test-bz22786.c
|
||||||
|
+++ b/stdlib/test-bz22786.c
|
||||||
|
@@ -26,28 +26,20 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <support/temp_file.h>
|
||||||
|
#include <support/test-driver.h>
|
||||||
|
#include <libc-diag.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
- const char dir[] = "bz22786";
|
||||||
|
- const char lnk[] = "bz22786/symlink";
|
||||||
|
+ const char *dir = support_create_temp_directory ("bz22786.");
|
||||||
|
+ const char *lnk = xasprintf ("%s/symlink", dir);
|
||||||
|
+ const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||||
|
|
||||||
|
- rmdir (dir);
|
||||||
|
- if (mkdir (dir, 0755) != 0 && errno != EEXIST)
|
||||||
|
- {
|
||||||
|
- printf ("mkdir %s: %m\n", dir);
|
||||||
|
- return EXIT_FAILURE;
|
||||||
|
- }
|
||||||
|
- if (symlink (".", lnk) != 0 && errno != EEXIST)
|
||||||
|
- {
|
||||||
|
- printf ("symlink (%s, %s): %m\n", dir, lnk);
|
||||||
|
- return EXIT_FAILURE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- const size_t path_len = (size_t) INT_MAX + 1;
|
||||||
|
+ TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
|
||||||
|
|
||||||
|
DIAG_PUSH_NEEDS_COMMENT;
|
||||||
|
#if __GNUC_PREREQ (7, 0)
|
||||||
|
@@ -55,20 +47,14 @@ do_test (void)
|
||||||
|
allocation to succeed for the test to work. */
|
||||||
|
DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
|
||||||
|
#endif
|
||||||
|
- char *path = malloc (path_len);
|
||||||
|
+ char *path = xmalloc (path_len);
|
||||||
|
DIAG_POP_NEEDS_COMMENT;
|
||||||
|
|
||||||
|
- if (path == NULL)
|
||||||
|
- {
|
||||||
|
- printf ("malloc (%zu): %m\n", path_len);
|
||||||
|
- return EXIT_UNSUPPORTED;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Construct very long path = "bz22786/symlink/aaaa....." */
|
||||||
|
- char *p = mempcpy (path, lnk, sizeof (lnk) - 1);
|
||||||
|
+ /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
|
||||||
|
+ char *p = mempcpy (path, lnk, strlen (lnk));
|
||||||
|
*(p++) = '/';
|
||||||
|
- memset (p, 'a', path_len - (path - p) - 2);
|
||||||
|
- p[path_len - (path - p) - 1] = '\0';
|
||||||
|
+ memset (p, 'a', path_len - (p - path) - 2);
|
||||||
|
+ p[path_len - (p - path) - 1] = '\0';
|
||||||
|
|
||||||
|
/* This call crashes before the fix for bz22786 on 32-bit platforms. */
|
||||||
|
p = realpath (path, NULL);
|
||||||
|
@@ -81,7 +67,6 @@ do_test (void)
|
||||||
|
|
||||||
|
/* Cleanup. */
|
||||||
|
unlink (lnk);
|
||||||
|
- rmdir (dir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
From d0b6db4acfba1f48b24da2c9b2a1530f6dd71503 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Liebler <stli@linux.ibm.com>
|
||||||
|
Date: Thu, 30 Aug 2018 08:44:32 +0200
|
||||||
|
Subject: [PATCH 28] Test stdlib/test-bz22786 exits now with unsupported if
|
||||||
|
malloc fails.
|
||||||
|
|
||||||
|
The test tries to allocate more than 2^31 bytes which will always fail on s390
|
||||||
|
as it has maximum 2^31bit of memory.
|
||||||
|
Before commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523, this test returned
|
||||||
|
unsupported if malloc fails. This patch re enables this behaviour.
|
||||||
|
|
||||||
|
Furthermore support_delete_temp_files() failed to remove the temp directory
|
||||||
|
in this case as it is not empty due to the created symlink.
|
||||||
|
Thus the creation of the symlink is moved behind malloc.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
ChangeLog:
|
||||||
|
|
||||||
|
* stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
|
||||||
|
if malloc fails.
|
||||||
|
|
||||||
|
(cherry picked from commit 3bad2358d67d371497079bba4f8eca9c0096f4e2)
|
||||||
|
---
|
||||||
|
ChangeLog | 5 +++++
|
||||||
|
stdlib/test-bz22786.c | 15 ++++++++++++---
|
||||||
|
2 files changed, 17 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 43cc1fbc32..645e6607b2 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+2018-08-30 Stefan Liebler <stli@linux.ibm.com>
|
||||||
|
+
|
||||||
|
+ * stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
|
||||||
|
+ if malloc fails.
|
||||||
|
+
|
||||||
|
2018-08-24 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
|
||||||
|
[BZ #23400]
|
||||||
|
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||||
|
index d1aa69106c..777bf9180f 100644
|
||||||
|
--- a/stdlib/test-bz22786.c
|
||||||
|
+++ b/stdlib/test-bz22786.c
|
||||||
|
@@ -39,16 +39,25 @@ do_test (void)
|
||||||
|
const char *lnk = xasprintf ("%s/symlink", dir);
|
||||||
|
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||||
|
|
||||||
|
- TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
|
||||||
|
-
|
||||||
|
DIAG_PUSH_NEEDS_COMMENT;
|
||||||
|
#if __GNUC_PREREQ (7, 0)
|
||||||
|
/* GCC 7 warns about too-large allocations; here we need such
|
||||||
|
allocation to succeed for the test to work. */
|
||||||
|
DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
|
||||||
|
#endif
|
||||||
|
- char *path = xmalloc (path_len);
|
||||||
|
+ char *path = malloc (path_len);
|
||||||
|
DIAG_POP_NEEDS_COMMENT;
|
||||||
|
+ if (path == NULL)
|
||||||
|
+ {
|
||||||
|
+ printf ("malloc (%zu): %m\n", path_len);
|
||||||
|
+ /* On 31-bit s390 the malloc will always fail as we do not have
|
||||||
|
+ so much memory, and we want to mark the test unsupported.
|
||||||
|
+ Likewise on systems with little physical memory the test will
|
||||||
|
+ fail and should be unsupported. */
|
||||||
|
+ return EXIT_UNSUPPORTED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
|
||||||
|
|
||||||
|
/* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
|
||||||
|
char *p = mempcpy (path, lnk, strlen (lnk));
|
||||||
|
|
|
@ -0,0 +1,540 @@
|
||||||
|
From dcd52b94bf50f337dc4cfffa24ed86d7dfe03dc0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue, 30 Oct 2018 13:11:47 +0100
|
||||||
|
Subject: [PATCH 29] stdlib/test-bz22786: Avoid spurious test failures using
|
||||||
|
alias mappings
|
||||||
|
|
||||||
|
On systems without enough random-access memory, stdlib/test-bz22786
|
||||||
|
will go deeply into swap and time out, even with a substantial
|
||||||
|
TIMEOUTFACTOR. This commit adds a facility to construct repeating
|
||||||
|
strings with alias mappings, so that the requirement for physical
|
||||||
|
memory, and uses it in stdlib/test-bz22786.
|
||||||
|
|
||||||
|
(cherry picked from commit f5e7e95921847bd83186bfe621fc2b48c4de5477)
|
||||||
|
---
|
||||||
|
ChangeLog | 11 ++
|
||||||
|
stdlib/test-bz22786.c | 16 +-
|
||||||
|
support/Makefile | 2 +
|
||||||
|
support/blob_repeat.c | 278 ++++++++++++++++++++++++++++++
|
||||||
|
support/blob_repeat.h | 44 +++++
|
||||||
|
support/tst-support_blob_repeat.c | 85 +++++++++
|
||||||
|
6 files changed, 426 insertions(+), 10 deletions(-)
|
||||||
|
create mode 100644 support/blob_repeat.c
|
||||||
|
create mode 100644 support/blob_repeat.h
|
||||||
|
create mode 100644 support/tst-support_blob_repeat.c
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 645e6607b2..2043b21dde 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,14 @@
|
||||||
|
+2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ Avoid spurious test failures in stdlib/test-bz22786.
|
||||||
|
+ * support/Makefile (libsupport-routines): Add blob_repeat.
|
||||||
|
+ (tests): Add tst-support_blob_repeat.
|
||||||
|
+ * support/blob_repeat.h: New file.
|
||||||
|
+ * support/blob_repeat.c: Likewise.
|
||||||
|
+ * support/tst-support_blob_repeat.c: Likewise.
|
||||||
|
+ * stdlib/test-bz22786.c (do_test): Replace malloc and memset with
|
||||||
|
+ support_blob_repeat_allocate.
|
||||||
|
+
|
||||||
|
2018-08-30 Stefan Liebler <stli@linux.ibm.com>
|
||||||
|
|
||||||
|
* stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
|
||||||
|
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||||
|
index 777bf9180f..bb1e04f2de 100644
|
||||||
|
--- a/stdlib/test-bz22786.c
|
||||||
|
+++ b/stdlib/test-bz22786.c
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
+#include <support/blob_repeat.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/support.h>
|
||||||
|
#include <support/temp_file.h>
|
||||||
|
@@ -39,17 +40,12 @@ do_test (void)
|
||||||
|
const char *lnk = xasprintf ("%s/symlink", dir);
|
||||||
|
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||||
|
|
||||||
|
- DIAG_PUSH_NEEDS_COMMENT;
|
||||||
|
-#if __GNUC_PREREQ (7, 0)
|
||||||
|
- /* GCC 7 warns about too-large allocations; here we need such
|
||||||
|
- allocation to succeed for the test to work. */
|
||||||
|
- DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
|
||||||
|
-#endif
|
||||||
|
- char *path = malloc (path_len);
|
||||||
|
- DIAG_POP_NEEDS_COMMENT;
|
||||||
|
+ struct support_blob_repeat repeat
|
||||||
|
+ = support_blob_repeat_allocate ("a", 1, path_len);
|
||||||
|
+ char *path = repeat.start;
|
||||||
|
if (path == NULL)
|
||||||
|
{
|
||||||
|
- printf ("malloc (%zu): %m\n", path_len);
|
||||||
|
+ printf ("Repeated allocation (%zu bytes): %m\n", path_len);
|
||||||
|
/* On 31-bit s390 the malloc will always fail as we do not have
|
||||||
|
so much memory, and we want to mark the test unsupported.
|
||||||
|
Likewise on systems with little physical memory the test will
|
||||||
|
@@ -62,7 +58,6 @@ do_test (void)
|
||||||
|
/* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
|
||||||
|
char *p = mempcpy (path, lnk, strlen (lnk));
|
||||||
|
*(p++) = '/';
|
||||||
|
- memset (p, 'a', path_len - (p - path) - 2);
|
||||||
|
p[path_len - (p - path) - 1] = '\0';
|
||||||
|
|
||||||
|
/* This call crashes before the fix for bz22786 on 32-bit platforms. */
|
||||||
|
@@ -76,6 +71,7 @@ do_test (void)
|
||||||
|
|
||||||
|
/* Cleanup. */
|
||||||
|
unlink (lnk);
|
||||||
|
+ support_blob_repeat_free (&repeat);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/support/Makefile b/support/Makefile
|
||||||
|
index 652d2cdf69..50470fb749 100644
|
||||||
|
--- a/support/Makefile
|
||||||
|
+++ b/support/Makefile
|
||||||
|
@@ -25,6 +25,7 @@ extra-libs-others = $(extra-libs)
|
||||||
|
extra-libs-noinstall := $(extra-libs)
|
||||||
|
|
||||||
|
libsupport-routines = \
|
||||||
|
+ blob_repeat \
|
||||||
|
check \
|
||||||
|
check_addrinfo \
|
||||||
|
check_dns_packet \
|
||||||
|
@@ -154,6 +155,7 @@ endif
|
||||||
|
tests = \
|
||||||
|
README-testing \
|
||||||
|
tst-support-namespace \
|
||||||
|
+ tst-support_blob_repeat \
|
||||||
|
tst-support_capture_subprocess \
|
||||||
|
tst-support_format_dns_packet \
|
||||||
|
tst-support_quote_blob \
|
||||||
|
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..da4ca83043
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/blob_repeat.c
|
||||||
|
@@ -0,0 +1,278 @@
|
||||||
|
+/* Repeating a memory blob, with alias mapping optimization.
|
||||||
|
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <support/blob_repeat.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <support/temp_file.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
+#include <sys/mman.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <wchar.h>
|
||||||
|
+
|
||||||
|
+/* Small allocations should use malloc directly instead of the mmap
|
||||||
|
+ optimization because mappings carry a lot of overhead. */
|
||||||
|
+static const size_t maximum_small_size = 4 * 1024 * 1024;
|
||||||
|
+
|
||||||
|
+/* Internal helper for fill. */
|
||||||
|
+static void
|
||||||
|
+fill0 (char *target, const char *element, size_t element_size,
|
||||||
|
+ size_t count)
|
||||||
|
+{
|
||||||
|
+ while (count > 0)
|
||||||
|
+ {
|
||||||
|
+ memcpy (target, element, element_size);
|
||||||
|
+ target += element_size;
|
||||||
|
+ --count;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Fill the buffer at TARGET with COUNT copies of the ELEMENT_SIZE
|
||||||
|
+ bytes starting at ELEMENT. */
|
||||||
|
+static void
|
||||||
|
+fill (char *target, const char *element, size_t element_size,
|
||||||
|
+ size_t count)
|
||||||
|
+{
|
||||||
|
+ if (element_size == 0 || count == 0)
|
||||||
|
+ return;
|
||||||
|
+ else if (element_size == 1)
|
||||||
|
+ memset (target, element[0], count);
|
||||||
|
+ else if (element_size == sizeof (wchar_t))
|
||||||
|
+ {
|
||||||
|
+ wchar_t wc;
|
||||||
|
+ memcpy (&wc, element, sizeof (wc));
|
||||||
|
+ wmemset ((wchar_t *) target, wc, count);
|
||||||
|
+ }
|
||||||
|
+ else if (element_size < 1024 && count > 4096)
|
||||||
|
+ {
|
||||||
|
+ /* Use larger copies for really small element sizes. */
|
||||||
|
+ char buffer[8192];
|
||||||
|
+ size_t buffer_count = sizeof (buffer) / element_size;
|
||||||
|
+ fill0 (buffer, element, element_size, buffer_count);
|
||||||
|
+ while (count > 0)
|
||||||
|
+ {
|
||||||
|
+ size_t copy_count = buffer_count;
|
||||||
|
+ if (copy_count > count)
|
||||||
|
+ copy_count = count;
|
||||||
|
+ size_t copy_bytes = copy_count * element_size;
|
||||||
|
+ memcpy (target, buffer, copy_bytes);
|
||||||
|
+ target += copy_bytes;
|
||||||
|
+ count -= copy_count;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ fill0 (target, element, element_size, count);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Use malloc instead of mmap for small allocations and unusual size
|
||||||
|
+ combinations. */
|
||||||
|
+static struct support_blob_repeat
|
||||||
|
+allocate_malloc (size_t total_size, const void *element, size_t element_size,
|
||||||
|
+ size_t count)
|
||||||
|
+{
|
||||||
|
+ void *buffer = malloc (total_size);
|
||||||
|
+ if (buffer == NULL)
|
||||||
|
+ return (struct support_blob_repeat) { 0 };
|
||||||
|
+ fill (buffer, element, element_size, count);
|
||||||
|
+ return (struct support_blob_repeat)
|
||||||
|
+ {
|
||||||
|
+ .start = buffer,
|
||||||
|
+ .size = total_size,
|
||||||
|
+ .use_malloc = true
|
||||||
|
+ };
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Return the least common multiple of PAGE_SIZE and ELEMENT_SIZE,
|
||||||
|
+ avoiding overflow. This assumes that PAGE_SIZE is a power of
|
||||||
|
+ two. */
|
||||||
|
+static size_t
|
||||||
|
+minimum_stride_size (size_t page_size, size_t element_size)
|
||||||
|
+{
|
||||||
|
+ TEST_VERIFY_EXIT (page_size > 0);
|
||||||
|
+ TEST_VERIFY_EXIT (element_size > 0);
|
||||||
|
+
|
||||||
|
+ /* Compute the number of trailing zeros common to both sizes. */
|
||||||
|
+ unsigned int common_zeros = __builtin_ctzll (page_size | element_size);
|
||||||
|
+
|
||||||
|
+ /* In the product, this power of two appears twice, but in the least
|
||||||
|
+ common multiple, it appears only once. Therefore, shift one
|
||||||
|
+ factor. */
|
||||||
|
+ size_t multiple;
|
||||||
|
+ if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
|
||||||
|
+ &multiple))
|
||||||
|
+ return 0;
|
||||||
|
+ return multiple;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Allocations larger than maximum_small_size potentially use mmap
|
||||||
|
+ with alias mappings. */
|
||||||
|
+static struct support_blob_repeat
|
||||||
|
+allocate_big (size_t total_size, const void *element, size_t element_size,
|
||||||
|
+ size_t count)
|
||||||
|
+{
|
||||||
|
+ unsigned long page_size = xsysconf (_SC_PAGESIZE);
|
||||||
|
+ size_t stride_size = minimum_stride_size (page_size, element_size);
|
||||||
|
+ if (stride_size == 0)
|
||||||
|
+ {
|
||||||
|
+ errno = EOVERFLOW;
|
||||||
|
+ return (struct support_blob_repeat) { 0 };
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Ensure that the stride size is at least maximum_small_size. This
|
||||||
|
+ is necessary to reduce the number of distinct mappings. */
|
||||||
|
+ if (stride_size < maximum_small_size)
|
||||||
|
+ stride_size
|
||||||
|
+ = ((maximum_small_size + stride_size - 1) / stride_size) * stride_size;
|
||||||
|
+
|
||||||
|
+ if (stride_size > total_size)
|
||||||
|
+ /* The mmap optimization would not save anything. */
|
||||||
|
+ return allocate_malloc (total_size, element, element_size, count);
|
||||||
|
+
|
||||||
|
+ /* Reserve the memory region. If we cannot create the mapping,
|
||||||
|
+ there is no reason to set up the backing file. */
|
||||||
|
+ void *target = mmap (NULL, total_size, PROT_NONE,
|
||||||
|
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
|
+ if (target == MAP_FAILED)
|
||||||
|
+ return (struct support_blob_repeat) { 0 };
|
||||||
|
+
|
||||||
|
+ /* Create the backing file for the repeated mapping. */
|
||||||
|
+ int fd;
|
||||||
|
+ {
|
||||||
|
+ char *temppath;
|
||||||
|
+ fd = create_temp_file ("support_blob_repeat-", &temppath);
|
||||||
|
+ if (fd < 0)
|
||||||
|
+ FAIL_EXIT1 ("create_temp_file: %m");
|
||||||
|
+ xunlink (temppath);
|
||||||
|
+ free (temppath);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Make sure that there is backing storage, so that the fill
|
||||||
|
+ operation will not fault. */
|
||||||
|
+ if (posix_fallocate (fd, 0, stride_size) != 0)
|
||||||
|
+ FAIL_EXIT1 ("posix_fallocate (%zu): %m", stride_size);
|
||||||
|
+
|
||||||
|
+ /* The stride size must still be a multiple of the page size and
|
||||||
|
+ element size. */
|
||||||
|
+ TEST_VERIFY_EXIT ((stride_size % page_size) == 0);
|
||||||
|
+ TEST_VERIFY_EXIT ((stride_size % element_size) == 0);
|
||||||
|
+
|
||||||
|
+ /* Fill the backing store. */
|
||||||
|
+ {
|
||||||
|
+ void *ptr = mmap (target, stride_size, PROT_READ | PROT_WRITE,
|
||||||
|
+ MAP_FIXED | MAP_FILE | MAP_SHARED, fd, 0);
|
||||||
|
+ if (ptr == MAP_FAILED)
|
||||||
|
+ {
|
||||||
|
+ int saved_errno = errno;
|
||||||
|
+ xmunmap (target, total_size);
|
||||||
|
+ xclose (fd);
|
||||||
|
+ errno = saved_errno;
|
||||||
|
+ return (struct support_blob_repeat) { 0 };
|
||||||
|
+ }
|
||||||
|
+ if (ptr != target)
|
||||||
|
+ FAIL_EXIT1 ("mapping of %zu bytes moved from %p to %p",
|
||||||
|
+ stride_size, target, ptr);
|
||||||
|
+
|
||||||
|
+ /* Write the repeating data. */
|
||||||
|
+ fill (target, element, element_size, stride_size / element_size);
|
||||||
|
+
|
||||||
|
+ /* Return to a PROT_NONE mapping, just to be on the safe side. */
|
||||||
|
+ ptr = mmap (target, stride_size, PROT_NONE,
|
||||||
|
+ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
|
+ if (ptr == MAP_FAILED)
|
||||||
|
+ FAIL_EXIT1 ("Failed to reinstate PROT_NONE mapping: %m");
|
||||||
|
+ if (ptr != target)
|
||||||
|
+ FAIL_EXIT1 ("PROT_NONE mapping of %zu bytes moved from %p to %p",
|
||||||
|
+ stride_size, target, ptr);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Create the alias mappings. */
|
||||||
|
+ {
|
||||||
|
+ size_t remaining_size = total_size;
|
||||||
|
+ char *current = target;
|
||||||
|
+ int flags = MAP_FIXED | MAP_FILE | MAP_PRIVATE;
|
||||||
|
+#ifdef MAP_NORESERVE
|
||||||
|
+ flags |= MAP_NORESERVE;
|
||||||
|
+#endif
|
||||||
|
+ while (remaining_size > 0)
|
||||||
|
+ {
|
||||||
|
+ size_t to_map = stride_size;
|
||||||
|
+ if (to_map > remaining_size)
|
||||||
|
+ to_map = remaining_size;
|
||||||
|
+ void *ptr = mmap (current, to_map, PROT_READ | PROT_WRITE,
|
||||||
|
+ flags, fd, 0);
|
||||||
|
+ if (ptr == MAP_FAILED)
|
||||||
|
+ {
|
||||||
|
+ int saved_errno = errno;
|
||||||
|
+ xmunmap (target, total_size);
|
||||||
|
+ xclose (fd);
|
||||||
|
+ errno = saved_errno;
|
||||||
|
+ return (struct support_blob_repeat) { 0 };
|
||||||
|
+ }
|
||||||
|
+ if (ptr != current)
|
||||||
|
+ FAIL_EXIT1 ("MAP_PRIVATE mapping of %zu bytes moved from %p to %p",
|
||||||
|
+ to_map, target, ptr);
|
||||||
|
+ remaining_size -= to_map;
|
||||||
|
+ current += to_map;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ xclose (fd);
|
||||||
|
+
|
||||||
|
+ return (struct support_blob_repeat)
|
||||||
|
+ {
|
||||||
|
+ .start = target,
|
||||||
|
+ .size = total_size,
|
||||||
|
+ .use_malloc = false
|
||||||
|
+ };
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct support_blob_repeat
|
||||||
|
+support_blob_repeat_allocate (const void *element, size_t element_size,
|
||||||
|
+ size_t count)
|
||||||
|
+{
|
||||||
|
+ size_t total_size;
|
||||||
|
+ if (__builtin_mul_overflow (element_size, count, &total_size))
|
||||||
|
+ {
|
||||||
|
+ errno = EOVERFLOW;
|
||||||
|
+ return (struct support_blob_repeat) { 0 };
|
||||||
|
+ }
|
||||||
|
+ if (total_size <= maximum_small_size)
|
||||||
|
+ return allocate_malloc (total_size, element, element_size, count);
|
||||||
|
+ else
|
||||||
|
+ return allocate_big (total_size, element, element_size, count);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+support_blob_repeat_free (struct support_blob_repeat *blob)
|
||||||
|
+{
|
||||||
|
+ if (blob->size > 0)
|
||||||
|
+ {
|
||||||
|
+ int saved_errno = errno;
|
||||||
|
+ if (blob->use_malloc)
|
||||||
|
+ free (blob->start);
|
||||||
|
+ else
|
||||||
|
+ xmunmap (blob->start, blob->size);
|
||||||
|
+ errno = saved_errno;
|
||||||
|
+ }
|
||||||
|
+ *blob = (struct support_blob_repeat) { 0 };
|
||||||
|
+}
|
||||||
|
diff --git a/support/blob_repeat.h b/support/blob_repeat.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..8e9d7ff5f1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/blob_repeat.h
|
||||||
|
@@ -0,0 +1,44 @@
|
||||||
|
+/* Repeating a memory blob, with alias mapping optimization.
|
||||||
|
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef SUPPORT_BLOB_REPEAT_H
|
||||||
|
+#define SUPPORT_BLOB_REPEAT_H
|
||||||
|
+
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+
|
||||||
|
+struct support_blob_repeat
|
||||||
|
+{
|
||||||
|
+ void *start;
|
||||||
|
+ size_t size;
|
||||||
|
+ bool use_malloc;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* Return an allocation of COUNT elements, each of ELEMENT_SIZE bytes,
|
||||||
|
+ initialized with the bytes starting at ELEMENT. The memory is
|
||||||
|
+ writable (and thus counts towards the commit charge). In case of
|
||||||
|
+ on error, all members of the return struct are zero-initialized,
|
||||||
|
+ and errno is set accordingly. */
|
||||||
|
+struct support_blob_repeat support_blob_repeat_allocate (const void *element,
|
||||||
|
+ size_t element_size,
|
||||||
|
+ size_t count);
|
||||||
|
+
|
||||||
|
+/* Deallocate the blob created by support_blob_repeat_allocate. */
|
||||||
|
+void support_blob_repeat_free (struct support_blob_repeat *);
|
||||||
|
+
|
||||||
|
+#endif /* SUPPORT_BLOB_REPEAT_H */
|
||||||
|
diff --git a/support/tst-support_blob_repeat.c b/support/tst-support_blob_repeat.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..1978c14488
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/tst-support_blob_repeat.c
|
||||||
|
@@ -0,0 +1,85 @@
|
||||||
|
+/* Tests for <support/blob_repeat.h>
|
||||||
|
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <support/blob_repeat.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ struct support_blob_repeat repeat
|
||||||
|
+ = support_blob_repeat_allocate ("5", 1, 5);
|
||||||
|
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "55555", 5);
|
||||||
|
+ support_blob_repeat_free (&repeat);
|
||||||
|
+
|
||||||
|
+ repeat = support_blob_repeat_allocate ("ABC", 3, 3);
|
||||||
|
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "ABCABCABC", 9);
|
||||||
|
+ support_blob_repeat_free (&repeat);
|
||||||
|
+
|
||||||
|
+ repeat = support_blob_repeat_allocate ("abc", 4, 3);
|
||||||
|
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "abc\0abc\0abc", 12);
|
||||||
|
+ support_blob_repeat_free (&repeat);
|
||||||
|
+
|
||||||
|
+ size_t gigabyte = 1U << 30;
|
||||||
|
+ repeat = support_blob_repeat_allocate ("X", 1, gigabyte + 1);
|
||||||
|
+ if (repeat.start == NULL)
|
||||||
|
+ puts ("warning: not enough memory for 1 GiB mapping");
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (repeat.size, gigabyte + 1);
|
||||||
|
+ {
|
||||||
|
+ unsigned char *p = repeat.start;
|
||||||
|
+ for (size_t i = 0; i < gigabyte + 1; ++i)
|
||||||
|
+ if (p[i] != 'X')
|
||||||
|
+ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
|
||||||
|
+
|
||||||
|
+ /* Check that there is no sharing across the mapping. */
|
||||||
|
+ p[0] = 'Y';
|
||||||
|
+ p[1U << 24] = 'Z';
|
||||||
|
+ for (size_t i = 0; i < gigabyte + 1; ++i)
|
||||||
|
+ if (i == 0)
|
||||||
|
+ TEST_COMPARE (p[i], 'Y');
|
||||||
|
+ else if (i == 1U << 24)
|
||||||
|
+ TEST_COMPARE (p[i], 'Z');
|
||||||
|
+ else if (p[i] != 'X')
|
||||||
|
+ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ support_blob_repeat_free (&repeat);
|
||||||
|
+
|
||||||
|
+ repeat = support_blob_repeat_allocate ("012345678", 9, 10 * 1000 * 1000);
|
||||||
|
+ if (repeat.start == NULL)
|
||||||
|
+ puts ("warning: not enough memory for large mapping");
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ unsigned char *p = repeat.start;
|
||||||
|
+ for (int i = 0; i < 10 * 1000 * 1000; ++i)
|
||||||
|
+ for (int j = 0; j <= 8; ++j)
|
||||||
|
+ if (p[i * 9 + j] != '0' + j)
|
||||||
|
+ {
|
||||||
|
+ printf ("error: element %d index %d\n", i, j);
|
||||||
|
+ TEST_COMPARE (p[i * 9 + j], '0' + j);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ support_blob_repeat_free (&repeat);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
From 69dcd992a0efdb53bc2ea4948cfc6b13416b9636 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue, 30 Oct 2018 13:56:40 +0100
|
||||||
|
Subject: [PATCH 30] stdlib/test-bz22786: Avoid memory leaks in the test
|
||||||
|
itself
|
||||||
|
|
||||||
|
(cherry picked from commit 60708030536df82616c16aa2f14f533c4362b969)
|
||||||
|
---
|
||||||
|
ChangeLog | 5 +++++
|
||||||
|
stdlib/test-bz22786.c | 6 ++++--
|
||||||
|
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 2043b21dde..a2a9fc3cc9 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ * stdlib/test-bz22786.c (do_test): Additional free calls to avoid
|
||||||
|
+ memory leaks.
|
||||||
|
+
|
||||||
|
2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Avoid spurious test failures in stdlib/test-bz22786.
|
||||||
|
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
|
||||||
|
index bb1e04f2de..8035e8a394 100644
|
||||||
|
--- a/stdlib/test-bz22786.c
|
||||||
|
+++ b/stdlib/test-bz22786.c
|
||||||
|
@@ -36,8 +36,8 @@
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
- const char *dir = support_create_temp_directory ("bz22786.");
|
||||||
|
- const char *lnk = xasprintf ("%s/symlink", dir);
|
||||||
|
+ char *dir = support_create_temp_directory ("bz22786.");
|
||||||
|
+ char *lnk = xasprintf ("%s/symlink", dir);
|
||||||
|
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
|
||||||
|
|
||||||
|
struct support_blob_repeat repeat
|
||||||
|
@@ -72,6 +72,8 @@ do_test (void)
|
||||||
|
/* Cleanup. */
|
||||||
|
unlink (lnk);
|
||||||
|
support_blob_repeat_free (&repeat);
|
||||||
|
+ free (lnk);
|
||||||
|
+ free (dir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
From 6c2b6e9e2758b7491ce89920a8711c1b41100269 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue, 30 Oct 2018 13:55:50 +0100
|
||||||
|
Subject: [PATCH 31] support_blob_repeat: Call mkstemp directory for the
|
||||||
|
backing file
|
||||||
|
|
||||||
|
This avoids a warning during post-test cleanup.
|
||||||
|
|
||||||
|
(cherry picked from commit a91e9301c47bb688f4e496a19cfc68261ff18293)
|
||||||
|
---
|
||||||
|
ChangeLog | 4 ++++
|
||||||
|
support/blob_repeat.c | 14 +++++++++-----
|
||||||
|
2 files changed, 13 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index a2a9fc3cc9..b4c48644ae 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ * support/blob_repeat.c (allocate_big): Call mkstemp directly.
|
||||||
|
+
|
||||||
|
2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
* stdlib/test-bz22786.c (do_test): Additional free calls to avoid
|
||||||
|
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
|
||||||
|
index da4ca83043..16c1e448b9 100644
|
||||||
|
--- a/support/blob_repeat.c
|
||||||
|
+++ b/support/blob_repeat.c
|
||||||
|
@@ -23,8 +23,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <support/blob_repeat.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
+#include <support/test-driver.h>
|
||||||
|
#include <support/support.h>
|
||||||
|
-#include <support/temp_file.h>
|
||||||
|
#include <support/xunistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
@@ -155,13 +155,17 @@ allocate_big (size_t total_size, const void *element, size_t element_size,
|
||||||
|
if (target == MAP_FAILED)
|
||||||
|
return (struct support_blob_repeat) { 0 };
|
||||||
|
|
||||||
|
- /* Create the backing file for the repeated mapping. */
|
||||||
|
+ /* Create the backing file for the repeated mapping. Call mkstemp
|
||||||
|
+ directly to remove the resources backing the temporary file
|
||||||
|
+ immediately, once support_blob_repeat_free is called. Using
|
||||||
|
+ create_temp_file would result in a warning during post-test
|
||||||
|
+ cleanup. */
|
||||||
|
int fd;
|
||||||
|
{
|
||||||
|
- char *temppath;
|
||||||
|
- fd = create_temp_file ("support_blob_repeat-", &temppath);
|
||||||
|
+ char *temppath = xasprintf ("%s/support_blob_repeat-XXXXXX", test_dir);
|
||||||
|
+ fd = mkstemp (temppath);
|
||||||
|
if (fd < 0)
|
||||||
|
- FAIL_EXIT1 ("create_temp_file: %m");
|
||||||
|
+ FAIL_EXIT1 ("mkstemp (\"%s\"): %m", temppath);
|
||||||
|
xunlink (temppath);
|
||||||
|
free (temppath);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
From e1af1df694603c0dcd5118c30eea2cdeb01a1a0b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue, 30 Oct 2018 13:55:01 +0100
|
||||||
|
Subject: [PATCH 32] stdlib/tst-strtod-overflow: Switch to
|
||||||
|
support_blob_repeat
|
||||||
|
|
||||||
|
This is another test with an avoidable large memory allocation.
|
||||||
|
|
||||||
|
(cherry picked from commit 07da99aad93c9364acb7efdab47c27ba698f6313)
|
||||||
|
---
|
||||||
|
ChangeLog | 5 +++++
|
||||||
|
stdlib/tst-strtod-overflow.c | 16 ++++++++++------
|
||||||
|
2 files changed, 15 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index b4c48644ae..51a8f488d9 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ * stdlib/tst-strtod-overflow.c (do_test): Switch to
|
||||||
|
+ support_blob_repeat.
|
||||||
|
+
|
||||||
|
2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
* support/blob_repeat.c (allocate_big): Call mkstemp directly.
|
||||||
|
diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
|
||||||
|
index d14638d68e..dc53c1e521 100644
|
||||||
|
--- a/stdlib/tst-strtod-overflow.c
|
||||||
|
+++ b/stdlib/tst-strtod-overflow.c
|
||||||
|
@@ -19,6 +19,8 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include <support/blob_repeat.h>
|
||||||
|
+#include <support/test-driver.h>
|
||||||
|
|
||||||
|
#define EXPONENT "e-2147483649"
|
||||||
|
#define SIZE 214748364
|
||||||
|
@@ -26,21 +28,23 @@
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
- char *p = malloc (1 + SIZE + sizeof (EXPONENT));
|
||||||
|
- if (p == NULL)
|
||||||
|
+ struct support_blob_repeat repeat = support_blob_repeat_allocate
|
||||||
|
+ ("0", 1, 1 + SIZE + sizeof (EXPONENT));
|
||||||
|
+ if (repeat.size == 0)
|
||||||
|
{
|
||||||
|
- puts ("malloc failed, cannot test for overflow");
|
||||||
|
- return 0;
|
||||||
|
+ puts ("warning: memory allocation failed, cannot test for overflow");
|
||||||
|
+ return EXIT_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
+ char *p = repeat.start;
|
||||||
|
p[0] = '1';
|
||||||
|
- memset (p + 1, '0', SIZE);
|
||||||
|
memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT));
|
||||||
|
double d = strtod (p, NULL);
|
||||||
|
if (d != 0)
|
||||||
|
{
|
||||||
|
- printf ("strtod returned wrong value: %a\n", d);
|
||||||
|
+ printf ("error: strtod returned wrong value: %a\n", d);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+ support_blob_repeat_free (&repeat);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
From 65010329f2c596bdd1204c1c9c9baac0193637af Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Fri, 2 Nov 2018 10:56:00 +0100
|
||||||
|
Subject: [PATCH 33] x86: Fix Haswell CPU string flags (BZ#23709)
|
||||||
|
|
||||||
|
Th commit 'Disable TSX on some Haswell processors.' (2702856bf4) changed the
|
||||||
|
default flags for Haswell models. Previously, new models were handled by the
|
||||||
|
default switch path, which assumed a Core i3/i5/i7 if AVX is available. After
|
||||||
|
the patch, Haswell models (0x3f, 0x3c, 0x45, 0x46) do not set the flags
|
||||||
|
Fast_Rep_String, Fast_Unaligned_Load, Fast_Unaligned_Copy, and
|
||||||
|
Prefer_PMINUB_for_stringop (only the TSX one).
|
||||||
|
|
||||||
|
This patch fixes it by disentangle the TSX flag handling from the memory
|
||||||
|
optimization ones. The strstr case cited on patch now selects the
|
||||||
|
__strstr_sse2_unaligned as expected for the Haswell cpu.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
[BZ #23709]
|
||||||
|
* sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
|
||||||
|
independently of other flags.
|
||||||
|
|
||||||
|
(cherry picked from commit c3d8dc45c9df199b8334599a6cbd98c9950dba62)
|
||||||
|
---
|
||||||
|
ChangeLog | 6 ++++++
|
||||||
|
NEWS | 1 +
|
||||||
|
sysdeps/x86/cpu-features.c | 6 ++++++
|
||||||
|
3 files changed, 13 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 51a8f488d9..d558df58af 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,9 @@
|
||||||
|
+2018-10-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
+
|
||||||
|
+ [BZ #23709]
|
||||||
|
+ * sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
|
||||||
|
+ independently of other flags.
|
||||||
|
+
|
||||||
|
2018-10-30 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
* stdlib/tst-strtod-overflow.c (do_test): Switch to
|
||||||
|
diff --git a/NEWS b/NEWS
|
||||||
|
index 79b028008d..f3004915f2 100644
|
||||||
|
--- a/NEWS
|
||||||
|
+++ b/NEWS
|
||||||
|
@@ -19,6 +19,7 @@ The following bugs are resolved with this release:
|
||||||
|
[23579] libc: Errors misreported in preadv2
|
||||||
|
[23606] Missing ENDBR32 in sysdeps/i386/start.S
|
||||||
|
[23679] gethostid: Missing NULL check for gethostbyname_r result
|
||||||
|
+ [23709] Fix CPU string flags for Haswell-type CPUs
|
||||||
|
[23717] Fix stack overflow in stdlib/tst-setcontext9
|
||||||
|
[23821] si_band in siginfo_t has wrong type long int on sparc64
|
||||||
|
[23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
|
||||||
|
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
|
||||||
|
index ea0b64fdb9..4695ac80d4 100644
|
||||||
|
--- a/sysdeps/x86/cpu-features.c
|
||||||
|
+++ b/sysdeps/x86/cpu-features.c
|
||||||
|
@@ -316,7 +316,13 @@ init_cpu_features (struct cpu_features *cpu_features)
|
||||||
|
| bit_arch_Fast_Unaligned_Copy
|
||||||
|
| bit_arch_Prefer_PMINUB_for_stringop);
|
||||||
|
break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ /* Disable TSX on some Haswell processors to avoid TSX on kernels that
|
||||||
|
+ weren't updated with the latest microcode package (which disables
|
||||||
|
+ broken feature by default). */
|
||||||
|
+ switch (model)
|
||||||
|
+ {
|
||||||
|
case 0x3f:
|
||||||
|
/* Xeon E7 v3 with stepping >= 4 has working TSX. */
|
||||||
|
if (stepping >= 4)
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
From fc0e3393ff775aa795b523083bb0db7f18d3b91e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andreas Schwab <schwab@suse.de>
|
||||||
|
Date: Tue, 6 Nov 2018 16:12:07 +0100
|
||||||
|
Subject: [PATCH 34] libanl: properly cleanup if first helper thread
|
||||||
|
creation failed (bug 22927)
|
||||||
|
|
||||||
|
(cherry picked from commit bd3b0fbae33a9a4cc5e2daf049443d5cf03d4251)
|
||||||
|
---
|
||||||
|
ChangeLog | 6 ++++++
|
||||||
|
NEWS | 1 +
|
||||||
|
resolv/gai_misc.c | 7 +++++--
|
||||||
|
3 files changed, 12 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index d558df58af..db4ac3b76a 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,9 @@
|
||||||
|
+2018-11-05 Andreas Schwab <schwab@suse.de>
|
||||||
|
+
|
||||||
|
+ [BZ #22927]
|
||||||
|
+ * resolv/gai_misc.c (__gai_enqueue_request): Don't crash if
|
||||||
|
+ creating the first helper thread failed.
|
||||||
|
+
|
||||||
|
2018-10-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
[BZ #23709]
|
||||||
|
diff --git a/NEWS b/NEWS
|
||||||
|
index f3004915f2..b85be4a9c1 100644
|
||||||
|
--- a/NEWS
|
||||||
|
+++ b/NEWS
|
||||||
|
@@ -10,6 +10,7 @@ Version 2.28.1
|
||||||
|
The following bugs are resolved with this release:
|
||||||
|
|
||||||
|
[20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
|
||||||
|
+ [22927] libanl: properly cleanup if first helper thread creation failed
|
||||||
|
[23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
|
||||||
|
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
|
||||||
|
[23521] nss_files aliases database file stream leak
|
||||||
|
diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
|
||||||
|
index e7c3b63cc5..80a2cff835 100644
|
||||||
|
--- a/resolv/gai_misc.c
|
||||||
|
+++ b/resolv/gai_misc.c
|
||||||
|
@@ -261,8 +261,11 @@ __gai_enqueue_request (struct gaicb *gaicbp)
|
||||||
|
/* We cannot create a thread in the moment and there is
|
||||||
|
also no thread running. This is a problem. `errno' is
|
||||||
|
set to EAGAIN if this is only a temporary problem. */
|
||||||
|
- assert (lastp->next == newp);
|
||||||
|
- lastp->next = NULL;
|
||||||
|
+ assert (requests == newp || lastp->next == newp);
|
||||||
|
+ if (lastp != NULL)
|
||||||
|
+ lastp->next = NULL;
|
||||||
|
+ else
|
||||||
|
+ requests = NULL;
|
||||||
|
requests_tail = lastp;
|
||||||
|
|
||||||
|
newp->next = freelist;
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
From 3e8d8dd5afba18a847ff7a80f473336f777cc329 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||||
|
Date: Thu, 8 Nov 2018 10:06:58 -0800
|
||||||
|
Subject: [PATCH 35] Check multiple NT_GNU_PROPERTY_TYPE_0 notes [BZ #23509]
|
||||||
|
|
||||||
|
Linkers group input note sections with the same name into one output
|
||||||
|
note section with the same name. One output note section is placed in
|
||||||
|
one PT_NOTE segment. Since new linkers merge input .note.gnu.property
|
||||||
|
sections into one output .note.gnu.property section, there is only
|
||||||
|
one NT_GNU_PROPERTY_TYPE_0 note in one PT_NOTE segment with new linkers.
|
||||||
|
Since older linkers treat input .note.gnu.property section as a generic
|
||||||
|
note section and just concatenate all input .note.gnu.property sections
|
||||||
|
into one output .note.gnu.property section without merging them, we may
|
||||||
|
see multiple NT_GNU_PROPERTY_TYPE_0 notes in one PT_NOTE segment with
|
||||||
|
older linkers.
|
||||||
|
|
||||||
|
When an older linker is used to created the program on CET-enabled OS,
|
||||||
|
the linker output has a single .note.gnu.property section with multiple
|
||||||
|
NT_GNU_PROPERTY_TYPE_0 notes, some of which have IBT and SHSTK enable
|
||||||
|
bits set even if the program isn't CET enabled. Such programs will
|
||||||
|
crash on CET-enabled machines. This patch updates the note parser:
|
||||||
|
|
||||||
|
1. Skip note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
|
||||||
|
2. Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
|
||||||
|
|
||||||
|
[BZ #23509]
|
||||||
|
* sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip
|
||||||
|
note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
|
||||||
|
Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note.
|
||||||
|
Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
|
||||||
|
* sysdeps/x86/link_map.h (l_cet): Expand to 3 bits, Add
|
||||||
|
lc_unknown.
|
||||||
|
|
||||||
|
(cherry picked from commit d524fa6c35e675eedbd8fe6cdf4db0b49c658026)
|
||||||
|
---
|
||||||
|
ChangeLog | 10 +++++++++
|
||||||
|
NEWS | 1 +
|
||||||
|
sysdeps/x86/dl-prop.h | 51 +++++++++++++++++++++++++++++++++---------
|
||||||
|
sysdeps/x86/link_map.h | 9 ++++----
|
||||||
|
4 files changed, 57 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index db4ac3b76a..86bdf17989 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,13 @@
|
||||||
|
+2018-11-08 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
+
|
||||||
|
+ [BZ #23509]
|
||||||
|
+ * sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip
|
||||||
|
+ note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
|
||||||
|
+ Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note.
|
||||||
|
+ Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
|
||||||
|
+ * sysdeps/x86/link_map.h (l_cet): Expand to 3 bits, Add
|
||||||
|
+ lc_unknown.
|
||||||
|
+
|
||||||
|
2018-11-05 Andreas Schwab <schwab@suse.de>
|
||||||
|
|
||||||
|
[BZ #22927]
|
||||||
|
diff --git a/NEWS b/NEWS
|
||||||
|
index b85be4a9c1..e5ca5903ec 100644
|
||||||
|
--- a/NEWS
|
||||||
|
+++ b/NEWS
|
||||||
|
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
|
||||||
|
[22927] libanl: properly cleanup if first helper thread creation failed
|
||||||
|
[23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
|
||||||
|
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
|
||||||
|
+ [23509] CET enabled glibc is incompatible with the older linker
|
||||||
|
[23521] nss_files aliases database file stream leak
|
||||||
|
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
|
||||||
|
[23562] signal: Use correct type for si_band in siginfo_t
|
||||||
|
diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
|
||||||
|
index 26c3131ac5..9ab890d12b 100644
|
||||||
|
--- a/sysdeps/x86/dl-prop.h
|
||||||
|
+++ b/sysdeps/x86/dl-prop.h
|
||||||
|
@@ -49,6 +49,10 @@ _dl_process_cet_property_note (struct link_map *l,
|
||||||
|
const ElfW(Addr) align)
|
||||||
|
{
|
||||||
|
#if CET_ENABLED
|
||||||
|
+ /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before. */
|
||||||
|
+ if (l->l_cet != lc_unknown)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
/* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in
|
||||||
|
32-bit objects and to 8 bytes in 64-bit objects. Skip notes
|
||||||
|
with incorrect alignment. */
|
||||||
|
@@ -57,6 +61,9 @@ _dl_process_cet_property_note (struct link_map *l,
|
||||||
|
|
||||||
|
const ElfW(Addr) start = (ElfW(Addr)) note;
|
||||||
|
|
||||||
|
+ unsigned int feature_1 = 0;
|
||||||
|
+ unsigned int last_type = 0;
|
||||||
|
+
|
||||||
|
while ((ElfW(Addr)) (note + 1) - start < size)
|
||||||
|
{
|
||||||
|
/* Find the NT_GNU_PROPERTY_TYPE_0 note. */
|
||||||
|
@@ -64,10 +71,18 @@ _dl_process_cet_property_note (struct link_map *l,
|
||||||
|
&& note->n_type == NT_GNU_PROPERTY_TYPE_0
|
||||||
|
&& memcmp (note + 1, "GNU", 4) == 0)
|
||||||
|
{
|
||||||
|
+ /* Stop if we see more than one GNU property note which may
|
||||||
|
+ be generated by the older linker. */
|
||||||
|
+ if (l->l_cet != lc_unknown)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Check CET status now. */
|
||||||
|
+ l->l_cet = lc_none;
|
||||||
|
+
|
||||||
|
/* Check for invalid property. */
|
||||||
|
if (note->n_descsz < 8
|
||||||
|
|| (note->n_descsz % sizeof (ElfW(Addr))) != 0)
|
||||||
|
- break;
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
/* Start and end of property array. */
|
||||||
|
unsigned char *ptr = (unsigned char *) (note + 1) + 4;
|
||||||
|
@@ -78,9 +93,15 @@ _dl_process_cet_property_note (struct link_map *l,
|
||||||
|
unsigned int type = *(unsigned int *) ptr;
|
||||||
|
unsigned int datasz = *(unsigned int *) (ptr + 4);
|
||||||
|
|
||||||
|
+ /* Property type must be in ascending order. */
|
||||||
|
+ if (type < last_type)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
ptr += 8;
|
||||||
|
if ((ptr + datasz) > ptr_end)
|
||||||
|
- break;
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ last_type = type;
|
||||||
|
|
||||||
|
if (type == GNU_PROPERTY_X86_FEATURE_1_AND)
|
||||||
|
{
|
||||||
|
@@ -89,14 +110,18 @@ _dl_process_cet_property_note (struct link_map *l,
|
||||||
|
we stop the search regardless if its size is correct
|
||||||
|
or not. There is no point to continue if this note
|
||||||
|
is ill-formed. */
|
||||||
|
- if (datasz == 4)
|
||||||
|
- {
|
||||||
|
- unsigned int feature_1 = *(unsigned int *) ptr;
|
||||||
|
- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
|
||||||
|
- l->l_cet |= lc_ibt;
|
||||||
|
- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
|
||||||
|
- l->l_cet |= lc_shstk;
|
||||||
|
- }
|
||||||
|
+ if (datasz != 4)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ feature_1 = *(unsigned int *) ptr;
|
||||||
|
+
|
||||||
|
+ /* Keep searching for the next GNU property note
|
||||||
|
+ generated by the older linker. */
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ else if (type > GNU_PROPERTY_X86_FEATURE_1_AND)
|
||||||
|
+ {
|
||||||
|
+ /* Stop since property type is in ascending order. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -112,6 +137,12 @@ _dl_process_cet_property_note (struct link_map *l,
|
||||||
|
+ ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz,
|
||||||
|
align));
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* We get here only if there is one or no GNU property note. */
|
||||||
|
+ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
|
||||||
|
+ l->l_cet |= lc_ibt;
|
||||||
|
+ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
|
||||||
|
+ l->l_cet |= lc_shstk;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h
|
||||||
|
index ef1206a9d2..9367ed0889 100644
|
||||||
|
--- a/sysdeps/x86/link_map.h
|
||||||
|
+++ b/sysdeps/x86/link_map.h
|
||||||
|
@@ -19,8 +19,9 @@
|
||||||
|
/* If this object is enabled with CET. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
- lc_none = 0, /* Not enabled with CET. */
|
||||||
|
- lc_ibt = 1 << 0, /* Enabled with IBT. */
|
||||||
|
- lc_shstk = 1 << 1, /* Enabled with STSHK. */
|
||||||
|
+ lc_unknown = 0, /* Unknown CET status. */
|
||||||
|
+ lc_none = 1 << 0, /* Not enabled with CET. */
|
||||||
|
+ lc_ibt = 1 << 1, /* Enabled with IBT. */
|
||||||
|
+ lc_shstk = 1 << 2, /* Enabled with STSHK. */
|
||||||
|
lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both. */
|
||||||
|
- } l_cet:2;
|
||||||
|
+ } l_cet:3;
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
From b21abc069f58da3f8e556ec730f0a387cfc91f5f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
|
||||||
|
Date: Fri, 19 Oct 2018 13:30:44 +0200
|
||||||
|
Subject: [PATCH 36] Add an additional test to resolv/tst-resolv-network.c
|
||||||
|
|
||||||
|
Test for the infinite loop in getnetbyname, bug #17630.
|
||||||
|
|
||||||
|
(cherry picked from commit ac8060265bcaca61568ef3a20b9a0140a270af54)
|
||||||
|
---
|
||||||
|
ChangeLog | 5 +++++
|
||||||
|
resolv/tst-resolv-network.c | 6 ++++++
|
||||||
|
2 files changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 86bdf17989..d020aff979 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+2018-11-08 Alexandra Hájková <ahajkova@redhat.com>
|
||||||
|
+
|
||||||
|
+ [BZ #17630]
|
||||||
|
+ * resolv/tst-resolv-network.c: Add test for getnetbyname.
|
||||||
|
+
|
||||||
|
2018-11-08 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
[BZ #23509]
|
||||||
|
diff --git a/resolv/tst-resolv-network.c b/resolv/tst-resolv-network.c
|
||||||
|
index 4b862d57e6..735e38d0f8 100644
|
||||||
|
--- a/resolv/tst-resolv-network.c
|
||||||
|
+++ b/resolv/tst-resolv-network.c
|
||||||
|
@@ -149,6 +149,9 @@ handle_code (const struct resolv_response_context *ctx,
|
||||||
|
resolv_response_add_data (b, &rrtype, sizeof (rrtype));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case 104:
|
||||||
|
+ send_ptr (b, qname, qclass, qtype, "host.example");
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
FAIL_EXIT1 ("invalid QNAME: %s (code %d)", qname, code);
|
||||||
|
}
|
||||||
|
@@ -257,6 +260,9 @@ do_test (void)
|
||||||
|
"error: TRY_AGAIN\n");
|
||||||
|
check_netent ("code103.example", getnetbyname ("code103.example"),
|
||||||
|
"error: NO_RECOVERY\n");
|
||||||
|
+ /* Test bug #17630. */
|
||||||
|
+ check_netent ("code104.example", getnetbyname ("code104.example"),
|
||||||
|
+ "error: TRY_AGAIN\n");
|
||||||
|
|
||||||
|
/* Lookup by address, success cases. */
|
||||||
|
check_reverse (1,
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
From 168035056eab9db4ee0e5d7f62060e111b86a0a4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Mon, 13 Aug 2018 21:35:27 +0000
|
||||||
|
Subject: [PATCH 37] Update syscall-names.list for Linux 4.18.
|
||||||
|
|
||||||
|
This patch updates sysdeps/unix/sysv/linux/syscall-names.list for
|
||||||
|
Linux 4.18. The io_pgetevents and rseq syscalls are added to the
|
||||||
|
kernel on various architectures, so need to be mentioned in this file.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||||
|
version to 4.18.
|
||||||
|
(io_pgetevents): New syscall.
|
||||||
|
(rseq): Likewise.
|
||||||
|
|
||||||
|
(cherry picked from commit 17b26500f9bb926d85e86821d014f7c1bb88043c)
|
||||||
|
---
|
||||||
|
ChangeLog | 7 +++++++
|
||||||
|
sysdeps/unix/sysv/linux/syscall-names.list | 6 ++++--
|
||||||
|
2 files changed, 11 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index d020aff979..88814e6947 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,10 @@
|
||||||
|
+2018-08-13 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
+
|
||||||
|
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||||
|
+ version to 4.18.
|
||||||
|
+ (io_pgetevents): New syscall.
|
||||||
|
+ (rseq): Likewise.
|
||||||
|
+
|
||||||
|
2018-11-08 Alexandra Hájková <ahajkova@redhat.com>
|
||||||
|
|
||||||
|
[BZ #17630]
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 5306d538e6..9982a6334d 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -22,8 +22,8 @@
|
||||||
|
# names are only used if the installed kernel headers also provide
|
||||||
|
# them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 4.17.
|
||||||
|
-kernel 4.17
|
||||||
|
+# The list of system calls is current as of Linux 4.18.
|
||||||
|
+kernel 4.18
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -186,6 +186,7 @@ inotify_rm_watch
|
||||||
|
io_cancel
|
||||||
|
io_destroy
|
||||||
|
io_getevents
|
||||||
|
+io_pgetevents
|
||||||
|
io_setup
|
||||||
|
io_submit
|
||||||
|
ioctl
|
||||||
|
@@ -431,6 +432,7 @@ renameat2
|
||||||
|
request_key
|
||||||
|
restart_syscall
|
||||||
|
rmdir
|
||||||
|
+rseq
|
||||||
|
rt_sigaction
|
||||||
|
rt_sigpending
|
||||||
|
rt_sigprocmask
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
From 510a25f2d208e3b0c86f54b053f61c5b647e4b9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pochang Chen <johnchen902@gmail.com>
|
||||||
|
Date: Thu, 16 Aug 2018 15:24:24 -0400
|
||||||
|
Subject: [PATCH 38] malloc: Verify size of top chunk.
|
||||||
|
|
||||||
|
The House of Force is a well-known technique to exploit heap
|
||||||
|
overflow. In essence, this exploit takes three steps:
|
||||||
|
1. Overwrite the size of top chunk with very large value (e.g. -1).
|
||||||
|
2. Request x bytes from top chunk. As the size of top chunk
|
||||||
|
is corrupted, x can be arbitrarily large and top chunk will
|
||||||
|
still be offset by x.
|
||||||
|
3. The next allocation from top chunk will thus be controllable.
|
||||||
|
|
||||||
|
If we verify the size of top chunk at step 2, we can stop such attack.
|
||||||
|
|
||||||
|
(cherry picked from commit 30a17d8c95fbfb15c52d1115803b63aaa73a285c)
|
||||||
|
---
|
||||||
|
ChangeLog | 4 ++++
|
||||||
|
malloc/malloc.c | 3 +++
|
||||||
|
2 files changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 88814e6947..44795b2e61 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+2018-08-16 Pochang Chen <johnchen902@gmail.com>
|
||||||
|
+
|
||||||
|
+ * malloc/malloc.c (_int_malloc.c): Verify size of top chunk.
|
||||||
|
+
|
||||||
|
2018-08-13 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index e247c77b7d..9431108626 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -4076,6 +4076,9 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
victim = av->top;
|
||||||
|
size = chunksize (victim);
|
||||||
|
|
||||||
|
+ if (__glibc_unlikely (size > av->system_mem))
|
||||||
|
+ malloc_printerr ("malloc(): corrupted top size");
|
||||||
|
+
|
||||||
|
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
|
||||||
|
{
|
||||||
|
remainder_size = size - nb;
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
From 7e40c3f804b5d5dbbc0519565b16101ab22fb899 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Moritz Eckert <m.eckert@cs.ucsb.edu>
|
||||||
|
Date: Thu, 16 Aug 2018 21:08:36 -0400
|
||||||
|
Subject: [PATCH 39] malloc: Mitigate null-byte overflow attacks
|
||||||
|
|
||||||
|
* malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
|
||||||
|
(malloc_consolidate): Likewise.
|
||||||
|
|
||||||
|
(cherry picked from commit d6db68e66dff25d12c3bc5641b60cbd7fb6ab44f)
|
||||||
|
---
|
||||||
|
ChangeLog | 5 +++++
|
||||||
|
malloc/malloc.c | 4 ++++
|
||||||
|
2 files changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 44795b2e61..e81991066e 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+2018-08-16 DJ Delorie <dj@delorie.com>
|
||||||
|
+
|
||||||
|
+ * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
|
||||||
|
+ (malloc_consolidate): Likewise.
|
||||||
|
+
|
||||||
|
2018-08-16 Pochang Chen <johnchen902@gmail.com>
|
||||||
|
|
||||||
|
* malloc/malloc.c (_int_malloc.c): Verify size of top chunk.
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 9431108626..7c8bf8413c 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -4281,6 +4281,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
prevsize = prev_size (p);
|
||||||
|
size += prevsize;
|
||||||
|
p = chunk_at_offset(p, -((long) prevsize));
|
||||||
|
+ if (__glibc_unlikely (chunksize(p) != prevsize))
|
||||||
|
+ malloc_printerr ("corrupted size vs. prev_size while consolidating");
|
||||||
|
unlink(av, p, bck, fwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4442,6 +4444,8 @@ static void malloc_consolidate(mstate av)
|
||||||
|
prevsize = prev_size (p);
|
||||||
|
size += prevsize;
|
||||||
|
p = chunk_at_offset(p, -((long) prevsize));
|
||||||
|
+ if (__glibc_unlikely (chunksize(p) != prevsize))
|
||||||
|
+ malloc_printerr ("corrupted size vs. prev_size in fastbins");
|
||||||
|
unlink(av, p, bck, fwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Istvan Kurucsai <pistukem@gmail.com>
|
||||||
|
Date: Tue, 16 Jan 2018 14:48:16 +0100
|
||||||
|
Subject: [PATCH v2 1] malloc: Additional checks for unsorted bin integrity
|
||||||
|
I.
|
||||||
|
|
||||||
|
Ensure the following properties of chunks encountered during binning:
|
||||||
|
- victim chunk has reasonable size
|
||||||
|
- next chunk has reasonable size
|
||||||
|
- next->prev_size == victim->size
|
||||||
|
- valid double linked list
|
||||||
|
- PREV_INUSE of next chunk is unset
|
||||||
|
|
||||||
|
* malloc/malloc.c (_int_malloc): Additional binning code checks.
|
||||||
|
|
||||||
|
(cherry picked from commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)
|
||||||
|
---
|
||||||
|
malloc/malloc.c | 19 +++++++++++++++----
|
||||||
|
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 7c8bf8413c..47795601c8 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -3716,11 +3716,22 @@ _int_malloc (mstate av, size_t bytes)
|
||||||
|
while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
|
||||||
|
{
|
||||||
|
bck = victim->bk;
|
||||||
|
- if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
|
||||||
|
- || __builtin_expect (chunksize_nomask (victim)
|
||||||
|
- > av->system_mem, 0))
|
||||||
|
- malloc_printerr ("malloc(): memory corruption");
|
||||||
|
size = chunksize (victim);
|
||||||
|
+ mchunkptr next = chunk_at_offset (victim, size);
|
||||||
|
+
|
||||||
|
+ if (__glibc_unlikely (size <= 2 * SIZE_SZ)
|
||||||
|
+ || __glibc_unlikely (size > av->system_mem))
|
||||||
|
+ malloc_printerr ("malloc(): invalid size (unsorted)");
|
||||||
|
+ if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ)
|
||||||
|
+ || __glibc_unlikely (chunksize_nomask (next) > av->system_mem))
|
||||||
|
+ malloc_printerr ("malloc(): invalid next size (unsorted)");
|
||||||
|
+ if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size))
|
||||||
|
+ malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)");
|
||||||
|
+ if (__glibc_unlikely (bck->fd != victim)
|
||||||
|
+ || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
|
||||||
|
+ malloc_printerr ("malloc(): unsorted double linked list corrupted");
|
||||||
|
+ if (__glibc_unlikely (prev_inuse(next)))
|
||||||
|
+ malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");
|
||||||
|
|
||||||
|
/*
|
||||||
|
If a small request, try to use last remainder if it is the
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
From 7d174f53539bfbfa9cdfa41ead605573d3f219eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue, 28 Aug 2018 13:19:27 +0200
|
||||||
|
Subject: [PATCH 41] nscd: Fix use-after-free in addgetnetgrentX [BZ #23520]
|
||||||
|
|
||||||
|
addinnetgrX may use the heap-allocated buffer, so free the buffer
|
||||||
|
in this function.
|
||||||
|
|
||||||
|
(cherry picked from commit 745664bd798ec8fd50438605948eea594179fba1)
|
||||||
|
---
|
||||||
|
ChangeLog | 12 ++++++++++++
|
||||||
|
nscd/netgroupcache.c | 42 +++++++++++++++++++++++++++++-------------
|
||||||
|
2 files changed, 41 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index e81991066e..79d303e7b6 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,15 @@
|
||||||
|
+2018-08-28 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ [BZ #23520]
|
||||||
|
+ nscd: Fix use-after-free in addgetnetgrentX and its callers.
|
||||||
|
+ * nscd/netgroupcache.c
|
||||||
|
+ (addgetnetgrentX): Add tofreep parameter. Do not free
|
||||||
|
+ heap-allocated buffer.
|
||||||
|
+ (addinnetgrX): Free buffer allocated bt addgetnetgrentX.
|
||||||
|
+ (addgetnetgrentX_ignore): New function.
|
||||||
|
+ (addgetnetgrent): Call it.
|
||||||
|
+ (readdgetnetgrent): Likewise.
|
||||||
|
+
|
||||||
|
2018-08-16 DJ Delorie <dj@delorie.com>
|
||||||
|
|
||||||
|
* malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
|
||||||
|
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
|
||||||
|
index 2b35389cc8..87059fb280 100644
|
||||||
|
--- a/nscd/netgroupcache.c
|
||||||
|
+++ b/nscd/netgroupcache.c
|
||||||
|
@@ -113,7 +113,8 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
static time_t
|
||||||
|
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
const char *key, uid_t uid, struct hashentry *he,
|
||||||
|
- struct datahead *dh, struct dataset **resultp)
|
||||||
|
+ struct datahead *dh, struct dataset **resultp,
|
||||||
|
+ void **tofreep)
|
||||||
|
{
|
||||||
|
if (__glibc_unlikely (debug_level > 0))
|
||||||
|
{
|
||||||
|
@@ -139,6 +140,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
size_t group_len = strlen (key) + 1;
|
||||||
|
struct name_list *first_needed
|
||||||
|
= alloca (sizeof (struct name_list) + group_len);
|
||||||
|
+ *tofreep = NULL;
|
||||||
|
|
||||||
|
if (netgroup_database == NULL
|
||||||
|
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
|
||||||
|
@@ -151,6 +153,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
|
||||||
|
memset (&data, '\0', sizeof (data));
|
||||||
|
buffer = xmalloc (buflen);
|
||||||
|
+ *tofreep = buffer;
|
||||||
|
first_needed->next = first_needed;
|
||||||
|
memcpy (first_needed->name, key, group_len);
|
||||||
|
data.needed_groups = first_needed;
|
||||||
|
@@ -439,8 +442,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
- free (buffer);
|
||||||
|
-
|
||||||
|
*resultp = dataset;
|
||||||
|
|
||||||
|
return timeout;
|
||||||
|
@@ -477,8 +478,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
group, group_len,
|
||||||
|
db, uid);
|
||||||
|
time_t timeout;
|
||||||
|
+ void *tofree;
|
||||||
|
if (result != NULL)
|
||||||
|
- timeout = result->head.timeout;
|
||||||
|
+ {
|
||||||
|
+ timeout = result->head.timeout;
|
||||||
|
+ tofree = NULL;
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request_header req_get =
|
||||||
|
@@ -487,7 +492,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
.key_len = group_len
|
||||||
|
};
|
||||||
|
timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
|
||||||
|
- &result);
|
||||||
|
+ &result, &tofree);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct indataset
|
||||||
|
@@ -560,7 +565,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
++dh->nreloads;
|
||||||
|
if (cacheable)
|
||||||
|
pthread_rwlock_unlock (&db->lock);
|
||||||
|
- return timeout;
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (he == NULL)
|
||||||
|
@@ -596,17 +601,30 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
dh->usable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ out:
|
||||||
|
+ free (tofree);
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+static time_t
|
||||||
|
+addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
+ const char *key, uid_t uid, struct hashentry *he,
|
||||||
|
+ struct datahead *dh)
|
||||||
|
+{
|
||||||
|
+ struct dataset *ignore;
|
||||||
|
+ void *tofree;
|
||||||
|
+ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
|
||||||
|
+ &ignore, &tofree);
|
||||||
|
+ free (tofree);
|
||||||
|
+ return timeout;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
addgetnetgrent (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
void *key, uid_t uid)
|
||||||
|
{
|
||||||
|
- struct dataset *ignore;
|
||||||
|
-
|
||||||
|
- addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore);
|
||||||
|
+ addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -619,10 +637,8 @@ readdgetnetgrent (struct database_dyn *db, struct hashentry *he,
|
||||||
|
.type = GETNETGRENT,
|
||||||
|
.key_len = he->len
|
||||||
|
};
|
||||||
|
- struct dataset *ignore;
|
||||||
|
-
|
||||||
|
- return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh,
|
||||||
|
- &ignore);
|
||||||
|
+ return addgetnetgrentX_ignore
|
||||||
|
+ (db, -1, &req, db->data + he->key, he->owner, he, dh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,286 @@
|
||||||
|
From 9071be6b3f78da905ab2b6403933fe14d4482e47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
Date: Fri, 31 Aug 2018 18:04:32 -0700
|
||||||
|
Subject: [PATCH 42] [BZ #20271] Add newlines in __libc_fatal calls.
|
||||||
|
|
||||||
|
(cherry picked from commit a6e8926f8d49a213a9abb1a61f6af964f612ab7f)
|
||||||
|
---
|
||||||
|
ChangeLog | 22 +++++++++++++++++++
|
||||||
|
grp/initgroups.c | 2 +-
|
||||||
|
include/stdio.h | 3 ++-
|
||||||
|
nptl/pthread_cond_wait.c | 2 +-
|
||||||
|
nscd/initgrcache.c | 2 +-
|
||||||
|
nss/nsswitch.c | 2 +-
|
||||||
|
sysdeps/aarch64/dl-irel.h | 2 +-
|
||||||
|
sysdeps/arm/dl-irel.h | 2 +-
|
||||||
|
sysdeps/generic/unwind-dw2.c | 2 +-
|
||||||
|
sysdeps/i386/dl-irel.h | 2 +-
|
||||||
|
sysdeps/nptl/futex-internal.h | 2 +-
|
||||||
|
sysdeps/powerpc/powerpc32/dl-irel.h | 2 +-
|
||||||
|
sysdeps/powerpc/powerpc64/dl-irel.h | 2 +-
|
||||||
|
sysdeps/s390/dl-irel.h | 2 +-
|
||||||
|
sysdeps/sparc/sparc32/dl-irel.h | 2 +-
|
||||||
|
sysdeps/sparc/sparc64/dl-irel.h | 2 +-
|
||||||
|
.../unix/sysv/linux/netlink_assert_response.c | 4 ++--
|
||||||
|
sysdeps/x86_64/dl-irel.h | 2 +-
|
||||||
|
18 files changed, 41 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 79d303e7b6..5145768a45 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,25 @@
|
||||||
|
+2018-08-31 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
+
|
||||||
|
+ [BZ #20271]
|
||||||
|
+ * include/stdio.h (__libc_fatal): Mention newline in comment.
|
||||||
|
+ * grp/initgroups.c (internal_getgrouplist): Add missing newline.
|
||||||
|
+ * nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Likewise.
|
||||||
|
+ * nscd/initgrcache.c (addinitgroupsX): Likewise.
|
||||||
|
+ * nss/nsswitch.c (__nss_next2): Likewise.
|
||||||
|
+ * sysdeps/aarch64/dl-irel.h (elf_irela): Likewise.
|
||||||
|
+ * sysdeps/arm/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/generic/unwind-dw2.c (execute_cfa_program): Likewise.
|
||||||
|
+ * sysdeps/i386/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/powerpc/powerpc32/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/powerpc/powerpc64/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/s390/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/sparc/sparc32/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/sparc/sparc64/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/x86_64/dl-irel.h (elf_irel): Likewise.
|
||||||
|
+ * sysdeps/nptl/futex-internal.h (futex_wake): Likewise.
|
||||||
|
+ * sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||||
|
+ (__netlink_assert_response): Likewise.
|
||||||
|
+
|
||||||
|
2018-08-28 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
[BZ #23520]
|
||||||
|
diff --git a/grp/initgroups.c b/grp/initgroups.c
|
||||||
|
index f056fbf5aa..93e7f5814d 100644
|
||||||
|
--- a/grp/initgroups.c
|
||||||
|
+++ b/grp/initgroups.c
|
||||||
|
@@ -128,7 +128,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
|
||||||
|
|
||||||
|
/* This is really only for debugging. */
|
||||||
|
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
|
||||||
|
- __libc_fatal ("illegal status in internal_getgrouplist");
|
||||||
|
+ __libc_fatal ("Illegal status in internal_getgrouplist.\n");
|
||||||
|
|
||||||
|
/* For compatibility reason we will continue to look for more
|
||||||
|
entries using the next service even though data has already
|
||||||
|
diff --git a/include/stdio.h b/include/stdio.h
|
||||||
|
index 9162d4e247..7a5c09089f 100644
|
||||||
|
--- a/include/stdio.h
|
||||||
|
+++ b/include/stdio.h
|
||||||
|
@@ -98,7 +98,8 @@ enum __libc_message_action
|
||||||
|
do_backtrace = 1 << 1 /* Backtrace. */
|
||||||
|
};
|
||||||
|
|
||||||
|
-/* Print out MESSAGE on the error output and abort. */
|
||||||
|
+/* Print out MESSAGE (which should end with a newline) on the error output
|
||||||
|
+ and abort. */
|
||||||
|
extern void __libc_fatal (const char *__message)
|
||||||
|
__attribute__ ((__noreturn__));
|
||||||
|
extern void __libc_message (enum __libc_message_action action,
|
||||||
|
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||||
|
index 3e11054182..ebf07ca82d 100644
|
||||||
|
--- a/nptl/pthread_cond_wait.c
|
||||||
|
+++ b/nptl/pthread_cond_wait.c
|
||||||
|
@@ -516,7 +516,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||||
|
struct timespec rt;
|
||||||
|
if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0)
|
||||||
|
__libc_fatal ("clock_gettime does not support "
|
||||||
|
- "CLOCK_MONOTONIC");
|
||||||
|
+ "CLOCK_MONOTONIC\n");
|
||||||
|
/* Convert the absolute timeout value to a relative
|
||||||
|
timeout. */
|
||||||
|
rt.tv_sec = abstime->tv_sec - rt.tv_sec;
|
||||||
|
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
|
||||||
|
index 2c74951f57..4764f14a45 100644
|
||||||
|
--- a/nscd/initgrcache.c
|
||||||
|
+++ b/nscd/initgrcache.c
|
||||||
|
@@ -159,7 +159,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
|
||||||
|
|
||||||
|
/* This is really only for debugging. */
|
||||||
|
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
|
||||||
|
- __libc_fatal ("illegal status in internal_getgrouplist");
|
||||||
|
+ __libc_fatal ("Illegal status in internal_getgrouplist.\n");
|
||||||
|
|
||||||
|
any_success |= status == NSS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
|
||||||
|
index ee46f24424..3c48b4b85e 100644
|
||||||
|
--- a/nss/nsswitch.c
|
||||||
|
+++ b/nss/nsswitch.c
|
||||||
|
@@ -235,7 +235,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name,
|
||||||
|
/* This is really only for debugging. */
|
||||||
|
if (__builtin_expect (NSS_STATUS_TRYAGAIN > status
|
||||||
|
|| status > NSS_STATUS_RETURN, 0))
|
||||||
|
- __libc_fatal ("illegal status in __nss_next");
|
||||||
|
+ __libc_fatal ("Illegal status in __nss_next.\n");
|
||||||
|
|
||||||
|
if (nss_next_action (*ni, status) == NSS_ACTION_RETURN)
|
||||||
|
return 1;
|
||||||
|
diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h
|
||||||
|
index 5889ee187b..bef71ed0f3 100644
|
||||||
|
--- a/sysdeps/aarch64/dl-irel.h
|
||||||
|
+++ b/sysdeps/aarch64/dl-irel.h
|
||||||
|
@@ -47,7 +47,7 @@ elf_irela (const ElfW(Rela) *reloc)
|
||||||
|
*reloc_addr = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/arm/dl-irel.h b/sysdeps/arm/dl-irel.h
|
||||||
|
index a7b6456075..be6eb7743e 100644
|
||||||
|
--- a/sysdeps/arm/dl-irel.h
|
||||||
|
+++ b/sysdeps/arm/dl-irel.h
|
||||||
|
@@ -46,7 +46,7 @@ elf_irel (const Elf32_Rel *reloc)
|
||||||
|
*reloc_addr = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c
|
||||||
|
index 082609b34a..724c16a7f0 100644
|
||||||
|
--- a/sysdeps/generic/unwind-dw2.c
|
||||||
|
+++ b/sysdeps/generic/unwind-dw2.c
|
||||||
|
@@ -843,7 +843,7 @@ execute_cfa_program (const unsigned char *insn_ptr,
|
||||||
|
struct frame_state_reg_info *old_rs = fs->regs.prev;
|
||||||
|
#ifdef _LIBC
|
||||||
|
if (old_rs == NULL)
|
||||||
|
- __libc_fatal ("invalid DWARF unwind data");
|
||||||
|
+ __libc_fatal ("Invalid DWARF unwind data.\n");
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
diff --git a/sysdeps/i386/dl-irel.h b/sysdeps/i386/dl-irel.h
|
||||||
|
index 55303180c7..bcaf0668ac 100644
|
||||||
|
--- a/sysdeps/i386/dl-irel.h
|
||||||
|
+++ b/sysdeps/i386/dl-irel.h
|
||||||
|
@@ -45,7 +45,7 @@ elf_irel (const Elf32_Rel *reloc)
|
||||||
|
*reloc_addr = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
|
||||||
|
index 1a5624789d..6fd27f0df6 100644
|
||||||
|
--- a/sysdeps/nptl/futex-internal.h
|
||||||
|
+++ b/sysdeps/nptl/futex-internal.h
|
||||||
|
@@ -197,7 +197,7 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private);
|
||||||
|
static __always_inline __attribute__ ((__noreturn__)) void
|
||||||
|
futex_fatal_error (void)
|
||||||
|
{
|
||||||
|
- __libc_fatal ("The futex facility returned an unexpected error code.");
|
||||||
|
+ __libc_fatal ("The futex facility returned an unexpected error code.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* futex-internal.h */
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc32/dl-irel.h b/sysdeps/powerpc/powerpc32/dl-irel.h
|
||||||
|
index a7368b2582..61d0e4cf61 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc32/dl-irel.h
|
||||||
|
+++ b/sysdeps/powerpc/powerpc32/dl-irel.h
|
||||||
|
@@ -46,7 +46,7 @@ elf_irela (const Elf32_Rela *reloc)
|
||||||
|
*reloc_addr = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h
|
||||||
|
index ab13c04358..2fd0ee8a86 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/dl-irel.h
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/dl-irel.h
|
||||||
|
@@ -57,7 +57,7 @@ elf_irela (const Elf64_Rela *reloc)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
diff --git a/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h
|
||||||
|
index d8ba7ba427..ecb24f0a9b 100644
|
||||||
|
--- a/sysdeps/s390/dl-irel.h
|
||||||
|
+++ b/sysdeps/s390/dl-irel.h
|
||||||
|
@@ -46,7 +46,7 @@ elf_irela (const ElfW(Rela) *reloc)
|
||||||
|
*reloc_addr = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
diff --git a/sysdeps/sparc/sparc32/dl-irel.h b/sysdeps/sparc/sparc32/dl-irel.h
|
||||||
|
index ffca36864f..cf47cda834 100644
|
||||||
|
--- a/sysdeps/sparc/sparc32/dl-irel.h
|
||||||
|
+++ b/sysdeps/sparc/sparc32/dl-irel.h
|
||||||
|
@@ -56,7 +56,7 @@ elf_irela (const Elf32_Rela *reloc)
|
||||||
|
else if (r_type == R_SPARC_NONE)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
diff --git a/sysdeps/sparc/sparc64/dl-irel.h b/sysdeps/sparc/sparc64/dl-irel.h
|
||||||
|
index c5cd3057ac..446fed1836 100644
|
||||||
|
--- a/sysdeps/sparc/sparc64/dl-irel.h
|
||||||
|
+++ b/sysdeps/sparc/sparc64/dl-irel.h
|
||||||
|
@@ -59,7 +59,7 @@ elf_irela (const Elf64_Rela *reloc)
|
||||||
|
else if (r_type == R_SPARC_NONE)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||||
|
index f31ccb52ff..6afc3a17ce 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
|
||||||
|
@@ -72,12 +72,12 @@ __netlink_assert_response (int fd, ssize_t result)
|
||||||
|
char message[200];
|
||||||
|
if (family < 0)
|
||||||
|
__snprintf (message, sizeof (message),
|
||||||
|
- "Unexpected error %d on netlink descriptor %d",
|
||||||
|
+ "Unexpected error %d on netlink descriptor %d.\n",
|
||||||
|
error_code, fd);
|
||||||
|
else
|
||||||
|
__snprintf (message, sizeof (message),
|
||||||
|
"Unexpected error %d on netlink descriptor %d"
|
||||||
|
- " (address family %d)",
|
||||||
|
+ " (address family %d).\n",
|
||||||
|
error_code, fd, family);
|
||||||
|
__libc_fatal (message);
|
||||||
|
}
|
||||||
|
diff --git a/sysdeps/x86_64/dl-irel.h b/sysdeps/x86_64/dl-irel.h
|
||||||
|
index 6ecc50fb42..33f100d8b1 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-irel.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-irel.h
|
||||||
|
@@ -45,7 +45,7 @@ elf_irela (const ElfW(Rela) *reloc)
|
||||||
|
*reloc_addr = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __libc_fatal ("unexpected reloc type in static binary");
|
||||||
|
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* dl-irel.h */
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
From e7388e5134471ef965bd48bafc71ba71eb8bf017 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
Date: Tue, 18 Sep 2018 15:02:10 -0700
|
||||||
|
Subject: [PATCH 43] Fix tzfile low-memory assertion failure
|
||||||
|
|
||||||
|
[BZ #21716]
|
||||||
|
* time/tzfile.c (__tzfile_read): Check for memory exhaustion
|
||||||
|
when registering time zone abbreviations.
|
||||||
|
|
||||||
|
(cherry picked from commit e4e4fde51a309801af5eed72d3494cbf4b7737aa)
|
||||||
|
---
|
||||||
|
ChangeLog | 7 +++++++
|
||||||
|
time/tzfile.c | 3 ++-
|
||||||
|
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 5145768a45..788f3f41be 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,10 @@
|
||||||
|
+2018-09-18 Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
+
|
||||||
|
+ Fix tzfile low-memory assertion failure
|
||||||
|
+ [BZ #21716]
|
||||||
|
+ * time/tzfile.c (__tzfile_read): Check for memory exhaustion
|
||||||
|
+ when registering time zone abbreviations.
|
||||||
|
+
|
||||||
|
2018-08-31 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
|
||||||
|
[BZ #20271]
|
||||||
|
diff --git a/time/tzfile.c b/time/tzfile.c
|
||||||
|
index 2a385b92bc..ea6e940303 100644
|
||||||
|
--- a/time/tzfile.c
|
||||||
|
+++ b/time/tzfile.c
|
||||||
|
@@ -410,7 +410,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
|
||||||
|
|
||||||
|
/* First "register" all timezone names. */
|
||||||
|
for (i = 0; i < num_types; ++i)
|
||||||
|
- (void) __tzstring (&zone_names[types[i].idx]);
|
||||||
|
+ if (__tzstring (&zone_names[types[i].idx]) == NULL)
|
||||||
|
+ goto ret_free_transitions;
|
||||||
|
|
||||||
|
/* Find the standard and daylight time offsets used by the rule file.
|
||||||
|
We choose the offsets in the types of each flavor that are
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
From f44c2ca5eacd2df76fc38be75f9ebb8f0ff555eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Mon, 22 Oct 2018 23:26:37 +0000
|
||||||
|
Subject: [PATCH 44] Update kernel version in syscall-names.list to 4.19.
|
||||||
|
|
||||||
|
Linux 4.19 does not add any new syscalls (some existing ones are added
|
||||||
|
to more architectures); this patch updates the version number in
|
||||||
|
syscall-names.list to reflect that it's still current for 4.19.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||||
|
version to 4.19.
|
||||||
|
|
||||||
|
(cherry picked from commit 029ad711b8ad4cf0e5d98e0c138a35a23a376a74)
|
||||||
|
---
|
||||||
|
ChangeLog | 5 +++++
|
||||||
|
sysdeps/unix/sysv/linux/syscall-names.list | 4 ++--
|
||||||
|
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 788f3f41be..f2e0f1ffd7 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+2018-10-22 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
+
|
||||||
|
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||||
|
+ version to 4.19.
|
||||||
|
+
|
||||||
|
2018-09-18 Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
|
||||||
|
Fix tzfile low-memory assertion failure
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 9982a6334d..f88001c9c3 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -22,8 +22,8 @@
|
||||||
|
# names are only used if the installed kernel headers also provide
|
||||||
|
# them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 4.18.
|
||||||
|
-kernel 4.18
|
||||||
|
+# The list of system calls is current as of Linux 4.19.
|
||||||
|
+kernel 4.19
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
From 10f1519f6a0acdc1fc45e962fa5c13312cc7b624 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Tue, 9 Oct 2018 14:31:28 +0100
|
||||||
|
Subject: [PATCH 45] Increase timeout of libio/tst-readline
|
||||||
|
|
||||||
|
Increase timeout from the default 20s to 100s. This test makes close to
|
||||||
|
20 million syscalls with distribution:
|
||||||
|
|
||||||
|
12327675 read
|
||||||
|
4143204 lseek
|
||||||
|
929475 close
|
||||||
|
929471 openat
|
||||||
|
92817 fstat
|
||||||
|
1431 write
|
||||||
|
...
|
||||||
|
|
||||||
|
The default timeout assumes each can finish in 1us on average which
|
||||||
|
is not true on slow machines.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
* libio/tst-readline.c (TIMEOUT): Define.
|
||||||
|
|
||||||
|
(cherry picked from commit ed643089cd3251038863d32e67ec47b94cd557f3)
|
||||||
|
---
|
||||||
|
ChangeLog | 4 ++++
|
||||||
|
libio/tst-readline.c | 1 +
|
||||||
|
2 files changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index f2e0f1ffd7..99462fa3d4 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,7 @@
|
||||||
|
+2018-10-09 Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
+
|
||||||
|
+ * libio/tst-readline.c (TIMEOUT): Define.
|
||||||
|
+
|
||||||
|
2018-10-22 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
|
||||||
|
diff --git a/libio/tst-readline.c b/libio/tst-readline.c
|
||||||
|
index 9322ef68da..63f5227760 100644
|
||||||
|
--- a/libio/tst-readline.c
|
||||||
|
+++ b/libio/tst-readline.c
|
||||||
|
@@ -232,5 +232,6 @@ do_test (void)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define TIMEOUT 100
|
||||||
|
#define PREPARE prepare
|
||||||
|
#include <support/test-driver.c>
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
From 2c7078bfb9cc426433ac08d951e24c29c01b5f7d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon, 19 Nov 2018 15:35:03 +0100
|
||||||
|
Subject: [PATCH 46] support: Print timestamps in timeout handler
|
||||||
|
|
||||||
|
This is sometimes useful to determine if a test truly got stuck, or if
|
||||||
|
it was making progress (logging information to standard output) and
|
||||||
|
was merely slow to finish.
|
||||||
|
|
||||||
|
(cherry picked from commit 35e3fbc4512c880fccb35b8e3abd132d4be18480)
|
||||||
|
---
|
||||||
|
ChangeLog | 7 +++++++
|
||||||
|
support/support_test_main.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 35 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 99462fa3d4..8c92ee7764 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,10 @@
|
||||||
|
+2018-11-19 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ support: Print timestamps in timeout handler.
|
||||||
|
+ * support/support_test_main.c (print_timestamp): New function.
|
||||||
|
+ (signal_handler): Use it to print the termination time and the
|
||||||
|
+ time of the last write to standard output.
|
||||||
|
+
|
||||||
|
2018-10-09 Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
* libio/tst-readline.c (TIMEOUT): Define.
|
||||||
|
diff --git a/support/support_test_main.c b/support/support_test_main.c
|
||||||
|
index 23429779ac..fa3c2e06de 100644
|
||||||
|
--- a/support/support_test_main.c
|
||||||
|
+++ b/support/support_test_main.c
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
+#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <time.h>
|
||||||
|
@@ -86,6 +87,19 @@ static pid_t test_pid;
|
||||||
|
/* The cleanup handler passed to test_main. */
|
||||||
|
static void (*cleanup_function) (void);
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+print_timestamp (const char *what, struct timeval tv)
|
||||||
|
+{
|
||||||
|
+ struct tm tm;
|
||||||
|
+ if (gmtime_r (&tv.tv_sec, &tm) == NULL)
|
||||||
|
+ printf ("%s: %lld.%06d\n",
|
||||||
|
+ what, (long long int) tv.tv_sec, (int) tv.tv_usec);
|
||||||
|
+ else
|
||||||
|
+ printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
|
||||||
|
+ what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
|
||||||
|
+ tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Timeout handler. We kill the child and exit with an error. */
|
||||||
|
static void
|
||||||
|
__attribute__ ((noreturn))
|
||||||
|
@@ -94,6 +108,13 @@ signal_handler (int sig)
|
||||||
|
int killed;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
+ /* Do this first to avoid further interference from the
|
||||||
|
+ subprocess. */
|
||||||
|
+ struct timeval now;
|
||||||
|
+ bool now_available = gettimeofday (&now, NULL) == 0;
|
||||||
|
+ struct stat64 st;
|
||||||
|
+ bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0;
|
||||||
|
+
|
||||||
|
assert (test_pid > 1);
|
||||||
|
/* Kill the whole process group. */
|
||||||
|
kill (-test_pid, SIGKILL);
|
||||||
|
@@ -144,6 +165,13 @@ signal_handler (int sig)
|
||||||
|
printf ("Timed out: killed the child process but it exited %d\n",
|
||||||
|
WEXITSTATUS (status));
|
||||||
|
|
||||||
|
+ if (now_available)
|
||||||
|
+ print_timestamp ("Termination time", now);
|
||||||
|
+ if (st_available)
|
||||||
|
+ print_timestamp ("Last write to standard output",
|
||||||
|
+ (struct timeval) { st.st_mtim.tv_sec,
|
||||||
|
+ st.st_mtim.tv_nsec / 1000 });
|
||||||
|
+
|
||||||
|
/* Exit with an error. */
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,261 @@
|
||||||
|
From 481a6cf0c24f02f251d7cd0b776c12d00e6b144f Mon Sep 17 00:00:00 2001
|
||||||
|
From: DJ Delorie <dj@delorie.com>
|
||||||
|
Date: Tue, 20 Nov 2018 13:24:09 -0500
|
||||||
|
Subject: [PATCH 47] malloc: tcache double free check
|
||||||
|
|
||||||
|
* malloc/malloc.c (tcache_entry): Add key field.
|
||||||
|
(tcache_put): Set it.
|
||||||
|
(tcache_get): Likewise.
|
||||||
|
(_int_free): Check for double free in tcache.
|
||||||
|
* malloc/tst-tcfree1.c: New.
|
||||||
|
* malloc/tst-tcfree2.c: New.
|
||||||
|
* malloc/Makefile: Run the new tests.
|
||||||
|
* manual/probes.texi: Document memory_tcache_double_free probe.
|
||||||
|
|
||||||
|
* dlfcn/dlerror.c (check_free): Prevent double frees.
|
||||||
|
---
|
||||||
|
ChangeLog | 12 +++++++++++
|
||||||
|
dlfcn/dlerror.c | 5 ++++-
|
||||||
|
malloc/Makefile | 1 +
|
||||||
|
malloc/malloc.c | 28 ++++++++++++++++++++++++++
|
||||||
|
malloc/tst-tcfree1.c | 42 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
malloc/tst-tcfree2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
manual/probes.texi | 12 +++++++++++
|
||||||
|
7 files changed, 147 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 malloc/tst-tcfree1.c
|
||||||
|
create mode 100644 malloc/tst-tcfree2.c
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 8c92ee7764..1ef4b4abe0 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,15 @@
|
||||||
|
+2018-11-20 DJ Delorie <dj@redhat.com>
|
||||||
|
+
|
||||||
|
+ * malloc/malloc.c (tcache_entry): Add key field.
|
||||||
|
+ (tcache_put): Set it.
|
||||||
|
+ (tcache_get): Likewise.
|
||||||
|
+ (_int_free): Check for double free in tcache.
|
||||||
|
+ * malloc/tst-tcfree1.c: New.
|
||||||
|
+ * malloc/tst-tcfree2.c: New.
|
||||||
|
+ * malloc/Makefile: Run the new tests.
|
||||||
|
+ * manual/probes.texi: Document memory_tcache_double_free probe.
|
||||||
|
+
|
||||||
|
+ * dlfcn/dlerror.c (check_free): Prevent double frees.
|
||||||
|
2018-11-19 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
support: Print timestamps in timeout handler.
|
||||||
|
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||||
|
index 33574faab6..96bf925333 100644
|
||||||
|
--- a/dlfcn/dlerror.c
|
||||||
|
+++ b/dlfcn/dlerror.c
|
||||||
|
@@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec)
|
||||||
|
Dl_info info;
|
||||||
|
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
|
||||||
|
#endif
|
||||||
|
- free ((char *) rec->errstring);
|
||||||
|
+ {
|
||||||
|
+ free ((char *) rec->errstring);
|
||||||
|
+ rec->errstring = NULL;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||||
|
index 7d54bad866..e6dfbfc14c 100644
|
||||||
|
--- a/malloc/Makefile
|
||||||
|
+++ b/malloc/Makefile
|
||||||
|
@@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
||||||
|
tst-malloc_info \
|
||||||
|
tst-malloc-too-large \
|
||||||
|
tst-malloc-stats-cancellation \
|
||||||
|
+ tst-tcfree1 tst-tcfree2 \
|
||||||
|
|
||||||
|
tests-static := \
|
||||||
|
tst-interpose-static-nothread \
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 47795601c8..6be2573868 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size)
|
||||||
|
typedef struct tcache_entry
|
||||||
|
{
|
||||||
|
struct tcache_entry *next;
|
||||||
|
+ /* This field exists to detect double frees. */
|
||||||
|
+ struct tcache_perthread_struct *key;
|
||||||
|
} tcache_entry;
|
||||||
|
|
||||||
|
/* There is one of these for each thread, which contains the
|
||||||
|
@@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
|
||||||
|
{
|
||||||
|
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
|
||||||
|
assert (tc_idx < TCACHE_MAX_BINS);
|
||||||
|
+
|
||||||
|
+ /* Mark this chunk as "in the tcache" so the test in _int_free will
|
||||||
|
+ detect a double free. */
|
||||||
|
+ e->key = tcache;
|
||||||
|
+
|
||||||
|
e->next = tcache->entries[tc_idx];
|
||||||
|
tcache->entries[tc_idx] = e;
|
||||||
|
++(tcache->counts[tc_idx]);
|
||||||
|
@@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx)
|
||||||
|
assert (tcache->entries[tc_idx] > 0);
|
||||||
|
tcache->entries[tc_idx] = e->next;
|
||||||
|
--(tcache->counts[tc_idx]);
|
||||||
|
+ e->key = NULL;
|
||||||
|
return (void *) e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4166,6 +4174,26 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
{
|
||||||
|
size_t tc_idx = csize2tidx (size);
|
||||||
|
|
||||||
|
+ /* Check to see if it's already in the tcache. */
|
||||||
|
+ tcache_entry *e = (tcache_entry *) chunk2mem (p);
|
||||||
|
+
|
||||||
|
+ /* This test succeeds on double free. However, we don't 100%
|
||||||
|
+ trust it (it also matches random payload data at a 1 in
|
||||||
|
+ 2^<size_t> chance), so verify it's not an unlikely coincidence
|
||||||
|
+ before aborting. */
|
||||||
|
+ if (__glibc_unlikely (e->key == tcache && tcache))
|
||||||
|
+ {
|
||||||
|
+ tcache_entry *tmp;
|
||||||
|
+ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
|
||||||
|
+ for (tmp = tcache->entries[tc_idx];
|
||||||
|
+ tmp;
|
||||||
|
+ tmp = tmp->next)
|
||||||
|
+ if (tmp == e)
|
||||||
|
+ malloc_printerr ("free(): double free detected in tcache 2");
|
||||||
|
+ /* If we get here, it was a coincidence. We've wasted a few
|
||||||
|
+ cycles, but don't abort. */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (tcache
|
||||||
|
&& tc_idx < mp_.tcache_bins
|
||||||
|
&& tcache->counts[tc_idx] < mp_.tcache_count)
|
||||||
|
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..bc29375ce7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/malloc/tst-tcfree1.c
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/* Test that malloc tcache catches double free.
|
||||||
|
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <error.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <malloc.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <sys/signal.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Do one allocation of any size that fits in tcache. */
|
||||||
|
+ char * volatile x = malloc (32);
|
||||||
|
+
|
||||||
|
+ free (x); // puts in tcache
|
||||||
|
+ free (x); // should abort
|
||||||
|
+
|
||||||
|
+ printf("FAIL: tcache double free not detected\n");
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION do_test
|
||||||
|
+#define EXPECTED_SIGNAL SIGABRT
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..17f06bacd4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/malloc/tst-tcfree2.c
|
||||||
|
@@ -0,0 +1,48 @@
|
||||||
|
+/* Test that malloc tcache catches double free.
|
||||||
|
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <error.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <malloc.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <sys/signal.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ char * volatile ptrs[20];
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ /* Allocate enough small chunks so that when we free them all, the tcache
|
||||||
|
+ is full, and the first one we freed is at the end of its linked list. */
|
||||||
|
+#define COUNT 20
|
||||||
|
+ for (i=0; i<COUNT; i++)
|
||||||
|
+ ptrs[i] = malloc (20);
|
||||||
|
+ for (i=0; i<COUNT; i++)
|
||||||
|
+ free (ptrs[i]);
|
||||||
|
+ free (ptrs[0]);
|
||||||
|
+
|
||||||
|
+ printf("FAIL: tcache double free\n");
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION do_test
|
||||||
|
+#define EXPECTED_SIGNAL SIGABRT
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/manual/probes.texi b/manual/probes.texi
|
||||||
|
index ab2a3102bb..0ea560ed78 100644
|
||||||
|
--- a/manual/probes.texi
|
||||||
|
+++ b/manual/probes.texi
|
||||||
|
@@ -243,6 +243,18 @@ This probe is triggered when the
|
||||||
|
value of this tunable.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
+@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
|
||||||
|
+This probe is triggered when @code{free} determines that the memory
|
||||||
|
+being freed has probably already been freed, and resides in the
|
||||||
|
+per-thread cache. Note that there is an extremely unlikely chance
|
||||||
|
+that this probe will trigger due to random payload data remaining in
|
||||||
|
+the allocated memory matching the key used to detect double frees.
|
||||||
|
+This probe actually indicates that an expensive linear search of the
|
||||||
|
+tcache, looking for a double free, has happened. Argument @var{$arg1}
|
||||||
|
+is the memory location as passed to @code{free}, Argument @var{$arg2}
|
||||||
|
+is the tcache bin it resides in.
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
@node Mathematical Function Probes
|
||||||
|
@section Mathematical Function Probes
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
From f5cc21eaeea6afbdfd543c63d2a552f141a91781 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Thu, 22 Nov 2018 22:05:57 +0100
|
||||||
|
Subject: [PATCH 48] Revert "malloc: tcache double free check" [BZ #23907]
|
||||||
|
|
||||||
|
This reverts commit 481a6cf0c24f02f251d7cd0b776c12d00e6b144f, the
|
||||||
|
backport of commit bcdaad21d4635931d1bd3b54a7894276925d081d on the
|
||||||
|
master branch.
|
||||||
|
---
|
||||||
|
ChangeLog | 12 -----------
|
||||||
|
dlfcn/dlerror.c | 5 +----
|
||||||
|
malloc/Makefile | 1 -
|
||||||
|
malloc/malloc.c | 28 --------------------------
|
||||||
|
malloc/tst-tcfree1.c | 42 --------------------------------------
|
||||||
|
malloc/tst-tcfree2.c | 48 --------------------------------------------
|
||||||
|
manual/probes.texi | 12 -----------
|
||||||
|
7 files changed, 1 insertion(+), 147 deletions(-)
|
||||||
|
delete mode 100644 malloc/tst-tcfree1.c
|
||||||
|
delete mode 100644 malloc/tst-tcfree2.c
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 1ef4b4abe0..8c92ee7764 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,15 +1,3 @@
|
||||||
|
-2018-11-20 DJ Delorie <dj@redhat.com>
|
||||||
|
-
|
||||||
|
- * malloc/malloc.c (tcache_entry): Add key field.
|
||||||
|
- (tcache_put): Set it.
|
||||||
|
- (tcache_get): Likewise.
|
||||||
|
- (_int_free): Check for double free in tcache.
|
||||||
|
- * malloc/tst-tcfree1.c: New.
|
||||||
|
- * malloc/tst-tcfree2.c: New.
|
||||||
|
- * malloc/Makefile: Run the new tests.
|
||||||
|
- * manual/probes.texi: Document memory_tcache_double_free probe.
|
||||||
|
-
|
||||||
|
- * dlfcn/dlerror.c (check_free): Prevent double frees.
|
||||||
|
2018-11-19 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
support: Print timestamps in timeout handler.
|
||||||
|
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||||
|
index 96bf925333..33574faab6 100644
|
||||||
|
--- a/dlfcn/dlerror.c
|
||||||
|
+++ b/dlfcn/dlerror.c
|
||||||
|
@@ -198,10 +198,7 @@ check_free (struct dl_action_result *rec)
|
||||||
|
Dl_info info;
|
||||||
|
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
|
||||||
|
#endif
|
||||||
|
- {
|
||||||
|
- free ((char *) rec->errstring);
|
||||||
|
- rec->errstring = NULL;
|
||||||
|
- }
|
||||||
|
+ free ((char *) rec->errstring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||||
|
index e6dfbfc14c..7d54bad866 100644
|
||||||
|
--- a/malloc/Makefile
|
||||||
|
+++ b/malloc/Makefile
|
||||||
|
@@ -38,7 +38,6 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
||||||
|
tst-malloc_info \
|
||||||
|
tst-malloc-too-large \
|
||||||
|
tst-malloc-stats-cancellation \
|
||||||
|
- tst-tcfree1 tst-tcfree2 \
|
||||||
|
|
||||||
|
tests-static := \
|
||||||
|
tst-interpose-static-nothread \
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 6be2573868..47795601c8 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -2888,8 +2888,6 @@ mremap_chunk (mchunkptr p, size_t new_size)
|
||||||
|
typedef struct tcache_entry
|
||||||
|
{
|
||||||
|
struct tcache_entry *next;
|
||||||
|
- /* This field exists to detect double frees. */
|
||||||
|
- struct tcache_perthread_struct *key;
|
||||||
|
} tcache_entry;
|
||||||
|
|
||||||
|
/* There is one of these for each thread, which contains the
|
||||||
|
@@ -2913,11 +2911,6 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
|
||||||
|
{
|
||||||
|
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
|
||||||
|
assert (tc_idx < TCACHE_MAX_BINS);
|
||||||
|
-
|
||||||
|
- /* Mark this chunk as "in the tcache" so the test in _int_free will
|
||||||
|
- detect a double free. */
|
||||||
|
- e->key = tcache;
|
||||||
|
-
|
||||||
|
e->next = tcache->entries[tc_idx];
|
||||||
|
tcache->entries[tc_idx] = e;
|
||||||
|
++(tcache->counts[tc_idx]);
|
||||||
|
@@ -2933,7 +2926,6 @@ tcache_get (size_t tc_idx)
|
||||||
|
assert (tcache->entries[tc_idx] > 0);
|
||||||
|
tcache->entries[tc_idx] = e->next;
|
||||||
|
--(tcache->counts[tc_idx]);
|
||||||
|
- e->key = NULL;
|
||||||
|
return (void *) e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4174,26 +4166,6 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
{
|
||||||
|
size_t tc_idx = csize2tidx (size);
|
||||||
|
|
||||||
|
- /* Check to see if it's already in the tcache. */
|
||||||
|
- tcache_entry *e = (tcache_entry *) chunk2mem (p);
|
||||||
|
-
|
||||||
|
- /* This test succeeds on double free. However, we don't 100%
|
||||||
|
- trust it (it also matches random payload data at a 1 in
|
||||||
|
- 2^<size_t> chance), so verify it's not an unlikely coincidence
|
||||||
|
- before aborting. */
|
||||||
|
- if (__glibc_unlikely (e->key == tcache && tcache))
|
||||||
|
- {
|
||||||
|
- tcache_entry *tmp;
|
||||||
|
- LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
|
||||||
|
- for (tmp = tcache->entries[tc_idx];
|
||||||
|
- tmp;
|
||||||
|
- tmp = tmp->next)
|
||||||
|
- if (tmp == e)
|
||||||
|
- malloc_printerr ("free(): double free detected in tcache 2");
|
||||||
|
- /* If we get here, it was a coincidence. We've wasted a few
|
||||||
|
- cycles, but don't abort. */
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (tcache
|
||||||
|
&& tc_idx < mp_.tcache_bins
|
||||||
|
&& tcache->counts[tc_idx] < mp_.tcache_count)
|
||||||
|
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index bc29375ce7..0000000000
|
||||||
|
--- a/malloc/tst-tcfree1.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,42 +0,0 @@
|
||||||
|
-/* Test that malloc tcache catches double free.
|
||||||
|
- Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <http://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-#include <errno.h>
|
||||||
|
-#include <error.h>
|
||||||
|
-#include <limits.h>
|
||||||
|
-#include <malloc.h>
|
||||||
|
-#include <stdlib.h>
|
||||||
|
-#include <stdio.h>
|
||||||
|
-#include <sys/signal.h>
|
||||||
|
-
|
||||||
|
-static int
|
||||||
|
-do_test (void)
|
||||||
|
-{
|
||||||
|
- /* Do one allocation of any size that fits in tcache. */
|
||||||
|
- char * volatile x = malloc (32);
|
||||||
|
-
|
||||||
|
- free (x); // puts in tcache
|
||||||
|
- free (x); // should abort
|
||||||
|
-
|
||||||
|
- printf("FAIL: tcache double free not detected\n");
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#define TEST_FUNCTION do_test
|
||||||
|
-#define EXPECTED_SIGNAL SIGABRT
|
||||||
|
-#include <support/test-driver.c>
|
||||||
|
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 17f06bacd4..0000000000
|
||||||
|
--- a/malloc/tst-tcfree2.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,48 +0,0 @@
|
||||||
|
-/* Test that malloc tcache catches double free.
|
||||||
|
- Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <http://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-#include <errno.h>
|
||||||
|
-#include <error.h>
|
||||||
|
-#include <limits.h>
|
||||||
|
-#include <malloc.h>
|
||||||
|
-#include <stdlib.h>
|
||||||
|
-#include <stdio.h>
|
||||||
|
-#include <sys/signal.h>
|
||||||
|
-
|
||||||
|
-static int
|
||||||
|
-do_test (void)
|
||||||
|
-{
|
||||||
|
- char * volatile ptrs[20];
|
||||||
|
- int i;
|
||||||
|
-
|
||||||
|
- /* Allocate enough small chunks so that when we free them all, the tcache
|
||||||
|
- is full, and the first one we freed is at the end of its linked list. */
|
||||||
|
-#define COUNT 20
|
||||||
|
- for (i=0; i<COUNT; i++)
|
||||||
|
- ptrs[i] = malloc (20);
|
||||||
|
- for (i=0; i<COUNT; i++)
|
||||||
|
- free (ptrs[i]);
|
||||||
|
- free (ptrs[0]);
|
||||||
|
-
|
||||||
|
- printf("FAIL: tcache double free\n");
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#define TEST_FUNCTION do_test
|
||||||
|
-#define EXPECTED_SIGNAL SIGABRT
|
||||||
|
-#include <support/test-driver.c>
|
||||||
|
diff --git a/manual/probes.texi b/manual/probes.texi
|
||||||
|
index 0ea560ed78..ab2a3102bb 100644
|
||||||
|
--- a/manual/probes.texi
|
||||||
|
+++ b/manual/probes.texi
|
||||||
|
@@ -243,18 +243,6 @@ This probe is triggered when the
|
||||||
|
value of this tunable.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
-@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
|
||||||
|
-This probe is triggered when @code{free} determines that the memory
|
||||||
|
-being freed has probably already been freed, and resides in the
|
||||||
|
-per-thread cache. Note that there is an extremely unlikely chance
|
||||||
|
-that this probe will trigger due to random payload data remaining in
|
||||||
|
-the allocated memory matching the key used to detect double frees.
|
||||||
|
-This probe actually indicates that an expensive linear search of the
|
||||||
|
-tcache, looking for a double free, has happened. Argument @var{$arg1}
|
||||||
|
-is the memory location as passed to @code{free}, Argument @var{$arg2}
|
||||||
|
-is the tcache bin it resides in.
|
||||||
|
-@end deftp
|
||||||
|
-
|
||||||
|
@node Mathematical Function Probes
|
||||||
|
@section Mathematical Function Probes
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
From ce6ba630dbc96f49eb1f30366aa62261df4792f9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue, 27 Nov 2018 16:12:43 +0100
|
||||||
|
Subject: [PATCH 49] CVE-2018-19591: if_nametoindex: Fix descriptor for
|
||||||
|
overlong name [BZ #23927]
|
||||||
|
|
||||||
|
(cherry picked from commit d527c860f5a3f0ed687bd03f0cb464612dc23408)
|
||||||
|
---
|
||||||
|
ChangeLog | 7 +++++++
|
||||||
|
NEWS | 6 ++++++
|
||||||
|
sysdeps/unix/sysv/linux/if_index.c | 11 ++++++-----
|
||||||
|
3 files changed, 19 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index 8c92ee7764..a997003664 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,10 @@
|
||||||
|
+2018-11-27 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ [BZ #23927]
|
||||||
|
+ CVE-2018-19591
|
||||||
|
+ * sysdeps/unix/sysv/linux/if_index.c (__if_nametoindex): Avoid
|
||||||
|
+ descriptor leak in case of ENODEV error.
|
||||||
|
+
|
||||||
|
2018-11-19 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
support: Print timestamps in timeout handler.
|
||||||
|
diff --git a/NEWS b/NEWS
|
||||||
|
index e5ca5903ec..5290e21da9 100644
|
||||||
|
--- a/NEWS
|
||||||
|
+++ b/NEWS
|
||||||
|
@@ -25,7 +25,13 @@ The following bugs are resolved with this release:
|
||||||
|
[23717] Fix stack overflow in stdlib/tst-setcontext9
|
||||||
|
[23821] si_band in siginfo_t has wrong type long int on sparc64
|
||||||
|
[23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
|
||||||
|
+ [23927] Linux if_nametoindex() does not close descriptor (CVE-2018-19591)
|
||||||
|
|
||||||
|
+Security related changes:
|
||||||
|
+
|
||||||
|
+ CVE-2018-19591: A file descriptor leak in if_nametoindex can lead to a
|
||||||
|
+ denial of service due to resource exhaustion when processing getaddrinfo
|
||||||
|
+ calls with crafted host names. Reported by Guido Vranken.
|
||||||
|
|
||||||
|
Version 2.28
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
|
||||||
|
index e3d08982d9..782fc5e175 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/if_index.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/if_index.c
|
||||||
|
@@ -38,11 +38,6 @@ __if_nametoindex (const char *ifname)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
struct ifreq ifr;
|
||||||
|
- int fd = __opensock ();
|
||||||
|
-
|
||||||
|
- if (fd < 0)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
if (strlen (ifname) >= IFNAMSIZ)
|
||||||
|
{
|
||||||
|
__set_errno (ENODEV);
|
||||||
|
@@ -50,6 +45,12 @@ __if_nametoindex (const char *ifname)
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
||||||
|
+
|
||||||
|
+ int fd = __opensock ();
|
||||||
|
+
|
||||||
|
+ if (fd < 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
|
||||||
|
{
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
|
@ -0,0 +1,291 @@
|
||||||
|
From b8dd0f42780a3133c02f064a2c0c5c4e7ab61aaa Mon Sep 17 00:00:00 2001
|
||||||
|
From: DJ Delorie <dj@delorie.com>
|
||||||
|
Date: Tue, 20 Nov 2018 13:24:09 -0500
|
||||||
|
Subject: [PATCH 50] malloc: tcache double free check
|
||||||
|
|
||||||
|
* malloc/malloc.c (tcache_entry): Add key field.
|
||||||
|
(tcache_put): Set it.
|
||||||
|
(tcache_get): Likewise.
|
||||||
|
(_int_free): Check for double free in tcache.
|
||||||
|
* malloc/tst-tcfree1.c: New.
|
||||||
|
* malloc/tst-tcfree2.c: New.
|
||||||
|
* malloc/Makefile: Run the new tests.
|
||||||
|
* manual/probes.texi: Document memory_tcache_double_free probe.
|
||||||
|
|
||||||
|
* dlfcn/dlerror.c (check_free): Prevent double frees.
|
||||||
|
|
||||||
|
(cherry picked from commit bcdaad21d4635931d1bd3b54a7894276925d081d)
|
||||||
|
|
||||||
|
malloc: tcache: Validate tc_idx before checking for double-frees [BZ #23907]
|
||||||
|
|
||||||
|
The previous check could read beyond the end of the tcache entry
|
||||||
|
array. If the e->key == tcache cookie check happened to pass, this
|
||||||
|
would result in crashes.
|
||||||
|
|
||||||
|
(cherry picked from commit affec03b713c82c43a5b025dddc21bde3334f41e)
|
||||||
|
---
|
||||||
|
ChangeLog | 20 ++++++++++++++++++
|
||||||
|
dlfcn/dlerror.c | 5 ++++-
|
||||||
|
malloc/Makefile | 1 +
|
||||||
|
malloc/malloc.c | 40 ++++++++++++++++++++++++++++++------
|
||||||
|
malloc/tst-tcfree1.c | 42 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
malloc/tst-tcfree2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
manual/probes.texi | 12 +++++++++++
|
||||||
|
7 files changed, 161 insertions(+), 7 deletions(-)
|
||||||
|
create mode 100644 malloc/tst-tcfree1.c
|
||||||
|
create mode 100644 malloc/tst-tcfree2.c
|
||||||
|
|
||||||
|
diff --git a/ChangeLog b/ChangeLog
|
||||||
|
index a997003664..bc62a59c2b 100644
|
||||||
|
--- a/ChangeLog
|
||||||
|
+++ b/ChangeLog
|
||||||
|
@@ -1,3 +1,23 @@
|
||||||
|
+2018-11-26 Florian Weimer <fweimer@redhat.com>
|
||||||
|
+
|
||||||
|
+ [BZ #23907]
|
||||||
|
+ * malloc/malloc.c (_int_free): Validate tc_idx before checking for
|
||||||
|
+ double-frees.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+2018-11-20 DJ Delorie <dj@redhat.com>
|
||||||
|
+
|
||||||
|
+ * malloc/malloc.c (tcache_entry): Add key field.
|
||||||
|
+ (tcache_put): Set it.
|
||||||
|
+ (tcache_get): Likewise.
|
||||||
|
+ (_int_free): Check for double free in tcache.
|
||||||
|
+ * malloc/tst-tcfree1.c: New.
|
||||||
|
+ * malloc/tst-tcfree2.c: New.
|
||||||
|
+ * malloc/Makefile: Run the new tests.
|
||||||
|
+ * manual/probes.texi: Document memory_tcache_double_free probe.
|
||||||
|
+
|
||||||
|
+ * dlfcn/dlerror.c (check_free): Prevent double frees.
|
||||||
|
+
|
||||||
|
2018-11-27 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
[BZ #23927]
|
||||||
|
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||||
|
index 33574faab6..96bf925333 100644
|
||||||
|
--- a/dlfcn/dlerror.c
|
||||||
|
+++ b/dlfcn/dlerror.c
|
||||||
|
@@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec)
|
||||||
|
Dl_info info;
|
||||||
|
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
|
||||||
|
#endif
|
||||||
|
- free ((char *) rec->errstring);
|
||||||
|
+ {
|
||||||
|
+ free ((char *) rec->errstring);
|
||||||
|
+ rec->errstring = NULL;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||||
|
index 7d54bad866..e6dfbfc14c 100644
|
||||||
|
--- a/malloc/Makefile
|
||||||
|
+++ b/malloc/Makefile
|
||||||
|
@@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
||||||
|
tst-malloc_info \
|
||||||
|
tst-malloc-too-large \
|
||||||
|
tst-malloc-stats-cancellation \
|
||||||
|
+ tst-tcfree1 tst-tcfree2 \
|
||||||
|
|
||||||
|
tests-static := \
|
||||||
|
tst-interpose-static-nothread \
|
||||||
|
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||||
|
index 47795601c8..dad0e73735 100644
|
||||||
|
--- a/malloc/malloc.c
|
||||||
|
+++ b/malloc/malloc.c
|
||||||
|
@@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size)
|
||||||
|
typedef struct tcache_entry
|
||||||
|
{
|
||||||
|
struct tcache_entry *next;
|
||||||
|
+ /* This field exists to detect double frees. */
|
||||||
|
+ struct tcache_perthread_struct *key;
|
||||||
|
} tcache_entry;
|
||||||
|
|
||||||
|
/* There is one of these for each thread, which contains the
|
||||||
|
@@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
|
||||||
|
{
|
||||||
|
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
|
||||||
|
assert (tc_idx < TCACHE_MAX_BINS);
|
||||||
|
+
|
||||||
|
+ /* Mark this chunk as "in the tcache" so the test in _int_free will
|
||||||
|
+ detect a double free. */
|
||||||
|
+ e->key = tcache;
|
||||||
|
+
|
||||||
|
e->next = tcache->entries[tc_idx];
|
||||||
|
tcache->entries[tc_idx] = e;
|
||||||
|
++(tcache->counts[tc_idx]);
|
||||||
|
@@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx)
|
||||||
|
assert (tcache->entries[tc_idx] > 0);
|
||||||
|
tcache->entries[tc_idx] = e->next;
|
||||||
|
--(tcache->counts[tc_idx]);
|
||||||
|
+ e->key = NULL;
|
||||||
|
return (void *) e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4165,13 +4173,33 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|
||||||
|
#if USE_TCACHE
|
||||||
|
{
|
||||||
|
size_t tc_idx = csize2tidx (size);
|
||||||
|
-
|
||||||
|
- if (tcache
|
||||||
|
- && tc_idx < mp_.tcache_bins
|
||||||
|
- && tcache->counts[tc_idx] < mp_.tcache_count)
|
||||||
|
+ if (tcache != NULL && tc_idx < mp_.tcache_bins)
|
||||||
|
{
|
||||||
|
- tcache_put (p, tc_idx);
|
||||||
|
- return;
|
||||||
|
+ /* Check to see if it's already in the tcache. */
|
||||||
|
+ tcache_entry *e = (tcache_entry *) chunk2mem (p);
|
||||||
|
+
|
||||||
|
+ /* This test succeeds on double free. However, we don't 100%
|
||||||
|
+ trust it (it also matches random payload data at a 1 in
|
||||||
|
+ 2^<size_t> chance), so verify it's not an unlikely
|
||||||
|
+ coincidence before aborting. */
|
||||||
|
+ if (__glibc_unlikely (e->key == tcache))
|
||||||
|
+ {
|
||||||
|
+ tcache_entry *tmp;
|
||||||
|
+ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
|
||||||
|
+ for (tmp = tcache->entries[tc_idx];
|
||||||
|
+ tmp;
|
||||||
|
+ tmp = tmp->next)
|
||||||
|
+ if (tmp == e)
|
||||||
|
+ malloc_printerr ("free(): double free detected in tcache 2");
|
||||||
|
+ /* If we get here, it was a coincidence. We've wasted a
|
||||||
|
+ few cycles, but don't abort. */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (tcache->counts[tc_idx] < mp_.tcache_count)
|
||||||
|
+ {
|
||||||
|
+ tcache_put (p, tc_idx);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..bc29375ce7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/malloc/tst-tcfree1.c
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/* Test that malloc tcache catches double free.
|
||||||
|
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <error.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <malloc.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <sys/signal.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Do one allocation of any size that fits in tcache. */
|
||||||
|
+ char * volatile x = malloc (32);
|
||||||
|
+
|
||||||
|
+ free (x); // puts in tcache
|
||||||
|
+ free (x); // should abort
|
||||||
|
+
|
||||||
|
+ printf("FAIL: tcache double free not detected\n");
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION do_test
|
||||||
|
+#define EXPECTED_SIGNAL SIGABRT
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..17f06bacd4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/malloc/tst-tcfree2.c
|
||||||
|
@@ -0,0 +1,48 @@
|
||||||
|
+/* Test that malloc tcache catches double free.
|
||||||
|
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <error.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <malloc.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <sys/signal.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ char * volatile ptrs[20];
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ /* Allocate enough small chunks so that when we free them all, the tcache
|
||||||
|
+ is full, and the first one we freed is at the end of its linked list. */
|
||||||
|
+#define COUNT 20
|
||||||
|
+ for (i=0; i<COUNT; i++)
|
||||||
|
+ ptrs[i] = malloc (20);
|
||||||
|
+ for (i=0; i<COUNT; i++)
|
||||||
|
+ free (ptrs[i]);
|
||||||
|
+ free (ptrs[0]);
|
||||||
|
+
|
||||||
|
+ printf("FAIL: tcache double free\n");
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION do_test
|
||||||
|
+#define EXPECTED_SIGNAL SIGABRT
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/manual/probes.texi b/manual/probes.texi
|
||||||
|
index ab2a3102bb..0ea560ed78 100644
|
||||||
|
--- a/manual/probes.texi
|
||||||
|
+++ b/manual/probes.texi
|
||||||
|
@@ -243,6 +243,18 @@ This probe is triggered when the
|
||||||
|
value of this tunable.
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
+@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
|
||||||
|
+This probe is triggered when @code{free} determines that the memory
|
||||||
|
+being freed has probably already been freed, and resides in the
|
||||||
|
+per-thread cache. Note that there is an extremely unlikely chance
|
||||||
|
+that this probe will trigger due to random payload data remaining in
|
||||||
|
+the allocated memory matching the key used to detect double frees.
|
||||||
|
+This probe actually indicates that an expensive linear search of the
|
||||||
|
+tcache, looking for a double free, has happened. Argument @var{$arg1}
|
||||||
|
+is the memory location as passed to @code{free}, Argument @var{$arg2}
|
||||||
|
+is the tcache bin it resides in.
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
@node Mathematical Function Probes
|
||||||
|
@section Mathematical Function Probes
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Template file for 'glibc'
|
# Template file for 'glibc'
|
||||||
pkgname=glibc
|
pkgname=glibc
|
||||||
version=2.28
|
version=2.28
|
||||||
revision=3
|
revision=4
|
||||||
bootstrap=yes
|
bootstrap=yes
|
||||||
short_desc="The GNU C library"
|
short_desc="The GNU C library"
|
||||||
maintainer="Juan RP <xtraeme@voidlinux.eu>"
|
maintainer="Juan RP <xtraeme@voidlinux.eu>"
|
||||||
|
|
Loading…
Reference in New Issue