glibc: sync patches with upstream
This commit is contained in:
parent
1498f4dfcc
commit
7c00d2d7ca
|
@ -289,3 +289,4 @@ index ab2a3102bb..0ea560ed78 100644
|
|||
@node Mathematical Function Probes
|
||||
@section Mathematical Function Probes
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,521 @@
|
|||
From 8c89e6b02d95cb4c0155eb3efc18fbd9c0f4582f Mon Sep 17 00:00:00 2001
|
||||
From: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
Date: Fri, 30 Nov 2018 18:05:32 -0200
|
||||
Subject: [PATCH 51] Fix _dl_profile_fixup data-dependency issue (Bug 23690)
|
||||
|
||||
There is a data-dependency between the fields of struct l_reloc_result
|
||||
and the field used as the initialization guard. Users of the guard
|
||||
expect writes to the structure to be observable when they also observe
|
||||
the guard initialized. The solution for this problem is to use an acquire
|
||||
and release load and store to ensure previous writes to the structure are
|
||||
observable if the guard is initialized.
|
||||
|
||||
The previous implementation used DL_FIXUP_VALUE_ADDR (l_reloc_result->addr)
|
||||
as the initialization guard, making it impossible for some architectures
|
||||
to load and store it atomically, i.e. hppa and ia64, due to its larger size.
|
||||
|
||||
This commit adds an unsigned int to l_reloc_result to be used as the new
|
||||
initialization guard of the struct, making it possible to load and store
|
||||
it atomically in all architectures. The fix ensures that the values
|
||||
observed in l_reloc_result are consistent and do not lead to crashes.
|
||||
The algorithm is documented in the code in elf/dl-runtime.c
|
||||
(_dl_profile_fixup). Not all data races have been eliminated.
|
||||
|
||||
Tested with build-many-glibcs and on powerpc, powerpc64, and powerpc64le.
|
||||
|
||||
[BZ #23690]
|
||||
* elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
|
||||
modification order when accessing reloc_result->addr.
|
||||
* include/link.h (reloc_result): Add field init.
|
||||
* nptl/Makefile (tests): Add tst-audit-threads.
|
||||
(modules-names): Add tst-audit-threads-mod1 and
|
||||
tst-audit-threads-mod2.
|
||||
Add rules to build tst-audit-threads.
|
||||
* nptl/tst-audit-threads-mod1.c: New file.
|
||||
* nptl/tst-audit-threads-mod2.c: Likewise.
|
||||
* nptl/tst-audit-threads.c: Likewise.
|
||||
* nptl/tst-audit-threads.h: Likewise.
|
||||
|
||||
Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit e5d262effe3a87164308a3f37e61b32d0348692a)
|
||||
---
|
||||
ChangeLog | 15 ++++++
|
||||
elf/dl-runtime.c | 48 +++++++++++++++--
|
||||
include/link.h | 4 ++
|
||||
nptl/Makefile | 14 ++++-
|
||||
nptl/tst-audit-threads-mod1.c | 74 ++++++++++++++++++++++++++
|
||||
nptl/tst-audit-threads-mod2.c | 22 ++++++++
|
||||
nptl/tst-audit-threads.c | 97 +++++++++++++++++++++++++++++++++++
|
||||
nptl/tst-audit-threads.h | 92 +++++++++++++++++++++++++++++++++
|
||||
8 files changed, 359 insertions(+), 7 deletions(-)
|
||||
create mode 100644 nptl/tst-audit-threads-mod1.c
|
||||
create mode 100644 nptl/tst-audit-threads-mod2.c
|
||||
create mode 100644 nptl/tst-audit-threads.c
|
||||
create mode 100644 nptl/tst-audit-threads.h
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index bc62a59c2b..fb57e61a22 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,18 @@
|
||||
+2018-11-30 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
+
|
||||
+ [BZ #23690]
|
||||
+ * elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
|
||||
+ modification order when accessing reloc_result->addr.
|
||||
+ * include/link.h (reloc_result): Add field init.
|
||||
+ * nptl/Makefile (tests): Add tst-audit-threads.
|
||||
+ (modules-names): Add tst-audit-threads-mod1 and
|
||||
+ tst-audit-threads-mod2.
|
||||
+ Add rules to build tst-audit-threads.
|
||||
+ * nptl/tst-audit-threads-mod1.c: New file.
|
||||
+ * nptl/tst-audit-threads-mod2.c: Likewise.
|
||||
+ * nptl/tst-audit-threads.c: Likewise.
|
||||
+ * nptl/tst-audit-threads.h: Likewise.
|
||||
+
|
||||
2018-11-26 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
[BZ #23907]
|
||||
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||
index 63bbc89776..3d2f4a7a76 100644
|
||||
--- a/elf/dl-runtime.c
|
||||
+++ b/elf/dl-runtime.c
|
||||
@@ -183,10 +183,36 @@ _dl_profile_fixup (
|
||||
/* This is the address in the array where we store the result of previous
|
||||
relocations. */
|
||||
struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
|
||||
- DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
|
||||
|
||||
- DL_FIXUP_VALUE_TYPE value = *resultp;
|
||||
- if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
|
||||
+ /* CONCURRENCY NOTES:
|
||||
+
|
||||
+ Multiple threads may be calling the same PLT sequence and with
|
||||
+ LD_AUDIT enabled they will be calling into _dl_profile_fixup to
|
||||
+ update the reloc_result with the result of the lazy resolution.
|
||||
+ The reloc_result guard variable is reloc_init, and we use
|
||||
+ acquire/release loads and store to it to ensure that the results of
|
||||
+ the structure are consistent with the loaded value of the guard.
|
||||
+ This does not fix all of the data races that occur when two or more
|
||||
+ threads read reloc_result->reloc_init with a value of zero and read
|
||||
+ and write to that reloc_result concurrently. The expectation is
|
||||
+ generally that while this is a data race it works because the
|
||||
+ threads write the same values. Until the data races are fixed
|
||||
+ there is a potential for problems to arise from these data races.
|
||||
+ The reloc result updates should happen in parallel but there should
|
||||
+ be an atomic RMW which does the final update to the real result
|
||||
+ entry (see bug 23790).
|
||||
+
|
||||
+ The following code uses reloc_result->init set to 0 to indicate if it is
|
||||
+ the first time this object is being relocated, otherwise 1 which
|
||||
+ indicates the object has already been relocated.
|
||||
+
|
||||
+ Reading/Writing from/to reloc_result->reloc_init must not happen
|
||||
+ before previous writes to reloc_result complete as they could
|
||||
+ end-up with an incomplete struct. */
|
||||
+ DL_FIXUP_VALUE_TYPE value;
|
||||
+ unsigned int init = atomic_load_acquire (&reloc_result->init);
|
||||
+
|
||||
+ if (init == 0)
|
||||
{
|
||||
/* This is the first time we have to relocate this object. */
|
||||
const ElfW(Sym) *const symtab
|
||||
@@ -346,19 +372,31 @@ _dl_profile_fixup (
|
||||
|
||||
/* Store the result for later runs. */
|
||||
if (__glibc_likely (! GLRO(dl_bind_not)))
|
||||
- *resultp = value;
|
||||
+ {
|
||||
+ reloc_result->addr = value;
|
||||
+ /* Guarantee all previous writes complete before
|
||||
+ init is updated. See CONCURRENCY NOTES earlier */
|
||||
+ atomic_store_release (&reloc_result->init, 1);
|
||||
+ }
|
||||
+ init = 1;
|
||||
}
|
||||
+ else
|
||||
+ value = reloc_result->addr;
|
||||
|
||||
/* By default we do not call the pltexit function. */
|
||||
long int framesize = -1;
|
||||
|
||||
+
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: report the PLT entering and allow the
|
||||
auditors to change the value. */
|
||||
- if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
|
||||
+ if (GLRO(dl_naudit) > 0
|
||||
/* Don't do anything if no auditor wants to intercept this call. */
|
||||
&& (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
|
||||
{
|
||||
+ /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||
+ initialized earlier in this function or in another thread. */
|
||||
+ assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
|
||||
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||
l_info[DT_SYMTAB])
|
||||
+ reloc_result->boundndx);
|
||||
diff --git a/include/link.h b/include/link.h
|
||||
index 5924594548..83b1c34b7b 100644
|
||||
--- a/include/link.h
|
||||
+++ b/include/link.h
|
||||
@@ -216,6 +216,10 @@ struct link_map
|
||||
unsigned int boundndx;
|
||||
uint32_t enterexit;
|
||||
unsigned int flags;
|
||||
+ /* CONCURRENCY NOTE: This is used to guard the concurrent initialization
|
||||
+ of the relocation result across multiple threads. See the more
|
||||
+ detailed notes in elf/dl-runtime.c. */
|
||||
+ unsigned int init;
|
||||
} *l_reloc_result;
|
||||
|
||||
/* Pointer to the version information if available. */
|
||||
diff --git a/nptl/Makefile b/nptl/Makefile
|
||||
index 49b6faa330..ee720960d1 100644
|
||||
--- a/nptl/Makefile
|
||||
+++ b/nptl/Makefile
|
||||
@@ -382,7 +382,8 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
|
||||
tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \
|
||||
tst-oncex3 tst-oncex4
|
||||
ifeq ($(build-shared),yes)
|
||||
-tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder
|
||||
+tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \
|
||||
+ tst-audit-threads
|
||||
tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1
|
||||
tests-nolibpthread += tst-fini1
|
||||
ifeq ($(have-z-execstack),yes)
|
||||
@@ -394,7 +395,8 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
|
||||
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
|
||||
tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
|
||||
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
|
||||
- tst-join7mod tst-compat-forwarder-mod
|
||||
+ tst-join7mod tst-compat-forwarder-mod tst-audit-threads-mod1 \
|
||||
+ tst-audit-threads-mod2
|
||||
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \
|
||||
tst-cleanup4aux.o tst-cleanupx4aux.o
|
||||
test-extras += tst-cleanup4aux tst-cleanupx4aux
|
||||
@@ -711,6 +713,14 @@ $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
|
||||
|
||||
tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1
|
||||
|
||||
+# Protect against a build using -Wl,-z,now.
|
||||
+LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy
|
||||
+LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy
|
||||
+LDFLAGS-tst-audit-threads = -Wl,-z,lazy
|
||||
+$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so
|
||||
+$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so
|
||||
+tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so
|
||||
+
|
||||
# The tests here better do not run in parallel
|
||||
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
|
||||
.NOTPARALLEL:
|
||||
diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c
|
||||
new file mode 100644
|
||||
index 0000000000..615d5ee512
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads-mod1.c
|
||||
@@ -0,0 +1,74 @@
|
||||
+/* Dummy audit library for test-audit-threads.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <elf.h>
|
||||
+#include <link.h>
|
||||
+#include <stdio.h>
|
||||
+#include <assert.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* We must use a dummy LD_AUDIT module to force the dynamic loader to
|
||||
+ *not* update the real PLT, and instead use a cached value for the
|
||||
+ lazy resolution result. It is the update of that cached value that
|
||||
+ we are testing for correctness by doing this. */
|
||||
+
|
||||
+/* Library to be audited. */
|
||||
+#define LIB "tst-audit-threads-mod2.so"
|
||||
+/* CALLNUM is the number of retNum functions. */
|
||||
+#define CALLNUM 7999
|
||||
+
|
||||
+#define CONCATX(a, b) __CONCAT (a, b)
|
||||
+
|
||||
+static int previous = 0;
|
||||
+
|
||||
+unsigned int
|
||||
+la_version (unsigned int ver)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||
+{
|
||||
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||
+}
|
||||
+
|
||||
+uintptr_t
|
||||
+CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym,
|
||||
+ unsigned int ndx,
|
||||
+ uintptr_t *refcook,
|
||||
+ uintptr_t *defcook,
|
||||
+ unsigned int *flags,
|
||||
+ const char *symname)
|
||||
+{
|
||||
+ const char * retnum = "retNum";
|
||||
+ char * num = strstr (symname, retnum);
|
||||
+ int n;
|
||||
+ /* Validate if the symbols are getting called in the correct order.
|
||||
+ This code is here to verify binutils does not optimize out the PLT
|
||||
+ entries that require the symbol binding. */
|
||||
+ if (num != NULL)
|
||||
+ {
|
||||
+ n = atoi (num);
|
||||
+ assert (n >= previous);
|
||||
+ assert (n <= CALLNUM);
|
||||
+ previous = n;
|
||||
+ }
|
||||
+ return sym->st_value;
|
||||
+}
|
||||
diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c
|
||||
new file mode 100644
|
||||
index 0000000000..f9817dd3dc
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads-mod2.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* Shared object with a huge number of functions for test-audit-threads.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* Define all the retNumN functions in a library. */
|
||||
+#define definenum
|
||||
+#include "tst-audit-threads.h"
|
||||
diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
|
||||
new file mode 100644
|
||||
index 0000000000..e4bf433bd8
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads.c
|
||||
@@ -0,0 +1,97 @@
|
||||
+/* Test multi-threading using LD_AUDIT.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a
|
||||
+ library with a huge number of functions in order to validate lazy symbol
|
||||
+ binding with an audit library. We use one thread per CPU to test that
|
||||
+ concurrent lazy resolution does not have any defects which would cause
|
||||
+ the process to fail. We use an LD_AUDIT library to force the testing of
|
||||
+ the relocation resolution caching code in the dynamic loader i.e.
|
||||
+ _dl_runtime_profile and _dl_profile_fixup. */
|
||||
+
|
||||
+#include <support/xthread.h>
|
||||
+#include <strings.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <sys/sysinfo.h>
|
||||
+
|
||||
+static int do_test (void);
|
||||
+
|
||||
+/* This test usually takes less than 3s to run. However, there are cases that
|
||||
+ take up to 30s. */
|
||||
+#define TIMEOUT 60
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
+
|
||||
+/* Declare the functions we are going to call. */
|
||||
+#define externnum
|
||||
+#include "tst-audit-threads.h"
|
||||
+#undef externnum
|
||||
+
|
||||
+int num_threads;
|
||||
+pthread_barrier_t barrier;
|
||||
+
|
||||
+void
|
||||
+sync_all (int num)
|
||||
+{
|
||||
+ pthread_barrier_wait (&barrier);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+call_all_ret_nums (void)
|
||||
+{
|
||||
+ /* Call each function one at a time from all threads. */
|
||||
+#define callnum
|
||||
+#include "tst-audit-threads.h"
|
||||
+#undef callnum
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+thread_main (void *unused)
|
||||
+{
|
||||
+ call_all_ret_nums ();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+#define STR2(X) #X
|
||||
+#define STR(X) STR2(X)
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int i;
|
||||
+ pthread_t *threads;
|
||||
+
|
||||
+ num_threads = get_nprocs ();
|
||||
+ if (num_threads <= 1)
|
||||
+ num_threads = 2;
|
||||
+
|
||||
+ /* Used to synchronize all the threads after calling each retNumN. */
|
||||
+ xpthread_barrier_init (&barrier, NULL, num_threads);
|
||||
+
|
||||
+ threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
|
||||
+ for (i = 0; i < num_threads; i++)
|
||||
+ threads[i] = xpthread_create(NULL, thread_main, NULL);
|
||||
+
|
||||
+ for (i = 0; i < num_threads; i++)
|
||||
+ xpthread_join(threads[i]);
|
||||
+
|
||||
+ free (threads);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h
|
||||
new file mode 100644
|
||||
index 0000000000..1c9ecc08df
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-audit-threads.h
|
||||
@@ -0,0 +1,92 @@
|
||||
+/* Helper header for test-audit-threads.
|
||||
+
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* We use this helper to create a large number of functions, all of
|
||||
+ which will be resolved lazily and thus have their PLT updated.
|
||||
+ This is done to provide enough functions that we can statistically
|
||||
+ observe a thread vs. PLT resolution failure if one exists. */
|
||||
+
|
||||
+#define CONCAT(a, b) a ## b
|
||||
+#define NUM(x, y) CONCAT (x, y)
|
||||
+
|
||||
+#define FUNC10(x) \
|
||||
+ FUNC (NUM (x, 0)); \
|
||||
+ FUNC (NUM (x, 1)); \
|
||||
+ FUNC (NUM (x, 2)); \
|
||||
+ FUNC (NUM (x, 3)); \
|
||||
+ FUNC (NUM (x, 4)); \
|
||||
+ FUNC (NUM (x, 5)); \
|
||||
+ FUNC (NUM (x, 6)); \
|
||||
+ FUNC (NUM (x, 7)); \
|
||||
+ FUNC (NUM (x, 8)); \
|
||||
+ FUNC (NUM (x, 9))
|
||||
+
|
||||
+#define FUNC100(x) \
|
||||
+ FUNC10 (NUM (x, 0)); \
|
||||
+ FUNC10 (NUM (x, 1)); \
|
||||
+ FUNC10 (NUM (x, 2)); \
|
||||
+ FUNC10 (NUM (x, 3)); \
|
||||
+ FUNC10 (NUM (x, 4)); \
|
||||
+ FUNC10 (NUM (x, 5)); \
|
||||
+ FUNC10 (NUM (x, 6)); \
|
||||
+ FUNC10 (NUM (x, 7)); \
|
||||
+ FUNC10 (NUM (x, 8)); \
|
||||
+ FUNC10 (NUM (x, 9))
|
||||
+
|
||||
+#define FUNC1000(x) \
|
||||
+ FUNC100 (NUM (x, 0)); \
|
||||
+ FUNC100 (NUM (x, 1)); \
|
||||
+ FUNC100 (NUM (x, 2)); \
|
||||
+ FUNC100 (NUM (x, 3)); \
|
||||
+ FUNC100 (NUM (x, 4)); \
|
||||
+ FUNC100 (NUM (x, 5)); \
|
||||
+ FUNC100 (NUM (x, 6)); \
|
||||
+ FUNC100 (NUM (x, 7)); \
|
||||
+ FUNC100 (NUM (x, 8)); \
|
||||
+ FUNC100 (NUM (x, 9))
|
||||
+
|
||||
+#define FUNC7000() \
|
||||
+ FUNC1000 (1); \
|
||||
+ FUNC1000 (2); \
|
||||
+ FUNC1000 (3); \
|
||||
+ FUNC1000 (4); \
|
||||
+ FUNC1000 (5); \
|
||||
+ FUNC1000 (6); \
|
||||
+ FUNC1000 (7);
|
||||
+
|
||||
+#ifdef FUNC
|
||||
+# undef FUNC
|
||||
+#endif
|
||||
+
|
||||
+#ifdef externnum
|
||||
+# define FUNC(x) extern int CONCAT (retNum, x) (void)
|
||||
+#endif
|
||||
+
|
||||
+#ifdef definenum
|
||||
+# define FUNC(x) int CONCAT (retNum, x) (void) { return x; }
|
||||
+#endif
|
||||
+
|
||||
+#ifdef callnum
|
||||
+# define FUNC(x) CONCAT (retNum, x) (); sync_all (x)
|
||||
+#endif
|
||||
+
|
||||
+/* A value of 7000 functions is chosen as an arbitrarily large
|
||||
+ number of functions that will allow us enough attempts to
|
||||
+ verify lazy resolution operation. */
|
||||
+FUNC7000 ();
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
From 5f1ae50a78d3f66b195668f1b863832d85d27f2f Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon, 10 Dec 2018 16:50:37 +0100
|
||||
Subject: [PATCH 52] compat getdents64: Use correct offset for retry [BZ
|
||||
#23972]
|
||||
|
||||
d_off is the offset of the *next* entry, not the offset of the current
|
||||
entry.
|
||||
|
||||
(cherry picked from commit 8d20a2f414fa52aceef8a0e3675415df54a840db)
|
||||
---
|
||||
ChangeLog | 10 ++++++++++
|
||||
NEWS | 1 +
|
||||
sysdeps/unix/sysv/linux/getdents64.c | 16 +++++++++++++---
|
||||
sysdeps/unix/sysv/linux/tst-readdir64-compat.c | 4 ++++
|
||||
4 files changed, 28 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index fb57e61a22..67213d487f 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,13 @@
|
||||
+2018-12-10 Florian Weimer <fweimer@redhat.com>
|
||||
+
|
||||
+ [BZ #23972]
|
||||
+ * sysdeps/unix/sysv/linux/getdents64.c (handle_overflow): Check
|
||||
+ offset instead of count for clarity. Fix typo in comment.
|
||||
+ (__old_getdents64): Keep track of previous offset. Use it to call
|
||||
+ handle_overflow.
|
||||
+ * sysdeps/unix/sysv/linux/tst-readdir64-compat.c (do_test): Check
|
||||
+ that d_off is never zero.
|
||||
+
|
||||
2018-11-30 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
|
||||
[BZ #23690]
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 5290e21da9..4d4a5a1911 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -26,6 +26,7 @@ The following bugs are resolved with this release:
|
||||
[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)
|
||||
+ [23972] __old_getdents64 uses wrong d_off value on overflow
|
||||
|
||||
Security related changes:
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
|
||||
index bc140b5a7f..46eb5f4419 100644
|
||||
--- a/sysdeps/unix/sysv/linux/getdents64.c
|
||||
+++ b/sysdeps/unix/sysv/linux/getdents64.c
|
||||
@@ -41,14 +41,14 @@ handle_overflow (int fd, __off64_t offset, ssize_t count)
|
||||
{
|
||||
/* If this is the first entry in the buffer, we can report the
|
||||
error. */
|
||||
- if (count == 0)
|
||||
+ if (offset == 0)
|
||||
{
|
||||
__set_errno (EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Otherwise, seek to the overflowing entry, so that the next call
|
||||
- will report the error, and return the data read so far.. */
|
||||
+ will report the error, and return the data read so far. */
|
||||
if (__lseek64 (fd, offset, SEEK_SET) != 0)
|
||||
return -1;
|
||||
return count;
|
||||
@@ -70,6 +70,15 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
|
||||
ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
|
||||
if (retval > 0)
|
||||
{
|
||||
+ /* This is the marker for the first entry. Offset 0 is reserved
|
||||
+ for the first entry (see rewinddir). Here, we use it as a
|
||||
+ marker for the first entry in the buffer. We never actually
|
||||
+ seek to offset 0 because handle_overflow reports the error
|
||||
+ directly, so it does not matter that the offset is incorrect
|
||||
+ if entries have been read from the descriptor before (so that
|
||||
+ the descriptor is not actually at offset 0). */
|
||||
+ __off64_t previous_offset = 0;
|
||||
+
|
||||
char *p = buf;
|
||||
char *end = buf + retval;
|
||||
while (p < end)
|
||||
@@ -84,7 +93,7 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
|
||||
|
||||
/* Check for ino_t overflow. */
|
||||
if (__glibc_unlikely (ino != source->d_ino))
|
||||
- return handle_overflow (fd, offset, p - buf);
|
||||
+ return handle_overflow (fd, previous_offset, p - buf);
|
||||
|
||||
/* Convert to the target layout. Use a separate struct and
|
||||
memcpy to side-step aliasing issues. */
|
||||
@@ -107,6 +116,7 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
|
||||
reclen - offsetof (struct dirent64, d_name));
|
||||
|
||||
p += reclen;
|
||||
+ previous_offset = offset;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
|
||||
index 43c4a8477c..cb78bc9be4 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
|
||||
@@ -88,6 +88,10 @@ do_test (void)
|
||||
else
|
||||
TEST_VERIFY_EXIT (entry_test != NULL);
|
||||
|
||||
+ /* d_off is never zero because it is the offset of the next
|
||||
+ entry (not the current entry). */
|
||||
+ TEST_VERIFY (entry_reference->d_off > 0);
|
||||
+
|
||||
/* Check that the entries are the same. */
|
||||
TEST_COMPARE_BLOB (entry_reference->d_name,
|
||||
strlen (entry_reference->d_name),
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
From 4718b053dfef495a4d5189e4210bc66106873522 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue, 27 Nov 2018 21:35:56 +0100
|
||||
Subject: [PATCH 53] support: Implement support_quote_string
|
||||
|
||||
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
|
||||
(cherry picked from commit c74a91deaa5de416237c02bbb3e41bda76ca4c7b)
|
||||
---
|
||||
ChangeLog | 9 +++++
|
||||
support/Makefile | 2 +
|
||||
support/support.h | 5 +++
|
||||
support/support_quote_string.c | 26 +++++++++++++
|
||||
support/tst-support_quote_string.c | 60 ++++++++++++++++++++++++++++++
|
||||
5 files changed, 102 insertions(+)
|
||||
create mode 100644 support/support_quote_string.c
|
||||
create mode 100644 support/tst-support_quote_string.c
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 67213d487f..aaeb1fc706 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,12 @@
|
||||
+2018-11-27 Florian Weimer <fweimer@redhat.com>
|
||||
+
|
||||
+ * support/support.h (support_quote_string): Declare.
|
||||
+ * support/support_quote_string.c: New file.
|
||||
+ * support/tst-support_quote_string.c: Likewise.
|
||||
+ * support/Makefile (libsupport-routines): Add
|
||||
+ support_quote_string.
|
||||
+ (tests): Add tst-support_quote_string.
|
||||
+
|
||||
2018-12-10 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
[BZ #23972]
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 50470fb749..6439d18343 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -55,6 +55,7 @@ libsupport-routines = \
|
||||
support_isolate_in_subprocess \
|
||||
support_openpty \
|
||||
support_quote_blob \
|
||||
+ support_quote_string \
|
||||
support_record_failure \
|
||||
support_run_diff \
|
||||
support_shared_allocate \
|
||||
@@ -159,6 +160,7 @@ tests = \
|
||||
tst-support_capture_subprocess \
|
||||
tst-support_format_dns_packet \
|
||||
tst-support_quote_blob \
|
||||
+ tst-support_quote_string \
|
||||
tst-support_record_failure \
|
||||
tst-test_compare \
|
||||
tst-test_compare_blob \
|
||||
diff --git a/support/support.h b/support/support.h
|
||||
index b61fe0735c..4d9f7528a6 100644
|
||||
--- a/support/support.h
|
||||
+++ b/support/support.h
|
||||
@@ -65,6 +65,11 @@ void support_write_file_string (const char *path, const char *contents);
|
||||
the result). */
|
||||
char *support_quote_blob (const void *blob, size_t length);
|
||||
|
||||
+/* Quote the contents of the at STR, in such a way that the result
|
||||
+ string can be included in a C literal (in single/double quotes,
|
||||
+ without putting the quotes into the result). */
|
||||
+char *support_quote_string (const char *str);
|
||||
+
|
||||
/* Error-checking wrapper functions which terminate the process on
|
||||
error. */
|
||||
|
||||
diff --git a/support/support_quote_string.c b/support/support_quote_string.c
|
||||
new file mode 100644
|
||||
index 0000000000..d324371b13
|
||||
--- /dev/null
|
||||
+++ b/support/support_quote_string.c
|
||||
@@ -0,0 +1,26 @@
|
||||
+/* Quote a string so that it can be used in C literals.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <string.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+char *
|
||||
+support_quote_string (const char *str)
|
||||
+{
|
||||
+ return support_quote_blob (str, strlen (str));
|
||||
+}
|
||||
diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c
|
||||
new file mode 100644
|
||||
index 0000000000..3c004759b7
|
||||
--- /dev/null
|
||||
+++ b/support/tst-support_quote_string.c
|
||||
@@ -0,0 +1,60 @@
|
||||
+/* Test the support_quote_string function.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <string.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *p = support_quote_string ("");
|
||||
+ TEST_COMPARE (strlen (p), 0);
|
||||
+ free (p);
|
||||
+ p = support_quote_string ("X");
|
||||
+ TEST_COMPARE (strlen (p), 1);
|
||||
+ TEST_COMPARE (p[0], 'X');
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check escaping of backslash-escaped characters, and lack of
|
||||
+ escaping for other shell meta-characters. */
|
||||
+ p = support_quote_string ("$()*?`@[]{}~\'\"X");
|
||||
+ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check lack of escaping for letters and digits. */
|
||||
+#define LETTERS_AND_DIGTS \
|
||||
+ "abcdefghijklmnopqrstuvwxyz" \
|
||||
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
|
||||
+ "0123456789"
|
||||
+ p = support_quote_string (LETTERS_AND_DIGTS "@");
|
||||
+ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ /* Check escaping of control characters and other non-printable
|
||||
+ characters. */
|
||||
+ p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@");
|
||||
+ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
|
||||
+ "\\177\\200\\377@"), 0);
|
||||
+ free (p);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
From 9dd07a91dba984c223730af30741565cb9bd88d5 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed, 28 Nov 2018 07:00:48 +0100
|
||||
Subject: [PATCH 54] support_quote_string: Do not use str parameter name
|
||||
|
||||
This avoids a build failure if this identifier is used as a macro
|
||||
in a test.
|
||||
|
||||
(cherry picked from commit 47d8d9a2172f827a8dde7695f415aa6f78a82d0e)
|
||||
---
|
||||
ChangeLog | 5 +++++
|
||||
support/support.h | 4 ++--
|
||||
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index aaeb1fc706..a979f53811 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,8 @@
|
||||
+2018-11-28 Florian Weimer <fweimer@redhat.com>
|
||||
+
|
||||
+ * support/support.h (support_quote_string): Do not use str
|
||||
+ parameter name.
|
||||
+
|
||||
2018-11-27 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* support/support.h (support_quote_string): Declare.
|
||||
diff --git a/support/support.h b/support/support.h
|
||||
index 4d9f7528a6..4ea92e1c21 100644
|
||||
--- a/support/support.h
|
||||
+++ b/support/support.h
|
||||
@@ -65,10 +65,10 @@ void support_write_file_string (const char *path, const char *contents);
|
||||
the result). */
|
||||
char *support_quote_blob (const void *blob, size_t length);
|
||||
|
||||
-/* Quote the contents of the at STR, in such a way that the result
|
||||
+/* Quote the contents of the string, in such a way that the result
|
||||
string can be included in a C literal (in single/double quotes,
|
||||
without putting the quotes into the result). */
|
||||
-char *support_quote_string (const char *str);
|
||||
+char *support_quote_string (const char *);
|
||||
|
||||
/* Error-checking wrapper functions which terminate the process on
|
||||
error. */
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From 874c28c9f5d14586ab71cd4af6899b11753caf25 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat, 1 Dec 2018 21:43:36 +0100
|
||||
Subject: [PATCH 55] support: Close original descriptors in
|
||||
support_capture_subprocess
|
||||
|
||||
(cherry picked from commit 02cd5c1a8d033d7f91fea12a66bb44d1bbf85f76)
|
||||
---
|
||||
ChangeLog | 6 ++++++
|
||||
support/support_capture_subprocess.c | 6 ++++++
|
||||
2 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index a979f53811..2951523334 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,9 @@
|
||||
+2018-12-01 Florian Weimer <fweimer@redhat.com>
|
||||
+
|
||||
+ * support/support_capture_subprocess.c
|
||||
+ (support_capture_subprocess): Check that pipe descriptors have
|
||||
+ expected values. Close original pipe descriptors in subprocess.
|
||||
+
|
||||
2018-11-28 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* support/support.h (support_quote_string): Do not use str
|
||||
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
|
||||
index 6d2029e13b..93f6ea3102 100644
|
||||
--- a/support/support_capture_subprocess.c
|
||||
+++ b/support/support_capture_subprocess.c
|
||||
@@ -59,8 +59,12 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
|
||||
|
||||
int stdout_pipe[2];
|
||||
xpipe (stdout_pipe);
|
||||
+ TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO);
|
||||
+ TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO);
|
||||
int stderr_pipe[2];
|
||||
xpipe (stderr_pipe);
|
||||
+ TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO);
|
||||
+ TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO);
|
||||
|
||||
TEST_VERIFY (fflush (stdout) == 0);
|
||||
TEST_VERIFY (fflush (stderr) == 0);
|
||||
@@ -72,6 +76,8 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
|
||||
xclose (stderr_pipe[0]);
|
||||
xdup2 (stdout_pipe[1], STDOUT_FILENO);
|
||||
xdup2 (stderr_pipe[1], STDERR_FILENO);
|
||||
+ xclose (stdout_pipe[1]);
|
||||
+ xclose (stderr_pipe[1]);
|
||||
callback (closure);
|
||||
_exit (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,628 @@
|
|||
From 4c2dada5070c9adc93e548826333c8be34f0c50a Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 6 Dec 2018 15:39:42 +0100
|
||||
Subject: [PATCH 56] support: Implement <support/descriptors.h> to track
|
||||
file descriptors
|
||||
|
||||
(cherry picked from commit f255336a9301619519045548acb2e1027065a837)
|
||||
---
|
||||
ChangeLog | 11 ++
|
||||
support/Makefile | 2 +
|
||||
support/check.h | 4 +
|
||||
support/descriptors.h | 47 +++++
|
||||
support/support_descriptors.c | 274 ++++++++++++++++++++++++++++++
|
||||
support/support_record_failure.c | 8 +
|
||||
support/tst-support_descriptors.c | 198 +++++++++++++++++++++
|
||||
7 files changed, 544 insertions(+)
|
||||
create mode 100644 support/descriptors.h
|
||||
create mode 100644 support/support_descriptors.c
|
||||
create mode 100644 support/tst-support_descriptors.c
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 2951523334..e6451fe03e 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,14 @@
|
||||
+2018-12-07 Florian Weimer <fweimer@redhat.com>
|
||||
+
|
||||
+ * support/check.h (support_record_failure_is_failed): Declare.
|
||||
+ * support/descriptors.h: New file.
|
||||
+ * support/support_descriptors.c: Likewise.
|
||||
+ * support/tst-support_descriptors.c: Likewise.
|
||||
+ * support/support_record_failure.c
|
||||
+ (support_record_failure_is_failed): New function.
|
||||
+ * support/Makefile (libsupport-routines): Add support_descriptors.
|
||||
+ (tests): Add tst-support_descriptors.
|
||||
+
|
||||
2018-12-01 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* support/support_capture_subprocess.c
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index 6439d18343..550fdba0f7 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -44,6 +44,7 @@ libsupport-routines = \
|
||||
support_capture_subprocess \
|
||||
support_capture_subprocess_check \
|
||||
support_chroot \
|
||||
+ support_descriptors \
|
||||
support_enter_mount_namespace \
|
||||
support_enter_network_namespace \
|
||||
support_format_address_family \
|
||||
@@ -158,6 +159,7 @@ tests = \
|
||||
tst-support-namespace \
|
||||
tst-support_blob_repeat \
|
||||
tst-support_capture_subprocess \
|
||||
+ tst-support_descriptors \
|
||||
tst-support_format_dns_packet \
|
||||
tst-support_quote_blob \
|
||||
tst-support_quote_string \
|
||||
diff --git a/support/check.h b/support/check.h
|
||||
index b3a4645e92..10468b74d8 100644
|
||||
--- a/support/check.h
|
||||
+++ b/support/check.h
|
||||
@@ -170,6 +170,10 @@ int support_report_failure (int status)
|
||||
/* Internal function used to test the failure recording framework. */
|
||||
void support_record_failure_reset (void);
|
||||
|
||||
+/* Returns true or false depending on whether there have been test
|
||||
+ failures or not. */
|
||||
+int support_record_failure_is_failed (void);
|
||||
+
|
||||
__END_DECLS
|
||||
|
||||
#endif /* SUPPORT_CHECK_H */
|
||||
diff --git a/support/descriptors.h b/support/descriptors.h
|
||||
new file mode 100644
|
||||
index 0000000000..8ec4cbbdfb
|
||||
--- /dev/null
|
||||
+++ b/support/descriptors.h
|
||||
@@ -0,0 +1,47 @@
|
||||
+/* Monitoring file descriptor usage.
|
||||
+ 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_DESCRIPTORS_H
|
||||
+#define SUPPORT_DESCRIPTORS_H
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+/* Opaque pointer, for capturing file descriptor lists. */
|
||||
+struct support_descriptors;
|
||||
+
|
||||
+/* Record the currently open file descriptors and store them in the
|
||||
+ returned list. Terminate the process if the listing operation
|
||||
+ fails. */
|
||||
+struct support_descriptors *support_descriptors_list (void);
|
||||
+
|
||||
+/* Deallocate the list of descriptors. */
|
||||
+void support_descriptors_free (struct support_descriptors *);
|
||||
+
|
||||
+/* Write the list of descriptors to STREAM, adding PREFIX to each
|
||||
+ line. */
|
||||
+void support_descriptors_dump (struct support_descriptors *,
|
||||
+ const char *prefix, FILE *stream);
|
||||
+
|
||||
+/* Check for file descriptor leaks and other file descriptor changes:
|
||||
+ Compare the current list of descriptors with the passed list.
|
||||
+ Record a test failure if there are additional open descriptors,
|
||||
+ descriptors have been closed, or if a change in file descriptor can
|
||||
+ be detected. */
|
||||
+void support_descriptors_check (struct support_descriptors *);
|
||||
+
|
||||
+#endif /* SUPPORT_DESCRIPTORS_H */
|
||||
diff --git a/support/support_descriptors.c b/support/support_descriptors.c
|
||||
new file mode 100644
|
||||
index 0000000000..d66cf55080
|
||||
--- /dev/null
|
||||
+++ b/support/support_descriptors.c
|
||||
@@ -0,0 +1,274 @@
|
||||
+/* Monitoring file descriptor usage.
|
||||
+ 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 <dirent.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/sysmacros.h>
|
||||
+#include <xunistd.h>
|
||||
+
|
||||
+struct procfs_descriptor
|
||||
+{
|
||||
+ int fd;
|
||||
+ char *link_target;
|
||||
+ dev_t dev;
|
||||
+ ino64_t ino;
|
||||
+};
|
||||
+
|
||||
+/* Used with qsort. */
|
||||
+static int
|
||||
+descriptor_compare (const void *l, const void *r)
|
||||
+{
|
||||
+ const struct procfs_descriptor *left = l;
|
||||
+ const struct procfs_descriptor *right = r;
|
||||
+ /* Cannot overflow due to limited file descriptor range. */
|
||||
+ return left->fd - right->fd;
|
||||
+}
|
||||
+
|
||||
+#define DYNARRAY_STRUCT descriptor_list
|
||||
+#define DYNARRAY_ELEMENT struct procfs_descriptor
|
||||
+#define DYNARRAY_PREFIX descriptor_list_
|
||||
+#define DYNARRAY_ELEMENT_FREE(e) free ((e)->link_target)
|
||||
+#define DYNARRAY_INITIAL_SIZE 0
|
||||
+#include <malloc/dynarray-skeleton.c>
|
||||
+
|
||||
+struct support_descriptors
|
||||
+{
|
||||
+ struct descriptor_list list;
|
||||
+};
|
||||
+
|
||||
+struct support_descriptors *
|
||||
+support_descriptors_list (void)
|
||||
+{
|
||||
+ struct support_descriptors *result = xmalloc (sizeof (*result));
|
||||
+ descriptor_list_init (&result->list);
|
||||
+
|
||||
+ DIR *fds = opendir ("/proc/self/fd");
|
||||
+ if (fds == NULL)
|
||||
+ FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m");
|
||||
+
|
||||
+ while (true)
|
||||
+ {
|
||||
+ errno = 0;
|
||||
+ struct dirent64 *e = readdir64 (fds);
|
||||
+ if (e == NULL)
|
||||
+ {
|
||||
+ if (errno != 0)
|
||||
+ FAIL_EXIT1 ("readdir: %m");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (e->d_name[0] == '.')
|
||||
+ continue;
|
||||
+
|
||||
+ char *endptr;
|
||||
+ long int fd = strtol (e->d_name, &endptr, 10);
|
||||
+ if (*endptr != '\0' || fd < 0 || fd > INT_MAX)
|
||||
+ FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s",
|
||||
+ e->d_name);
|
||||
+
|
||||
+ /* Skip the descriptor which is used to enumerate the
|
||||
+ descriptors. */
|
||||
+ if (fd == dirfd (fds))
|
||||
+ continue;
|
||||
+
|
||||
+ char *target;
|
||||
+ {
|
||||
+ char *path = xasprintf ("/proc/self/fd/%ld", fd);
|
||||
+ target = xreadlink (path);
|
||||
+ free (path);
|
||||
+ }
|
||||
+ struct stat64 st;
|
||||
+ if (fstat64 (fd, &st) != 0)
|
||||
+ FAIL_EXIT1 ("readdir: fstat64 (%ld) failed: %m", fd);
|
||||
+
|
||||
+ struct procfs_descriptor *item = descriptor_list_emplace (&result->list);
|
||||
+ if (item == NULL)
|
||||
+ FAIL_EXIT1 ("descriptor_list_emplace: %m");
|
||||
+ item->fd = fd;
|
||||
+ item->link_target = target;
|
||||
+ item->dev = st.st_dev;
|
||||
+ item->ino = st.st_ino;
|
||||
+ }
|
||||
+
|
||||
+ closedir (fds);
|
||||
+
|
||||
+ /* Perform a merge join between descrs and current. This assumes
|
||||
+ that the arrays are sorted by file descriptor. */
|
||||
+
|
||||
+ qsort (descriptor_list_begin (&result->list),
|
||||
+ descriptor_list_size (&result->list),
|
||||
+ sizeof (struct procfs_descriptor), descriptor_compare);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+support_descriptors_free (struct support_descriptors *descrs)
|
||||
+{
|
||||
+ descriptor_list_free (&descrs->list);
|
||||
+ free (descrs);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+support_descriptors_dump (struct support_descriptors *descrs,
|
||||
+ const char *prefix, FILE *fp)
|
||||
+{
|
||||
+ struct procfs_descriptor *end = descriptor_list_end (&descrs->list);
|
||||
+ for (struct procfs_descriptor *d = descriptor_list_begin (&descrs->list);
|
||||
+ d != end; ++d)
|
||||
+ {
|
||||
+ char *quoted = support_quote_string (d->link_target);
|
||||
+ fprintf (fp, "%s%d: target=\"%s\" major=%lld minor=%lld ino=%lld\n",
|
||||
+ prefix, d->fd, quoted,
|
||||
+ (long long int) major (d->dev),
|
||||
+ (long long int) minor (d->dev),
|
||||
+ (long long int) d->ino);
|
||||
+ free (quoted);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dump_mismatch (bool *first,
|
||||
+ struct support_descriptors *descrs,
|
||||
+ struct support_descriptors *current)
|
||||
+{
|
||||
+ if (*first)
|
||||
+ *first = false;
|
||||
+ else
|
||||
+ return;
|
||||
+
|
||||
+ puts ("error: Differences found in descriptor set");
|
||||
+ puts ("Reference descriptor set:");
|
||||
+ support_descriptors_dump (descrs, " ", stdout);
|
||||
+ puts ("Current descriptor set:");
|
||||
+ support_descriptors_dump (current, " ", stdout);
|
||||
+ puts ("Differences:");
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+report_closed_descriptor (bool *first,
|
||||
+ struct support_descriptors *descrs,
|
||||
+ struct support_descriptors *current,
|
||||
+ struct procfs_descriptor *left)
|
||||
+{
|
||||
+ support_record_failure ();
|
||||
+ dump_mismatch (first, descrs, current);
|
||||
+ printf ("error: descriptor %d was closed\n", left->fd);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+report_opened_descriptor (bool *first,
|
||||
+ struct support_descriptors *descrs,
|
||||
+ struct support_descriptors *current,
|
||||
+ struct procfs_descriptor *right)
|
||||
+{
|
||||
+ support_record_failure ();
|
||||
+ dump_mismatch (first, descrs, current);
|
||||
+ char *quoted = support_quote_string (right->link_target);
|
||||
+ printf ("error: descriptor %d was opened (\"%s\")\n", right->fd, quoted);
|
||||
+ free (quoted);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+support_descriptors_check (struct support_descriptors *descrs)
|
||||
+{
|
||||
+ struct support_descriptors *current = support_descriptors_list ();
|
||||
+
|
||||
+ /* Perform a merge join between descrs and current. This assumes
|
||||
+ that the arrays are sorted by file descriptor. */
|
||||
+
|
||||
+ struct procfs_descriptor *left = descriptor_list_begin (&descrs->list);
|
||||
+ struct procfs_descriptor *left_end = descriptor_list_end (&descrs->list);
|
||||
+ struct procfs_descriptor *right = descriptor_list_begin (¤t->list);
|
||||
+ struct procfs_descriptor *right_end = descriptor_list_end (¤t->list);
|
||||
+
|
||||
+ bool first = true;
|
||||
+ while (left != left_end && right != right_end)
|
||||
+ {
|
||||
+ if (left->fd == right->fd)
|
||||
+ {
|
||||
+ if (strcmp (left->link_target, right->link_target) != 0)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ char *left_quoted = support_quote_string (left->link_target);
|
||||
+ char *right_quoted = support_quote_string (right->link_target);
|
||||
+ dump_mismatch (&first, descrs, current);
|
||||
+ printf ("error: descriptor %d changed from \"%s\" to \"%s\"\n",
|
||||
+ left->fd, left_quoted, right_quoted);
|
||||
+ free (left_quoted);
|
||||
+ free (right_quoted);
|
||||
+ }
|
||||
+ if (left->dev != right->dev)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ dump_mismatch (&first, descrs, current);
|
||||
+ printf ("error: descriptor %d changed device"
|
||||
+ " from %lld:%lld to %lld:%lld\n",
|
||||
+ left->fd,
|
||||
+ (long long int) major (left->dev),
|
||||
+ (long long int) minor (left->dev),
|
||||
+ (long long int) major (right->dev),
|
||||
+ (long long int) minor (right->dev));
|
||||
+ }
|
||||
+ if (left->ino != right->ino)
|
||||
+ {
|
||||
+ support_record_failure ();
|
||||
+ dump_mismatch (&first, descrs, current);
|
||||
+ printf ("error: descriptor %d changed ino from %lld to %lld\n",
|
||||
+ left->fd,
|
||||
+ (long long int) left->ino, (long long int) right->ino);
|
||||
+ }
|
||||
+ ++left;
|
||||
+ ++right;
|
||||
+ }
|
||||
+ else if (left->fd < right->fd)
|
||||
+ {
|
||||
+ /* Gap on the right. */
|
||||
+ report_closed_descriptor (&first, descrs, current, left);
|
||||
+ ++left;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Gap on the left. */
|
||||
+ TEST_VERIFY_EXIT (left->fd > right->fd);
|
||||
+ report_opened_descriptor (&first, descrs, current, right);
|
||||
+ ++right;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (left != left_end)
|
||||
+ {
|
||||
+ /* Closed descriptors (more descriptors on the left). */
|
||||
+ report_closed_descriptor (&first, descrs, current, left);
|
||||
+ ++left;
|
||||
+ }
|
||||
+
|
||||
+ while (right != right_end)
|
||||
+ {
|
||||
+ /* Opened descriptors (more descriptors on the right). */
|
||||
+ report_opened_descriptor (&first, descrs, current, right);
|
||||
+ ++right;
|
||||
+ }
|
||||
+
|
||||
+ support_descriptors_free (current);
|
||||
+}
|
||||
diff --git a/support/support_record_failure.c b/support/support_record_failure.c
|
||||
index 356798f556..17ab1d80ef 100644
|
||||
--- a/support/support_record_failure.c
|
||||
+++ b/support/support_record_failure.c
|
||||
@@ -104,3 +104,11 @@ support_record_failure_reset (void)
|
||||
__atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED);
|
||||
__atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED);
|
||||
}
|
||||
+
|
||||
+int
|
||||
+support_record_failure_is_failed (void)
|
||||
+{
|
||||
+ /* Relaxed MO is sufficient because we need (blocking) external
|
||||
+ synchronization for reliable test error reporting anyway. */
|
||||
+ return __atomic_load_n (&state->failed, __ATOMIC_RELAXED);
|
||||
+}
|
||||
diff --git a/support/tst-support_descriptors.c b/support/tst-support_descriptors.c
|
||||
new file mode 100644
|
||||
index 0000000000..5e9e824bc3
|
||||
--- /dev/null
|
||||
+++ b/support/tst-support_descriptors.c
|
||||
@@ -0,0 +1,198 @@
|
||||
+/* Tests for monitoring file descriptor usage.
|
||||
+ 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 <fcntl.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/descriptors.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+/* This is the next free descriptor that the subprocess will pick. */
|
||||
+static int free_descriptor;
|
||||
+
|
||||
+static void
|
||||
+subprocess_no_change (void *closure)
|
||||
+{
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
|
||||
+ TEST_COMPARE (fd, free_descriptor);
|
||||
+ xclose (fd);
|
||||
+ support_descriptors_free (descrs);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+subprocess_closed_descriptor (void *closure)
|
||||
+{
|
||||
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
|
||||
+ TEST_COMPARE (fd, free_descriptor);
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+ xclose (fd);
|
||||
+ support_descriptors_check (descrs); /* Will report failure. */
|
||||
+ puts ("EOT");
|
||||
+ support_descriptors_free (descrs);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+subprocess_opened_descriptor (void *closure)
|
||||
+{
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
|
||||
+ TEST_COMPARE (fd, free_descriptor);
|
||||
+ support_descriptors_check (descrs); /* Will report failure. */
|
||||
+ puts ("EOT");
|
||||
+ support_descriptors_free (descrs);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+subprocess_changed_descriptor (void *closure)
|
||||
+{
|
||||
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
|
||||
+ TEST_COMPARE (fd, free_descriptor);
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+ xclose (fd);
|
||||
+ TEST_COMPARE (xopen ("/dev", O_DIRECTORY | O_RDONLY, 0), fd);
|
||||
+ support_descriptors_check (descrs); /* Will report failure. */
|
||||
+ puts ("EOT");
|
||||
+ support_descriptors_free (descrs);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+report_subprocess_output (const char *name,
|
||||
+ struct support_capture_subprocess *proc)
|
||||
+{
|
||||
+ printf ("info: BEGIN %s output\n"
|
||||
+ "%s"
|
||||
+ "info: END %s output\n",
|
||||
+ name, proc->out.buffer, name);
|
||||
+}
|
||||
+
|
||||
+/* Use an explicit flag to preserve failure status across
|
||||
+ support_record_failure_reset calls. */
|
||||
+static bool good = true;
|
||||
+
|
||||
+static void
|
||||
+test_run (void)
|
||||
+{
|
||||
+ struct support_capture_subprocess proc = support_capture_subprocess
|
||||
+ (&subprocess_no_change, NULL);
|
||||
+ support_capture_subprocess_check (&proc, "subprocess_no_change",
|
||||
+ 0, sc_allow_none);
|
||||
+ support_capture_subprocess_free (&proc);
|
||||
+
|
||||
+ char *expected = xasprintf ("\nDifferences:\n"
|
||||
+ "error: descriptor %d was closed\n"
|
||||
+ "EOT\n",
|
||||
+ free_descriptor);
|
||||
+ good = good && !support_record_failure_is_failed ();
|
||||
+ proc = support_capture_subprocess (&subprocess_closed_descriptor, NULL);
|
||||
+ good = good && support_record_failure_is_failed ();
|
||||
+ support_record_failure_reset (); /* Discard the reported error. */
|
||||
+ report_subprocess_output ("subprocess_closed_descriptor", &proc);
|
||||
+ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
|
||||
+ support_capture_subprocess_check (&proc, "subprocess_closed_descriptor",
|
||||
+ 0, sc_allow_stdout);
|
||||
+ support_capture_subprocess_free (&proc);
|
||||
+ free (expected);
|
||||
+
|
||||
+ expected = xasprintf ("\nDifferences:\n"
|
||||
+ "error: descriptor %d was opened (\"/dev/null\")\n"
|
||||
+ "EOT\n",
|
||||
+ free_descriptor);
|
||||
+ good = good && !support_record_failure_is_failed ();
|
||||
+ proc = support_capture_subprocess (&subprocess_opened_descriptor, NULL);
|
||||
+ good = good && support_record_failure_is_failed ();
|
||||
+ support_record_failure_reset (); /* Discard the reported error. */
|
||||
+ report_subprocess_output ("subprocess_opened_descriptor", &proc);
|
||||
+ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
|
||||
+ support_capture_subprocess_check (&proc, "subprocess_opened_descriptor",
|
||||
+ 0, sc_allow_stdout);
|
||||
+ support_capture_subprocess_free (&proc);
|
||||
+ free (expected);
|
||||
+
|
||||
+ expected = xasprintf ("\nDifferences:\n"
|
||||
+ "error: descriptor %d changed from \"/dev/null\""
|
||||
+ " to \"/dev\"\n"
|
||||
+ "error: descriptor %d changed ino ",
|
||||
+ free_descriptor, free_descriptor);
|
||||
+ good = good && !support_record_failure_is_failed ();
|
||||
+ proc = support_capture_subprocess (&subprocess_changed_descriptor, NULL);
|
||||
+ good = good && support_record_failure_is_failed ();
|
||||
+ support_record_failure_reset (); /* Discard the reported error. */
|
||||
+ report_subprocess_output ("subprocess_changed_descriptor", &proc);
|
||||
+ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
|
||||
+ support_capture_subprocess_check (&proc, "subprocess_changed_descriptor",
|
||||
+ 0, sc_allow_stdout);
|
||||
+ support_capture_subprocess_free (&proc);
|
||||
+ free (expected);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ puts ("info: initial descriptor set");
|
||||
+ {
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+ support_descriptors_dump (descrs, "info: ", stdout);
|
||||
+ support_descriptors_free (descrs);
|
||||
+ }
|
||||
+
|
||||
+ free_descriptor = xopen ("/dev/null", O_WRONLY, 0);
|
||||
+ puts ("info: descriptor set with additional free descriptor");
|
||||
+ {
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+ support_descriptors_dump (descrs, "info: ", stdout);
|
||||
+ support_descriptors_free (descrs);
|
||||
+ }
|
||||
+ TEST_VERIFY (free_descriptor >= 3);
|
||||
+ xclose (free_descriptor);
|
||||
+
|
||||
+ /* Initial test run without a sentinel descriptor. The presence of
|
||||
+ such a descriptor exercises different conditions in the list
|
||||
+ comparison in support_descriptors_check. */
|
||||
+ test_run ();
|
||||
+
|
||||
+ /* Allocate a sentinel descriptor at the end of the descriptor list,
|
||||
+ after free_descriptor. */
|
||||
+ int sentinel_fd;
|
||||
+ {
|
||||
+ int fd = xopen ("/dev/full", O_WRONLY, 0);
|
||||
+ TEST_COMPARE (fd, free_descriptor);
|
||||
+ sentinel_fd = dup (fd);
|
||||
+ TEST_VERIFY_EXIT (sentinel_fd > fd);
|
||||
+ xclose (fd);
|
||||
+ }
|
||||
+ puts ("info: descriptor set with sentinel descriptor");
|
||||
+ {
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+ support_descriptors_dump (descrs, "info: ", stdout);
|
||||
+ support_descriptors_free (descrs);
|
||||
+ }
|
||||
+
|
||||
+ /* Second test run with sentinel descriptor. */
|
||||
+ test_run ();
|
||||
+
|
||||
+ xclose (sentinel_fd);
|
||||
+
|
||||
+ return !good;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
From b5a9a19b82bb00b5419162f49331a7580ac06b4e Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 6 Dec 2018 15:39:50 +0100
|
||||
Subject: [PATCH 57] inet/tst-if_index-long: New test case for
|
||||
CVE-2018-19591 [BZ #23927]
|
||||
|
||||
(cherry picked from commit 899478c2bfa00c5df8d8bedb52effbb065700278)
|
||||
---
|
||||
ChangeLog | 7 +++++
|
||||
inet/Makefile | 2 +-
|
||||
inet/tst-if_index-long.c | 61 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 69 insertions(+), 1 deletion(-)
|
||||
create mode 100644 inet/tst-if_index-long.c
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index e6451fe03e..44202d96fd 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,10 @@
|
||||
+2018-12-07 Florian Weimer <fweimer@redhat.com>
|
||||
+
|
||||
+ [BZ #23927]
|
||||
+ CVE-2018-19591
|
||||
+ * inet/tst-if_index-long.c: New file.
|
||||
+ * inet/Makefile (tests): Add tst-if_index-long.
|
||||
+
|
||||
2018-12-07 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* support/check.h (support_record_failure_is_failed): Declare.
|
||||
diff --git a/inet/Makefile b/inet/Makefile
|
||||
index 09f5ba78fc..7782913b4c 100644
|
||||
--- a/inet/Makefile
|
||||
+++ b/inet/Makefile
|
||||
@@ -52,7 +52,7 @@ aux := check_pf check_native ifreq
|
||||
tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
|
||||
tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
|
||||
tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-checks-posix \
|
||||
- tst-sockaddr test-hnto-types
|
||||
+ tst-sockaddr test-hnto-types tst-if_index-long
|
||||
|
||||
# tst-deadline must be linked statically so that we can access
|
||||
# internal functions.
|
||||
diff --git a/inet/tst-if_index-long.c b/inet/tst-if_index-long.c
|
||||
new file mode 100644
|
||||
index 0000000000..3dc74874e5
|
||||
--- /dev/null
|
||||
+++ b/inet/tst-if_index-long.c
|
||||
@@ -0,0 +1,61 @@
|
||||
+/* Check for descriptor leak in if_nametoindex with a long interface name.
|
||||
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This test checks for a descriptor leak in case of a long interface
|
||||
+ name (CVE-2018-19591, bug 23927). */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <net/if.h>
|
||||
+#include <netdb.h>
|
||||
+#include <string.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/descriptors.h>
|
||||
+#include <support/support.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ struct support_descriptors *descrs = support_descriptors_list ();
|
||||
+
|
||||
+ /* Prepare a name which is just as long as required for trigging the
|
||||
+ bug. */
|
||||
+ char name[IFNAMSIZ + 1];
|
||||
+ memset (name, 'A', IFNAMSIZ);
|
||||
+ name[IFNAMSIZ] = '\0';
|
||||
+ TEST_COMPARE (strlen (name), IFNAMSIZ);
|
||||
+ struct ifreq ifr;
|
||||
+ TEST_COMPARE (strlen (name), sizeof (ifr.ifr_name));
|
||||
+
|
||||
+ /* Test directly via if_nametoindex. */
|
||||
+ TEST_COMPARE (if_nametoindex (name), 0);
|
||||
+ TEST_COMPARE (errno, ENODEV);
|
||||
+ support_descriptors_check (descrs);
|
||||
+
|
||||
+ /* Same test via getaddrinfo. */
|
||||
+ char *host = xasprintf ("fea0::%%%s", name);
|
||||
+ struct addrinfo hints = { .ai_flags = AI_NUMERICHOST, };
|
||||
+ struct addrinfo *ai;
|
||||
+ TEST_COMPARE (getaddrinfo (host, NULL, &hints, &ai), EAI_NONAME);
|
||||
+ support_descriptors_check (descrs);
|
||||
+
|
||||
+ support_descriptors_free (descrs);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
From ea16a6938d7ca5f4c2b67c11251c70b30796602a Mon Sep 17 00:00:00 2001
|
||||
From: DJ Delorie <dj@redhat.com>
|
||||
Date: Fri, 30 Nov 2018 22:13:09 -0500
|
||||
Subject: [PATCH 58] malloc: Add another test for tcache double free check.
|
||||
|
||||
This one tests for BZ#23907 where the double free
|
||||
test didn't check the tcache bin bounds before dereferencing
|
||||
the bin.
|
||||
|
||||
[BZ #23907]
|
||||
* malloc/tst-tcfree3.c: New.
|
||||
* malloc/Makefile: Add it.
|
||||
|
||||
(cherry picked from commit 7c9a7c68363051cfc5fa1ebb96b3b2c1f82dcb76)
|
||||
---
|
||||
ChangeLog | 6 +++++
|
||||
malloc/Makefile | 2 +-
|
||||
malloc/tst-tcfree3.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 63 insertions(+), 1 deletion(-)
|
||||
create mode 100644 malloc/tst-tcfree3.c
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 44202d96fd..09f50f28a0 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,9 @@
|
||||
+2018-12-07 DJ Delorie <dj@redhat.com>
|
||||
+
|
||||
+ [BZ #23907]
|
||||
+ * malloc/tst-tcfree3.c: New.
|
||||
+ * malloc/Makefile: Add it.
|
||||
+
|
||||
2018-12-07 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
[BZ #23927]
|
||||
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||
index e6dfbfc14c..388cf7e9ee 100644
|
||||
--- a/malloc/Makefile
|
||||
+++ b/malloc/Makefile
|
||||
@@ -38,7 +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 \
|
||||
+ tst-tcfree1 tst-tcfree2 tst-tcfree3 \
|
||||
|
||||
tests-static := \
|
||||
tst-interpose-static-nothread \
|
||||
diff --git a/malloc/tst-tcfree3.c b/malloc/tst-tcfree3.c
|
||||
new file mode 100644
|
||||
index 0000000000..016d30ddd8
|
||||
--- /dev/null
|
||||
+++ b/malloc/tst-tcfree3.c
|
||||
@@ -0,0 +1,56 @@
|
||||
+/* 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 <malloc.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* Prevent GCC from optimizing away any malloc/free pairs. */
|
||||
+#pragma GCC optimize ("O0")
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* Do two allocation of any size that fit in tcache, and one that
|
||||
+ doesn't. */
|
||||
+ int ** volatile a = malloc (32);
|
||||
+ int ** volatile b = malloc (32);
|
||||
+ /* This is just under the mmap threshold. */
|
||||
+ int ** volatile c = malloc (127 * 1024);
|
||||
+
|
||||
+ /* The invalid "tcache bucket" we might dereference will likely end
|
||||
+ up somewhere within this memory block, so make all the accidental
|
||||
+ "next" pointers cause segfaults. BZ #23907. */
|
||||
+ memset (c, 0xff, 127 * 1024);
|
||||
+
|
||||
+ free (a); // puts in tcache
|
||||
+
|
||||
+ /* A is now free and contains the key we use to detect in-tcache.
|
||||
+ Copy the key to the other chunks. */
|
||||
+ memcpy (b, a, 32);
|
||||
+ memcpy (c, a, 32);
|
||||
+
|
||||
+ /* This free tests the "are we in the tcache already" loop with a
|
||||
+ VALID bin but "coincidental" matching key. */
|
||||
+ free (b); // should NOT abort
|
||||
+ /* This free tests the "is it a valid tcache bin" test. */
|
||||
+ free (c); // should NOT abort
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
From 852620258deea8afda5674f397113fa87ce1007c Mon Sep 17 00:00:00 2001
|
||||
From: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
Date: Thu, 13 Dec 2018 09:42:22 +0100
|
||||
Subject: [PATCH 59] powerpc: Add missing CFI register information (bug
|
||||
#23614)
|
||||
|
||||
Add CFI information about the offset of registers stored in the stack
|
||||
frame.
|
||||
|
||||
[BZ #23614]
|
||||
* sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for
|
||||
registers saved in the stack frame.
|
||||
* sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise.
|
||||
* sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise.
|
||||
|
||||
Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
Reviewed-by: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
|
||||
(cherry picked from commit 1d880d4a9bf7608c2cd33bbe954ce6995f79121a)
|
||||
---
|
||||
ChangeLog | 8 +++++++
|
||||
NEWS | 1 +
|
||||
sysdeps/powerpc/powerpc64/addmul_1.S | 31 +++++++++++++++++++---------
|
||||
sysdeps/powerpc/powerpc64/lshift.S | 12 +++++++----
|
||||
sysdeps/powerpc/powerpc64/mul_1.S | 13 ++++++++----
|
||||
5 files changed, 47 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 09f50f28a0..6ad1f7a913 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,11 @@
|
||||
+2018-12-12 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
+
|
||||
+ [BZ #23614]
|
||||
+ * sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for
|
||||
+ registers saved in the stack frame.
|
||||
+ * sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise.
|
||||
+ * sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise.
|
||||
+
|
||||
2018-12-07 DJ Delorie <dj@redhat.com>
|
||||
|
||||
[BZ #23907]
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 4d4a5a1911..05f7342fcb 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -20,6 +20,7 @@ The following bugs are resolved with this release:
|
||||
[23578] regex: Fix memory overread in re_compile_pattern
|
||||
[23579] libc: Errors misreported in preadv2
|
||||
[23606] Missing ENDBR32 in sysdeps/i386/start.S
|
||||
+ [23614] powerpc: missing CFI register information in __mpn_* functions
|
||||
[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
|
||||
diff --git a/sysdeps/powerpc/powerpc64/addmul_1.S b/sysdeps/powerpc/powerpc64/addmul_1.S
|
||||
index 48e3b1b290..e450d6a52c 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/addmul_1.S
|
||||
+++ b/sysdeps/powerpc/powerpc64/addmul_1.S
|
||||
@@ -34,16 +34,27 @@
|
||||
#define N r5
|
||||
#define VL r6
|
||||
|
||||
+#define R27SAVE (-40)
|
||||
+#define R28SAVE (-32)
|
||||
+#define R29SAVE (-24)
|
||||
+#define R30SAVE (-16)
|
||||
+#define R31SAVE (-8)
|
||||
+
|
||||
ENTRY_TOCLESS (FUNC, 5)
|
||||
- std r31, -8(r1)
|
||||
+ std r31, R31SAVE(r1)
|
||||
rldicl. r0, N, 0, 62
|
||||
- std r30, -16(r1)
|
||||
+ std r30, R30SAVE(r1)
|
||||
cmpdi VL, r0, 2
|
||||
- std r29, -24(r1)
|
||||
+ std r29, R29SAVE(r1)
|
||||
addi N, N, 3
|
||||
- std r28, -32(r1)
|
||||
+ std r28, R28SAVE(r1)
|
||||
srdi N, N, 2
|
||||
- std r27, -40(r1)
|
||||
+ std r27, R27SAVE(r1)
|
||||
+ cfi_offset(r31, R31SAVE)
|
||||
+ cfi_offset(r30, R30SAVE)
|
||||
+ cfi_offset(r29, R29SAVE)
|
||||
+ cfi_offset(r28, R28SAVE)
|
||||
+ cfi_offset(r27, R27SAVE)
|
||||
mtctr N
|
||||
beq cr0, L(b00)
|
||||
blt cr6, L(b01)
|
||||
@@ -199,10 +210,10 @@ L(end): mulld r0, r9, VL
|
||||
addic r11, r11, 1
|
||||
#endif
|
||||
addze RP, r8
|
||||
- ld r31, -8(r1)
|
||||
- ld r30, -16(r1)
|
||||
- ld r29, -24(r1)
|
||||
- ld r28, -32(r1)
|
||||
- ld r27, -40(r1)
|
||||
+ ld r31, R31SAVE(r1)
|
||||
+ ld r30, R30SAVE(r1)
|
||||
+ ld r29, R29SAVE(r1)
|
||||
+ ld r28, R28SAVE(r1)
|
||||
+ ld r27, R27SAVE(r1)
|
||||
blr
|
||||
END(FUNC)
|
||||
diff --git a/sysdeps/powerpc/powerpc64/lshift.S b/sysdeps/powerpc/powerpc64/lshift.S
|
||||
index 8b6396ee6c..855d6f2993 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/lshift.S
|
||||
+++ b/sysdeps/powerpc/powerpc64/lshift.S
|
||||
@@ -26,11 +26,15 @@
|
||||
#define TNC r0
|
||||
#define U0 r30
|
||||
#define U1 r31
|
||||
+#define U0SAVE (-16)
|
||||
+#define U1SAVE (-8)
|
||||
#define RETVAL r5
|
||||
|
||||
ENTRY_TOCLESS (__mpn_lshift, 5)
|
||||
- std U1, -8(r1)
|
||||
- std U0, -16(r1)
|
||||
+ std U1, U1SAVE(r1)
|
||||
+ std U0, U0SAVE(r1)
|
||||
+ cfi_offset(U1, U1SAVE)
|
||||
+ cfi_offset(U0, U0SAVE)
|
||||
subfic TNC, CNT, 64
|
||||
sldi r7, N, RP
|
||||
add UP, UP, r7
|
||||
@@ -170,8 +174,8 @@ L(cj3): or r10, r12, r7
|
||||
L(cj2): std r10, -32(RP)
|
||||
std r8, -40(RP)
|
||||
|
||||
-L(ret): ld U1, -8(r1)
|
||||
- ld U0, -16(r1)
|
||||
+L(ret): ld U1, U1SAVE(r1)
|
||||
+ ld U0, U0SAVE(r1)
|
||||
mr RP, RETVAL
|
||||
blr
|
||||
END(__mpn_lshift)
|
||||
diff --git a/sysdeps/powerpc/powerpc64/mul_1.S b/sysdeps/powerpc/powerpc64/mul_1.S
|
||||
index 953ded8028..cade365258 100644
|
||||
--- a/sysdeps/powerpc/powerpc64/mul_1.S
|
||||
+++ b/sysdeps/powerpc/powerpc64/mul_1.S
|
||||
@@ -24,9 +24,14 @@
|
||||
#define N r5
|
||||
#define VL r6
|
||||
|
||||
+#define R26SAVE (-48)
|
||||
+#define R27SAVE (-40)
|
||||
+
|
||||
ENTRY_TOCLESS (__mpn_mul_1, 5)
|
||||
- std r27, -40(r1)
|
||||
- std r26, -48(r1)
|
||||
+ std r27, R27SAVE(r1)
|
||||
+ std r26, R26SAVE(r1)
|
||||
+ cfi_offset(r27, R27SAVE)
|
||||
+ cfi_offset(r26, R26SAVE)
|
||||
li r12, 0
|
||||
ld r26, 0(UP)
|
||||
|
||||
@@ -129,7 +134,7 @@ L(end): mulld r0, r26, VL
|
||||
std r0, 0(RP)
|
||||
std r7, 8(RP)
|
||||
L(ret): addze RP, r8
|
||||
- ld r27, -40(r1)
|
||||
- ld r26, -48(r1)
|
||||
+ ld r27, R27SAVE(r1)
|
||||
+ ld r26, R26SAVE(r1)
|
||||
blr
|
||||
END(__mpn_mul_1)
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
From 4d7af7815af5217db6e8fde6032ddf4f6b2a4420 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schwab <schwab@suse.de>
|
||||
Date: Thu, 8 Nov 2018 14:28:22 +0100
|
||||
Subject: [PATCH 60] Fix rwlock stall with PREFER_WRITER_NONRECURSIVE_NP
|
||||
(bug 23861)
|
||||
|
||||
In the read lock function (__pthread_rwlock_rdlock_full) there was a
|
||||
code path which would fail to reload __readers while waiting for
|
||||
PTHREAD_RWLOCK_RWAITING to change. This failure to reload __readers
|
||||
into a local value meant that various conditionals used the old value
|
||||
of __readers and with only two threads left it could result in an
|
||||
indefinite stall of one of the readers (waiting for PTHREAD_RWLOCK_RWAITING
|
||||
to go to zero, but it never would).
|
||||
|
||||
(cherry picked from commit f21e8f8ca466320fed38bdb71526c574dae98026)
|
||||
---
|
||||
ChangeLog | 9 ++++
|
||||
nptl/Makefile | 3 +-
|
||||
nptl/pthread_rwlock_common.c | 4 +-
|
||||
nptl/tst-rwlock-pwn.c | 87 ++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 100 insertions(+), 3 deletions(-)
|
||||
create mode 100644 nptl/tst-rwlock-pwn.c
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 6ad1f7a913..c12b5995a3 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,12 @@
|
||||
+2018-12-13 Andreas Schwab <schwab@suse.de>
|
||||
+
|
||||
+ [BZ #23861]
|
||||
+ * nptl/pthread_rwlock_common.c: Reindent. Fix typos.
|
||||
+ (__pthread_rwlock_rdlock_full): Update expected value for
|
||||
+ __readers while waiting on PTHREAD_RWLOCK_RWAITING.
|
||||
+ * nptl/tst-rwlock-pwn.c: New file.
|
||||
+ * nptl/Makefile (tests): Add tst-rwlock-pwn.
|
||||
+
|
||||
2018-12-12 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
|
||||
|
||||
[BZ #23614]
|
||||
diff --git a/nptl/Makefile b/nptl/Makefile
|
||||
index ee720960d1..2d2db648f7 100644
|
||||
--- a/nptl/Makefile
|
||||
+++ b/nptl/Makefile
|
||||
@@ -318,7 +318,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
|
||||
tst-minstack-throw \
|
||||
tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
|
||||
tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \
|
||||
- tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock
|
||||
+ tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \
|
||||
+ tst-rwlock-pwn
|
||||
|
||||
tests-internal := tst-rwlock19 tst-rwlock20 \
|
||||
tst-sem11 tst-sem12 tst-sem13 \
|
||||
diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
|
||||
index a290d08332..9ce36d1026 100644
|
||||
--- a/nptl/pthread_rwlock_common.c
|
||||
+++ b/nptl/pthread_rwlock_common.c
|
||||
@@ -314,8 +314,8 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
|
||||
harmless because the flag is just about the state of
|
||||
__readers, and all threads set the flag under the same
|
||||
conditions. */
|
||||
- while ((atomic_load_relaxed (&rwlock->__data.__readers)
|
||||
- & PTHREAD_RWLOCK_RWAITING) != 0)
|
||||
+ while (((r = atomic_load_relaxed (&rwlock->__data.__readers))
|
||||
+ & PTHREAD_RWLOCK_RWAITING) != 0)
|
||||
{
|
||||
int private = __pthread_rwlock_get_private (rwlock);
|
||||
int err = futex_abstimed_wait (&rwlock->__data.__readers,
|
||||
diff --git a/nptl/tst-rwlock-pwn.c b/nptl/tst-rwlock-pwn.c
|
||||
new file mode 100644
|
||||
index 0000000000..c39dd70973
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-rwlock-pwn.c
|
||||
@@ -0,0 +1,87 @@
|
||||
+/* Test rwlock with PREFER_WRITER_NONRECURSIVE_NP (bug 23861).
|
||||
+ 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 <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <pthread.h>
|
||||
+#include <support/xthread.h>
|
||||
+
|
||||
+/* We choose 10 iterations because this happens to be able to trigger the
|
||||
+ stall on contemporary hardware. */
|
||||
+#define LOOPS 10
|
||||
+/* We need 3 threads to trigger bug 23861. One thread as a writer, and
|
||||
+ two reader threads. The test verifies that the second-to-last reader
|
||||
+ is able to notify the *last* reader that it should be done waiting.
|
||||
+ If the second-to-last reader fails to notify the last reader or does
|
||||
+ so incorrectly then the last reader may stall indefinitely. */
|
||||
+#define NTHREADS 3
|
||||
+
|
||||
+_Atomic int do_exit;
|
||||
+pthread_rwlockattr_t mylock_attr;
|
||||
+pthread_rwlock_t mylock;
|
||||
+
|
||||
+void *
|
||||
+run_loop (void *a)
|
||||
+{
|
||||
+ while (!do_exit)
|
||||
+ {
|
||||
+ if (random () & 1)
|
||||
+ {
|
||||
+ xpthread_rwlock_wrlock (&mylock);
|
||||
+ xpthread_rwlock_unlock (&mylock);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ xpthread_rwlock_rdlock (&mylock);
|
||||
+ xpthread_rwlock_unlock (&mylock);
|
||||
+ }
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ xpthread_rwlockattr_init (&mylock_attr);
|
||||
+ xpthread_rwlockattr_setkind_np (&mylock_attr,
|
||||
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
|
||||
+ xpthread_rwlock_init (&mylock, &mylock_attr);
|
||||
+
|
||||
+ for (int n = 0; n < LOOPS; n++)
|
||||
+ {
|
||||
+ pthread_t tids[NTHREADS];
|
||||
+ do_exit = 0;
|
||||
+ for (int i = 0; i < NTHREADS; i++)
|
||||
+ tids[i] = xpthread_create (NULL, run_loop, NULL);
|
||||
+ /* Let the threads run for some time. */
|
||||
+ sleep (1);
|
||||
+ printf ("Exiting...");
|
||||
+ fflush (stdout);
|
||||
+ do_exit = 1;
|
||||
+ for (int i = 0; i < NTHREADS; i++)
|
||||
+ xpthread_join (tids[i]);
|
||||
+ printf ("done.\n");
|
||||
+ }
|
||||
+ pthread_rwlock_destroy (&mylock);
|
||||
+ pthread_rwlockattr_destroy (&mylock_attr);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TIMEOUT (DEFAULT_TIMEOUT + 3 * LOOPS)
|
||||
+#include <support/test-driver.c>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
From 1a8db070fa42276f290e20c294a51b4fc9c51f83 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Sat, 15 Dec 2018 18:58:09 +0100
|
||||
Subject: [PATCH 61] support: Do not require overflow builtin in
|
||||
support/blob_repeat.c
|
||||
|
||||
It is only available in GCC 5 and later.
|
||||
|
||||
Tested-by: Romain Naour <romain.naour@gmail.com>
|
||||
(cherry picked from commit 0c1719e65b2a5a80331d4f635612799f853b0479)
|
||||
---
|
||||
ChangeLog | 6 ++++++
|
||||
support/blob_repeat.c | 26 +++++++++++++++++++++++---
|
||||
2 files changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index c12b5995a3..d8459496ba 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,9 @@
|
||||
+2018-12-15 Florian Weimer <fweimer@redhat.com>
|
||||
+
|
||||
+ * support/blob_repeat.c (check_mul_overflow_size_t): New function.
|
||||
+ (minimum_stride_size): Use it.
|
||||
+ (support_blob_repeat_allocate): Likewise.
|
||||
+
|
||||
2018-12-13 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
[BZ #23861]
|
||||
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
|
||||
index 16c1e448b9..718846d81d 100644
|
||||
--- a/support/blob_repeat.c
|
||||
+++ b/support/blob_repeat.c
|
||||
@@ -34,6 +34,26 @@
|
||||
optimization because mappings carry a lot of overhead. */
|
||||
static const size_t maximum_small_size = 4 * 1024 * 1024;
|
||||
|
||||
+/* Set *RESULT to LEFT * RIGHT. Return true if the multiplication
|
||||
+ overflowed. See <malloc/malloc-internal.h>. */
|
||||
+static inline bool
|
||||
+check_mul_overflow_size_t (size_t left, size_t right, size_t *result)
|
||||
+{
|
||||
+#if __GNUC__ >= 5
|
||||
+ return __builtin_mul_overflow (left, right, result);
|
||||
+#else
|
||||
+ /* size_t is unsigned so the behavior on overflow is defined. */
|
||||
+ *result = left * right;
|
||||
+ size_t half_size_t = ((size_t) 1) << (8 * sizeof (size_t) / 2);
|
||||
+ if (__glibc_unlikely ((left | right) >= half_size_t))
|
||||
+ {
|
||||
+ if (__glibc_unlikely (right != 0 && *result / right != left))
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
/* Internal helper for fill. */
|
||||
static void
|
||||
fill0 (char *target, const char *element, size_t element_size,
|
||||
@@ -118,8 +138,8 @@ minimum_stride_size (size_t page_size, size_t element_size)
|
||||
common multiple, it appears only once. Therefore, shift one
|
||||
factor. */
|
||||
size_t multiple;
|
||||
- if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
|
||||
- &multiple))
|
||||
+ if (check_mul_overflow_size_t (page_size >> common_zeros, element_size,
|
||||
+ &multiple))
|
||||
return 0;
|
||||
return multiple;
|
||||
}
|
||||
@@ -255,7 +275,7 @@ support_blob_repeat_allocate (const void *element, size_t element_size,
|
||||
size_t count)
|
||||
{
|
||||
size_t total_size;
|
||||
- if (__builtin_mul_overflow (element_size, count, &total_size))
|
||||
+ if (check_mul_overflow_size_t (element_size, count, &total_size))
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return (struct support_blob_repeat) { 0 };
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
From b4ce4476fc5d14fff413abe130b2ea7a7554f8d3 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schwab <schwab@suse.de>
|
||||
Date: Tue, 25 Sep 2018 11:11:27 +0200
|
||||
Subject: [PATCH 62] RISC-V: properly terminate call chain (bug 23125)
|
||||
|
||||
Mark the ra register as undefined in _start, so that unwinding through
|
||||
main works correctly. Also, don't use a tail call so that ra points after
|
||||
the call to __libc_start_main, not after the previous call.
|
||||
|
||||
(cherry picked from commit 2dd12baa045f25c52b30a34b10f72d51f2605413)
|
||||
---
|
||||
ChangeLog | 9 +++++++++
|
||||
elf/Makefile | 5 ++++-
|
||||
elf/tst-unwind-main.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
sysdeps/riscv/start.S | 7 ++++++-
|
||||
4 files changed, 57 insertions(+), 2 deletions(-)
|
||||
create mode 100644 elf/tst-unwind-main.c
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index d8459496ba..81555f1675 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,12 @@
|
||||
+2018-10-30 Andreas Schwab <schwab@suse.de>
|
||||
+
|
||||
+ [BZ #23125]
|
||||
+ * sysdeps/riscv/start.S (ENTRY_POINT): Mark ra as undefined.
|
||||
+ Don't use tail call.
|
||||
+ * elf/tst-unwind-main.c: New file.
|
||||
+ * elf/Makefile (tests): Add tst-unwind-main.
|
||||
+ (CFLAGS-tst-unwind-main.c): Define.
|
||||
+
|
||||
2018-12-15 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* support/blob_repeat.c (check_mul_overflow_size_t): New function.
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index cd0771307f..43f625af05 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -186,7 +186,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
|
||||
tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
|
||||
tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
|
||||
- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note
|
||||
+ tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
|
||||
+ tst-unwind-main
|
||||
# reldep9
|
||||
tests-internal += loadtest unload unload2 circleload1 \
|
||||
neededtest neededtest2 neededtest3 neededtest4 \
|
||||
@@ -1484,3 +1485,5 @@ tst-libc_dlvsym-static-ENV = \
|
||||
$(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so
|
||||
|
||||
$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
|
||||
+
|
||||
+CFLAGS-tst-unwind-main.c += -funwind-tables
|
||||
diff --git a/elf/tst-unwind-main.c b/elf/tst-unwind-main.c
|
||||
new file mode 100644
|
||||
index 0000000000..d1236032d7
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-unwind-main.c
|
||||
@@ -0,0 +1,38 @@
|
||||
+/* Test unwinding through main.
|
||||
+ 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 <unwind.h>
|
||||
+#include <unistd.h>
|
||||
+#include <support/test-driver.h>
|
||||
+
|
||||
+static _Unwind_Reason_Code
|
||||
+callback (struct _Unwind_Context *ctx, void *arg)
|
||||
+{
|
||||
+ return _URC_NO_REASON;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ /* Arrange for this test to be killed if _Unwind_Backtrace runs into an
|
||||
+ endless loop. We cannot use the test driver because the complete
|
||||
+ call chain needs to be compiled with -funwind-tables so that
|
||||
+ _Unwind_Backtrace is able to reach _start. */
|
||||
+ alarm (DEFAULT_TIMEOUT);
|
||||
+ _Unwind_Backtrace (callback, 0);
|
||||
+}
|
||||
diff --git a/sysdeps/riscv/start.S b/sysdeps/riscv/start.S
|
||||
index 4635ddb5eb..2d6f06e630 100644
|
||||
--- a/sysdeps/riscv/start.S
|
||||
+++ b/sysdeps/riscv/start.S
|
||||
@@ -43,6 +43,10 @@
|
||||
__libc_start_main wants this in a5. */
|
||||
|
||||
ENTRY (ENTRY_POINT)
|
||||
+ /* Terminate call stack by noting ra is undefined. Use a dummy
|
||||
+ .cfi_label to force starting the FDE. */
|
||||
+ .cfi_label .Ldummy
|
||||
+ cfi_undefined (ra)
|
||||
call .Lload_gp
|
||||
mv a5, a0 /* rtld_fini. */
|
||||
/* main may be in a shared library. */
|
||||
@@ -54,7 +58,8 @@ ENTRY (ENTRY_POINT)
|
||||
lla a4, __libc_csu_fini
|
||||
mv a6, sp /* stack_end. */
|
||||
|
||||
- tail __libc_start_main@plt
|
||||
+ call __libc_start_main@plt
|
||||
+ ebreak
|
||||
END (ENTRY_POINT)
|
||||
|
||||
/* Dynamic links need the global pointer to be initialized prior to calling
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
From 27e039455d5ef0d30b835fb422fffafd42600fa4 Mon Sep 17 00:00:00 2001
|
||||
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue, 11 Dec 2018 16:52:47 -0200
|
||||
Subject: [PATCH 63] m68k: Fix sigaction kernel definition (BZ #23967)
|
||||
|
||||
Commit b4a5d26d883 (linux: Consolidate sigaction implementation) added
|
||||
a wrong kernel_sigaction definition for m68k, meant for __NR_sigaction
|
||||
instead of __NR_rt_sigaction as used on generic Linux sigaction
|
||||
implementation. This patch fixes it by using the Linux generic
|
||||
definition meant for the RT kernel ABI.
|
||||
|
||||
Checked the signal tests on emulated m68-linux-gnu (Aranym). It fixes
|
||||
the faulty signal/tst-sigaction and man works as expected.
|
||||
|
||||
Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
James Clarke <jrtc27@jrtc27.com>
|
||||
|
||||
[BZ #23967]
|
||||
* sysdeps/unix/sysv/linux/kernel_sigaction.h (HAS_SA_RESTORER):
|
||||
Define if SA_RESTORER is defined.
|
||||
(kernel_sigaction): Define sa_restorer if HAS_SA_RESTORER is defined.
|
||||
(SET_SA_RESTORER, RESET_SA_RESTORER): Define iff the macro are not
|
||||
already defined.
|
||||
* sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h (SA_RESTORER,
|
||||
kernel_sigaction, SET_SA_RESTORER, RESET_SA_RESTORER): Remove
|
||||
definitions.
|
||||
(HAS_SA_RESTORER): Define.
|
||||
* sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h (SA_RESTORER,
|
||||
SET_SA_RESTORER, RESET_SA_RESTORER): Remove definition.
|
||||
(HAS_SA_RESTORER): Define.
|
||||
* sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Include generic
|
||||
kernel_sigaction after define SET_SA_RESTORER and RESET_SA_RESTORER.
|
||||
* sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise.
|
||||
|
||||
(cherry picked from commit 43a45c2d829f164c1fb94d5f44afe326fae946e1)
|
||||
---
|
||||
ChangeLog | 22 ++++++++++++++++
|
||||
sysdeps/unix/sysv/linux/kernel_sigaction.h | 12 +++++++--
|
||||
.../unix/sysv/linux/m68k/kernel_sigaction.h | 26 +++----------------
|
||||
.../unix/sysv/linux/nios2/kernel_sigaction.h | 3 ++-
|
||||
.../sysv/linux/powerpc/kernel_sigaction.h | 3 ++-
|
||||
sysdeps/unix/sysv/linux/sh/kernel_sigaction.h | 3 ++-
|
||||
.../unix/sysv/linux/sparc/kernel_sigaction.h | 7 +----
|
||||
sysdeps/unix/sysv/linux/x86_64/sigaction.c | 3 ++-
|
||||
8 files changed, 45 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 81555f1675..739fe56d73 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,25 @@
|
||||
+2018-12-18 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
+ James Clarke <jrtc27@jrtc27.com>
|
||||
+
|
||||
+ [BZ #23967]
|
||||
+ * sysdeps/unix/sysv/linux/kernel_sigaction.h (HAS_SA_RESTORER):
|
||||
+ Define if SA_RESTORER is defined.
|
||||
+ (kernel_sigaction): Define sa_restorer if HAS_SA_RESTORER is defined.
|
||||
+ (SET_SA_RESTORER, RESET_SA_RESTORER): Define iff the macro are not
|
||||
+ already defined.
|
||||
+ * sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h (SA_RESTORER,
|
||||
+ kernel_sigaction, SET_SA_RESTORER, RESET_SA_RESTORER): Remove
|
||||
+ definitions.
|
||||
+ (HAS_SA_RESTORER): Define.
|
||||
+ * sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h (SA_RESTORER,
|
||||
+ SET_SA_RESTORER, RESET_SA_RESTORER): Remove definition.
|
||||
+ (HAS_SA_RESTORER): Define.
|
||||
+ * sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Include generic
|
||||
+ kernel_sigaction after define SET_SA_RESTORER and RESET_SA_RESTORER.
|
||||
+ * sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h: Likewise.
|
||||
+ * sysdeps/unix/sysv/linux/s390/kernel_sigaction.h: Likewise.
|
||||
+ * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise.
|
||||
+
|
||||
2018-10-30 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
[BZ #23125]
|
||||
diff --git a/sysdeps/unix/sysv/linux/kernel_sigaction.h b/sysdeps/unix/sysv/linux/kernel_sigaction.h
|
||||
index 2dbec08099..1c36146d46 100644
|
||||
--- a/sysdeps/unix/sysv/linux/kernel_sigaction.h
|
||||
+++ b/sysdeps/unix/sysv/linux/kernel_sigaction.h
|
||||
@@ -1,19 +1,27 @@
|
||||
#ifndef _KERNEL_SIGACTION_H
|
||||
# define _KERNEL_SIGACTION_H
|
||||
|
||||
+#ifdef SA_RESTORER
|
||||
+# define HAS_SA_RESTORER 1
|
||||
+#endif
|
||||
+
|
||||
/* This is the sigaction structure from the Linux 3.2 kernel. */
|
||||
struct kernel_sigaction
|
||||
{
|
||||
__sighandler_t k_sa_handler;
|
||||
unsigned long sa_flags;
|
||||
-#ifdef SA_RESTORER
|
||||
+#ifdef HAS_SA_RESTORER
|
||||
void (*sa_restorer) (void);
|
||||
#endif
|
||||
+ /* glibc sigset is larger than kernel expected one, however sigaction
|
||||
+ passes the kernel expected size on rt_sigaction syscall. */
|
||||
sigset_t sa_mask;
|
||||
};
|
||||
|
||||
-#ifndef SA_RESTORER
|
||||
+#ifndef SET_SA_RESTORER
|
||||
# define SET_SA_RESTORER(kact, act)
|
||||
+#endif
|
||||
+#ifndef RESET_SA_RESTORER
|
||||
# define RESET_SA_RESTORER(act, kact)
|
||||
#endif
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h
|
||||
index 54972feb13..464b351d6d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h
|
||||
+++ b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h
|
||||
@@ -1,22 +1,4 @@
|
||||
-#ifndef _KERNEL_SIGACTION_H
|
||||
-# define _KERNEL_SIGACTION_H
|
||||
-
|
||||
-#include <signal.h>
|
||||
-
|
||||
-#define SA_RESTORER 0x04000000
|
||||
-
|
||||
-/* This is the sigaction structure from the Linux 3.2 kernel. */
|
||||
-struct kernel_sigaction
|
||||
-{
|
||||
- __sighandler_t k_sa_handler;
|
||||
- sigset_t sa_mask;
|
||||
- unsigned long sa_flags;
|
||||
- void (*sa_restorer) (void);
|
||||
-};
|
||||
-
|
||||
-#define SET_SA_RESTORER(kact, act) \
|
||||
- (kact)->sa_restorer = (act)->sa_restorer
|
||||
-#define RESET_SA_RESTORER(act, kact) \
|
||||
- (act)->sa_restorer = (kact)->sa_restorer
|
||||
-
|
||||
-#endif
|
||||
+/* m68k does not define SA_RESTORER, but does have sa_restorer member
|
||||
+ on kernel sigaction struct. */
|
||||
+#define HAS_SA_RESTORER 1
|
||||
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h
|
||||
index 4ada322104..89f9bcedfd 100644
|
||||
--- a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h
|
||||
+++ b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h
|
||||
@@ -1,8 +1,9 @@
|
||||
/* NIOS2 uses the generic Linux UAPI but defines SA_RESTORER. */
|
||||
#define SA_RESTORER 0x04000000
|
||||
-#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
|
||||
#define SET_SA_RESTORER(kact, act) \
|
||||
(kact)->sa_restorer = (act)->sa_restorer
|
||||
#define RESET_SA_RESTORER(act, kact) \
|
||||
(act)->sa_restorer = (kact)->sa_restorer
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h
|
||||
index aef3d5a3b3..bac03ee45d 100644
|
||||
--- a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h
|
||||
+++ b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h
|
||||
@@ -1,9 +1,10 @@
|
||||
/* powerpc kernel sigaction is similar to generic Linux UAPI one,
|
||||
but the architecture also defines SA_RESTORER. */
|
||||
#define SA_RESTORER 0x04000000
|
||||
-#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
|
||||
#define SET_SA_RESTORER(kact, act) \
|
||||
(kact)->sa_restorer = (act)->sa_restorer
|
||||
#define RESET_SA_RESTORER(act, kact) \
|
||||
(act)->sa_restorer = (kact)->sa_restorer
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
diff --git a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h
|
||||
index 7ebcd08d62..c8dc77a02b 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h
|
||||
@@ -1,8 +1,9 @@
|
||||
/* SH uses the generic Linux UAPI but defines SA_RESTORER. */
|
||||
#define SA_RESTORER 0x04000000
|
||||
-#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
|
||||
#define SET_SA_RESTORER(kact, act) \
|
||||
(kact)->sa_restorer = (act)->sa_restorer
|
||||
#define RESET_SA_RESTORER(act, kact) \
|
||||
(act)->sa_restorer = (kact)->sa_restorer
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
|
||||
index bee7e9cd03..eb4a522453 100644
|
||||
--- a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
|
||||
+++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
|
||||
@@ -1,10 +1,5 @@
|
||||
/* SPARC 'struct __new_sigaction' is similar to generic Linux UAPI with
|
||||
a sa_restorer field, even though function is passed as an argument
|
||||
to rt_sigaction syscall. */
|
||||
-#define SA_RESTORER 0x04000000
|
||||
+#define HAS_SA_RESTORER 1
|
||||
#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
|
||||
-
|
||||
-#define SET_SA_RESTORER(kact, act) \
|
||||
- (kact)->sa_restorer = NULL
|
||||
-#define RESET_SA_RESTORER(act, kact) \
|
||||
- (act)->sa_restorer = (kact)->sa_restorer
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
|
||||
index 4e6d9cc32e..9aa2c7f860 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <signal.h>
|
||||
#define SA_RESTORER 0x04000000
|
||||
-#include <kernel_sigaction.h>
|
||||
|
||||
extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
|
||||
|
||||
@@ -29,6 +28,8 @@ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
|
||||
#define RESET_SA_RESTORER(act, kact) \
|
||||
(act)->sa_restorer = (kact)->sa_restorer
|
||||
|
||||
+#include <kernel_sigaction.h>
|
||||
+
|
||||
#include <sysdeps/unix/sysv/linux/sigaction.c>
|
||||
|
||||
/* NOTE: Please think twice before making any changes to the bits of
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
From 69b914a99e24da875f9f4f2449ec9a6126ac3bc2 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 28 Dec 2018 11:24:48 +0100
|
||||
Subject: [PATCH 64] Update Alpha libm-test-ulps
|
||||
|
||||
Changelog:
|
||||
* sysdeps/alpha/fpu/libm-test-ulps: Regenerated.
|
||||
---
|
||||
ChangeLog | 4 ++++
|
||||
sysdeps/alpha/fpu/libm-test-ulps | 8 ++++++++
|
||||
2 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 739fe56d73..c7a04d8717 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,7 @@
|
||||
+2018-12-28 Aurelien Jarno <aurelien@aurel32.net>
|
||||
+
|
||||
+ * sysdeps/alpha/fpu/libm-test-ulps: Regenerated.
|
||||
+
|
||||
2018-12-18 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
James Clarke <jrtc27@jrtc27.com>
|
||||
|
||||
diff --git a/sysdeps/alpha/fpu/libm-test-ulps b/sysdeps/alpha/fpu/libm-test-ulps
|
||||
index 12a6127ddf..3fc18d57d7 100644
|
||||
--- a/sysdeps/alpha/fpu/libm-test-ulps
|
||||
+++ b/sysdeps/alpha/fpu/libm-test-ulps
|
||||
@@ -1006,7 +1006,9 @@ ildouble: 2
|
||||
ldouble: 2
|
||||
|
||||
Function: "cos":
|
||||
+double: 1
|
||||
float: 1
|
||||
+idouble: 1
|
||||
ifloat: 1
|
||||
ildouble: 1
|
||||
ldouble: 1
|
||||
@@ -1932,7 +1934,9 @@ ildouble: 1
|
||||
ldouble: 1
|
||||
|
||||
Function: "pow":
|
||||
+double: 1
|
||||
float: 1
|
||||
+idouble: 1
|
||||
ifloat: 1
|
||||
ildouble: 2
|
||||
ldouble: 2
|
||||
@@ -1962,7 +1966,9 @@ ildouble: 2
|
||||
ldouble: 2
|
||||
|
||||
Function: "sin":
|
||||
+double: 1
|
||||
float: 1
|
||||
+idouble: 1
|
||||
ifloat: 1
|
||||
ildouble: 1
|
||||
ldouble: 1
|
||||
@@ -1992,7 +1998,9 @@ ildouble: 3
|
||||
ldouble: 3
|
||||
|
||||
Function: "sincos":
|
||||
+double: 1
|
||||
float: 1
|
||||
+idouble: 1
|
||||
ifloat: 1
|
||||
ildouble: 1
|
||||
ldouble: 1
|
|
@ -1,12 +1,12 @@
|
|||
# Template file for 'glibc'
|
||||
pkgname=glibc
|
||||
version=2.28
|
||||
revision=4
|
||||
revision=5
|
||||
bootstrap=yes
|
||||
short_desc="The GNU C library"
|
||||
maintainer="Juan RP <xtraeme@voidlinux.eu>"
|
||||
homepage="http://www.gnu.org/software/libc"
|
||||
license="GPL-2.0-or-later, LGPL-2.1-or-later, BSD-3-Clause"
|
||||
homepage="http://www.gnu.org/software/libc"
|
||||
distfiles="${GNU_SITE}/glibc/glibc-${version}.tar.xz"
|
||||
checksum=b1900051afad76f7a4f73e71413df4826dce085ef8ddb785a945b66d7d513082
|
||||
patch_args="-Np1"
|
||||
|
|
Loading…
Reference in New Issue