Accepting request 670585 from home:Andreas_Schwab:Factory

- Update to glibc 2.29
  * The getcpu wrapper function has been added, which returns the currently
    used CPU and NUMA node
  * Optimized generic exp, exp2, log, log2, pow, sinf, cosf, sincosf and tanf
  * The reallocarray function is now declared under _DEFAULT_SOURCE, not just
    for _GNU_SOURCE, to match BSD environments
  * For powercp64le ABI, Transactional Lock Elision is now enabled iff kernel
    indicates that it will abort the transaction prior to entering the kernel
    (PPC_FEATURE2_HTM_NOSC on hwcap2)
  * The functions posix_spawn_file_actions_addchdir_np and
    posix_spawn_file_actions_addfchdir_np have been added, enabling
    posix_spawn and posix_spawnp to run the new process in a different
    directory
  * The popen and system do not run atfork handlers anymore (BZ#17490)
  * strftime's default formatting of a locale's alternative year (%Ey)
    has been changed to zero-pad the year to a minimum of two digits,
    like "%y"
  * As a GNU extension, the '_' and '-' flags can now be applied to
    "%EY" to control how the year number is formatted
  * The glibc.tune tunable namespace has been renamed to glibc.cpu and the
    tunable glibc.tune.cpu has been renamed to glibc.cpu.name
  * The type of the pr_uid and pr_gid members of struct elf_prpsinfo, defined
    in <sys/procfs.h>, has been corrected to match the type actually used by
    the Linux kernel
  * An archaic GNU extension to scanf, under which '%as', '%aS', and '%a[...]'
    meant to scan a string and allocate space for it with malloc, is now
    restricted to programs compiled in C89 or C++98 mode with _GNU_SOURCE
    defined
- unwind-ctor.patch, old-getdents64.patch, nss-files-leak.patch,
  riscv-feholdexcept-setround.patch,

OBS-URL: https://build.opensuse.org/request/show/670585
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=516
This commit is contained in:
Andreas Schwab 2019-02-01 13:45:56 +00:00 committed by Git OBS Bridge
parent c8985eb9db
commit add9e7bf61
22 changed files with 86 additions and 2155 deletions

View File

@ -506,20 +506,31 @@ Index: glibc-2.28/sysdeps/i386/i686/multiarch/wmemcmp.c
+libc_ifunc_redirected (__redirect_wmemcmp, __wmemcmp, IFUNC_SELECTOR ());
+weak_alias (__wmemcmp, wmemcmp)
#endif
Index: glibc-2.28/sysdeps/s390/multiarch/wmemcmp.c
Index: glibc-2.28/sysdeps/s390/wmemcmp.c
===================================================================
--- glibc-2.28.orig/sysdeps/s390/multiarch/wmemcmp.c
+++ glibc-2.28/sysdeps/s390/multiarch/wmemcmp.c
@@ -20,7 +20,8 @@
# include <wchar.h>
--- glibc-2.28.orig/sysdeps/s390/wmemcmp.c
+++ glibc-2.28/sysdeps/s390/wmemcmp.c
@@ -23,16 +23,17 @@
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp)
+s390_vx_libc_ifunc (__wmemcmp)
+weak_alias (__wmemcmp, wmemcmp)
# if HAVE_WMEMCMP_C
-extern __typeof (wmemcmp) WMEMCMP_C attribute_hidden;
+extern __typeof (__wmemcmp) WMEMCMP_C attribute_hidden;
# endif
#else
# include <wcsmbs/wmemcmp.c>
# if HAVE_WMEMCMP_Z13
-extern __typeof (wmemcmp) WMEMCMP_Z13 attribute_hidden;
+extern __typeof (__wmemcmp) WMEMCMP_Z13 attribute_hidden;
# endif
-s390_libc_ifunc_expr (wmemcmp, wmemcmp,
+s390_libc_ifunc_expr (__wmemcmp, __wmemcmp,
(HAVE_WMEMCMP_Z13 && (hwcap & HWCAP_S390_VX))
? WMEMCMP_Z13
: WMEMCMP_DEFAULT
)
+weak_alias (__wmemcmp, wmemcmp)
#endif
Index: glibc-2.28/sysdeps/x86_64/multiarch/wmemcmp.c
===================================================================
--- glibc-2.28.orig/sysdeps/x86_64/multiarch/wmemcmp.c

View File

@ -1,165 +0,0 @@
2018-09-20 Florian Weimer <fweimer@redhat.com>
* misc/tst-gethostid.c: New file.
* misc/Makefile [$(build-shared)] (tests): Add tst-gethostid.
(tst-gethostid): Link with -ldl.
2018-09-20 Mingli Yu <Mingli.Yu@windriver.com>
* sysdeps/unix/sysv/linux/gethostid.c (gethostid): Check for NULL
value from gethostbyname_r.
Index: glibc-2.28/misc/Makefile
===================================================================
--- glibc-2.28.orig/misc/Makefile
+++ glibc-2.28/misc/Makefile
@@ -86,6 +86,11 @@ tests := tst-dirname tst-tsearch tst-fds
tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
tst-preadvwritev2 tst-preadvwritev64v2
+# Tests which need libdl.
+ifeq (yes,$(build-shared))
+tests += tst-gethostid
+endif
+
tests-internal := tst-atomic tst-atomic-long tst-allocate_once
tests-static := tst-empty
@@ -145,3 +150,5 @@ tst-allocate_once-ENV = MALLOC_TRACE=$(o
$(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
$(evaluate-test)
+
+$(objpfx)tst-gethostid: $(libdl)
Index: glibc-2.28/misc/tst-gethostid.c
===================================================================
--- /dev/null
+++ glibc-2.28/misc/tst-gethostid.c
@@ -0,0 +1,108 @@
+/* Basic test for gethostid.
+ 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 <gnu/lib-names.h>
+#include <nss.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+/* Initial test is run outside a chroot, to increase the likelihood of
+ success. */
+static void
+outside_chroot (void *closure)
+{
+ long id = gethostid ();
+ printf ("info: host ID outside chroot: 0x%lx\n", id);
+}
+
+/* The same, but this time perform a chroot operation. */
+static void
+in_chroot (void *closure)
+{
+ const char *chroot_path = closure;
+ xchroot (chroot_path);
+ long id = gethostid ();
+ printf ("info: host ID in chroot: 0x%lx\n", id);
+}
+
+static int
+do_test (void)
+{
+ support_isolate_in_subprocess (outside_chroot, NULL);
+
+ /* Now run the test inside a chroot. */
+ support_become_root ();
+ if (!support_can_chroot ())
+ /* Cannot perform further tests. */
+ return 0;
+
+ /* Only use nss_files. */
+ __nss_configure_lookup ("hosts", "files");
+
+ /* Load the DSO outside of the chroot. */
+ xdlopen (LIBNSS_FILES_SO, RTLD_LAZY);
+
+ char *chroot_dir = support_create_temp_directory ("tst-gethostid-");
+ support_isolate_in_subprocess (in_chroot, chroot_dir);
+
+ /* Tests with /etc/hosts in the chroot. */
+ {
+ char *path = xasprintf ("%s/etc", chroot_dir);
+ add_temp_file (path);
+ xmkdir (path, 0777);
+ free (path);
+ path = xasprintf ("%s/etc/hosts", chroot_dir);
+ add_temp_file (path);
+
+ FILE *fp = xfopen (path, "w");
+ xfclose (fp);
+ printf ("info: chroot test with an empty /etc/hosts file\n");
+ support_isolate_in_subprocess (in_chroot, chroot_dir);
+
+ char hostname[1024];
+ int ret = gethostname (hostname, sizeof (hostname));
+ if (ret < 0)
+ printf ("warning: invalid result from gethostname: %d\n", ret);
+ else if (strlen (hostname) == 0)
+ puts ("warning: gethostname returned empty string");
+ else
+ {
+ printf ("info: chroot test with IPv6 address in /etc/hosts for: %s\n",
+ hostname);
+ fp = xfopen (path, "w");
+ /* Use an IPv6 address to induce another lookup failure. */
+ fprintf (fp, "2001:db8::1 %s\n", hostname);
+ xfclose (fp);
+ support_isolate_in_subprocess (in_chroot, chroot_dir);
+ }
+ free (path);
+ }
+ free (chroot_dir);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
Index: glibc-2.28/sysdeps/unix/sysv/linux/gethostid.c
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/gethostid.c
+++ glibc-2.28/sysdeps/unix/sysv/linux/gethostid.c
@@ -102,12 +102,12 @@ gethostid (void)
{
int ret = __gethostbyname_r (hostname, &hostbuf,
tmpbuf.data, tmpbuf.length, &hp, &herr);
- if (ret == 0)
+ if (ret == 0 && hp != NULL)
break;
else
{
/* Enlarge the buffer on ERANGE. */
- if (herr == NETDB_INTERNAL && errno == ERANGE)
+ if (ret != 0 && herr == NETDB_INTERNAL && errno == ERANGE)
{
if (!scratch_buffer_grow (&tmpbuf))
return 0;

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b1900051afad76f7a4f73e71413df4826dce085ef8ddb785a945b66d7d513082
size 16484344

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIcBAABAgAGBQJbYVUmAAoJEBZ5K06iU0D43VkP/19+lsSsDZ97QfojgE/lXgJU
5CmHV4Agjhf1MaFSbmDOwFjlMeU7TXkygQ7z9+E8oikRi69bGhFZjeUenr2mcWWi
FKaF4EVYIM+r4nXJJeZVBKgmFZdzjyqklH2P7/koKuqzMuC8zHX8fLYqDhwxpquO
lHGTR7ai5wFgBSfx/CflpAJ6ZVg9FCMA/GA2W9gJU9C3iyCux5LSrF2Oq035bQ0z
3WAHdjqTzLV8SI2B4XEadmjMseLk+AQwJ+xEa5eoZd5qF3TJVzOWRfSNEJC1jd9S
PonzLStU7u/YcDs33jiW+h4heXA8qK5grF6HaBvh8DBkzzJrMLRKBiprgRdt/UBq
jGSTVUlGDCs39QnnOedWOBxza/mmm24nE6cOE8eTq+OUvdwR9uY4ADrx3bCYNJ+N
B15JAkdfJguAYtqEFbXJL7j4ws18sjfphWbdQYZCUxgSZ9BRjrmPM1MFHlv7BDkx
u/gDEYyGZSVcYAAZ6WOdRD5mjTFpN9kx7qxMqCWL9O1L0UL6cIc2tN6ZI+zBI24m
60Nkh1R5zIepmsTxurYGm9vB+YqoR74N4gUz2LHMNRhZBCjGd4DYkriNOHlqLs1q
W72Bn1uDnWqyWaH59HjNyHEh38qiF+4yD8pJIV38+EUJiUROt1f26ZDgtcys1l+5
7mN5kVcGKT//Sim81yI5
=nbAu
-----END PGP SIGNATURE-----

3
glibc-2.29.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f3eeb8d57e25ca9fc13c2af3dae97754f9f643bc69229546828e3a240e2af04b
size 16515488

11
glibc-2.29.tar.xz.sig Normal file
View File

@ -0,0 +1,11 @@
-----BEGIN PGP SIGNATURE-----
iQEzBAABCAAdFiEEvHxzcmN+wQxX16plecQ9+/HPIYcFAlxTOTQACgkQecQ9+/HP
IYcW+Qf9EeusdF3KQfwpErbtSgoLwthbLWv93f9+r/XIa0oWvAeaU7DHeZf85px2
OLA0mG+p0D8JIBMXPX1oQUKLA+0mN7jdX9K29q2ibMYMDbHfTTfFhMdP3JDaixvx
XSAHOjvmLPteb1yix5hH0l7GhyWhV4n9GAMUdpOJ8Gbsof78i4eNdlLReQYqH/R7
frsmuFomNrpy+CMNGxEHpcTrUqkL7x78d/msgaQjDQi1eoqpTWmgzgCjvxv5HMPN
JKMwYTsgLk5cr51lHCDYbLE2ksn84yoMLJQz8dV7JH28EaBlgl1nss1aquX2zUGM
SDtYqhBBGB8d6ijv5x26NbyfFP6bvQ==
=Xdix
-----END PGP SIGNATURE-----

View File

@ -8,7 +8,7 @@ Index: glibc-2.27/csu/version.c
static const char banner[] =
-"GNU C Library "PKGVERSION RELEASE" release version "VERSION".\n\
+"GNU C Library "PKGVERSION RELEASE" release version "VERSION" (git "GITID").\n\
Copyright (C) 2018 Free Software Foundation, Inc.\n\
Copyright (C) 2019 Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
PARTICULAR PURPOSE.\n\

View File

@ -1,3 +1,42 @@
-------------------------------------------------------------------
Fri Feb 1 10:34:39 UTC 2019 - schwab@suse.de
- Update to glibc 2.29
* The getcpu wrapper function has been added, which returns the currently
used CPU and NUMA node
* Optimized generic exp, exp2, log, log2, pow, sinf, cosf, sincosf and tanf
* The reallocarray function is now declared under _DEFAULT_SOURCE, not just
for _GNU_SOURCE, to match BSD environments
* For powercp64le ABI, Transactional Lock Elision is now enabled iff kernel
indicates that it will abort the transaction prior to entering the kernel
(PPC_FEATURE2_HTM_NOSC on hwcap2)
* The functions posix_spawn_file_actions_addchdir_np and
posix_spawn_file_actions_addfchdir_np have been added, enabling
posix_spawn and posix_spawnp to run the new process in a different
directory
* The popen and system do not run atfork handlers anymore (BZ#17490)
* strftime's default formatting of a locale's alternative year (%Ey)
has been changed to zero-pad the year to a minimum of two digits,
like "%y"
* As a GNU extension, the '_' and '-' flags can now be applied to
"%EY" to control how the year number is formatted
* The glibc.tune tunable namespace has been renamed to glibc.cpu and the
tunable glibc.tune.cpu has been renamed to glibc.cpu.name
* The type of the pr_uid and pr_gid members of struct elf_prpsinfo, defined
in <sys/procfs.h>, has been corrected to match the type actually used by
the Linux kernel
* An archaic GNU extension to scanf, under which '%as', '%aS', and '%a[...]'
meant to scan a string and allocate space for it with malloc, is now
restricted to programs compiled in C89 or C++98 mode with _GNU_SOURCE
defined
- unwind-ctor.patch, old-getdents64.patch, nss-files-leak.patch,
riscv-feholdexcept-setround.patch,
pthread-cond-broadcast-waiters-after-spinning.patch,
regex-uninit-memory-access.patch, spawni-maybe-script-execute.patch,
gethostid-gethostbyname-failure.patch, strstr-huge-needle.patch,
pthread-mutex-lock-elision-race.patch, x86-haswell-string-flags.patch,
if-nametoindex-descr-leak.patch, riscv-flush-icache.patch: Removed
-------------------------------------------------------------------
Wed Jan 9 14:21:04 UTC 2019 - schwab@suse.de

View File

@ -63,6 +63,7 @@ BuildRequires: libcap-devel
BuildRequires: libselinux-devel
BuildRequires: makeinfo
BuildRequires: pwdutils
BuildRequires: python3-base
BuildRequires: systemd-rpm-macros
BuildRequires: systemtap-headers
BuildRequires: xz
@ -70,7 +71,8 @@ BuildRequires: xz
BuildRequires: gcc-c++
BuildRequires: gdb
BuildRequires: glibc-devel-static
BuildRequires: libidn2-0
# BZ #24113
#BuildRequires: libidn2-0
BuildRequires: libstdc++-devel
BuildRequires: python3-pexpect
%endif
@ -148,10 +150,10 @@ BuildArch: i686
%define enablekernel 4.15
%endif
Version: 2.28
Version: 2.29
Release: 0
%if !%{build_snapshot}
%define git_id 3c03baca37fd
%define git_id 56c86f5dd516
%define libversion %version
%else
%define git_id %(echo %version | sed 's/.*\.g//')
@ -268,32 +270,6 @@ Patch306: glibc-fix-double-loopback.diff
###
# Patches from upstream
###
# PATCH-FIX-UPSTREAM Add missing unwind information to ld.so on powerpc32 (BZ #23707)
Patch1000: unwind-ctor.patch
# PATCH-FIX-UPSTREAM Rewrite __old_getdents64 (BZ #23497)
Patch1001: old-getdents64.patch
# PATCH-FIX-UPSTREAM nss_files: Fix file stream leak in aliases lookup (BZ #23521)
Patch1002: nss-files-leak.patch
# PATCH-FIX-UPSTREAM RISC-V: Fix rounding save/restore bug
Patch1003: riscv-feholdexcept-setround.patch
# PATCH-FIX-UPSTREAM pthread_cond_broadcast: Fix waiters-after-spinning case (BZ #23538)
Patch1004: pthread-cond-broadcast-waiters-after-spinning.patch
# PATCH-FIX-UPSTREAM regex: fix uninitialized memory access (BZ #23578)
Patch1005: regex-uninit-memory-access.patch
# PATCH-FIX-UPSTREAM Fix segfault in maybe_script_execute
Patch1006: spawni-maybe-script-execute.patch
# PATCH-FIX-UPSTREAM Linux gethostid: Check for NULL value from gethostbyname_r (BZ #23679)
Patch1007: gethostid-gethostbyname-failure.patch
# PATCH-FIX-UPSTREAM Fix strstr bug with huge needles (BZ #23637)
Patch1008: strstr-huge-needle.patch
# PATCH-FIX-UPSTREAM Fix race in pthread_mutex_lock while promoting to PTHREAD_MUTEX_ELISION_NP (BZ #23275)
Patch1009: pthread-mutex-lock-elision-race.patch
# PATCH-FIX-UPSTREAM x86: Fix Haswell CPU string flags (BZ #23709)
Patch1010: x86-haswell-string-flags.patch
# PATCH-FIX-UPSTREAM if_nametoindex: Fix descriptor leak for overlong name (CVE-2018-19591, BZ #23927)
Patch1011: if-nametoindex-descr-leak.patch
# PATCH-FIX-UPSTREAM riscv: Use __has_include__ to include <asm/syscalls.h> (BZ #24022)
Patch1012: riscv-flush-icache.patch
###
# Patches awaiting upstream approval
@ -503,20 +479,6 @@ makedb: A program to create a database for nss
%patch304 -p1
%patch306 -p1
%patch1000 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch1004 -p1
%patch1005 -p1
%patch1006 -p1
%patch1007 -p1
%patch1008 -p1
%patch1009 -p1
%patch1010 -p1
%patch1011 -p1
%patch1012 -p1
%patch2000 -p1
%patch2004 -p1
%patch2005 -p1
@ -888,9 +850,9 @@ cc-base/elf/ldconfig -vn $destdir
# this will not work if we generate them in parallel.
# thus we need to run fdupes on /usr/lib/locale/
# Still, on my system this is a speed advantage:
# non-parallel build for install-locales: 9:34mins
# non-parallel build for install-locale-files: 9:34mins
# parallel build with fdupes: 7:08mins
make %{?_smp_mflags} install_root=%{buildroot} localedata/install-locales
make %{?_smp_mflags} install_root=%{buildroot} localedata/install-locale-files
# Avoid hardlinks across subpackages
mv %{buildroot}/usr/lib/locale/{en_US,C}.utf8 .
%fdupes %{buildroot}/usr/lib/locale

View File

@ -17,13 +17,12 @@ Index: glibc-2.27/iconv/Makefile
===================================================================
--- glibc-2.27.orig/iconv/Makefile
+++ glibc-2.27/iconv/Makefile
@@ -43,7 +43,8 @@ CFLAGS-charmap.c += -DCHARMAP_PATH='"$(i
CFLAGS-linereader.c += -DNO_TRANSLITERATION
@@ -44,7 +44,7 @@ CFLAGS-charmap.c += -DCHARMAP_PATH='"$(i
CFLAGS-simple-hash.c += -I../locale
-tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6
+tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 \
+ tst-iconv7
tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 \
- tst-iconv-mt
+ tst-iconv7 tst-iconv-mt
others = iconv_prog iconvconfig
install-others-programs = $(inst_bindir)/iconv

View File

@ -1,36 +0,0 @@
2018-11-27 Florian Weimer <fweimer@redhat.com>
[BZ #23927]
CVE-2018-19591
* sysdeps/unix/sysv/linux/if_index.c (__if_nametoindex): Avoid
descriptor leak in case of ENODEV error.
Index: glibc-2.28/sysdeps/unix/sysv/linux/if_index.c
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/if_index.c
+++ glibc-2.28/sysdeps/unix/sysv/linux/if_index.c
@@ -38,11 +38,6 @@ __if_nametoindex (const char *ifname)
return 0;
#else
struct ifreq ifr;
- int fd = __opensock ();
-
- if (fd < 0)
- return 0;
-
if (strlen (ifname) >= IFNAMSIZ)
{
__set_errno (ENODEV);
@@ -50,6 +45,12 @@ __if_nametoindex (const char *ifname)
}
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return 0;
+
if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
{
int saved_errno = errno;

View File

@ -1,307 +0,0 @@
2018-08-14 Florian Weimer <fweimer@redhat.com>
[BZ #23521]
[BZ #23522]
* nss/nss_files/files-alias.c (get_next_alias): During :include:
processing, bail out if no room, and close the stream before
returning ERANGE.
* nss/Makefile (tests): Add tst-nss-files-alias-leak.
(tst-nss-files-alias-leak): Link with libdl.
(tst-nss-files-alias-leak.out): Depend on nss_files.
* nss/tst-nss-files-alias-leak.c: New file.
Index: glibc-2.28/nss/Makefile
===================================================================
--- glibc-2.28.orig/nss/Makefile
+++ glibc-2.28/nss/Makefile
@@ -65,6 +65,7 @@ ifeq (yes,$(build-shared))
tests += tst-nss-files-hosts-erange
tests += tst-nss-files-hosts-multi
tests += tst-nss-files-hosts-getent
+tests += tst-nss-files-alias-leak
endif
# If we have a thread library then we can test cancellation against
@@ -171,3 +172,5 @@ endif
$(objpfx)tst-nss-files-hosts-erange: $(libdl)
$(objpfx)tst-nss-files-hosts-multi: $(libdl)
$(objpfx)tst-nss-files-hosts-getent: $(libdl)
+$(objpfx)tst-nss-files-alias-leak: $(libdl)
+$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
Index: glibc-2.28/nss/nss_files/files-alias.c
===================================================================
--- glibc-2.28.orig/nss/nss_files/files-alias.c
+++ glibc-2.28/nss/nss_files/files-alias.c
@@ -221,6 +221,13 @@ get_next_alias (FILE *stream, const char
{
while (! feof_unlocked (listfile))
{
+ if (room_left < 2)
+ {
+ free (old_line);
+ fclose (listfile);
+ goto no_more_room;
+ }
+
first_unused[room_left - 1] = '\xff';
line = fgets_unlocked (first_unused, room_left,
listfile);
@@ -229,6 +236,7 @@ get_next_alias (FILE *stream, const char
if (first_unused[room_left - 1] != '\xff')
{
free (old_line);
+ fclose (listfile);
goto no_more_room;
}
@@ -256,6 +264,7 @@ get_next_alias (FILE *stream, const char
+ __alignof__ (char *)))
{
free (old_line);
+ fclose (listfile);
goto no_more_room;
}
room_left -= ((first_unused - cp)
Index: glibc-2.28/nss/tst-nss-files-alias-leak.c
===================================================================
--- /dev/null
+++ glibc-2.28/nss/tst-nss-files-alias-leak.c
@@ -0,0 +1,237 @@
+/* Check for file descriptor leak in alias :include: processing (bug 23521).
+ 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 <aliases.h>
+#include <array_length.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gnu/lib-names.h>
+#include <nss.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+static struct support_chroot *chroot_env;
+
+/* Number of the aliases for the "many" user. This must be large
+ enough to trigger reallocation for the pointer array, but result in
+ answers below the maximum size tried in do_test. */
+enum { many_aliases = 30 };
+
+static void
+prepare (int argc, char **argv)
+{
+ chroot_env = support_chroot_create
+ ((struct support_chroot_configuration) { } );
+
+ char *path = xasprintf ("%s/etc/aliases", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string
+ (path,
+ "user1: :include:/etc/aliases.user1\n"
+ "user2: :include:/etc/aliases.user2\n"
+ "comment: comment1, :include:/etc/aliases.comment\n"
+ "many: :include:/etc/aliases.many\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.user1", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string (path, "alias1\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.user2", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string (path, "alias1a, alias2\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.comment", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string
+ (path,
+ /* The line must be longer than the line with the :include:
+ directive in /etc/aliases. */
+ "# Long line. ##############################################\n"
+ "comment2\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.many", chroot_env->path_chroot);
+ add_temp_file (path);
+ FILE *fp = xfopen (path, "w");
+ for (int i = 0; i < many_aliases; ++i)
+ fprintf (fp, "a%d\n", i);
+ TEST_VERIFY_EXIT (! ferror (fp));
+ xfclose (fp);
+ free (path);
+}
+
+/* The names of the users to test. */
+static const char *users[] = { "user1", "user2", "comment", "many" };
+
+static void
+check_aliases (int id, const struct aliasent *e)
+{
+ TEST_VERIFY_EXIT (id >= 0 || id < array_length (users));
+ const char *name = users[id];
+ TEST_COMPARE_BLOB (e->alias_name, strlen (e->alias_name),
+ name, strlen (name));
+
+ switch (id)
+ {
+ case 0:
+ TEST_COMPARE (e->alias_members_len, 1);
+ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+ "alias1", strlen ("alias1"));
+ break;
+
+ case 1:
+ TEST_COMPARE (e->alias_members_len, 2);
+ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+ "alias1a", strlen ("alias1a"));
+ TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
+ "alias2", strlen ("alias2"));
+ break;
+
+ case 2:
+ TEST_COMPARE (e->alias_members_len, 2);
+ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+ "comment1", strlen ("comment1"));
+ TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
+ "comment2", strlen ("comment2"));
+ break;
+
+ case 3:
+ TEST_COMPARE (e->alias_members_len, many_aliases);
+ for (int i = 0; i < e->alias_members_len; ++i)
+ {
+ char alias[30];
+ int len = snprintf (alias, sizeof (alias), "a%d", i);
+ TEST_VERIFY_EXIT (len > 0);
+ TEST_COMPARE_BLOB (e->alias_members[i], strlen (e->alias_members[i]),
+ alias, len);
+ }
+ break;
+ }
+}
+
+static int
+do_test (void)
+{
+ /* Make sure we don't try to load the module in the chroot. */
+ if (dlopen (LIBNSS_FILES_SO, RTLD_NOW) == NULL)
+ FAIL_EXIT1 ("could not load " LIBNSS_FILES_SO ": %s", dlerror ());
+
+ /* Some of these descriptors will become unavailable if there is a
+ file descriptor leak. 10 is chosen somewhat arbitrarily. The
+ array must be longer than the number of files opened by nss_files
+ at the same time (currently that number is 2). */
+ int next_descriptors[10];
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ {
+ next_descriptors[i] = dup (0);
+ TEST_VERIFY_EXIT (next_descriptors[i] > 0);
+ }
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ xclose (next_descriptors[i]);
+
+ support_become_root ();
+ if (!support_can_chroot ())
+ return EXIT_UNSUPPORTED;
+
+ __nss_configure_lookup ("aliases", "files");
+
+ xchroot (chroot_env->path_chroot);
+
+ /* Attempt various buffer sizes. If the operation succeeds, we
+ expect correct data. */
+ for (int id = 0; id < array_length (users); ++id)
+ {
+ bool found = false;
+ for (size_t size = 1; size <= 1000; ++size)
+ {
+ void *buffer = malloc (size);
+ struct aliasent result;
+ struct aliasent *res;
+ errno = EINVAL;
+ int ret = getaliasbyname_r (users[id], &result, buffer, size, &res);
+ if (ret == 0)
+ {
+ if (res != NULL)
+ {
+ found = true;
+ check_aliases (id, res);
+ }
+ else
+ {
+ support_record_failure ();
+ printf ("error: failed lookup for user \"%s\", size %zu\n",
+ users[id], size);
+ }
+ }
+ else if (ret != ERANGE)
+ {
+ support_record_failure ();
+ printf ("error: invalid return code %d (user \%s\", size %zu)\n",
+ ret, users[id], size);
+ }
+ free (buffer);
+
+ /* Make sure that we did not have a file descriptor leak. */
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ {
+ int new_fd = dup (0);
+ if (new_fd != next_descriptors[i])
+ {
+ support_record_failure ();
+ printf ("error: descriptor %d at index %zu leaked"
+ " (user \"%s\", size %zu)\n",
+ next_descriptors[i], i, users[id], size);
+
+ /* Close unexpected descriptor, the leak probing
+ descriptors, and the leaked descriptor
+ next_descriptors[i]. */
+ xclose (new_fd);
+ for (size_t j = 0; j <= i; ++j)
+ xclose (next_descriptors[j]);
+ goto next_size;
+ }
+ }
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ xclose (next_descriptors[i]);
+
+ next_size:
+ ;
+ }
+ if (!found)
+ {
+ support_record_failure ();
+ printf ("error: user %s not found\n", users[id]);
+ }
+ }
+
+ support_chroot_free (chroot_env);
+ return 0;
+}
+
+#define PREPARE prepare
+#include <support/test-driver.c>

View File

@ -1,249 +0,0 @@
2018-08-10 Florian Weimer <fweimer@redhat.com>
[BZ #23497]
* sysdeps/unix/sysv/linux/getdents64.c (handle_overflow): New
function.
(__old_getdents64): Use getdents64. Convert entries without
moving them.
* sysdeps/unix/sysv/linux/tst-readdir64-compat.c: New file.
* sysdeps/unix/sysv/linux/Makefile (tests-internal): Add
tst-readdir64-compat.
Index: glibc-2.28/sysdeps/unix/sysv/linux/Makefile
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/Makefile
+++ glibc-2.28/sysdeps/unix/sysv/linux/Makefile
@@ -161,6 +161,7 @@ inhibit-glue = yes
ifeq ($(subdir),dirent)
sysdep_routines += getdirentries getdirentries64
+tests-internal += tst-readdir64-compat
endif
ifeq ($(subdir),nis)
Index: glibc-2.28/sysdeps/unix/sysv/linux/getdents64.c
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/getdents64.c
+++ glibc-2.28/sysdeps/unix/sysv/linux/getdents64.c
@@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents)
# include <shlib-compat.h>
# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-# include <olddirent.h>
+# include <olddirent.h>
+# include <unistd.h>
-/* kernel definition of as of 3.2. */
-struct compat_linux_dirent
+static ssize_t
+handle_overflow (int fd, __off64_t offset, ssize_t count)
{
- /* Both d_ino and d_off are compat_ulong_t which are defined in all
- architectures as 'u32'. */
- uint32_t d_ino;
- uint32_t d_off;
- unsigned short d_reclen;
- char d_name[1];
-};
+ /* If this is the first entry in the buffer, we can report the
+ error. */
+ if (count == 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.. */
+ if (__lseek64 (fd, offset, SEEK_SET) != 0)
+ return -1;
+ return count;
+}
ssize_t
__old_getdents64 (int fd, char *buf, size_t nbytes)
{
- ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes);
+ /* We do not move the individual directory entries. This is only
+ possible if the target type (struct __old_dirent64) is smaller
+ than the source type. */
+ _Static_assert (offsetof (struct __old_dirent64, d_name)
+ <= offsetof (struct dirent64, d_name),
+ "__old_dirent64 is larger than dirent64");
+ _Static_assert (__alignof__ (struct __old_dirent64)
+ <= __alignof__ (struct dirent64),
+ "alignment of __old_dirent64 is larger than dirent64");
- /* The kernel added the d_type value after the name. Change this now. */
- if (retval != -1)
+ ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
+ if (retval > 0)
{
- union
- {
- struct compat_linux_dirent k;
- struct dirent u;
- } *kbuf = (void *) buf;
-
- while ((char *) kbuf < buf + retval)
+ char *p = buf;
+ char *end = buf + retval;
+ while (p < end)
{
- char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1);
- memmove (kbuf->u.d_name, kbuf->k.d_name,
- strlen (kbuf->k.d_name) + 1);
- kbuf->u.d_type = d_type;
+ struct dirent64 *source = (struct dirent64 *) p;
+
+ /* Copy out the fixed-size data. */
+ __ino_t ino = source->d_ino;
+ __off64_t offset = source->d_off;
+ unsigned int reclen = source->d_reclen;
+ unsigned char type = source->d_type;
+
+ /* Check for ino_t overflow. */
+ if (__glibc_unlikely (ino != source->d_ino))
+ return handle_overflow (fd, offset, p - buf);
+
+ /* Convert to the target layout. Use a separate struct and
+ memcpy to side-step aliasing issues. */
+ struct __old_dirent64 result;
+ result.d_ino = ino;
+ result.d_off = offset;
+ result.d_reclen = reclen;
+ result.d_type = type;
+
+ /* Write the fixed-sized part of the result to the
+ buffer. */
+ size_t result_name_offset = offsetof (struct __old_dirent64, d_name);
+ memcpy (p, &result, result_name_offset);
+
+ /* Adjust the position of the name if necessary. Copy
+ everything until the end of the record, including the
+ terminating NUL byte. */
+ if (result_name_offset != offsetof (struct dirent64, d_name))
+ memmove (p + result_name_offset, source->d_name,
+ reclen - offsetof (struct dirent64, d_name));
- kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen);
+ p += reclen;
}
}
return retval;
Index: glibc-2.28/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
===================================================================
--- /dev/null
+++ glibc-2.28/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
@@ -0,0 +1,111 @@
+/* Test readdir64 compatibility symbol.
+ 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 <dlfcn.h>
+#include <errno.h>
+#include <shlib-compat.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+
+/* Copied from <olddirent.h>. */
+struct __old_dirent64
+ {
+ __ino_t d_ino;
+ __off64_t d_off;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+ };
+
+typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *);
+
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
+struct __old_dirent64 *compat_readdir64 (DIR *);
+compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1);
+#endif
+
+static int
+do_test (void)
+{
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
+
+ /* Directory stream using the non-compat readdir64 symbol. The test
+ checks against this. */
+ DIR *dir_reference = opendir (".");
+ TEST_VERIFY_EXIT (dir_reference != NULL);
+ DIR *dir_test = opendir (".");
+ TEST_VERIFY_EXIT (dir_test != NULL);
+
+ /* This loop assumes that the enumeration order is consistent for
+ two different handles. Nothing should write to the current
+ directory (in the source tree) while this test runs, so there
+ should not be any difference due to races. */
+ size_t count = 0;
+ while (true)
+ {
+ errno = 0;
+ struct dirent64 *entry_reference = readdir64 (dir_reference);
+ if (entry_reference == NULL && errno != 0)
+ FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count);
+ struct __old_dirent64 *entry_test = compat_readdir64 (dir_test);
+ if (entry_reference == NULL)
+ {
+ if (errno == EOVERFLOW)
+ {
+ TEST_VERIFY (entry_reference->d_ino
+ != (__ino_t) entry_reference->d_ino);
+ printf ("info: inode number overflow at entry %zu\n", count);
+ break;
+ }
+ if (errno != 0)
+ FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count);
+ }
+
+ /* Check that both streams end at the same time. */
+ if (entry_reference == NULL)
+ {
+ TEST_VERIFY (entry_test == NULL);
+ break;
+ }
+ else
+ TEST_VERIFY_EXIT (entry_test != NULL);
+
+ /* Check that the entries are the same. */
+ TEST_COMPARE_BLOB (entry_reference->d_name,
+ strlen (entry_reference->d_name),
+ entry_test->d_name, strlen (entry_test->d_name));
+ TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino);
+ TEST_COMPARE (entry_reference->d_off, entry_test->d_off);
+ TEST_COMPARE (entry_reference->d_type, entry_test->d_type);
+ TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen);
+
+ ++count;
+ }
+ printf ("info: %zu directory entries found\n", count);
+ TEST_VERIFY (count >= 3); /* ".", "..", and some source files. */
+
+ TEST_COMPARE (closedir (dir_test), 0);
+ TEST_COMPARE (closedir (dir_reference), 0);
+#endif
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -1,27 +0,0 @@
2018-08-27 Martin Kuchta <martin.kuchta@netapp.com>
Torvald Riegel <triegel@redhat.com>
[BZ #23538]
* nptl/pthread_cond_common.c (__condvar_quiesce_and_switch_g1):
Update r to include the set wake-request flag if waiters are
remaining after spinning.
Index: glibc-2.28/nptl/pthread_cond_common.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_cond_common.c
+++ glibc-2.28/nptl/pthread_cond_common.c
@@ -405,8 +405,12 @@ __condvar_quiesce_and_switch_g1 (pthread
{
/* There is still a waiter after spinning. Set the wake-request
flag and block. Relaxed MO is fine because this is just about
- this futex word. */
- r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1);
+ this futex word.
+
+ Update r to include the set wake-request flag so that the upcoming
+ futex_wait only blocks if the flag is still set (otherwise, we'd
+ violate the basic client-side futex protocol). */
+ r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1;
if ((r >> 1) > 0)
futex_wait_simple (cond->__data.__g_refs + g1, r, private);

View File

@ -1,717 +0,0 @@
2018-10-17 Stefan Liebler <stli@linux.ibm.com>
[BZ #23275]
* nptl/tst-mutex10.c: New File.
* nptl/Makefile (tests): Add tst-mutex10.
(tst-mutex10-ENV): New variable.
* sysdeps/unix/sysv/linux/s390/force-elision.h: (FORCE_ELISION):
Ensure that elision path is used if elision is available.
* sysdeps/unix/sysv/linux/powerpc/force-elision.h (FORCE_ELISION):
Likewise.
* sysdeps/unix/sysv/linux/x86/force-elision.h: (FORCE_ELISION):
Likewise.
* nptl/pthreadP.h (PTHREAD_MUTEX_TYPE, PTHREAD_MUTEX_TYPE_ELISION)
(PTHREAD_MUTEX_PSHARED): Use atomic_load_relaxed.
* nptl/pthread_mutex_consistent.c (pthread_mutex_consistent): Likewise.
* nptl/pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling):
Likewise.
* nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full)
(__pthread_mutex_cond_lock_adjust): Likewise.
* nptl/pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling):
Likewise.
* nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Likewise.
* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise.
* nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise.
* sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s):
Add comments.
* nptl/pthread_mutex_destroy.c (__pthread_mutex_destroy):
Use atomic_load_relaxed and atomic_store_relaxed.
* nptl/pthread_mutex_init.c (__pthread_mutex_init):
Use atomic_store_relaxed.
Index: glibc-2.28/nptl/Makefile
===================================================================
--- glibc-2.28.orig/nptl/Makefile
+++ glibc-2.28/nptl/Makefile
@@ -241,9 +241,9 @@ LDLIBS-tst-minstack-throw = -lstdc++
tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
- tst-mutex7 tst-mutex9 tst-mutex5a tst-mutex7a tst-mutex7robust \
- tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
- tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
+ tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \
+ tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \
+ tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
tst-mutexpi9 \
tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
@@ -709,6 +709,8 @@ endif
$(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
+tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1
+
# The tests here better do not run in parallel
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
.NOTPARALLEL:
Index: glibc-2.28/nptl/pthreadP.h
===================================================================
--- glibc-2.28.orig/nptl/pthreadP.h
+++ glibc-2.28/nptl/pthreadP.h
@@ -110,19 +110,23 @@ enum
};
#define PTHREAD_MUTEX_PSHARED_BIT 128
+/* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
#define PTHREAD_MUTEX_TYPE(m) \
- ((m)->__data.__kind & 127)
+ (atomic_load_relaxed (&((m)->__data.__kind)) & 127)
/* Don't include NO_ELISION, as that type is always the same
as the underlying lock type. */
#define PTHREAD_MUTEX_TYPE_ELISION(m) \
- ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP))
+ (atomic_load_relaxed (&((m)->__data.__kind)) \
+ & (127 | PTHREAD_MUTEX_ELISION_NP))
#if LLL_PRIVATE == 0 && LLL_SHARED == 128
# define PTHREAD_MUTEX_PSHARED(m) \
- ((m)->__data.__kind & 128)
+ (atomic_load_relaxed (&((m)->__data.__kind)) & 128)
#else
# define PTHREAD_MUTEX_PSHARED(m) \
- (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE)
+ ((atomic_load_relaxed (&((m)->__data.__kind)) & 128) \
+ ? LLL_SHARED : LLL_PRIVATE)
#endif
/* The kernel when waking robust mutexes on exit never uses
Index: glibc-2.28/nptl/pthread_mutex_consistent.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_consistent.c
+++ glibc-2.28/nptl/pthread_mutex_consistent.c
@@ -23,8 +23,11 @@
int
pthread_mutex_consistent (pthread_mutex_t *mutex)
{
- /* Test whether this is a robust mutex with a dead owner. */
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+ /* Test whether this is a robust mutex with a dead owner.
+ See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
|| mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT)
return EINVAL;
Index: glibc-2.28/nptl/pthread_mutex_destroy.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_destroy.c
+++ glibc-2.28/nptl/pthread_mutex_destroy.c
@@ -27,12 +27,17 @@ __pthread_mutex_destroy (pthread_mutex_t
{
LIBC_PROBE (mutex_destroy, 1, mutex);
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
&& mutex->__data.__nusers != 0)
return EBUSY;
- /* Set to an invalid value. */
- mutex->__data.__kind = -1;
+ /* Set to an invalid value. Relaxed MO is enough as it is undefined behavior
+ if the mutex is used after it has been destroyed. But you can reinitialize
+ it with pthread_mutex_init. */
+ atomic_store_relaxed (&(mutex->__data.__kind), -1);
return 0;
}
Index: glibc-2.28/nptl/pthread_mutex_getprioceiling.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_getprioceiling.c
+++ glibc-2.28/nptl/pthread_mutex_getprioceiling.c
@@ -24,7 +24,9 @@
int
pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling)
{
- if (__builtin_expect ((mutex->__data.__kind
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if (__builtin_expect ((atomic_load_relaxed (&(mutex->__data.__kind))
& PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0, 0))
return EINVAL;
Index: glibc-2.28/nptl/pthread_mutex_init.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_init.c
+++ glibc-2.28/nptl/pthread_mutex_init.c
@@ -101,7 +101,7 @@ __pthread_mutex_init (pthread_mutex_t *m
memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T);
/* Copy the values from the attribute. */
- mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
+ int mutex_kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0)
{
@@ -111,17 +111,17 @@ __pthread_mutex_init (pthread_mutex_t *m
return ENOTSUP;
#endif
- mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ mutex_kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
}
switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
{
case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
+ mutex_kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
break;
case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
+ mutex_kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
int ceiling = (imutexattr->mutexkind
& PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
@@ -145,7 +145,11 @@ __pthread_mutex_init (pthread_mutex_t *m
FUTEX_PRIVATE_FLAG FUTEX_WAKE. */
if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED
| PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0)
- mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT;
+ mutex_kind |= PTHREAD_MUTEX_PSHARED_BIT;
+
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ atomic_store_relaxed (&(mutex->__data.__kind), mutex_kind);
/* Default values: mutex not used yet. */
// mutex->__count = 0; already done by memset
Index: glibc-2.28/nptl/pthread_mutex_lock.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_lock.c
+++ glibc-2.28/nptl/pthread_mutex_lock.c
@@ -62,6 +62,8 @@ static int __pthread_mutex_lock_full (pt
int
__pthread_mutex_lock (pthread_mutex_t *mutex)
{
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
LIBC_PROBE (mutex_entry, 1, mutex);
@@ -350,8 +352,14 @@ __pthread_mutex_lock_full (pthread_mutex
case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ int kind, robust;
+ {
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ }
if (robust)
{
@@ -502,7 +510,10 @@ __pthread_mutex_lock_full (pthread_mutex
case PTHREAD_MUTEX_PP_NORMAL_NP:
case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int kind = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_KIND_MASK_NP;
oldval = mutex->__data.__lock;
@@ -607,15 +618,18 @@ hidden_def (__pthread_mutex_lock)
void
__pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex)
{
- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
- assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ assert ((mutex_kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
+ assert ((mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
+ assert ((mutex_kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
/* Record the ownership. */
pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
mutex->__data.__owner = id;
- if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
+ if (mutex_kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
++mutex->__data.__count;
}
#endif
Index: glibc-2.28/nptl/pthread_mutex_setprioceiling.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_setprioceiling.c
+++ glibc-2.28/nptl/pthread_mutex_setprioceiling.c
@@ -27,9 +27,10 @@ int
pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
int *old_ceiling)
{
- /* The low bits of __kind aren't ever changed after pthread_mutex_init,
- so we don't need a lock yet. */
- if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
return EINVAL;
/* See __init_sched_fifo_prio. */
Index: glibc-2.28/nptl/pthread_mutex_timedlock.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_timedlock.c
+++ glibc-2.28/nptl/pthread_mutex_timedlock.c
@@ -53,6 +53,8 @@ __pthread_mutex_timedlock (pthread_mutex
/* We must not check ABSTIME here. If the thread does not block
abstime must not be checked for a valid value. */
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex),
PTHREAD_MUTEX_TIMED_NP))
{
@@ -338,8 +340,14 @@ __pthread_mutex_timedlock (pthread_mutex
case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ int kind, robust;
+ {
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ }
if (robust)
{
@@ -509,7 +517,10 @@ __pthread_mutex_timedlock (pthread_mutex
case PTHREAD_MUTEX_PP_NORMAL_NP:
case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int kind = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_KIND_MASK_NP;
oldval = mutex->__data.__lock;
Index: glibc-2.28/nptl/pthread_mutex_trylock.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_trylock.c
+++ glibc-2.28/nptl/pthread_mutex_trylock.c
@@ -36,6 +36,8 @@ __pthread_mutex_trylock (pthread_mutex_t
int oldval;
pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex),
PTHREAD_MUTEX_TIMED_NP))
{
@@ -199,8 +201,14 @@ __pthread_mutex_trylock (pthread_mutex_t
case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ int kind, robust;
+ {
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ }
if (robust)
/* Note: robust PI futexes are signaled by setting bit 0. */
@@ -325,7 +333,10 @@ __pthread_mutex_trylock (pthread_mutex_t
case PTHREAD_MUTEX_PP_NORMAL_NP:
case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int kind = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_KIND_MASK_NP;
oldval = mutex->__data.__lock;
Index: glibc-2.28/nptl/pthread_mutex_unlock.c
===================================================================
--- glibc-2.28.orig/nptl/pthread_mutex_unlock.c
+++ glibc-2.28/nptl/pthread_mutex_unlock.c
@@ -35,6 +35,8 @@ int
attribute_hidden
__pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr)
{
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
if (__builtin_expect (type &
~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0))
@@ -222,13 +224,19 @@ __pthread_mutex_unlock_full (pthread_mut
/* If the previous owner died and the caller did not succeed in
making the state consistent, mark the mutex as unrecoverable
and make all waiters. */
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
&& __builtin_expect (mutex->__data.__owner
== PTHREAD_MUTEX_INCONSISTENT, 0))
pi_notrecoverable:
newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
{
continue_pi_robust:
/* Remove mutex from the list.
@@ -251,7 +259,10 @@ __pthread_mutex_unlock_full (pthread_mut
/* Unlock. Load all necessary mutex data before releasing the mutex
to not violate the mutex destruction requirements (see
lll_unlock). */
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int robust = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
private = (robust
? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
: PTHREAD_MUTEX_PSHARED (mutex));
Index: glibc-2.28/nptl/tst-mutex10.c
===================================================================
--- /dev/null
+++ glibc-2.28/nptl/tst-mutex10.c
@@ -0,0 +1,109 @@
+/* Testing race while enabling lock elision.
+ 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 <stdint.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <support/support.h>
+#include <support/xthread.h>
+
+static pthread_barrier_t barrier;
+static pthread_mutex_t mutex;
+static long long int iteration_count = 1000000;
+static unsigned int thread_count = 3;
+
+static void *
+thr_func (void *arg)
+{
+ long long int i;
+ for (i = 0; i < iteration_count; i++)
+ {
+ if ((uintptr_t) arg == 0)
+ {
+ xpthread_mutex_destroy (&mutex);
+ xpthread_mutex_init (&mutex, NULL);
+ }
+
+ xpthread_barrier_wait (&barrier);
+
+ /* Test if enabling lock elision works if it is enabled concurrently.
+ There was a race in FORCE_ELISION macro which leads to either
+ pthread_mutex_destroy returning EBUSY as the owner was recorded
+ by pthread_mutex_lock - in "normal mutex" code path - but was not
+ resetted in pthread_mutex_unlock - in "elision" code path.
+ Or it leads to the assertion in nptl/pthread_mutex_lock.c:
+ assert (mutex->__data.__owner == 0);
+ Please ensure that the test is run with lock elision:
+ export GLIBC_TUNABLES=glibc.elision.enable=1 */
+ xpthread_mutex_lock (&mutex);
+ xpthread_mutex_unlock (&mutex);
+
+ xpthread_barrier_wait (&barrier);
+ }
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ unsigned int i;
+ printf ("Starting %d threads to run %lld iterations.\n",
+ thread_count, iteration_count);
+
+ pthread_t *threads = xmalloc (thread_count * sizeof (pthread_t));
+ xpthread_barrier_init (&barrier, NULL, thread_count);
+ xpthread_mutex_init (&mutex, NULL);
+
+ for (i = 0; i < thread_count; i++)
+ threads[i] = xpthread_create (NULL, thr_func, (void *) (uintptr_t) i);
+
+ for (i = 0; i < thread_count; i++)
+ xpthread_join (threads[i]);
+
+ xpthread_barrier_destroy (&barrier);
+ free (threads);
+
+ return EXIT_SUCCESS;
+}
+
+#define OPT_ITERATIONS 10000
+#define OPT_THREADS 10001
+#define CMDLINE_OPTIONS \
+ { "iterations", required_argument, NULL, OPT_ITERATIONS }, \
+ { "threads", required_argument, NULL, OPT_THREADS },
+static void
+cmdline_process (int c)
+{
+ long long int arg = strtoll (optarg, NULL, 0);
+ switch (c)
+ {
+ case OPT_ITERATIONS:
+ if (arg > 0)
+ iteration_count = arg;
+ break;
+ case OPT_THREADS:
+ if (arg > 0 && arg < 100)
+ thread_count = arg;
+ break;
+ }
+}
+#define CMDLINE_PROCESS cmdline_process
+#define TIMEOUT 50
+#include <support/test-driver.c>
Index: glibc-2.28/sysdeps/nptl/bits/thread-shared-types.h
===================================================================
--- glibc-2.28.orig/sysdeps/nptl/bits/thread-shared-types.h
+++ glibc-2.28/sysdeps/nptl/bits/thread-shared-types.h
@@ -124,7 +124,27 @@ struct __pthread_mutex_s
unsigned int __nusers;
#endif
/* KIND must stay at this position in the structure to maintain
- binary compatibility with static initializers. */
+ binary compatibility with static initializers.
+
+ Concurrency notes:
+ The __kind of a mutex is initialized either by the static
+ PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init.
+
+ After a mutex has been initialized, the __kind of a mutex is usually not
+ changed. BUT it can be set to -1 in pthread_mutex_destroy or elision can
+ be enabled. This is done concurrently in the pthread_mutex_*lock functions
+ by using the macro FORCE_ELISION. This macro is only defined for
+ architectures which supports lock elision.
+
+ For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
+ PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set
+ type of a mutex.
+ Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set
+ with pthread_mutexattr_settype.
+ After a mutex has been initialized, the functions pthread_mutex_*lock can
+ enable elision - if the mutex-type and the machine supports it - by setting
+ the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards
+ the lock / unlock functions are using specific elision code-paths. */
int __kind;
__PTHREAD_COMPAT_PADDING_MID
#if __PTHREAD_MUTEX_NUSERS_AFTER_KIND
Index: glibc-2.28/sysdeps/unix/sysv/linux/powerpc/force-elision.h
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/powerpc/force-elision.h
+++ glibc-2.28/sysdeps/unix/sysv/linux/powerpc/force-elision.h
@@ -18,9 +18,45 @@
/* Automatically enable elision for existing user lock kinds. */
#define FORCE_ELISION(m, s) \
- if (__pthread_force_elision \
- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ if (__pthread_force_elision) \
{ \
- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
- s; \
+ /* See concurrency notes regarding __kind in \
+ struct __pthread_mutex_s in \
+ sysdeps/nptl/bits/thread-shared-types.h. \
+ \
+ There are the following cases for the kind of a mutex \
+ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \
+ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \
+ only one of both flags can be set): \
+ - both flags are not set: \
+ This is the first lock operation for this mutex. Enable \
+ elision as it is not enabled so far. \
+ Note: It can happen that multiple threads are calling e.g. \
+ pthread_mutex_lock at the same time as the first lock \
+ operation for this mutex. Then elision is enabled for this \
+ mutex by multiple threads. Storing with relaxed MO is enough \
+ as all threads will store the same new value for the kind of \
+ the mutex. But we have to ensure that we always use the \
+ elision path regardless if this thread has enabled elision or \
+ another one. \
+ \
+ - PTHREAD_MUTEX_ELISION_NP flag is set: \
+ Elision was already enabled for this mutex by a previous lock \
+ operation. See case above. Just use the elision path. \
+ \
+ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \
+ Elision was explicitly disabled by pthread_mutexattr_settype. \
+ Do not use the elision path. \
+ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \
+ changed after mutex initialization. */ \
+ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ { \
+ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \
+ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \
+ } \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \
+ { \
+ s; \
+ } \
}
Index: glibc-2.28/sysdeps/unix/sysv/linux/s390/force-elision.h
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/s390/force-elision.h
+++ glibc-2.28/sysdeps/unix/sysv/linux/s390/force-elision.h
@@ -18,9 +18,45 @@
/* Automatically enable elision for existing user lock kinds. */
#define FORCE_ELISION(m, s) \
- if (__pthread_force_elision \
- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ if (__pthread_force_elision) \
{ \
- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
- s; \
+ /* See concurrency notes regarding __kind in \
+ struct __pthread_mutex_s in \
+ sysdeps/nptl/bits/thread-shared-types.h. \
+ \
+ There are the following cases for the kind of a mutex \
+ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \
+ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \
+ only one of both flags can be set): \
+ - both flags are not set: \
+ This is the first lock operation for this mutex. Enable \
+ elision as it is not enabled so far. \
+ Note: It can happen that multiple threads are calling e.g. \
+ pthread_mutex_lock at the same time as the first lock \
+ operation for this mutex. Then elision is enabled for this \
+ mutex by multiple threads. Storing with relaxed MO is enough \
+ as all threads will store the same new value for the kind of \
+ the mutex. But we have to ensure that we always use the \
+ elision path regardless if this thread has enabled elision or \
+ another one. \
+ \
+ - PTHREAD_MUTEX_ELISION_NP flag is set: \
+ Elision was already enabled for this mutex by a previous lock \
+ operation. See case above. Just use the elision path. \
+ \
+ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \
+ Elision was explicitly disabled by pthread_mutexattr_settype. \
+ Do not use the elision path. \
+ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \
+ changed after mutex initialization. */ \
+ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ { \
+ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \
+ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \
+ } \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \
+ { \
+ s; \
+ } \
}
Index: glibc-2.28/sysdeps/unix/sysv/linux/x86/force-elision.h
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/x86/force-elision.h
+++ glibc-2.28/sysdeps/unix/sysv/linux/x86/force-elision.h
@@ -18,9 +18,45 @@
/* Automatically enable elision for existing user lock kinds. */
#define FORCE_ELISION(m, s) \
- if (__pthread_force_elision \
- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ if (__pthread_force_elision) \
{ \
- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
- s; \
+ /* See concurrency notes regarding __kind in \
+ struct __pthread_mutex_s in \
+ sysdeps/nptl/bits/thread-shared-types.h. \
+ \
+ There are the following cases for the kind of a mutex \
+ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \
+ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \
+ only one of both flags can be set): \
+ - both flags are not set: \
+ This is the first lock operation for this mutex. Enable \
+ elision as it is not enabled so far. \
+ Note: It can happen that multiple threads are calling e.g. \
+ pthread_mutex_lock at the same time as the first lock \
+ operation for this mutex. Then elision is enabled for this \
+ mutex by multiple threads. Storing with relaxed MO is enough \
+ as all threads will store the same new value for the kind of \
+ the mutex. But we have to ensure that we always use the \
+ elision path regardless if this thread has enabled elision or \
+ another one. \
+ \
+ - PTHREAD_MUTEX_ELISION_NP flag is set: \
+ Elision was already enabled for this mutex by a previous lock \
+ operation. See case above. Just use the elision path. \
+ \
+ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \
+ Elision was explicitly disabled by pthread_mutexattr_settype. \
+ Do not use the elision path. \
+ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \
+ changed after mutex initialization. */ \
+ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ { \
+ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \
+ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \
+ } \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \
+ { \
+ s; \
+ } \
}

View File

@ -1,261 +0,0 @@
2018-08-28 Florian Weimer <fweimer@redhat.com>
[BZ #23578]
* posix/tst-regcomp-truncated.c: New file.
* posix/Makefile (tests): Add it.
(tst-regcomp-truncated.out): Depend on generated locales.
2018-08-25 Paul Eggert <eggert@cs.ucla.edu>
[BZ #23578]
regex: fix uninitialized memory access
I introduced this bug into gnulib in commit
8335a4d6c7b4448cd0bcb6d0bebf1d456bcfdb17 dated 2006-04-10;
eventually it was merged into glibc. The bug was found by
project-repo <bugs@feusi.co> and reported here:
https://lists.gnu.org/r/sed-devel/2018-08/msg00017.html
Diagnosis and draft fix reported by Assaf Gordon here:
https://lists.gnu.org/r/bug-gnulib/2018-08/msg00071.html
https://lists.gnu.org/r/bug-gnulib/2018-08/msg00142.html
* posix/regex_internal.c (build_wcs_upper_buffer):
Fix bug when mbrtowc returns 0.
Index: glibc-2.28/posix/Makefile
===================================================================
--- glibc-2.28.orig/posix/Makefile
+++ glibc-2.28/posix/Makefile
@@ -96,7 +96,7 @@ tests := test-errno tstgetopt testfnm r
tst-posix_fadvise tst-posix_fadvise64 \
tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
- bug-regex38
+ bug-regex38 tst-regcomp-truncated
tests-internal := bug-regex5 bug-regex20 bug-regex33 \
tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
tst-glob_lstat_compat tst-spawn4-compat
@@ -194,6 +194,7 @@ $(objpfx)tst-regex2.out: $(gen-locales)
$(objpfx)tst-regexloc.out: $(gen-locales)
$(objpfx)tst-rxspencer.out: $(gen-locales)
$(objpfx)tst-rxspencer-no-utf8.out: $(gen-locales)
+$(objpfx)tst-regcomp-truncated.out: $(gen-locales)
endif
# If we will use the generic uname implementation, we must figure out what
Index: glibc-2.28/posix/regex_internal.c
===================================================================
--- glibc-2.28.orig/posix/regex_internal.c
+++ glibc-2.28/posix/regex_internal.c
@@ -317,7 +317,7 @@ build_wcs_upper_buffer (re_string_t *pst
mbclen = __mbrtowc (&wc,
((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+ byte_idx), remain_len, &pstr->cur_state);
- if (BE (mbclen < (size_t) -2, 1))
+ if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
{
wchar_t wcu = __towupper (wc);
if (wcu != wc)
@@ -386,7 +386,7 @@ build_wcs_upper_buffer (re_string_t *pst
else
p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
- if (BE (mbclen < (size_t) -2, 1))
+ if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
{
wchar_t wcu = __towupper (wc);
if (wcu != wc)
Index: glibc-2.28/posix/tst-regcomp-truncated.c
===================================================================
--- /dev/null
+++ glibc-2.28/posix/tst-regcomp-truncated.c
@@ -0,0 +1,191 @@
+/* Test compilation of truncated regular expressions.
+ 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 constructs various patterns in an attempt to trigger
+ over-reading the regular expression compiler, such as bug
+ 23578. */
+
+#include <array_length.h>
+#include <errno.h>
+#include <locale.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/next_to_fault.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <wchar.h>
+
+/* Locales to test. */
+static const char locales[][17] =
+ {
+ "C",
+ "en_US.UTF-8",
+ "de_DE.ISO-8859-1",
+ };
+
+/* Syntax options. Will be combined with other flags. */
+static const reg_syntax_t syntaxes[] =
+ {
+ RE_SYNTAX_EMACS,
+ RE_SYNTAX_AWK,
+ RE_SYNTAX_GNU_AWK,
+ RE_SYNTAX_POSIX_AWK,
+ RE_SYNTAX_GREP,
+ RE_SYNTAX_EGREP,
+ RE_SYNTAX_POSIX_EGREP,
+ RE_SYNTAX_POSIX_BASIC,
+ RE_SYNTAX_POSIX_EXTENDED,
+ RE_SYNTAX_POSIX_MINIMAL_EXTENDED,
+ };
+
+/* Trailing characters placed after the initial character. */
+static const char trailing_strings[][4] =
+ {
+ "",
+ "[",
+ "\\",
+ "[\\",
+ "(",
+ "(\\",
+ "\\(",
+ };
+
+static int
+do_test (void)
+{
+ /* Staging buffer for the constructed regular expression. */
+ char buffer[16];
+
+ /* Allocation used to detect over-reading by the regular expression
+ compiler. */
+ struct support_next_to_fault ntf
+ = support_next_to_fault_allocate (sizeof (buffer));
+
+ /* Arbitrary Unicode codepoint at which we stop generating
+ characters. We do not probe the whole range because that would
+ take too long due to combinatorical exploision as the result of
+ combination with other flags. */
+ static const wchar_t last_character = 0xfff;
+
+ for (size_t locale_idx = 0; locale_idx < array_length (locales);
+ ++ locale_idx)
+ {
+ if (setlocale (LC_ALL, locales[locale_idx]) == NULL)
+ {
+ support_record_failure ();
+ printf ("error: setlocale (\"%s\"): %m", locales[locale_idx]);
+ continue;
+ }
+ if (test_verbose > 0)
+ printf ("info: testing locale \"%s\"\n", locales[locale_idx]);
+
+ for (wchar_t wc = 0; wc <= last_character; ++wc)
+ {
+ char *after_wc;
+ if (wc == 0)
+ {
+ /* wcrtomb treats L'\0' in a special way. */
+ *buffer = '\0';
+ after_wc = &buffer[1];
+ }
+ else
+ {
+ mbstate_t ps = { };
+ size_t ret = wcrtomb (buffer, wc, &ps);
+ if (ret == (size_t) -1)
+ {
+ /* EILSEQ means that the target character set
+ cannot encode the character. */
+ if (errno != EILSEQ)
+ {
+ support_record_failure ();
+ printf ("error: wcrtomb (0x%x) failed: %m\n",
+ (unsigned) wc);
+ }
+ continue;
+ }
+ TEST_VERIFY_EXIT (ret != 0);
+ after_wc = &buffer[ret];
+ }
+
+ for (size_t trailing_idx = 0;
+ trailing_idx < array_length (trailing_strings);
+ ++trailing_idx)
+ {
+ char *after_trailing
+ = stpcpy (after_wc, trailing_strings[trailing_idx]);
+
+ for (int do_nul = 0; do_nul < 2; ++do_nul)
+ {
+ char *after_nul;
+ if (do_nul)
+ {
+ *after_trailing = '\0';
+ after_nul = &after_trailing[1];
+ }
+ else
+ after_nul = after_trailing;
+
+ size_t length = after_nul - buffer;
+
+ /* Make sure that the faulting region starts
+ after the used portion of the buffer. */
+ char *ntf_start = ntf.buffer + sizeof (buffer) - length;
+ memcpy (ntf_start, buffer, length);
+
+ for (const reg_syntax_t *psyntax = syntaxes;
+ psyntax < array_end (syntaxes); ++psyntax)
+ for (int do_icase = 0; do_icase < 2; ++do_icase)
+ {
+ re_syntax_options = *psyntax;
+ if (do_icase)
+ re_syntax_options |= RE_ICASE;
+
+ regex_t reg;
+ memset (&reg, 0, sizeof (reg));
+ const char *msg = re_compile_pattern
+ (ntf_start, length, &reg);
+ if (msg != NULL)
+ {
+ if (test_verbose > 0)
+ {
+ char *quoted = support_quote_blob
+ (buffer, length);
+ printf ("info: compilation failed for pattern"
+ " \"%s\", syntax 0x%lx: %s\n",
+ quoted, re_syntax_options, msg);
+ free (quoted);
+ }
+ }
+ else
+ regfree (&reg);
+ }
+ }
+ }
+ }
+ }
+
+ support_next_to_fault_free (&ntf);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -1,19 +0,0 @@
2018-08-03 DJ Delorie <dj@redhat.com>
* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
Move libc_fesetround_riscv after libc_feholdexcept_riscv.
Index: glibc-2.28/sysdeps/riscv/rvf/math_private.h
===================================================================
--- glibc-2.28.orig/sysdeps/riscv/rvf/math_private.h
+++ glibc-2.28/sysdeps/riscv/rvf/math_private.h
@@ -72,8 +72,8 @@ libc_fesetround_riscv (int round)
static __always_inline void
libc_feholdexcept_setround_riscv (fenv_t *envp, int round)
{
- libc_fesetround_riscv (round);
libc_feholdexcept_riscv (envp);
+ libc_fesetround_riscv (round);
}
#define libc_feholdexcept_setround libc_feholdexcept_setround_riscv

View File

@ -1,26 +0,0 @@
2018-12-31 H.J. Lu <hongjiu.lu@intel.com>
[BZ #24022]
* sysdeps/unix/sysv/linux/riscv/flush-icache.c: Check if
<asm/syscalls.h> exists with __has_include__ before including it.
diff --git a/sysdeps/unix/sysv/linux/riscv/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
index d612ef4c6c..0b2042620b 100644
--- a/sysdeps/unix/sysv/linux/riscv/flush-icache.c
+++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
@@ -21,7 +21,11 @@
#include <stdlib.h>
#include <atomic.h>
#include <sys/cachectl.h>
-#include <asm/syscalls.h>
+#if __has_include__ (<asm/syscalls.h>)
+# include <asm/syscalls.h>
+#else
+# include <asm/unistd.h>
+#endif
typedef int (*func_type) (void *, void *, unsigned long int);
--
2.20.1

View File

@ -1,18 +0,0 @@
2018-09-06 Stefan Liebler <stli@linux.ibm.com>
* sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
Increment size of new_argv by one.
Index: glibc-2.28/sysdeps/unix/sysv/linux/spawni.c
===================================================================
--- glibc-2.28.orig/sysdeps/unix/sysv/linux/spawni.c
+++ glibc-2.28/sysdeps/unix/sysv/linux/spawni.c
@@ -101,7 +101,7 @@ maybe_script_execute (struct posix_spawn
ptrdiff_t argc = args->argc;
/* Construct an argument list for the shell. */
- char *new_argv[argc + 1];
+ char *new_argv[argc + 2];
new_argv[0] = (char *) _PATH_BSHELL;
new_argv[1] = (char *) args->file;
if (argc > 1)

View File

@ -1,95 +0,0 @@
2018-09-19 Wilco Dijkstra <wdijkstr@arm.com>
[BZ #23637]
* string/test-strstr.c (pr23637): New function.
(test_main): Add tests with longer needles.
* string/strcasestr.c (AVAILABLE): Fix readahead distance.
* string/strstr.c (AVAILABLE): Likewise.
Index: glibc-2.28/string/strcasestr.c
===================================================================
--- glibc-2.28.orig/string/strcasestr.c
+++ glibc-2.28/string/strcasestr.c
@@ -37,8 +37,9 @@
/* Two-Way algorithm. */
#define RETURN_TYPE char *
#define AVAILABLE(h, h_l, j, n_l) \
- (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
- (j) + (n_l) <= (h_l)))
+ (((j) + (n_l) <= (h_l)) \
+ || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
+ (j) + (n_l) <= (h_l)))
#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
#define CANON_ELEMENT(c) TOLOWER (c)
Index: glibc-2.28/string/strstr.c
===================================================================
--- glibc-2.28.orig/string/strstr.c
+++ glibc-2.28/string/strstr.c
@@ -33,8 +33,9 @@
#define RETURN_TYPE char *
#define AVAILABLE(h, h_l, j, n_l) \
- (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
- (j) + (n_l) <= (h_l)))
+ (((j) + (n_l) <= (h_l)) \
+ || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
+ (j) + (n_l) <= (h_l)))
#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
#define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C))
Index: glibc-2.28/string/test-strstr.c
===================================================================
--- glibc-2.28.orig/string/test-strstr.c
+++ glibc-2.28/string/test-strstr.c
@@ -151,6 +151,32 @@ check2 (void)
}
}
+#define N 1024
+
+static void
+pr23637 (void)
+{
+ char *h = (char*) buf1;
+ char *n = (char*) buf2;
+
+ for (int i = 0; i < N; i++)
+ {
+ n[i] = 'x';
+ h[i] = ' ';
+ h[i + N] = 'x';
+ }
+
+ n[N] = '\0';
+ h[N * 2] = '\0';
+
+ /* Ensure we don't match at the first 'x'. */
+ h[0] = 'x';
+
+ char *exp_result = stupid_strstr (h, n);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, h, n, exp_result);
+}
+
static int
test_main (void)
{
@@ -158,6 +184,7 @@ test_main (void)
check1 ();
check2 ();
+ pr23637 ();
printf ("%23s", "");
FOR_EACH_IMPL (impl, 0)
@@ -202,6 +229,9 @@ test_main (void)
do_test (15, 9, hlen, klen, 1);
do_test (15, 15, hlen, klen, 0);
do_test (15, 15, hlen, klen, 1);
+
+ do_test (15, 15, hlen + klen * 4, klen * 4, 0);
+ do_test (15, 15, hlen + klen * 4, klen * 4, 1);
}
do_test (0, 0, page_size - 1, 16, 0);

View File

@ -1,131 +0,0 @@
2018-09-26 Andreas Schwab <schwab@suse.de>
[BZ #23707]
* sysdeps/powerpc/powerpc32/dl-start.S: Add unwind information.
* elf/Makefile (tests): Add tst-unwind-ctor.
(modules-names): Add tst-unwind-ctor-lib.
($(objpfx)tst-unwind-ctor): Depend on
$(objpfx)tst-unwind-ctor-lib.so.
Index: glibc-2.28/elf/Makefile
===================================================================
--- glibc-2.28.orig/elf/Makefile
+++ glibc-2.28/elf/Makefile
@@ -186,7 +186,8 @@ tests += restest1 preloadtest loadfail m
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-ctor
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -273,7 +274,7 @@ modules-names = testobj1 testobj2 testob
tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \
- tst-absolute-zero-lib tst-big-note-lib
+ tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib
ifeq (yes,$(have-mtls-dialect-gnu2))
tests += tst-gnu2-tls1
@@ -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
+
+$(objpfx)tst-unwind-ctor: $(objpfx)tst-unwind-ctor-lib.so
Index: glibc-2.28/elf/tst-unwind-ctor-lib.c
===================================================================
--- /dev/null
+++ glibc-2.28/elf/tst-unwind-ctor-lib.c
@@ -0,0 +1,42 @@
+/* Unit test for _Unwind_Backtrace in a shared object constructor.
+ 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>
+
+static _Unwind_Reason_Code
+callback (struct _Unwind_Context *ctx, void *arg)
+{
+ return _URC_NO_REASON;
+}
+
+static void
+__attribute__ ((constructor))
+do_unwind (void)
+{
+ /* Arrange for this test to be killed if _Unwind_Backtrace runs into an
+ endless loop. We cannot use the test driver since the test needs to
+ run in a constructor. */
+ alarm (20);
+ _Unwind_Backtrace (callback, 0);
+}
+
+void
+dummy (void)
+{
+}
Index: glibc-2.28/elf/tst-unwind-ctor.c
===================================================================
--- /dev/null
+++ glibc-2.28/elf/tst-unwind-ctor.c
@@ -0,0 +1,27 @@
+/* Unit test for _Unwind_Backtrace in a shared object constructor.
+ 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/>. */
+
+extern void dummy (void);
+
+int
+main (void)
+{
+ /* Just call a dummy function in the shared library. The actual test
+ runs in its constructor. */
+ dummy ();
+}
Index: glibc-2.28/sysdeps/powerpc/powerpc32/dl-start.S
===================================================================
--- glibc-2.28.orig/sysdeps/powerpc/powerpc32/dl-start.S
+++ glibc-2.28/sysdeps/powerpc/powerpc32/dl-start.S
@@ -34,6 +34,9 @@ ENTRY(_start)
_dl_start to save the link register). */
li r4,0
addi r1,r1,-16
+ cfi_adjust_cfa_offset (16)
+/* Mark lr as undefined to stop unwinding. */
+ cfi_undefined (lr)
stw r4,0(r1)
bl _dl_start@local

View File

@ -1,24 +0,0 @@
2018-10-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #23709]
* sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
independently of other flags.
Index: glibc-2.28/sysdeps/x86/cpu-features.c
===================================================================
--- glibc-2.28.orig/sysdeps/x86/cpu-features.c
+++ glibc-2.28/sysdeps/x86/cpu-features.c
@@ -316,7 +316,13 @@ init_cpu_features (struct cpu_features *
| bit_arch_Fast_Unaligned_Copy
| bit_arch_Prefer_PMINUB_for_stringop);
break;
+ }
+ /* Disable TSX on some Haswell processors to avoid TSX on kernels that
+ weren't updated with the latest microcode package (which disables
+ broken feature by default). */
+ switch (model)
+ {
case 0x3f:
/* Xeon E7 v3 with stepping >= 4 has working TSX. */
if (stepping >= 4)