glibc: sync patches with upstream

This commit is contained in:
maxice8 2018-12-29 19:48:13 -02:00 committed by maxice8
parent 1498f4dfcc
commit 7c00d2d7ca
16 changed files with 2592 additions and 2 deletions

View file

@ -289,3 +289,4 @@ index ab2a3102bb..0ea560ed78 100644
@node Mathematical Function Probes
@section Mathematical Function Probes

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 (&current->list);
+ struct procfs_descriptor *right_end = descriptor_list_end (&current->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>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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