SHA256
3
0
forked from pool/glibc

Accepting request 720569 from home:Andreas_Schwab:Factory

- Update to glibc 2.30
  * Unicode 12.1.0 Support
  * The dynamic linker accepts the --preload argument to preload shared
    objects
  * The twalk_r function has been added
  * On Linux, the getdents64, gettid, and tgkill functions have been added
  * Minguo (Republic of China) calendar support has been added
  * The entry for the new Japanese era has been added
  * Memory allocation functions malloc, calloc, realloc, reallocarray, valloc,
    pvalloc, memalign, and posix_memalign fail now with total object size
    larger than PTRDIFF_MAX
  * The dynamic linker no longer refuses to load objects which reference
    versioned symbols whose implementation has moved to a different soname
    since the object has been linked
  * Add new POSIX-proposed pthread_cond_clockwait, pthread_mutex_clocklock,
    pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock and sem_clockwait
    functions
  * On AArch64 the GNU IFUNC resolver call ABI changed
  * The copy_file_range function fails with ENOSYS if the kernel does not
    support the system call of the same name
  * The functions clock_gettime, clock_getres, clock_settime,
    clock_getcpuclockid, clock_nanosleep were removed from the librt library
    for new applications (on architectures which had them)
  * The obsolete and never-implemented XSI STREAMS header files <stropts.h>
    and <sys/stropts.h> have been removed
  * Support for the "inet6" option in /etc/resolv.conf and the RES_USE_INET6
    resolver flag (deprecated in glibc 2.25) have been removed
  * The obsolete RES_INSECURE1 and RES_INSECURE2 option flags for the DNS stub
    resolver have been removed from <resolv.h>
  * With --enable-bind-now, installed programs are now linked with the

OBS-URL: https://build.opensuse.org/request/show/720569
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=535
This commit is contained in:
Andreas Schwab 2019-08-02 10:32:26 +00:00 committed by Git OBS Bridge
parent c331c761b9
commit 5a64f33a11
28 changed files with 121 additions and 3187 deletions

View File

@ -1,114 +0,0 @@
2019-03-07 Martin Liska <mliska@suse.cz>
* math/Makefile: Change location where math-vector-fortran.h is
installed.
* math/finclude/math-vector-fortran.h: Move from bits/math-vector-fortran.h.
* sysdeps/x86/fpu/finclude/math-vector-fortran.h: Move
from sysdeps/x86/fpu/bits/math-vector-fortran.h.
* scripts/check-installed-headers.sh: Skip Fortran header files.
2019-02-20 Martin Liska <mliska@suse.cz>
* math/Makefile: Install math-vector-fortran.h.
* bits/math-vector-fortran.h: New file.
* sysdeps/x86/fpu/bits/math-vector-fortran.h: New file.
Index: glibc-2.29/math/Makefile
===================================================================
--- glibc-2.29.orig/math/Makefile
+++ glibc-2.29/math/Makefile
@@ -26,6 +26,7 @@ headers := math.h bits/mathcalls.h bits
fpu_control.h complex.h bits/cmathcalls.h fenv.h \
bits/fenv.h bits/fenvinline.h bits/mathdef.h tgmath.h \
bits/math-finite.h bits/math-vector.h \
+ finclude/math-vector-fortran.h \
bits/libm-simd-decl-stubs.h bits/iscanonical.h \
bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \
bits/long-double.h bits/mathcalls-helper-functions.h \
Index: glibc-2.29/math/finclude/math-vector-fortran.h
===================================================================
--- /dev/null
+++ glibc-2.29/math/finclude/math-vector-fortran.h
@@ -0,0 +1,19 @@
+! Platform-specific declarations of SIMD math functions for Fortran. -*- f90 -*-
+! Copyright (C) 2019 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/>.
+
+! No SIMD math functions are available for this platform.
Index: glibc-2.29/scripts/check-installed-headers.sh
===================================================================
--- glibc-2.29.orig/scripts/check-installed-headers.sh
+++ glibc-2.29/scripts/check-installed-headers.sh
@@ -84,6 +84,10 @@ for header in "$@"; do
(sys/elf.h)
continue;;
+ # Skip Fortran headers.
+ (finclude/*)
+ continue;;
+
# sys/sysctl.h is unsupported for x32.
(sys/sysctl.h)
case "$is_x32" in
Index: glibc-2.29/sysdeps/x86/fpu/finclude/math-vector-fortran.h
===================================================================
--- /dev/null
+++ glibc-2.29/sysdeps/x86/fpu/finclude/math-vector-fortran.h
@@ -0,0 +1,43 @@
+! Platform-specific declarations of SIMD math functions for Fortran. -*- f90 -*-
+! Copyright (C) 2019 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/>.
+
+!GCC$ builtin (cos) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (cosf) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (sin) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (sinf) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (sincos) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (sincosf) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (log) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (logf) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (exp) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (expf) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (pow) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (powf) attributes simd (notinbranch) if('x86_64')
+
+!GCC$ builtin (cos) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (cosf) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (sin) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (sinf) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (sincos) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (sincosf) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (log) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (logf) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (exp) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (expf) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (pow) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (powf) attributes simd (notinbranch) if('x32')

View File

@ -1,74 +0,0 @@
2019-02-05 Florian Weimer <fweimer@redhat.com>
[BZ #24164]
arm: Use "nr" constraint for Systemtap probes, to avoid the
compiler using memory operands for constants, due to the "o"
alternative in the default "nor" constraint.
* include/stap-probe.h [USE_STAP_PROBE]: Include
<stap-probe-machine.h>
* sysdeps/generic/stap-probe-machine.h: New file.
* sysdeps/arm/stap-probe-machine.h: Likewise.
Index: glibc-2.29/include/stap-probe.h
===================================================================
--- glibc-2.29.orig/include/stap-probe.h
+++ glibc-2.29/include/stap-probe.h
@@ -21,6 +21,7 @@
#ifdef USE_STAP_PROBE
+# include <stap-probe-machine.h>
# include <sys/sdt.h>
/* Our code uses one macro LIBC_PROBE (name, n, arg1, ..., argn).
Index: glibc-2.29/sysdeps/arm/stap-probe-machine.h
===================================================================
--- /dev/null
+++ glibc-2.29/sysdeps/arm/stap-probe-machine.h
@@ -0,0 +1,22 @@
+/* Macros for customizing Systemtap <sys/sdt.h>. Arm version.
+ Copyright (C) 2019 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/>. */
+
+/* The default "nor" constraint produces unparseable memory references
+ for constants. Omit the problematic "o" constraint. See bug 24164
+ and GCC PR 89146. */
+#define STAP_SDT_ARG_CONSTRAINT nr
Index: glibc-2.29/sysdeps/generic/stap-probe-machine.h
===================================================================
--- /dev/null
+++ glibc-2.29/sysdeps/generic/stap-probe-machine.h
@@ -0,0 +1,19 @@
+/* Macros for customizing Systemtap <sys/sdt.h>. Generic version.
+ Copyright (C) 2019 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/>. */
+
+/* By default, there are no customizations. */

View File

@ -1,107 +0,0 @@
2019-03-13 Stefan Liebler <stli@linux.ibm.com>
* elf/dl-sysdep.c (_dl_show_auxv): Remove condition and always
call _dl_procinfo.
* sysdeps/unix/sysv/linux/s390/dl-procinfo.h (_dl_procinfo):
Ignore types other than AT_HWCAP.
* sysdeps/sparc/dl-procinfo.h (_dl_procinfo): Likewise.
* sysdeps/unix/sysv/linux/i386/dl-procinfo.h (_dl_procinfo):
Likewise.
* sysdeps/powerpc/dl-procinfo.h (_dl_procinfo): Adjust comment
in the case of falling back to generic output mechanism.
* sysdeps/unix/sysv/linux/arm/dl-procinfo.h (_dl_procinfo):
Likewise.
Index: glibc-2.29/elf/dl-sysdep.c
===================================================================
--- glibc-2.29.orig/elf/dl-sysdep.c
+++ glibc-2.29/elf/dl-sysdep.c
@@ -328,14 +328,9 @@ _dl_show_auxv (void)
assert (AT_NULL == 0);
assert (AT_IGNORE == 1);
- if (av->a_type == AT_HWCAP || av->a_type == AT_HWCAP2
- || AT_L1I_CACHEGEOMETRY || AT_L1D_CACHEGEOMETRY
- || AT_L2_CACHEGEOMETRY || AT_L3_CACHEGEOMETRY)
- {
- /* These are handled in a special way per platform. */
- if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
- continue;
- }
+ /* Some entries are handled in a special way per platform. */
+ if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
+ continue;
if (idx < sizeof (auxvars) / sizeof (auxvars[0])
&& auxvars[idx].form != unknown)
Index: glibc-2.29/sysdeps/powerpc/dl-procinfo.h
===================================================================
--- glibc-2.29.orig/sysdeps/powerpc/dl-procinfo.h
+++ glibc-2.29/sysdeps/powerpc/dl-procinfo.h
@@ -225,7 +225,7 @@ _dl_procinfo (unsigned int type, unsigne
break;
}
default:
- /* This should not happen. */
+ /* Fallback to generic output mechanism. */
return -1;
}
_dl_printf ("\n");
Index: glibc-2.29/sysdeps/sparc/dl-procinfo.h
===================================================================
--- glibc-2.29.orig/sysdeps/sparc/dl-procinfo.h
+++ glibc-2.29/sysdeps/sparc/dl-procinfo.h
@@ -31,8 +31,8 @@ _dl_procinfo (unsigned int type, unsigne
{
int i;
- /* Fallback to unknown output mechanism. */
- if (type == AT_HWCAP2)
+ /* Fallback to generic output mechanism. */
+ if (type != AT_HWCAP)
return -1;
_dl_printf ("AT_HWCAP: ");
Index: glibc-2.29/sysdeps/unix/sysv/linux/arm/dl-procinfo.h
===================================================================
--- glibc-2.29.orig/sysdeps/unix/sysv/linux/arm/dl-procinfo.h
+++ glibc-2.29/sysdeps/unix/sysv/linux/arm/dl-procinfo.h
@@ -67,7 +67,7 @@ _dl_procinfo (unsigned int type, unsigne
break;
}
default:
- /* This should not happen. */
+ /* Fallback to generic output mechanism. */
return -1;
}
_dl_printf ("\n");
Index: glibc-2.29/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
===================================================================
--- glibc-2.29.orig/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
+++ glibc-2.29/sysdeps/unix/sysv/linux/i386/dl-procinfo.h
@@ -30,8 +30,8 @@ _dl_procinfo (unsigned int type, unsigne
in the kernel sources. */
int i;
- /* Fallback to unknown output mechanism. */
- if (type == AT_HWCAP2)
+ /* Fallback to generic output mechanism. */
+ if (type != AT_HWCAP)
return -1;
_dl_printf ("AT_HWCAP: ");
Index: glibc-2.29/sysdeps/unix/sysv/linux/s390/dl-procinfo.h
===================================================================
--- glibc-2.29.orig/sysdeps/unix/sysv/linux/s390/dl-procinfo.h
+++ glibc-2.29/sysdeps/unix/sysv/linux/s390/dl-procinfo.h
@@ -32,8 +32,8 @@ _dl_procinfo (unsigned int type, unsigne
in the kernel sources. */
int i;
- /* Fallback to unknown output mechanism. */
- if (type == AT_HWCAP2)
+ /* Fallback to generic output mechanism. */
+ if (type != AT_HWCAP)
return -1;
_dl_printf ("AT_HWCAP: ");

View File

@ -83,7 +83,7 @@ Index: glibc-2.27/libio/genops.c
}
libc_hidden_def (_IO_flush_all)
@@ -852,22 +860,18 @@ _IO_unbuffer_all (void)
@@ -852,6 +860,14 @@ _IO_unbuffer_all (void)
for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
{
@ -95,9 +95,12 @@ Index: glibc-2.27/libio/genops.c
+ continue;
+ }
+
if (! (fp->_flags & _IO_UNBUFFERED)
int legacy = 0;
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
@@ -863,18 +879,6 @@ _IO_unbuffer_all (void)
/* Iff stream is un-orientated, it wasn't used. */
&& fp->_mode != 0)
&& (legacy || fp->_mode != 0))
{
-#ifdef _IO_MTSAFE_IO
- int cnt;
@ -111,12 +114,12 @@ Index: glibc-2.27/libio/genops.c
- __sched_yield ();
-#endif
-
if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
{
fp->_flags |= _IO_USER_BUF;
@@ -881,16 +885,14 @@ _IO_unbuffer_all (void)
@@ -881,17 +885,15 @@ _IO_unbuffer_all (void)
if (fp->_mode > 0)
if (! legacy && fp->_mode > 0)
_IO_wsetb (fp, NULL, NULL, 0);
-
-#ifdef _IO_MTSAFE_IO
@ -127,7 +130,8 @@ Index: glibc-2.27/libio/genops.c
/* Make sure that never again the wide char functions can be
used. */
fp->_mode = -1;
if (! legacy)
fp->_mode = -1;
+
+ _IO_funlockfile (fp);
+ run_fp = NULL;

View File

@ -1,572 +0,0 @@
Fix handling of collating elements in fnmatch (bug 17396, bug 16976)
This fixes the same bug in fnmatch that was fixed by commit 7e2f0d2d77 for
regexp matching. As a side effect it also removes the use of an unbound
VLA.
[BZ #16976]
[BZ #17396]
* posix/fnmatch_loop.c (internal_fnmatch, internal_fnwmatch): When
looking up collating elements match against (wide) character
sequence instead of name. Correct alignment adjustment.
* posix/fnmatch.c: Don't include "../locale/elem-hash.h".
(WMEMCMP) [HANDLE_MULTIBYTE]: Define.
* posix/Makefile (tests): Add tst-fnmatch4 and tst-fnmatch5.
(LOCALES): Add cs_CZ.ISO-8859-2.
* posix/tst-fnmatch4.c: New file.
* posix/tst-fnmatch5.c: New file.
* include/wchar.h (__wmemcmp): Declare.
* wcsmbs/wmemcmp.c: Define __wmemcmp and add wmemcmp as weak alias.
* sysdeps/i386/i686/multiarch/wmemcmp.c: Likewise.
* sysdeps/x86_64/multiarch/wmemcmp.c: Likewise.
* sysdeps/s390/wmemcmp.c: Likewise.
Index: glibc-2.28/include/wchar.h
===================================================================
--- glibc-2.28.orig/include/wchar.h
+++ glibc-2.28/include/wchar.h
@@ -143,6 +143,8 @@ libc_hidden_proto (wmemchr)
libc_hidden_proto (__wmemchr)
libc_hidden_proto (wmemset)
libc_hidden_proto (__wmemset)
+extern int __wmemcmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n)
+ __THROW __attribute_pure__;
/* Now define the internal interfaces. */
extern int __wcscasecmp (const wchar_t *__s1, const wchar_t *__s2)
Index: glibc-2.28/posix/Makefile
===================================================================
--- glibc-2.28.orig/posix/Makefile
+++ glibc-2.28/posix/Makefile
@@ -92,6 +92,7 @@ tests := test-errno tstgetopt testfnm r
bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
tst-pathconf tst-rxspencer-no-utf8 \
tst-fnmatch3 bug-regex36 \
+ tst-fnmatch4 tst-fnmatch5 \
tst-posix_spawn-fd tst-posix_spawn-setsid \
tst-posix_fadvise tst-posix_fadvise64 \
tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
@@ -166,7 +167,8 @@ $(objpfx)wordexp-tst.out: wordexp-tst.sh
endif
LOCALES := cs_CZ.UTF-8 da_DK.ISO-8859-1 de_DE.ISO-8859-1 de_DE.UTF-8 \
- en_US.UTF-8 es_US.ISO-8859-1 es_US.UTF-8 ja_JP.EUC-JP tr_TR.UTF-8
+ en_US.UTF-8 es_US.ISO-8859-1 es_US.UTF-8 ja_JP.EUC-JP tr_TR.UTF-8 \
+ cs_CZ.ISO-8859-2
include ../gen-locales.mk
$(objpfx)bug-regex1.out: $(gen-locales)
Index: glibc-2.28/posix/fnmatch.c
===================================================================
--- glibc-2.28.orig/posix/fnmatch.c
+++ glibc-2.28/posix/fnmatch.c
@@ -53,7 +53,6 @@
we support a correct implementation only in glibc. */
#ifdef _LIBC
# include "../locale/localeinfo.h"
-# include "../locale/elem-hash.h"
# include "../locale/coll-lookup.h"
# include <shlib-compat.h>
@@ -237,6 +236,11 @@ __wcschrnul (const wchar_t *s, wint_t c)
# define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
# define MEMCHR(S, C, N) __wmemchr (S, C, N)
# define STRCOLL(S1, S2) wcscoll (S1, S2)
+# ifdef _LIBC
+# define WMEMCMP(S1, S2, N) __wmemcmp (S1, S2, N)
+# else
+# define WMEMCMP(S1, S2, N) wmemcmp (S1, S2, N)
+# endif
# define WIDE_CHAR_VERSION 1
/* Change the name the header defines so it doesn't conflict with
the <locale/weight.h> version included above. */
Index: glibc-2.28/posix/fnmatch_loop.c
===================================================================
--- glibc-2.28.orig/posix/fnmatch_loop.c
+++ glibc-2.28/posix/fnmatch_loop.c
@@ -494,26 +494,12 @@ FCT (const CHAR *pattern, const CHAR *st
{
int32_t table_size;
const int32_t *symb_table;
-# if WIDE_CHAR_VERSION
- char str[c1];
- unsigned int strcnt;
-# else
-# define str (startp + 1)
-# endif
const unsigned char *extra;
int32_t idx;
int32_t elem;
- int32_t second;
- int32_t hash;
-
# if WIDE_CHAR_VERSION
- /* We have to convert the name to a single-byte
- string. This is possible since the names
- consist of ASCII characters and the internal
- representation is UCS4. */
- for (strcnt = 0; strcnt < c1; ++strcnt)
- str[strcnt] = startp[1 + strcnt];
-#endif
+ CHAR *wextra;
+# endif
table_size =
_NL_CURRENT_WORD (LC_COLLATE,
@@ -525,71 +511,54 @@ FCT (const CHAR *pattern, const CHAR *st
_NL_CURRENT (LC_COLLATE,
_NL_COLLATE_SYMB_EXTRAMB);
- /* Locate the character in the hashing table. */
- hash = elem_hash (str, c1);
-
- idx = 0;
- elem = hash % table_size;
- if (symb_table[2 * elem] != 0)
- {
- second = hash % (table_size - 2) + 1;
-
- do
- {
- /* First compare the hashing value. */
- if (symb_table[2 * elem] == hash
- && (c1
- == extra[symb_table[2 * elem + 1]])
- && memcmp (str,
- &extra[symb_table[2 * elem
- + 1]
- + 1], c1) == 0)
- {
- /* Yep, this is the entry. */
- idx = symb_table[2 * elem + 1];
- idx += 1 + extra[idx];
- break;
- }
-
- /* Next entry. */
- elem += second;
- }
- while (symb_table[2 * elem] != 0);
- }
+ for (elem = 0; elem < table_size; elem++)
+ if (symb_table[2 * elem] != 0)
+ {
+ idx = symb_table[2 * elem + 1];
+ /* Skip the name of collating element. */
+ idx += 1 + extra[idx];
+# if WIDE_CHAR_VERSION
+ /* Skip the byte sequence of the
+ collating element. */
+ idx += 1 + extra[idx];
+ /* Adjust for the alignment. */
+ idx = (idx + 3) & ~3;
+
+ wextra = (CHAR *) &extra[idx + 4];
+
+ if (/* Compare the length of the sequence. */
+ c1 == wextra[0]
+ /* Compare the wide char sequence. */
+ && WMEMCMP (startp + 1, &wextra[1],
+ c1) == 0)
+ /* Yep, this is the entry. */
+ break;
+# else
+ if (/* Compare the length of the sequence. */
+ c1 == extra[idx]
+ /* Compare the byte sequence. */
+ && memcmp (startp + 1,
+ &extra[idx + 1], c1) == 0)
+ /* Yep, this is the entry. */
+ break;
+# endif
+ }
- if (symb_table[2 * elem] != 0)
+ if (elem < table_size)
{
/* Compare the byte sequence but only if
this is not part of a range. */
-# if WIDE_CHAR_VERSION
- int32_t *wextra;
-
- idx += 1 + extra[idx];
- /* Adjust for the alignment. */
- idx = (idx + 3) & ~3;
+ if (! is_range
- wextra = (int32_t *) &extra[idx + 4];
-# endif
-
- if (! is_range)
- {
# if WIDE_CHAR_VERSION
- for (c1 = 0;
- (int32_t) c1 < wextra[idx];
- ++c1)
- if (n[c1] != wextra[1 + c1])
- break;
-
- if ((int32_t) c1 == wextra[idx])
- goto matched;
+ && WMEMCMP (n, &wextra[1], c1) == 0
# else
- for (c1 = 0; c1 < extra[idx]; ++c1)
- if (n[c1] != extra[1 + c1])
- break;
-
- if (c1 == extra[idx])
- goto matched;
+ && memcmp (n, &extra[idx + 1], c1) == 0
# endif
+ )
+ {
+ n += c1 - 1;
+ goto matched;
}
/* Get the collation sequence value. */
@@ -597,9 +566,9 @@ FCT (const CHAR *pattern, const CHAR *st
# if WIDE_CHAR_VERSION
cold = wextra[1 + wextra[idx]];
# else
- /* Adjust for the alignment. */
idx += 1 + extra[idx];
- idx = (idx + 3) & ~4;
+ /* Adjust for the alignment. */
+ idx = (idx + 3) & ~3;
cold = *((int32_t *) &extra[idx]);
# endif
@@ -609,10 +578,10 @@ FCT (const CHAR *pattern, const CHAR *st
{
/* No valid character. Match it as a
single byte. */
- if (!is_range && *n == str[0])
+ if (!is_range && *n == startp[1])
goto matched;
- cold = str[0];
+ cold = startp[1];
c = *p++;
}
else
@@ -620,7 +589,6 @@ FCT (const CHAR *pattern, const CHAR *st
}
}
else
-# undef str
#endif
{
c = FOLD (c);
@@ -712,25 +680,11 @@ FCT (const CHAR *pattern, const CHAR *st
{
int32_t table_size;
const int32_t *symb_table;
-# if WIDE_CHAR_VERSION
- char str[c1];
- unsigned int strcnt;
-# else
-# define str (startp + 1)
-# endif
const unsigned char *extra;
int32_t idx;
int32_t elem;
- int32_t second;
- int32_t hash;
-
# if WIDE_CHAR_VERSION
- /* We have to convert the name to a single-byte
- string. This is possible since the names
- consist of ASCII characters and the internal
- representation is UCS4. */
- for (strcnt = 0; strcnt < c1; ++strcnt)
- str[strcnt] = startp[1 + strcnt];
+ CHAR *wextra;
# endif
table_size =
@@ -743,71 +697,63 @@ FCT (const CHAR *pattern, const CHAR *st
_NL_CURRENT (LC_COLLATE,
_NL_COLLATE_SYMB_EXTRAMB);
- /* Locate the character in the hashing
- table. */
- hash = elem_hash (str, c1);
-
- idx = 0;
- elem = hash % table_size;
- if (symb_table[2 * elem] != 0)
- {
- second = hash % (table_size - 2) + 1;
-
- do
- {
- /* First compare the hashing value. */
- if (symb_table[2 * elem] == hash
- && (c1
- == extra[symb_table[2 * elem + 1]])
- && memcmp (str,
- &extra[symb_table[2 * elem + 1]
- + 1], c1) == 0)
- {
- /* Yep, this is the entry. */
- idx = symb_table[2 * elem + 1];
- idx += 1 + extra[idx];
- break;
- }
-
- /* Next entry. */
- elem += second;
- }
- while (symb_table[2 * elem] != 0);
- }
-
- if (symb_table[2 * elem] != 0)
- {
- /* Compare the byte sequence but only if
- this is not part of a range. */
+ for (elem = 0; elem < table_size; elem++)
+ if (symb_table[2 * elem] != 0)
+ {
+ idx = symb_table[2 * elem + 1];
+ /* Skip the name of collating
+ element. */
+ idx += 1 + extra[idx];
# if WIDE_CHAR_VERSION
- int32_t *wextra;
-
- idx += 1 + extra[idx];
- /* Adjust for the alignment. */
- idx = (idx + 3) & ~4;
-
- wextra = (int32_t *) &extra[idx + 4];
+ /* Skip the byte sequence of the
+ collating element. */
+ idx += 1 + extra[idx];
+ /* Adjust for the alignment. */
+ idx = (idx + 3) & ~3;
+
+ wextra = (CHAR *) &extra[idx + 4];
+
+ if (/* Compare the length of the
+ sequence. */
+ c1 == wextra[0]
+ /* Compare the wide char sequence. */
+ && WMEMCMP (startp + 1, &wextra[1],
+ c1) == 0)
+ /* Yep, this is the entry. */
+ break;
+# else
+ if (/* Compare the length of the
+ sequence. */
+ c1 == extra[idx]
+ /* Compare the byte sequence. */
+ && memcmp (startp + 1,
+ &extra[idx + 1], c1) == 0)
+ /* Yep, this is the entry. */
+ break;
# endif
+ }
+
+ if (elem < table_size)
+ {
/* Get the collation sequence value. */
is_seqval = 1;
# if WIDE_CHAR_VERSION
cend = wextra[1 + wextra[idx]];
# else
- /* Adjust for the alignment. */
idx += 1 + extra[idx];
- idx = (idx + 3) & ~4;
+ /* Adjust for the alignment. */
+ idx = (idx + 3) & ~3;
cend = *((int32_t *) &extra[idx]);
# endif
}
- else if (symb_table[2 * elem] != 0 && c1 == 1)
+ else if (c1 == 1)
{
- cend = str[0];
+ cend = startp[1];
c = *p++;
}
else
return FNM_NOMATCH;
}
-# undef str
}
else
{
Index: glibc-2.28/posix/tst-fnmatch4.c
===================================================================
--- /dev/null
+++ glibc-2.28/posix/tst-fnmatch4.c
@@ -0,0 +1,41 @@
+/* Test for fnmatch handling of collating elements
+ Copyright (C) 2019 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 <locale.h>
+#include <fnmatch.h>
+#include <support/check.h>
+
+static void
+do_test_locale (const char *locale)
+{
+ TEST_VERIFY_EXIT (setlocale (LC_ALL, locale) != NULL);
+
+ TEST_VERIFY (fnmatch ("[[.ch.]]", "ch", 0) == 0);
+}
+
+static int
+do_test (void)
+{
+ do_test_locale ("cs_CZ.ISO-8859-2");
+ do_test_locale ("cs_CZ.UTF-8");
+
+ return 0;
+}
+
+#include <support/test-driver.c>
Index: glibc-2.28/posix/tst-fnmatch5.c
===================================================================
--- /dev/null
+++ glibc-2.28/posix/tst-fnmatch5.c
@@ -0,0 +1,46 @@
+/* Test for fnmatch handling of collating elements
+ Copyright (C) 2019 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 <fnmatch.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+
+#define LENGTH 20000000
+
+static char pattern[LENGTH + 7];
+
+static int
+do_test (void)
+{
+ TEST_VERIFY_EXIT (setlocale (LC_ALL, "en_US.UTF-8") != NULL);
+
+ pattern[0] = '[';
+ pattern[1] = '[';
+ pattern[2] = '.';
+ memset (pattern + 3, 'a', LENGTH);
+ pattern[LENGTH + 3] = '.';
+ pattern[LENGTH + 4] = ']';
+ pattern[LENGTH + 5] = ']';
+ TEST_VERIFY (fnmatch (pattern, "a", 0) != 0);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
Index: glibc-2.28/sysdeps/i386/i686/multiarch/wmemcmp.c
===================================================================
--- glibc-2.28.orig/sysdeps/i386/i686/multiarch/wmemcmp.c
+++ glibc-2.28/sysdeps/i386/i686/multiarch/wmemcmp.c
@@ -26,5 +26,6 @@
# define SYMBOL_NAME wmemcmp
# include "ifunc-ssse3-sse4_2.h"
-libc_ifunc_redirected (__redirect_wmemcmp, wmemcmp, IFUNC_SELECTOR ());
+libc_ifunc_redirected (__redirect_wmemcmp, __wmemcmp, IFUNC_SELECTOR ());
+weak_alias (__wmemcmp, wmemcmp)
#endif
Index: glibc-2.28/sysdeps/s390/wmemcmp.c
===================================================================
--- glibc-2.28.orig/sysdeps/s390/wmemcmp.c
+++ glibc-2.28/sysdeps/s390/wmemcmp.c
@@ -23,16 +23,17 @@
# include <ifunc-resolve.h>
# if HAVE_WMEMCMP_C
-extern __typeof (wmemcmp) WMEMCMP_C attribute_hidden;
+extern __typeof (__wmemcmp) WMEMCMP_C attribute_hidden;
# endif
# 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
+++ glibc-2.28/sysdeps/x86_64/multiarch/wmemcmp.c
@@ -26,5 +26,6 @@
# define SYMBOL_NAME wmemcmp
# include "ifunc-memcmp.h"
-libc_ifunc_redirected (__redirect_wmemcmp, wmemcmp, IFUNC_SELECTOR ());
+libc_ifunc_redirected (__redirect_wmemcmp, __wmemcmp, IFUNC_SELECTOR ());
+weak_alias (__wmemcmp, wmemcmp)
#endif
Index: glibc-2.28/wcsmbs/wmemcmp.c
===================================================================
--- glibc-2.28.orig/wcsmbs/wmemcmp.c
+++ glibc-2.28/wcsmbs/wmemcmp.c
@@ -18,12 +18,12 @@
#include <wchar.h>
-#ifndef WMEMCMP
-# define WMEMCMP wmemcmp
+#ifdef WMEMCMP
+# define __wmemcmp WMEMCMP
#endif
int
-WMEMCMP (const wchar_t *s1, const wchar_t *s2, size_t n)
+__wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n)
{
wchar_t c1;
wchar_t c2;
@@ -81,3 +81,6 @@ WMEMCMP (const wchar_t *s1, const wchar_
return 0;
}
+#ifndef WMEMCMP
+weak_alias (__wmemcmp, wmemcmp)
+#endif

View File

@ -1,91 +0,0 @@
2019-02-08 Florian Weimer <fweimer@redhat.com>
[BZ #24161]
* sysdeps/nptl/fork.h (__run_fork_handlers): Add multiple_threads
argument.
* nptl/register-atfork.c (__run_fork_handlers): Only perform
locking if the new do_locking argument is true.
* sysdeps/nptl/fork.c (__libc_fork): Pass multiple_threads to
__run_fork_handlers.
Index: glibc-2.29/nptl/register-atfork.c
===================================================================
--- glibc-2.29.orig/nptl/register-atfork.c
+++ glibc-2.29/nptl/register-atfork.c
@@ -107,13 +107,14 @@ __unregister_atfork (void *dso_handle)
}
void
-__run_fork_handlers (enum __run_fork_handler_type who)
+__run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking)
{
struct fork_handler *runp;
if (who == atfork_run_prepare)
{
- lll_lock (atfork_lock, LLL_PRIVATE);
+ if (do_locking)
+ lll_lock (atfork_lock, LLL_PRIVATE);
size_t sl = fork_handler_list_size (&fork_handlers);
for (size_t i = sl; i > 0; i--)
{
@@ -133,7 +134,8 @@ __run_fork_handlers (enum __run_fork_han
else if (who == atfork_run_parent && runp->parent_handler)
runp->parent_handler ();
}
- lll_unlock (atfork_lock, LLL_PRIVATE);
+ if (do_locking)
+ lll_unlock (atfork_lock, LLL_PRIVATE);
}
}
Index: glibc-2.29/sysdeps/nptl/fork.c
===================================================================
--- glibc-2.29.orig/sysdeps/nptl/fork.c
+++ glibc-2.29/sysdeps/nptl/fork.c
@@ -55,7 +55,7 @@ __libc_fork (void)
but our current fork implementation is not. */
bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads);
- __run_fork_handlers (atfork_run_prepare);
+ __run_fork_handlers (atfork_run_prepare, multiple_threads);
/* If we are not running multiple threads, we do not have to
preserve lock state. If fork runs from a signal handler, only
@@ -134,7 +134,7 @@ __libc_fork (void)
__rtld_lock_initialize (GL(dl_load_lock));
/* Run the handlers registered for the child. */
- __run_fork_handlers (atfork_run_child);
+ __run_fork_handlers (atfork_run_child, multiple_threads);
}
else
{
@@ -149,7 +149,7 @@ __libc_fork (void)
}
/* Run the handlers registered for the parent. */
- __run_fork_handlers (atfork_run_parent);
+ __run_fork_handlers (atfork_run_parent, multiple_threads);
}
return pid;
Index: glibc-2.29/sysdeps/nptl/fork.h
===================================================================
--- glibc-2.29.orig/sysdeps/nptl/fork.h
+++ glibc-2.29/sysdeps/nptl/fork.h
@@ -52,9 +52,11 @@ enum __run_fork_handler_type
- atfork_run_child: run all the CHILD_HANDLER and unlocks the internal
lock.
- atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal
- lock. */
-extern void __run_fork_handlers (enum __run_fork_handler_type who)
- attribute_hidden;
+ lock.
+
+ Perform locking only if DO_LOCKING. */
+extern void __run_fork_handlers (enum __run_fork_handler_type who,
+ _Bool do_locking) attribute_hidden;
/* C library side function to register new fork handlers. */
extern int __register_atfork (void (*__prepare) (void),

View File

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

View File

@ -1,11 +0,0 @@
-----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-----

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

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

16
glibc-2.30.tar.xz.sig Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEcnNUKzmWLfeymZMUFnkrTqJTQPgFAl1DRIYACgkQFnkrTqJT
QPjGfBAAhds1wnuzs5K1NDOCurXDu/WLe+isQB3zEQEQy15Wy2ZHNN801k9Wt9j7
vd4mG5whsMdjzXE6QmEY9x/kREQ5XQV4vlGBO8r9ZO42retlWWYBtuoLo6weS2WK
FstZ8k5hcS83ZBs/fbea4OFv5L6kopVkqYbqHQMudxLZIjTGVXjjwWBZqlAbW9UE
iIynJ/f5SwLisIQfRKT//B4lANaH2hvxfZlfngbWRaSnsj28BK3Ut+HwgZpVU+N0
O/Yi5hp38IKBNvso4h1//LYCYIOiZVbvdWFXUXhvpOySrKpU+/akSk3B3okgsAnO
WjcCqJNtdjJqRhhLhn8IxJtBOxojqfY5Yjchjj6VkXm9AYDjWxxiwQuNOkyK6nRC
KBLkwAkOAI45yAd5p9oBiVDAeyQFww1bwdojBjHgPKySM2JJI6fooQ1c8wd8ZCiO
QsHpd7JnBhWaLr6Xm50U2aED4s6lf3auEr49mQDbuizl6DUHLHzFGx7kN6vXGQaC
FPNuskYdKzM+eEbdpbP49niska1DBjSYjDddO/AMGRHlzjcPUn5mQht3XquUQNby
EP6S9DrS6J3rM88Wz4Rl/8tsWQ9W+u/fImtHjobC7oZ+0eFGpZ0ZT50pbZxzsQkb
7yWU92RXuN7ySg9MUzLG7Z60iVTWgkFU8gaZGBTOXcskm04K5og=
=i6A/
-----END PGP SIGNATURE-----

View File

@ -1,3 +1,57 @@
-------------------------------------------------------------------
Fri Aug 2 08:59:46 UTC 2019 - Andreas Schwab <schwab@suse.de>
- Update to glibc 2.30
* Unicode 12.1.0 Support
* The dynamic linker accepts the --preload argument to preload shared
objects
* The twalk_r function has been added
* On Linux, the getdents64, gettid, and tgkill functions have been added
* Minguo (Republic of China) calendar support has been added
* The entry for the new Japanese era has been added
* Memory allocation functions malloc, calloc, realloc, reallocarray, valloc,
pvalloc, memalign, and posix_memalign fail now with total object size
larger than PTRDIFF_MAX
* The dynamic linker no longer refuses to load objects which reference
versioned symbols whose implementation has moved to a different soname
since the object has been linked
* Add new POSIX-proposed pthread_cond_clockwait, pthread_mutex_clocklock,
pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock and sem_clockwait
functions
* On AArch64 the GNU IFUNC resolver call ABI changed
* The copy_file_range function fails with ENOSYS if the kernel does not
support the system call of the same name
* The functions clock_gettime, clock_getres, clock_settime,
clock_getcpuclockid, clock_nanosleep were removed from the librt library
for new applications (on architectures which had them)
* The obsolete and never-implemented XSI STREAMS header files <stropts.h>
and <sys/stropts.h> have been removed
* Support for the "inet6" option in /etc/resolv.conf and the RES_USE_INET6
resolver flag (deprecated in glibc 2.25) have been removed
* The obsolete RES_INSECURE1 and RES_INSECURE2 option flags for the DNS stub
resolver have been removed from <resolv.h>
* With --enable-bind-now, installed programs are now linked with the
BIND_NOW flag.
* On 32-bit Arm, support for the port-based I/O emulation and the <sys/io.h>
header have been removed
* The Linux-specific <sys/sysctl.h> header and the sysctl function have been
deprecated and will be removed from a future version of glibc
* CVE-2019-7309: x86-64 memcmp used signed Jcc instructions to check
size
* CVE-2019-9169: Attempted case-insensitive regular-expression match
via proceed_next_node in posix/regexec.c leads to heap-based buffer
over-read
- pthread-rwlock-trylock-stalls.patch,
arm-systemtap-probe-constraint.patch, pthread-mutex-barrier.patch,
fork-handler-lock.patch, pthread-join-probe.patch,
riscv-clone-unwind.patch, add-new-Fortran-vector-math-header-file.patch,
regex-read-overrun.patch, japanese-era-name-may-2019.patch,
dl-show-auxv.patch, s390-vx-vxe-hwcap.patch, taisho-era-string.patch,
malloc-tracing-hooks.patch, pldd-inf-loop.patch,
malloc-large-bin-corruption-check.patch, wfile-sync-crash.patch,
malloc-tests-warnings.patch, fnmatch-collating-elements.patch,
iconv-reset-input-buffer.patch: Removed
-------------------------------------------------------------------
Wed Jul 17 09:47:02 UTC 2019 - Andreas Schwab <schwab@suse.de>

View File

@ -1,3 +1,4 @@
GPG keys of Andreas Schwab <schwab>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2
@ -39,6 +40,7 @@ h7J3UPL0JriHbmA3gbutataR5wnv9HmXtepz3rNglnjZFpMumTIaOKS86TjJ
=oOhV
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Roland McGrath <roland>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.0.7 (NetBSD)
@ -88,6 +90,7 @@ XavWgG39OPlPqENUx7GIRgQYEQIABgUCPh6PKQAKCRDa9zUKfrvWJYxEAJ9FFDtc
=SLj7
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Paul Eggert <eggert>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.10 (GNU/Linux)
@ -141,6 +144,7 @@ WtkGoi8buNcby4U=
=AL6o
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Ian Wienand <ianw>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: PGP Key Server 0.9.6
@ -168,6 +172,7 @@ ZthBvjkZUZCOl+wjwbn3k4bpiEYEGBECAAYFAj0n9DwACgkQWDlSU/gp6efSHgCc
DxXIOrZyOO3jtbtsTYR/VrsdK9sAn0lrUm/jZKWyvK6V1CCA3TwXyvLQ
=dSXY
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Siddhesh Poyarekar <siddhesh>
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFMAZNMBCACeatEKl6YY9iEVxzS64bPbvJsA1mLE2XFWmKXyYzm58dFqPMa0
@ -299,6 +304,7 @@ sYfhl4H9GvFqm7QfT9MCEEG1sOjrrkZpFvc1IrMbislKNdIRBziudr9jv+zdz24H
TKN3JdfTyacfNU4=
=IcJn
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Carlos O'Donell <codonell>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
@ -377,6 +383,7 @@ tmATw6qr79EWeqLgPNQnKWojra9N7xcGRCULdhSOw0mQ5pryIMQheWqdPUhKURmX
c8HFfqRDMIQCPexAXgsSKg==
=d45e
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Karl Berry <karl>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.5 (GNU/Linux)
@ -410,6 +417,7 @@ KLEPtgs1HkI=
=5dqZ
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Alexandre Oliva <oliva>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.2 (GNU/Linux)
@ -621,6 +629,7 @@ N7JGzLVNo+A=
=fZUN
-----END PGP PUBLIC KEY BLOCK-----
GPG keys of Eric Blake <ericb>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Public key at http://people.redhat.com/eblake/eblake.gpg

View File

@ -148,10 +148,10 @@ BuildArch: i686
%define enablekernel 4.15
%endif
Version: 2.29
Version: 2.30
Release: 0
%if !%{build_snapshot}
%define git_id 56c86f5dd516
%define git_id 0a8262a1b2
%define libversion %version
%else
%define git_id %(echo %version | sed 's/.*\.g//')
@ -267,52 +267,16 @@ Patch306: glibc-fix-double-loopback.diff
###
# Patches from upstream
###
# PATCH-FIX-UPSTREAM nptl: Fix pthread_rwlock_try*lock stalls (BZ #23844)
Patch1000: pthread-rwlock-trylock-stalls.patch
# PATCH-FIX-UPSTREAM arm: Use "nr" constraint for Systemtap probes (BZ #24164)
Patch1001: arm-systemtap-probe-constraint.patch
# PATCH-FIX-UPSTREAM Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock (BZ #24180)
Patch1002: pthread-mutex-barrier.patch
# PATCH-FIX-UPSTREAM nptl: Avoid fork handler lock for async-signal-safe fork (BZ #24161)
Patch1003: fork-handler-lock.patch
# PATCH-FIX-UPSTREAM nptl: Fix invalid Systemtap probe in pthread_join (BZ #24211)
Patch1004: pthread-join-probe.patch
# PATCH-FIX-UPSTREAM RISC-V: Fix elfutils testsuite unwind failures (BZ #24040)
Patch1005: riscv-clone-unwind.patch
# PATCH-FIX-UPSTREAM Add new Fortran vector math header file.
Patch1006: add-new-Fortran-vector-math-header-file.patch
# PATCH-FIX-UPSTREAM regex: fix read overrun (CVE-2019-9169, BZ #24114)
Patch1007: regex-read-overrun.patch
# PATCH-FIX-UPSTREAM ja_JP locale: Add entry for the new Japanese era (BZ #22964)
Patch1008: japanese-era-name-may-2019.patch
# PATCH-FIX-UPSTREAM Fix output of LD_SHOW_AUXV=1
Patch1009: dl-show-auxv.patch
# PATCH-FIX-UPSTREAM S390: Mark vx and vxe as important hwcap
Patch1010: s390-vx-vxe-hwcap.patch
# PATCH-FIX-UPSTREAM ja_JP: Change the offset for Taisho gan-nen from 2 to 1 (BZ #24162)
Patch1011: taisho-era-string.patch
# PATCH-FIX-UPSTREAM malloc: Set and reset all hooks for tracing (BZ #16573)
Patch1012: malloc-tracing-hooks.patch
# PATCH-FIX-UPSTREAM elf: Fix pldd (BZ#18035)
Patch1013: pldd-inf-loop.patch
# PATCH-FIX-UPSTREAM malloc: Check for large bin list corruption when inserting unsorted chunk (BZ #24216)
Patch1014: malloc-large-bin-corruption-check.patch
# PATCH-FIX-UPSTREAM Fix crash in _IO_wfile_sync (BZ #20568)
Patch1015: wfile-sync-crash.patch
# PATCH-FIX-UPSTREAM malloc: Fix warnings in tests with GCC 9
Patch1016: malloc-tests-warnings.patch
# PATCH-FIX-UPSTREAM malloc: Remove unwanted leading whitespace in malloc_info (BZ #24867)
Patch1000: malloc-info-whitespace.patch
###
# Patches awaiting upstream approval
###
# PATCH-FIX-UPSTREAM Always to locking when accessing streams (BZ #15142)
Patch2000: fix-locking-in-_IO_cleanup.patch
# PATCH-FIX-UPSTREAM Fix fnmatch handling of collating elements (BZ #17396, BZ #16976)
Patch2004: fnmatch-collating-elements.patch
# PATCH-FIX-UPSTREAM Fix iconv buffer handling with IGNORE error handler (BZ #18830)
Patch2006: iconv-reset-input-buffer.patch
# PATCH-FIX-UPSTREAM Avoid concurrency problem in ldconfig (BZ #23973)
Patch2007: ldconfig-concurrency.patch
Patch2001: ldconfig-concurrency.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -511,27 +475,9 @@ makedb: A program to create a database for nss
%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
%patch1013 -p1
%patch1014 -p1
%patch1015 -p1
%patch1016 -p1
%patch2000 -p1
%patch2004 -p1
%patch2006 -p1
%patch2007 -p1
%patch2001 -p1
%patch3000

View File

@ -1,329 +0,0 @@
Fix iconv buffer handling with IGNORE error handler (bug #18830)
[BZ #18830]
* iconv/skeleton.c (FUNCTION_NAME): Use RESET_INPUT_BUFFER only if
no irreversible characters occurred.
* iconv/gconv_simple.c (internal_ucs4_loop)
(internal_ucs4_loop_unaligned, internal_ucs4_loop_single)
(ucs4_internal_loop, ucs4_internal_loop_unaligned)
(ucs4_internal_loop_single, internal_ucs4le_loop)
(internal_ucs4le_loop_unaligned, internal_ucs4le_loop_single)
(ucs4le_internal_loop, ucs4le_internal_loop_unaligned)
(ucs4le_internal_loop_single): Add const to outend.
* iconv/Makefile (tests): Add tst-iconv7.
* iconv/tst-iconv7.c: New file.
Index: glibc-2.27/iconv/Makefile
===================================================================
--- glibc-2.27.orig/iconv/Makefile
+++ glibc-2.27/iconv/Makefile
@@ -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 \
- tst-iconv-mt
+ tst-iconv7 tst-iconv-mt
others = iconv_prog iconvconfig
install-others-programs = $(inst_bindir)/iconv
Index: glibc-2.27/iconv/gconv_simple.c
===================================================================
--- glibc-2.27.orig/iconv/gconv_simple.c
+++ glibc-2.27/iconv/gconv_simple.c
@@ -76,7 +76,7 @@ __attribute ((always_inline))
internal_ucs4_loop (struct __gconv_step *step,
struct __gconv_step_data *step_data,
const unsigned char **inptrp, const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp, const unsigned char *outend,
size_t *irreversible)
{
const unsigned char *inptr = *inptrp;
@@ -120,7 +120,8 @@ internal_ucs4_loop_unaligned (struct __g
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
const unsigned char *inptr = *inptrp;
@@ -169,7 +170,8 @@ internal_ucs4_loop_single (struct __gcon
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
mbstate_t *state = step_data->__statep;
@@ -231,7 +233,7 @@ __attribute ((always_inline))
ucs4_internal_loop (struct __gconv_step *step,
struct __gconv_step_data *step_data,
const unsigned char **inptrp, const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp, const unsigned char *outend,
size_t *irreversible)
{
int flags = step_data->__flags;
@@ -298,7 +300,8 @@ ucs4_internal_loop_unaligned (struct __g
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
int flags = step_data->__flags;
@@ -368,7 +371,8 @@ ucs4_internal_loop_single (struct __gcon
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
mbstate_t *state = step_data->__statep;
@@ -443,7 +447,7 @@ __attribute ((always_inline))
internal_ucs4le_loop (struct __gconv_step *step,
struct __gconv_step_data *step_data,
const unsigned char **inptrp, const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp, const unsigned char *outend,
size_t *irreversible)
{
const unsigned char *inptr = *inptrp;
@@ -488,7 +492,8 @@ internal_ucs4le_loop_unaligned (struct _
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
const unsigned char *inptr = *inptrp;
@@ -540,7 +545,8 @@ internal_ucs4le_loop_single (struct __gc
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
mbstate_t *state = step_data->__statep;
@@ -601,7 +607,7 @@ __attribute ((always_inline))
ucs4le_internal_loop (struct __gconv_step *step,
struct __gconv_step_data *step_data,
const unsigned char **inptrp, const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp, const unsigned char *outend,
size_t *irreversible)
{
int flags = step_data->__flags;
@@ -671,7 +677,8 @@ ucs4le_internal_loop_unaligned (struct _
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
int flags = step_data->__flags;
@@ -745,7 +752,8 @@ ucs4le_internal_loop_single (struct __gc
struct __gconv_step_data *step_data,
const unsigned char **inptrp,
const unsigned char *inend,
- unsigned char **outptrp, unsigned char *outend,
+ unsigned char **outptrp,
+ const unsigned char *outend,
size_t *irreversible)
{
mbstate_t *state = step_data->__statep;
Index: glibc-2.27/iconv/skeleton.c
===================================================================
--- glibc-2.27.orig/iconv/skeleton.c
+++ glibc-2.27/iconv/skeleton.c
@@ -597,6 +597,10 @@ FUNCTION_NAME (struct __gconv_step *step
inptr = *inptrp;
/* The outbuf buffer is empty. */
outstart = outbuf;
+#ifdef RESET_INPUT_BUFFER
+ size_t loop_irreversible
+ = lirreversible + (irreversible ? *irreversible : 0);
+#endif
#ifdef SAVE_RESET_STATE
SAVE_RESET_STATE (1);
@@ -671,8 +675,16 @@ FUNCTION_NAME (struct __gconv_step *step
if (__glibc_unlikely (outerr != outbuf))
{
#ifdef RESET_INPUT_BUFFER
- RESET_INPUT_BUFFER;
-#else
+ if (loop_irreversible
+ == lirreversible + (irreversible ? *irreversible : 0))
+ {
+ /* RESET_INPUT_BUFFER can only work if there
+ were no irreversible characters during the
+ last loop. */
+ RESET_INPUT_BUFFER;
+ goto done_reset;
+ }
+#endif
/* We have a problem in one of the functions below.
Undo the conversion upto the error point. */
size_t nstatus __attribute__ ((unused));
@@ -682,9 +694,9 @@ FUNCTION_NAME (struct __gconv_step *step
outbuf = outstart;
/* Restore the state. */
-# ifdef SAVE_RESET_STATE
+#ifdef SAVE_RESET_STATE
SAVE_RESET_STATE (0);
-# endif
+#endif
if (__glibc_likely (!unaligned))
{
@@ -701,7 +713,7 @@ FUNCTION_NAME (struct __gconv_step *step
lirreversiblep
EXTRA_LOOP_ARGS);
}
-# if POSSIBLY_UNALIGNED
+#if POSSIBLY_UNALIGNED
else
{
if (FROM_DIRECTION)
@@ -720,7 +732,7 @@ FUNCTION_NAME (struct __gconv_step *step
lirreversiblep
EXTRA_LOOP_ARGS);
}
-# endif
+#endif
/* We must run out of output buffer space in this
rerun. */
@@ -731,9 +743,11 @@ FUNCTION_NAME (struct __gconv_step *step
the invocation counter. */
if (__glibc_unlikely (outbuf == outstart))
--data->__invocation_counter;
-#endif /* reset input buffer */
}
+#ifdef RESET_INPUT_BUFFER
+ done_reset:
+#endif
/* Change the status. */
status = result;
}
Index: glibc-2.27/iconv/tst-iconv7.c
===================================================================
--- /dev/null
+++ glibc-2.27/iconv/tst-iconv7.c
@@ -0,0 +1,68 @@
+/* Test iconv buffer handling with the IGNORE error handler.
+ Copyright (C) 2015 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/>. */
+
+/* Derived from BZ #18830 */
+#include <errno.h>
+#include <iconv.h>
+#include <stdio.h>
+
+
+static int
+do_test (void)
+{
+ iconv_t cd = iconv_open ("ASCII//IGNORE", "ASCII");
+ if (cd == (iconv_t) -1)
+ {
+ puts ("iconv_open failed");
+ return 1;
+ }
+
+ char input[5 + 3] = { 0, 0, 0, 0, 0, '1', '\200', '2' };
+ char *inptr = input;
+ size_t insize = sizeof (input);
+ char output[5];
+ char *outptr = output;
+ size_t outsize = sizeof (output);
+
+ size_t ret = iconv (cd, &inptr, &insize, &outptr, &outsize);
+ if (ret != (size_t) -1)
+ {
+ puts ("iconv succeeded");
+ return 1;
+ }
+ if (errno != E2BIG)
+ {
+ puts ("iconv did not set errno to E2BIG");
+ return 1;
+ }
+ if (inptr != input + sizeof (output) - outsize)
+ {
+ printf ("iconv consumed %td characters\n", inptr - input);
+ return 1;
+ }
+
+ if (iconv_close (cd) == -1)
+ {
+ puts ("iconv_close failed");
+ return 1;
+ }
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Index: glibc-2.27/sysdeps/s390/multiarch/gconv_simple.c
===================================================================
--- glibc-2.27.orig/sysdeps/s390/multiarch/gconv_simple.c
+++ glibc-2.27/sysdeps/s390/multiarch/gconv_simple.c
@@ -403,7 +403,7 @@ ICONV_VX_NAME (internal_ucs4le_loop) (st
const unsigned char **inptrp,
const unsigned char *inend,
unsigned char **outptrp,
- unsigned char *outend,
+ const unsigned char *outend,
size_t *irreversible)
{
const unsigned char *inptr = *inptrp;
@@ -503,7 +503,7 @@ ICONV_VX_NAME (ucs4_internal_loop) (stru
const unsigned char **inptrp,
const unsigned char *inend,
unsigned char **outptrp,
- unsigned char *outend,
+ const unsigned char *outend,
size_t *irreversible)
{
int flags = step_data->__flags;
@@ -630,7 +630,7 @@ ICONV_VX_NAME (ucs4le_internal_loop) (st
const unsigned char **inptrp,
const unsigned char *inend,
unsigned char **outptrp,
- unsigned char *outend,
+ const unsigned char *outend,
size_t *irreversible)
{
int flags = step_data->__flags;

View File

@ -1,21 +0,0 @@
2019-04-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
[BZ #22964]
* localedata/locales/ja_JP (LC_TIME): Add entry for the new Japanese
era.
Index: glibc-2.29/localedata/locales/ja_JP
===================================================================
--- glibc-2.29.orig/localedata/locales/ja_JP
+++ glibc-2.29/localedata/locales/ja_JP
@@ -14946,7 +14946,9 @@ am_pm "<U5348><U524D>";"<U5348><U5F8C>"
t_fmt_ampm "%p%I<U6642>%M<U5206>%S<U79D2>"
-era "+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
+era "+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
+ "+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
+ "+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/

View File

@ -0,0 +1,22 @@
2019-08-01 Florian Weimer <fweimer@redhat.com>
[BZ #24867]
* malloc/malloc.c (__malloc_info): Remove unwanted leading
whitespace.
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 00ce48cf58..343d89f489 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -5491,7 +5491,7 @@ __malloc_info (int options, FILE *fp)
for (size_t i = 0; i < nsizes; ++i)
if (sizes[i].count != 0 && i != NFASTBINS)
- fprintf (fp, " \
+ fprintf (fp, "\
<size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
--
2.22.0

View File

@ -1,19 +0,0 @@
Index: glibc-2.29/malloc/malloc.c
===================================================================
--- glibc-2.29.orig/malloc/malloc.c
+++ glibc-2.29/malloc/malloc.c
@@ -3876,10 +3876,14 @@ _int_malloc (mstate av, size_t bytes)
{
victim->fd_nextsize = fwd;
victim->bk_nextsize = fwd->bk_nextsize;
+ if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd))
+ malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)");
fwd->bk_nextsize = victim;
victim->bk_nextsize->fd_nextsize = victim;
}
bck = fwd->bk;
+ if (bck->fd != fwd)
+ malloc_printerr ("malloc(): largebin double linked list corrupted (bk)");
}
}
else

View File

@ -1,123 +0,0 @@
2019-04-18 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* malloc/tst-memalign.c (do_test): Disable
-Walloc-size-larger-than= around tests of malloc with negative
sizes.
* malloc/tst-malloc-too-large.c (do_test): Likewise.
Index: glibc-2.29/malloc/tst-malloc-too-large.c
===================================================================
--- glibc-2.29.orig/malloc/tst-malloc-too-large.c
+++ glibc-2.29/malloc/tst-malloc-too-large.c
@@ -72,13 +72,28 @@ test_large_allocations (size_t size)
void * ptr_to_realloc;
test_setup ();
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about too-large allocations; here we want to test
+ that they fail. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+#endif
TEST_VERIFY (malloc (size) == NULL);
+#if __GNUC_PREREQ (7, 0)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
TEST_VERIFY (errno == ENOMEM);
ptr_to_realloc = malloc (16);
TEST_VERIFY_EXIT (ptr_to_realloc != NULL);
test_setup ();
+#if __GNUC_PREREQ (7, 0)
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+#endif
TEST_VERIFY (realloc (ptr_to_realloc, size) == NULL);
+#if __GNUC_PREREQ (7, 0)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
TEST_VERIFY (errno == ENOMEM);
free (ptr_to_realloc);
@@ -135,7 +150,13 @@ test_large_aligned_allocations (size_t s
for (align = 1; align <= pagesize; align *= 2)
{
test_setup ();
+#if __GNUC_PREREQ (7, 0)
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+#endif
TEST_VERIFY (memalign (align, size) == NULL);
+#if __GNUC_PREREQ (7, 0)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
TEST_VERIFY (errno == ENOMEM);
/* posix_memalign expects an alignment that is a power of 2 *and* a
@@ -151,7 +172,13 @@ test_large_aligned_allocations (size_t s
if ((size % align) == 0)
{
test_setup ();
+#if __GNUC_PREREQ (7, 0)
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+#endif
TEST_VERIFY (aligned_alloc (align, size) == NULL);
+#if __GNUC_PREREQ (7, 0)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
TEST_VERIFY (errno == ENOMEM);
}
}
@@ -159,11 +186,23 @@ test_large_aligned_allocations (size_t s
/* Both valloc and pvalloc return page-aligned memory. */
test_setup ();
+#if __GNUC_PREREQ (7, 0)
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+#endif
TEST_VERIFY (valloc (size) == NULL);
+#if __GNUC_PREREQ (7, 0)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
TEST_VERIFY (errno == ENOMEM);
test_setup ();
+#if __GNUC_PREREQ (7, 0)
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+#endif
TEST_VERIFY (pvalloc (size) == NULL);
+#if __GNUC_PREREQ (7, 0)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
TEST_VERIFY (errno == ENOMEM);
}
Index: glibc-2.29/malloc/tst-memalign.c
===================================================================
--- glibc-2.29.orig/malloc/tst-memalign.c
+++ glibc-2.29/malloc/tst-memalign.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <libc-diag.h>
static int errors = 0;
@@ -41,9 +42,18 @@ do_test (void)
errno = 0;
+ DIAG_PUSH_NEEDS_COMMENT;
+#if __GNUC_PREREQ (7, 0)
+ /* GCC 7 warns about too-large allocations; here we want to test
+ that they fail. */
+ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
+#endif
/* An attempt to allocate a huge value should return NULL and set
errno to ENOMEM. */
p = memalign (sizeof (void *), -1);
+#if __GNUC_PREREQ (7, 0)
+ DIAG_POP_NEEDS_COMMENT;
+#endif
save = errno;

View File

@ -1,156 +0,0 @@
2019-04-09 Carlos O'Donell <carlos@redhat.com>
Kwok Cheung Yeung <kcy@codesourcery.com>
[BZ #16573]
* malloc/mtrace.c: Define prototypes for all hooks.
(set_default_hooks): New function.
(set_trace_hooks): Likewise.
(save_default_hooks): Likewise.
(tr_freehook): Use new s*_hooks functions.
(tr_mallochook): Likewise.
(tr_reallochook): Likewise.
(tr_memalignhook): Likewise.
(mtrace): Likewise.
(muntrace): Likewise.
Index: glibc-2.29/malloc/mtrace.c
===================================================================
--- glibc-2.29.orig/malloc/mtrace.c
+++ glibc-2.29/malloc/mtrace.c
@@ -121,6 +121,41 @@ lock_and_info (const void *caller, Dl_in
return res;
}
+static void tr_freehook (void *, const void *);
+static void * tr_mallochook (size_t, const void *);
+static void * tr_reallochook (void *, size_t, const void *);
+static void * tr_memalignhook (size_t, size_t, const void *);
+
+/* Set all the default non-trace hooks. */
+static __always_inline void
+set_default_hooks (void)
+{
+ __free_hook = tr_old_free_hook;
+ __malloc_hook = tr_old_malloc_hook;
+ __realloc_hook = tr_old_realloc_hook;
+ __memalign_hook = tr_old_memalign_hook;
+}
+
+/* Set all of the tracing hooks used for mtrace. */
+static __always_inline void
+set_trace_hooks (void)
+{
+ __free_hook = tr_freehook;
+ __malloc_hook = tr_mallochook;
+ __realloc_hook = tr_reallochook;
+ __memalign_hook = tr_memalignhook;
+}
+
+/* Save the current set of hooks as the default hooks. */
+static __always_inline void
+save_default_hooks (void)
+{
+ tr_old_free_hook = __free_hook;
+ tr_old_malloc_hook = __malloc_hook;
+ tr_old_realloc_hook = __realloc_hook;
+ tr_old_memalign_hook = __memalign_hook;
+}
+
static void
tr_freehook (void *ptr, const void *caller)
{
@@ -138,12 +173,12 @@ tr_freehook (void *ptr, const void *call
tr_break ();
__libc_lock_lock (lock);
}
- __free_hook = tr_old_free_hook;
+ set_default_hooks ();
if (tr_old_free_hook != NULL)
(*tr_old_free_hook)(ptr, caller);
else
free (ptr);
- __free_hook = tr_freehook;
+ set_trace_hooks ();
__libc_lock_unlock (lock);
}
@@ -155,12 +190,12 @@ tr_mallochook (size_t size, const void *
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
- __malloc_hook = tr_old_malloc_hook;
+ set_default_hooks ();
if (tr_old_malloc_hook != NULL)
hdr = (void *) (*tr_old_malloc_hook)(size, caller);
else
hdr = (void *) malloc (size);
- __malloc_hook = tr_mallochook;
+ set_trace_hooks ();
tr_where (caller, info);
/* We could be printing a NULL here; that's OK. */
@@ -185,16 +220,12 @@ tr_reallochook (void *ptr, size_t size,
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
- __free_hook = tr_old_free_hook;
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
+ set_default_hooks ();
if (tr_old_realloc_hook != NULL)
hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
else
hdr = (void *) realloc (ptr, size);
- __free_hook = tr_freehook;
- __malloc_hook = tr_mallochook;
- __realloc_hook = tr_reallochook;
+ set_trace_hooks ();
tr_where (caller, info);
if (hdr == NULL)
@@ -230,14 +261,12 @@ tr_memalignhook (size_t alignment, size_
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
- __memalign_hook = tr_old_memalign_hook;
- __malloc_hook = tr_old_malloc_hook;
+ set_default_hooks ();
if (tr_old_memalign_hook != NULL)
hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
else
hdr = (void *) memalign (alignment, size);
- __memalign_hook = tr_memalignhook;
- __malloc_hook = tr_mallochook;
+ set_trace_hooks ();
tr_where (caller, info);
/* We could be printing a NULL here; that's OK. */
@@ -305,14 +334,8 @@ mtrace (void)
malloc_trace_buffer = mtb;
setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
fprintf (mallstream, "= Start\n");
- tr_old_free_hook = __free_hook;
- __free_hook = tr_freehook;
- tr_old_malloc_hook = __malloc_hook;
- __malloc_hook = tr_mallochook;
- tr_old_realloc_hook = __realloc_hook;
- __realloc_hook = tr_reallochook;
- tr_old_memalign_hook = __memalign_hook;
- __memalign_hook = tr_memalignhook;
+ save_default_hooks ();
+ set_trace_hooks ();
#ifdef _LIBC
if (!added_atexit_handler)
{
@@ -338,10 +361,7 @@ muntrace (void)
file. */
FILE *f = mallstream;
mallstream = NULL;
- __free_hook = tr_old_free_hook;
- __malloc_hook = tr_old_malloc_hook;
- __realloc_hook = tr_old_realloc_hook;
- __memalign_hook = tr_old_memalign_hook;
+ set_default_hooks ();
fprintf (f, "= End\n");
fclose (f);

View File

@ -1,393 +0,0 @@
2019-04-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #18035]
* elf/pldd-xx.c: Use _Static_assert in of pldd_assert.
(E(find_maps)): Avoid use alloca, use default read file operations
instead of explicit LFS names, and fix infinite loop.
* elf/pldd.c: Explicit set _FILE_OFFSET_BITS, cleanup headers.
(get_process_info): Use _Static_assert instead of assert, use default
directory operations instead of explicit LFS names, and free some
leadek pointers.
Index: glibc-2.29/elf/pldd-xx.c
===================================================================
--- glibc-2.29.orig/elf/pldd-xx.c
+++ glibc-2.29/elf/pldd-xx.c
@@ -23,10 +23,6 @@
#define EW_(e, w, t) EW__(e, w, _##t)
#define EW__(e, w, t) e##w##t
-#define pldd_assert(name, exp) \
- typedef int __assert_##name[((exp) != 0) - 1]
-
-
struct E(link_map)
{
EW(Addr) l_addr;
@@ -39,12 +35,12 @@ struct E(link_map)
EW(Addr) l_libname;
};
#if CLASS == __ELF_NATIVE_CLASS
-pldd_assert (l_addr, (offsetof (struct link_map, l_addr)
- == offsetof (struct E(link_map), l_addr)));
-pldd_assert (l_name, (offsetof (struct link_map, l_name)
- == offsetof (struct E(link_map), l_name)));
-pldd_assert (l_next, (offsetof (struct link_map, l_next)
- == offsetof (struct E(link_map), l_next)));
+_Static_assert (offsetof (struct link_map, l_addr)
+ == offsetof (struct E(link_map), l_addr), "l_addr");
+_Static_assert (offsetof (struct link_map, l_name)
+ == offsetof (struct E(link_map), l_name), "l_name");
+_Static_assert (offsetof (struct link_map, l_next)
+ == offsetof (struct E(link_map), l_next), "l_next");
#endif
@@ -54,10 +50,10 @@ struct E(libname_list)
EW(Addr) next;
};
#if CLASS == __ELF_NATIVE_CLASS
-pldd_assert (name, (offsetof (struct libname_list, name)
- == offsetof (struct E(libname_list), name)));
-pldd_assert (next, (offsetof (struct libname_list, next)
- == offsetof (struct E(libname_list), next)));
+_Static_assert (offsetof (struct libname_list, name)
+ == offsetof (struct E(libname_list), name), "name");
+_Static_assert (offsetof (struct libname_list, next)
+ == offsetof (struct E(libname_list), next), "next");
#endif
struct E(r_debug)
@@ -69,16 +65,17 @@ struct E(r_debug)
EW(Addr) r_map;
};
#if CLASS == __ELF_NATIVE_CLASS
-pldd_assert (r_version, (offsetof (struct r_debug, r_version)
- == offsetof (struct E(r_debug), r_version)));
-pldd_assert (r_map, (offsetof (struct r_debug, r_map)
- == offsetof (struct E(r_debug), r_map)));
+_Static_assert (offsetof (struct r_debug, r_version)
+ == offsetof (struct E(r_debug), r_version), "r_version");
+_Static_assert (offsetof (struct r_debug, r_map)
+ == offsetof (struct E(r_debug), r_map), "r_map");
#endif
static int
-E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
+E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv,
+ size_t auxv_size)
{
EW(Addr) phdr = 0;
unsigned int phnum = 0;
@@ -104,12 +101,9 @@ E(find_maps) (pid_t pid, void *auxv, siz
if (phdr == 0 || phnum == 0 || phent == 0)
error (EXIT_FAILURE, 0, gettext ("cannot find program header of process"));
- EW(Phdr) *p = alloca (phnum * phent);
- if (pread64 (memfd, p, phnum * phent, phdr) != phnum * phent)
- {
- error (0, 0, gettext ("cannot read program header"));
- return EXIT_FAILURE;
- }
+ EW(Phdr) *p = xmalloc (phnum * phent);
+ if (pread (memfd, p, phnum * phent, phdr) != phnum * phent)
+ error (EXIT_FAILURE, 0, gettext ("cannot read program header"));
/* Determine the load offset. We need this for interpreting the
other program header entries so we do this in a separate loop.
@@ -129,24 +123,18 @@ E(find_maps) (pid_t pid, void *auxv, siz
if (p[i].p_type == PT_DYNAMIC)
{
EW(Dyn) *dyn = xmalloc (p[i].p_filesz);
- if (pread64 (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr)
+ if (pread (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr)
!= p[i].p_filesz)
- {
- error (0, 0, gettext ("cannot read dynamic section"));
- return EXIT_FAILURE;
- }
+ error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section"));
/* Search for the DT_DEBUG entry. */
for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j)
if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0)
{
struct E(r_debug) r;
- if (pread64 (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr)
+ if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr)
!= sizeof (r))
- {
- error (0, 0, gettext ("cannot read r_debug"));
- return EXIT_FAILURE;
- }
+ error (EXIT_FAILURE, 0, gettext ("cannot read r_debug"));
if (r.r_map != 0)
{
@@ -160,13 +148,10 @@ E(find_maps) (pid_t pid, void *auxv, siz
}
else if (p[i].p_type == PT_INTERP)
{
- interp = alloca (p[i].p_filesz);
- if (pread64 (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr)
+ interp = xmalloc (p[i].p_filesz);
+ if (pread (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr)
!= p[i].p_filesz)
- {
- error (0, 0, gettext ("cannot read program interpreter"));
- return EXIT_FAILURE;
- }
+ error (EXIT_FAILURE, 0, gettext ("cannot read program interpreter"));
}
if (list == 0)
@@ -174,14 +159,16 @@ E(find_maps) (pid_t pid, void *auxv, siz
if (interp == NULL)
{
// XXX check whether the executable itself is the loader
- return EXIT_FAILURE;
+ exit (EXIT_FAILURE);
}
// XXX perhaps try finding ld.so and _r_debug in it
-
- return EXIT_FAILURE;
+ exit (EXIT_FAILURE);
}
+ free (p);
+ free (interp);
+
/* Print the PID and program name first. */
printf ("%lu:\t%s\n", (unsigned long int) pid, exe);
@@ -192,47 +179,27 @@ E(find_maps) (pid_t pid, void *auxv, siz
do
{
struct E(link_map) m;
- if (pread64 (memfd, &m, sizeof (m), list) != sizeof (m))
- {
- error (0, 0, gettext ("cannot read link map"));
- status = EXIT_FAILURE;
- goto out;
- }
+ if (pread (memfd, &m, sizeof (m), list) != sizeof (m))
+ error (EXIT_FAILURE, 0, gettext ("cannot read link map"));
EW(Addr) name_offset = m.l_name;
- again:
while (1)
{
- ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset);
+ ssize_t n = pread (memfd, tmpbuf.data, tmpbuf.length, name_offset);
if (n == -1)
- {
- error (0, 0, gettext ("cannot read object name"));
- status = EXIT_FAILURE;
- goto out;
- }
+ error (EXIT_FAILURE, 0, gettext ("cannot read object name"));
if (memchr (tmpbuf.data, '\0', n) != NULL)
break;
if (!scratch_buffer_grow (&tmpbuf))
- {
- error (0, 0, gettext ("cannot allocate buffer for object name"));
- status = EXIT_FAILURE;
- goto out;
- }
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot allocate buffer for object name"));
}
- if (((char *)tmpbuf.data)[0] == '\0' && name_offset == m.l_name
- && m.l_libname != 0)
- {
- /* Try the l_libname element. */
- struct E(libname_list) ln;
- if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
- {
- name_offset = ln.name;
- goto again;
- }
- }
+ /* The m.l_name and m.l_libname.name for loader linkmap points to same
+ values (since BZ#387 fix). Trying to use l_libname name as the
+ shared object name might lead to an infinite loop (BZ#18035). */
/* Skip over the executable. */
if (((char *)tmpbuf.data)[0] != '\0')
@@ -242,7 +209,6 @@ E(find_maps) (pid_t pid, void *auxv, siz
}
while (list != 0);
- out:
scratch_buffer_free (&tmpbuf);
return status;
}
Index: glibc-2.29/elf/pldd.c
===================================================================
--- glibc-2.29.orig/elf/pldd.c
+++ glibc-2.29/elf/pldd.c
@@ -17,23 +17,17 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <alloca.h>
+#define _FILE_OFFSET_BITS 64
+
#include <argp.h>
-#include <assert.h>
#include <dirent.h>
-#include <elf.h>
-#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <libintl.h>
-#include <link.h>
-#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
#include <sys/ptrace.h>
-#include <sys/stat.h>
#include <sys/wait.h>
#include <scratch_buffer.h>
@@ -76,14 +70,9 @@ static struct argp argp =
options, parse_opt, args_doc, doc, NULL, more_help, NULL
};
-// File descriptor of /proc/*/mem file.
-static int memfd;
-
-/* Name of the executable */
-static char *exe;
/* Local functions. */
-static int get_process_info (int dfd, long int pid);
+static int get_process_info (const char *exe, int dfd, long int pid);
static void wait_for_ptrace_stop (long int pid);
@@ -102,8 +91,10 @@ main (int argc, char *argv[])
return 1;
}
- assert (sizeof (pid_t) == sizeof (int)
- || sizeof (pid_t) == sizeof (long int));
+ _Static_assert (sizeof (pid_t) == sizeof (int)
+ || sizeof (pid_t) == sizeof (long int),
+ "sizeof (pid_t) != sizeof (int) or sizeof (long int)");
+
char *endp;
errno = 0;
long int pid = strtol (argv[remaining], &endp, 10);
@@ -119,25 +110,24 @@ main (int argc, char *argv[])
if (dfd == -1)
error (EXIT_FAILURE, errno, gettext ("cannot open %s"), buf);
- struct scratch_buffer exebuf;
- scratch_buffer_init (&exebuf);
+ /* Name of the executable */
+ struct scratch_buffer exe;
+ scratch_buffer_init (&exe);
ssize_t nexe;
while ((nexe = readlinkat (dfd, "exe",
- exebuf.data, exebuf.length)) == exebuf.length)
+ exe.data, exe.length)) == exe.length)
{
- if (!scratch_buffer_grow (&exebuf))
+ if (!scratch_buffer_grow (&exe))
{
nexe = -1;
break;
}
}
if (nexe == -1)
- exe = (char *) "<program name undetermined>";
+ /* Default stack allocation is at least 1024. */
+ snprintf (exe.data, exe.length, "<program name undetermined>");
else
- {
- exe = exebuf.data;
- exe[nexe] = '\0';
- }
+ ((char*)exe.data)[nexe] = '\0';
/* Stop all threads since otherwise the list of loaded modules might
change while we are reading it. */
@@ -155,8 +145,8 @@ main (int argc, char *argv[])
error (EXIT_FAILURE, errno, gettext ("cannot prepare reading %s/task"),
buf);
- struct dirent64 *d;
- while ((d = readdir64 (dir)) != NULL)
+ struct dirent *d;
+ while ((d = readdir (dir)) != NULL)
{
if (! isdigit (d->d_name[0]))
continue;
@@ -182,7 +172,7 @@ main (int argc, char *argv[])
wait_for_ptrace_stop (tid);
- struct thread_list *newp = alloca (sizeof (*newp));
+ struct thread_list *newp = xmalloc (sizeof (*newp));
newp->tid = tid;
newp->next = thread_list;
thread_list = newp;
@@ -190,17 +180,22 @@ main (int argc, char *argv[])
closedir (dir);
- int status = get_process_info (dfd, pid);
+ if (thread_list == NULL)
+ error (EXIT_FAILURE, 0, gettext ("no valid %s/task entries"), buf);
+
+ int status = get_process_info (exe.data, dfd, pid);
- assert (thread_list != NULL);
do
{
ptrace (PTRACE_DETACH, thread_list->tid, NULL, NULL);
+ struct thread_list *prev = thread_list;
thread_list = thread_list->next;
+ free (prev);
}
while (thread_list != NULL);
close (dfd);
+ scratch_buffer_free (&exe);
return status;
}
@@ -281,9 +276,10 @@ warranty; not even for MERCHANTABILITY o
static int
-get_process_info (int dfd, long int pid)
+get_process_info (const char *exe, int dfd, long int pid)
{
- memfd = openat (dfd, "mem", O_RDONLY);
+ /* File descriptor of /proc/<pid>/mem file. */
+ int memfd = openat (dfd, "mem", O_RDONLY);
if (memfd == -1)
goto no_info;
@@ -333,9 +329,9 @@ get_process_info (int dfd, long int pid)
int retval;
if (e_ident[EI_CLASS] == ELFCLASS32)
- retval = find_maps32 (pid, auxv, auxv_size);
+ retval = find_maps32 (exe, memfd, pid, auxv, auxv_size);
else
- retval = find_maps64 (pid, auxv, auxv_size);
+ retval = find_maps64 (exe, memfd, pid, auxv, auxv_size);
free (auxv);
close (memfd);

View File

@ -1,36 +0,0 @@
2019-02-15 Florian Weimer <fweimer@redhat.com>
[BZ #24211]
* nptl/pthread_join_common.c (__pthread_timedjoin_ex): Do not read
pd->result after the thread descriptor has been freed.
Index: glibc-2.29/nptl/pthread_join_common.c
===================================================================
--- glibc-2.29.orig/nptl/pthread_join_common.c
+++ glibc-2.29/nptl/pthread_join_common.c
@@ -86,6 +86,7 @@ __pthread_timedjoin_ex (pthread_t thread
pthread_cleanup_pop (0);
}
+ void *pd_result = pd->result;
if (__glibc_likely (result == 0))
{
/* We mark the thread as terminated and as joined. */
@@ -93,7 +94,7 @@ __pthread_timedjoin_ex (pthread_t thread
/* Store the return value if the caller is interested. */
if (thread_return != NULL)
- *thread_return = pd->result;
+ *thread_return = pd_result;
/* Free the TCB. */
__free_tcb (pd);
@@ -101,7 +102,7 @@ __pthread_timedjoin_ex (pthread_t thread
else
pd->joinid = NULL;
- LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd->result);
+ LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd_result);
return result;
}

View File

@ -1,173 +0,0 @@
2019-02-07 Stefan Liebler <stli@linux.ibm.com>
[BZ #24180]
* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock):
Add compiler barriers and comments.
Index: glibc-2.29/nptl/pthread_mutex_trylock.c
===================================================================
--- glibc-2.29.orig/nptl/pthread_mutex_trylock.c
+++ glibc-2.29/nptl/pthread_mutex_trylock.c
@@ -94,6 +94,9 @@ __pthread_mutex_trylock (pthread_mutex_t
case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
&mutex->__data.__list.__next);
+ /* We need to set op_pending before starting the operation. Also
+ see comments at ENQUEUE_MUTEX. */
+ __asm ("" ::: "memory");
oldval = mutex->__data.__lock;
do
@@ -119,7 +122,12 @@ __pthread_mutex_trylock (pthread_mutex_t
/* But it is inconsistent unless marked otherwise. */
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+ /* We must not enqueue the mutex before we have acquired it.
+ Also see comments at ENQUEUE_MUTEX. */
+ __asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
+ /* We need to clear op_pending after we enqueue the mutex. */
+ __asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exist here. If we fall
@@ -135,6 +143,8 @@ __pthread_mutex_trylock (pthread_mutex_t
int kind = PTHREAD_MUTEX_TYPE (mutex);
if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
{
+ /* We do not need to ensure ordering wrt another memory
+ access. Also see comments at ENQUEUE_MUTEX. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
return EDEADLK;
@@ -142,6 +152,8 @@ __pthread_mutex_trylock (pthread_mutex_t
if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
+ /* We do not need to ensure ordering wrt another memory
+ access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
@@ -160,6 +172,9 @@ __pthread_mutex_trylock (pthread_mutex_t
id, 0);
if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
{
+ /* We haven't acquired the lock as it is already acquired by
+ another owner. We do not need to ensure ordering wrt another
+ memory access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -173,13 +188,20 @@ __pthread_mutex_trylock (pthread_mutex_t
if (oldval == id)
lll_unlock (mutex->__data.__lock,
PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+ /* FIXME This violates the mutex destruction requirements. See
+ __pthread_mutex_unlock_full. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
}
while ((oldval & FUTEX_OWNER_DIED) != 0);
+ /* We must not enqueue the mutex before we have acquired it.
+ Also see comments at ENQUEUE_MUTEX. */
+ __asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
+ /* We need to clear op_pending after we enqueue the mutex. */
+ __asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
mutex->__data.__owner = id;
@@ -211,10 +233,15 @@ __pthread_mutex_trylock (pthread_mutex_t
}
if (robust)
- /* Note: robust PI futexes are signaled by setting bit 0. */
- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
- (void *) (((uintptr_t) &mutex->__data.__list.__next)
- | 1));
+ {
+ /* Note: robust PI futexes are signaled by setting bit 0. */
+ THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+ (void *) (((uintptr_t) &mutex->__data.__list.__next)
+ | 1));
+ /* We need to set op_pending before starting the operation. Also
+ see comments at ENQUEUE_MUTEX. */
+ __asm ("" ::: "memory");
+ }
oldval = mutex->__data.__lock;
@@ -223,12 +250,16 @@ __pthread_mutex_trylock (pthread_mutex_t
{
if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
{
+ /* We do not need to ensure ordering wrt another memory
+ access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EDEADLK;
}
if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
{
+ /* We do not need to ensure ordering wrt another memory
+ access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Just bump the counter. */
@@ -250,6 +281,9 @@ __pthread_mutex_trylock (pthread_mutex_t
{
if ((oldval & FUTEX_OWNER_DIED) == 0)
{
+ /* We haven't acquired the lock as it is already acquired by
+ another owner. We do not need to ensure ordering wrt another
+ memory access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -270,6 +304,9 @@ __pthread_mutex_trylock (pthread_mutex_t
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
{
+ /* The kernel has not yet finished the mutex owner death.
+ We do not need to ensure ordering wrt another memory
+ access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -287,7 +324,12 @@ __pthread_mutex_trylock (pthread_mutex_t
/* But it is inconsistent unless marked otherwise. */
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+ /* We must not enqueue the mutex before we have acquired it.
+ Also see comments at ENQUEUE_MUTEX. */
+ __asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
+ /* We need to clear op_pending after we enqueue the mutex. */
+ __asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exit here. If we fall
@@ -310,13 +352,20 @@ __pthread_mutex_trylock (pthread_mutex_t
PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
0, 0);
+ /* To the kernel, this will be visible after the kernel has
+ acquired the mutex in the syscall. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
if (robust)
{
+ /* We must not enqueue the mutex before we have acquired it.
+ Also see comments at ENQUEUE_MUTEX. */
+ __asm ("" ::: "memory");
ENQUEUE_MUTEX_PI (mutex);
+ /* We need to clear op_pending after we enqueue the mutex. */
+ __asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
}

View File

@ -1,616 +0,0 @@
2019-01-31 Carlos O'Donell <carlos@redhat.com>
Torvald Riegel <triegel@redhat.com>
Rik Prohaska <prohaska7@gmail.com>
[BZ# 23844]
* nptl/Makefile (tests): Add tst-rwlock-tryrdlock-stall, and
tst-rwlock-trywrlock-stall.
* nptl/pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock):
Wake waiters if PTHREAD_RWLOCK_FUTEX_USED is set.
* nptl/pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock):
Set __wrphase_fute to 1 only if we started the write phase.
* nptl/tst-rwlock-tryrdlock-stall.c: New file.
* nptl/tst-rwlock-trywrlock-stall.c: New file.
* support/Makefile (libsupport-routines): Add xpthread_rwlock_destroy.
* support/xpthread_rwlock_destroy.c: New file.
* support/xthread.h: Declare xpthread_rwlock_destroy.
Index: glibc-2.29/nptl/Makefile
===================================================================
--- glibc-2.29.orig/nptl/Makefile
+++ glibc-2.29/nptl/Makefile
@@ -319,7 +319,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 ts
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-rwlock-pwn
+ tst-rwlock-pwn \
+ tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall
tests-internal := tst-rwlock19 tst-rwlock20 \
tst-sem11 tst-sem12 tst-sem13 \
Index: glibc-2.29/nptl/pthread_rwlock_tryrdlock.c
===================================================================
--- glibc-2.29.orig/nptl/pthread_rwlock_tryrdlock.c
+++ glibc-2.29/nptl/pthread_rwlock_tryrdlock.c
@@ -94,15 +94,22 @@ __pthread_rwlock_tryrdlock (pthread_rwlo
/* Same as in __pthread_rwlock_rdlock_full:
We started the read phase, so we are also responsible for
updating the write-phase futex. Relaxed MO is sufficient.
- Note that there can be no other reader that we have to wake
- because all other readers will see the read phase started by us
- (or they will try to start it themselves); if a writer started
- the read phase, we cannot have started it. Furthermore, we
- cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will
- overwrite the value set by the most recent writer (or the readers
- before it in case of explicit hand-over) and we know that there
- are no waiting readers. */
- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
+ We have to do the same steps as a writer would when handing over the
+ read phase to use because other readers cannot distinguish between
+ us and the writer.
+ Note that __pthread_rwlock_tryrdlock callers will not have to be
+ woken up because they will either see the read phase started by us
+ or they will try to start it themselves; however, callers of
+ __pthread_rwlock_rdlock_full just increase the reader count and then
+ check what state the lock is in, so they cannot distinguish between
+ us and a writer that acquired and released the lock in the
+ meantime. */
+ if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
+ & PTHREAD_RWLOCK_FUTEX_USED) != 0)
+ {
+ int private = __pthread_rwlock_get_private (rwlock);
+ futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
+ }
}
return 0;
Index: glibc-2.29/nptl/pthread_rwlock_trywrlock.c
===================================================================
--- glibc-2.29.orig/nptl/pthread_rwlock_trywrlock.c
+++ glibc-2.29/nptl/pthread_rwlock_trywrlock.c
@@ -46,8 +46,15 @@ __pthread_rwlock_trywrlock (pthread_rwlo
&rwlock->__data.__readers, &r,
r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
{
+ /* We have become the primary writer and we cannot have shared
+ the PTHREAD_RWLOCK_FUTEX_USED flag with someone else, so we
+ can simply enable blocking (see full wrlock code). */
atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
- atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
+ /* If we started a write phase, we need to enable readers to
+ wait. If we did not, we must not change it because other threads
+ may have set the PTHREAD_RWLOCK_FUTEX_USED in the meantime. */
+ if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
+ atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
atomic_store_relaxed (&rwlock->__data.__cur_writer,
THREAD_GETMEM (THREAD_SELF, tid));
return 0;
Index: glibc-2.29/nptl/tst-rwlock-tryrdlock-stall.c
===================================================================
--- /dev/null
+++ glibc-2.29/nptl/tst-rwlock-tryrdlock-stall.c
@@ -0,0 +1,355 @@
+/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls.
+ Copyright (C) 2019 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/>. */
+
+/* For a full analysis see comment:
+ https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14
+
+ Provided here for reference:
+
+ --- Analysis of pthread_rwlock_tryrdlock() stall ---
+ A read lock begins to execute.
+
+ In __pthread_rwlock_rdlock_full:
+
+ We can attempt a read lock, but find that the lock is
+ in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit
+ is set), and the lock is held by a primary writer
+ (PTHREAD_RWLOCK_WRLOCKED is set). In this case we must
+ wait for explicit hand over from the writer to us or
+ one of the other waiters. The read lock threads are
+ about to execute:
+
+ 341 r = (atomic_fetch_add_acquire (&rwlock->__data.__readers,
+ 342 (1 << PTHREAD_RWLOCK_READER_SHIFT))
+ 343 + (1 << PTHREAD_RWLOCK_READER_SHIFT));
+
+ An unlock beings to execute.
+
+ Then in __pthread_rwlock_wrunlock:
+
+ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
+ ...
+ 549 while (!atomic_compare_exchange_weak_release
+ 550 (&rwlock->__data.__readers, &r,
+ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED)
+ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
+ 553 : PTHREAD_RWLOCK_WRPHASE))))
+ 554 {
+ ...
+ 556 }
+
+ We clear PTHREAD_RWLOCK_WRLOCKED, and if there are
+ no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE.
+
+ Back in the read lock.
+
+ The read lock adjusts __readres as above.
+
+ 383 while ((r & PTHREAD_RWLOCK_WRPHASE) != 0
+ 384 && (r & PTHREAD_RWLOCK_WRLOCKED) == 0)
+ 385 {
+ ...
+ 390 if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r,
+ 391 r ^ PTHREAD_RWLOCK_WRPHASE))
+ 392 {
+
+ And then attemps to start the read phase.
+
+ Assume there happens to be a tryrdlock at this point, noting
+ that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE
+ is 1. So the try lock attemps to start the read phase.
+
+ In __pthread_rwlock_tryrdlock:
+
+ 44 if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
+ 45 {
+ ...
+ 49 if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
+ 50 && (rwlock->__data.__flags
+ 51 == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP))
+ 52 return EBUSY;
+ 53 rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT);
+ 54 }
+ ...
+ 89 while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers,
+ 90 &r, rnew));
+
+ And succeeds.
+
+ Back in the write unlock:
+
+ 557 if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0)
+ 558 {
+ ...
+ 563 if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
+ 564 & PTHREAD_RWLOCK_FUTEX_USED) != 0)
+ 565 futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
+ 566 }
+
+ We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero
+ and don't wake anyone. This is OK because we handed
+ over to the trylock. It will be the trylock's responsibility
+ to wake any waiters.
+
+ Back in the read lock:
+
+ The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because
+ the __readers value was adjusted by the trylock, and so it falls through
+ to waiting on the lock for explicit handover from either a new writer
+ or a new reader.
+
+ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
+ 449 1 | PTHREAD_RWLOCK_FUTEX_USED,
+ 450 abstime, private);
+
+ We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex
+ is in use.
+
+ At this point we have readers waiting on the read lock
+ to unlock. The wrlock is done. The trylock is finishing
+ the installation of the read phase.
+
+ 92 if ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
+ 93 {
+ ...
+ 105 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
+ 106 }
+
+ The trylock does note that we were the one that
+ installed the read phase, but the comments are not
+ correct, the execution ordering above shows that
+ readers might indeed be waiting, and they are.
+
+ The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED,
+ and the waiting reader is never worken becuase as noted
+ above it is conditional on the futex being used.
+
+ The solution is for the trylock thread to inspect
+ PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers.
+
+ --- Analysis of pthread_rwlock_trywrlock() stall ---
+
+ A write lock begins to execute, takes the write lock,
+ and then releases the lock...
+
+ In pthread_rwlock_wrunlock():
+
+ 547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
+ ...
+ 549 while (!atomic_compare_exchange_weak_release
+ 550 (&rwlock->__data.__readers, &r,
+ 551 ((r ^ PTHREAD_RWLOCK_WRLOCKED)
+ 552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
+ 553 : PTHREAD_RWLOCK_WRPHASE))))
+ 554 {
+ ...
+ 556 }
+
+ ... leaving it in the write phase with zero readers
+ (the case where we leave the write phase in place
+ during a write unlock).
+
+ A write trylock begins to execute.
+
+ In __pthread_rwlock_trywrlock:
+
+ 40 while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0)
+ 41 && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
+ 42 || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0))))
+ 43 {
+
+ The lock is not locked.
+
+ There are no readers.
+
+ 45 if (atomic_compare_exchange_weak_acquire (
+ 46 &rwlock->__data.__readers, &r,
+ 47 r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
+
+ We atomically install the write phase and we take the
+ exclusive write lock.
+
+ 48 {
+ 49 atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
+
+ We get this far.
+
+ A reader lock begins to execute.
+
+ In pthread_rwlock_rdlock:
+
+ 437 for (;;)
+ 438 {
+ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
+ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
+ 441 {
+ 442 int private = __pthread_rwlock_get_private (rwlock);
+ 443 if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
+ 444 && (!atomic_compare_exchange_weak_relaxed
+ 445 (&rwlock->__data.__wrphase_futex,
+ 446 &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)))
+ 447 continue;
+ 448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
+ 449 1 | PTHREAD_RWLOCK_FUTEX_USED,
+ 450 abstime, private);
+
+ We are in a write phase, so the while() on line 439 is true.
+
+ The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set
+ since this is the first reader to lock.
+
+ The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED
+ on the expectation that this reader will be woken during
+ the handoff.
+
+ Back in pthread_rwlock_trywrlock:
+
+ 50 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
+ 51 atomic_store_relaxed (&rwlock->__data.__cur_writer,
+ 52 THREAD_GETMEM (THREAD_SELF, tid));
+ 53 return 0;
+ 54 }
+ ...
+ 57 }
+
+ We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED,
+ and so in the unlock we will not awaken the waiting reader.
+
+ The solution to this is to realize that if we did not start the write
+ phase we need not write 1 or any other value to __wrphase_futex.
+ This ensures that any readers (which saw __wrphase_futex != 0) can
+ set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to
+ wake them.
+
+ If we installed the write phase then all other readers are looping
+ here:
+
+ In __pthread_rwlock_rdlock_full:
+
+ 437 for (;;)
+ 438 {
+ 439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
+ 440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
+ 441 {
+ ...
+ 508 }
+
+ waiting for the write phase to be installed or removed before they
+ can begin waiting on __wrphase_futex (part of the algorithm), or
+ taking a concurrent read lock, and thus we can safely write 1 to
+ __wrphase_futex.
+
+ If we did not install the write phase then the readers may already
+ be waiting on the futex, the original writer wrote 1 to __wrphase_futex
+ as part of starting the write phase, and we cannot also write 1
+ without loosing the PTHREAD_RWLOCK_FUTEX_USED bit.
+
+ ---
+
+ Summary for the pthread_rwlock_tryrdlock() stall:
+
+ The stall is caused by pthread_rwlock_tryrdlock failing to check
+ that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex
+ and then waking the futex.
+
+ The fix for bug 23844 ensures that waiters on __wrphase_futex are
+ correctly woken. Before the fix the test stalls as readers can
+ wait forever on __wrphase_futex. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <support/xthread.h>
+#include <errno.h>
+
+/* We need only one lock to reproduce the issue. We will need multiple
+ threads to get the exact case where we have a read, try, and unlock
+ all interleaving to produce the case where the readers are waiting
+ and the try fails to wake them. */
+pthread_rwlock_t onelock;
+
+/* The number of threads is arbitrary but empirically chosen to have
+ enough threads that we see the condition where waiting readers are
+ not woken by a successful tryrdlock. */
+#define NTHREADS 32
+
+_Atomic int do_exit;
+
+void *
+run_loop (void *arg)
+{
+ int i = 0, ret;
+ while (!do_exit)
+ {
+ /* Arbitrarily choose if we are the writer or reader. Choose a
+ high enough ratio of readers to writers to make it likely
+ that readers block (and eventually are susceptable to
+ stalling).
+
+ If we are a writer, take the write lock, and then unlock.
+ If we are a reader, try the lock, then lock, then unlock. */
+ if ((i % 8) != 0)
+ xpthread_rwlock_wrlock (&onelock);
+ else
+ {
+ if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0)
+ {
+ if (ret == EBUSY)
+ xpthread_rwlock_rdlock (&onelock);
+ else
+ exit (EXIT_FAILURE);
+ }
+ }
+ /* Thread does some work and then unlocks. */
+ xpthread_rwlock_unlock (&onelock);
+ i++;
+ }
+ return NULL;
+}
+
+int
+do_test (void)
+{
+ int i;
+ pthread_t tids[NTHREADS];
+ xpthread_rwlock_init (&onelock, NULL);
+ for (i = 0; i < NTHREADS; i++)
+ tids[i] = xpthread_create (NULL, run_loop, NULL);
+ /* Run for some amount of time. Empirically speaking exercising
+ the stall via pthread_rwlock_tryrdlock is much harder, and on
+ a 3.5GHz 4 core x86_64 VM system it takes somewhere around
+ 20-200s to stall, approaching 100% stall past 200s. We can't
+ wait that long for a regression test so we just test for 20s,
+ and expect the stall to happen with a 5-10% chance (enough for
+ developers to see). */
+ sleep (20);
+ /* Then exit. */
+ printf ("INFO: Exiting...\n");
+ do_exit = 1;
+ /* If any readers stalled then we will timeout waiting for them. */
+ for (i = 0; i < NTHREADS; i++)
+ xpthread_join (tids[i]);
+ printf ("INFO: Done.\n");
+ xpthread_rwlock_destroy (&onelock);
+ printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n");
+ return 0;
+}
+
+#define TIMEOUT 30
+#include <support/test-driver.c>
Index: glibc-2.29/nptl/tst-rwlock-trywrlock-stall.c
===================================================================
--- /dev/null
+++ glibc-2.29/nptl/tst-rwlock-trywrlock-stall.c
@@ -0,0 +1,108 @@
+/* Bug 23844: Test for pthread_rwlock_trywrlock stalls.
+ Copyright (C) 2019 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/>. */
+
+/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c.
+
+ Summary for the pthread_rwlock_trywrlock() stall:
+
+ The stall is caused by pthread_rwlock_trywrlock setting
+ __wrphase_futex futex to 1 and loosing the
+ PTHREAD_RWLOCK_FUTEX_USED bit.
+
+ The fix for bug 23844 ensures that waiters on __wrphase_futex are
+ correctly woken. Before the fix the test stalls as readers can
+ wait forever on __wrphase_futex. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <support/xthread.h>
+#include <errno.h>
+
+/* We need only one lock to reproduce the issue. We will need multiple
+ threads to get the exact case where we have a read, try, and unlock
+ all interleaving to produce the case where the readers are waiting
+ and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a
+ subsequent unlock fails to wake them. */
+pthread_rwlock_t onelock;
+
+/* The number of threads is arbitrary but empirically chosen to have
+ enough threads that we see the condition where waiting readers are
+ not woken by a successful unlock. */
+#define NTHREADS 32
+
+_Atomic int do_exit;
+
+void *
+run_loop (void *arg)
+{
+ int i = 0, ret;
+ while (!do_exit)
+ {
+ /* Arbitrarily choose if we are the writer or reader. Choose a
+ high enough ratio of readers to writers to make it likely
+ that readers block (and eventually are susceptable to
+ stalling).
+
+ If we are a writer, take the write lock, and then unlock.
+ If we are a reader, try the lock, then lock, then unlock. */
+ if ((i % 8) != 0)
+ {
+ if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0)
+ {
+ if (ret == EBUSY)
+ xpthread_rwlock_wrlock (&onelock);
+ else
+ exit (EXIT_FAILURE);
+ }
+ }
+ else
+ xpthread_rwlock_rdlock (&onelock);
+ /* Thread does some work and then unlocks. */
+ xpthread_rwlock_unlock (&onelock);
+ i++;
+ }
+ return NULL;
+}
+
+int
+do_test (void)
+{
+ int i;
+ pthread_t tids[NTHREADS];
+ xpthread_rwlock_init (&onelock, NULL);
+ for (i = 0; i < NTHREADS; i++)
+ tids[i] = xpthread_create (NULL, run_loop, NULL);
+ /* Run for some amount of time. The pthread_rwlock_tryrwlock stall
+ is very easy to trigger and happens in seconds under the test
+ conditions. */
+ sleep (10);
+ /* Then exit. */
+ printf ("INFO: Exiting...\n");
+ do_exit = 1;
+ /* If any readers stalled then we will timeout waiting for them. */
+ for (i = 0; i < NTHREADS; i++)
+ xpthread_join (tids[i]);
+ printf ("INFO: Done.\n");
+ xpthread_rwlock_destroy (&onelock);
+ printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n");
+ return 0;
+}
+
+#include <support/test-driver.c>
Index: glibc-2.29/support/Makefile
===================================================================
--- glibc-2.29.orig/support/Makefile
+++ glibc-2.29/support/Makefile
@@ -129,6 +129,7 @@ libsupport-routines = \
xpthread_mutexattr_settype \
xpthread_once \
xpthread_rwlock_init \
+ xpthread_rwlock_destroy \
xpthread_rwlock_rdlock \
xpthread_rwlock_unlock \
xpthread_rwlock_wrlock \
Index: glibc-2.29/support/xpthread_rwlock_destroy.c
===================================================================
--- /dev/null
+++ glibc-2.29/support/xpthread_rwlock_destroy.c
@@ -0,0 +1,26 @@
+/* pthread_rwlock_destroy with error checking.
+ Copyright (C) 2019 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/xthread.h>
+
+void
+xpthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+ xpthread_check_return ("pthread_rwlock_destroy",
+ pthread_rwlock_destroy (rwlock));
+}
Index: glibc-2.29/support/xthread.h
===================================================================
--- glibc-2.29.orig/support/xthread.h
+++ glibc-2.29/support/xthread.h
@@ -84,6 +84,7 @@ void xpthread_rwlockattr_setkind_np (pth
void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock);
+void xpthread_rwlock_destroy (pthread_rwlock_t *rwlock);
__END_DECLS

View File

@ -1,25 +0,0 @@
2019-01-31 Paul Eggert <eggert@cs.ucla.edu>
regex: fix read overrun [BZ #24114]
Problem found by AddressSanitizer, reported by Hongxu Chen in:
https://debbugs.gnu.org/34140
* posix/regexec.c (proceed_next_node):
Do not read past end of input buffer.
Index: glibc-2.29/posix/regexec.c
===================================================================
--- glibc-2.29.orig/posix/regexec.c
+++ glibc-2.29/posix/regexec.c
@@ -1293,8 +1293,10 @@ proceed_next_node (const re_match_contex
else if (naccepted)
{
char *buf = (char *) re_string_get_buffer (&mctx->input);
- if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
- naccepted) != 0)
+ if (mctx->input.valid_len - *pidx < naccepted
+ || (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
+ naccepted)
+ != 0))
return -1;
}
}

View File

@ -1,119 +0,0 @@
2019-01-13 Jim Wilson <jimw@sifive.com>
[BZ #24040]
* elf/Makefile (CFLAGS-tst-unwind-main.c): Add -DUSE_PTHREADS=0.
* elf/tst-unwind-main.c: If USE_PTHEADS, include pthread.h and error.h
(func): New.
(main): If USE_PTHREADS, call pthread_create to run func. Otherwise
call func directly.
* nptl/Makefile (tests): Add tst-unwind-thread.
(CFLAGS-tst-unwind-thread.c): Define.
* nptl/tst-unwind-thread.c: New file.
* sysdeps/unix/sysv/linux/riscv/clone.S (__thread_start): Mark ra
as undefined.
Index: glibc-2.29/elf/Makefile
===================================================================
--- glibc-2.29.orig/elf/Makefile
+++ glibc-2.29/elf/Makefile
@@ -1497,4 +1497,4 @@ $(objpfx)tst-big-note: $(objpfx)tst-big-
$(objpfx)tst-unwind-ctor: $(objpfx)tst-unwind-ctor-lib.so
-CFLAGS-tst-unwind-main.c += -funwind-tables
+CFLAGS-tst-unwind-main.c += -funwind-tables -DUSE_PTHREADS=0
Index: glibc-2.29/elf/tst-unwind-main.c
===================================================================
--- glibc-2.29.orig/elf/tst-unwind-main.c
+++ glibc-2.29/elf/tst-unwind-main.c
@@ -20,19 +20,41 @@
#include <unistd.h>
#include <support/test-driver.h>
+#if USE_PTHREADS
+# include <pthread.h>
+# include <error.h>
+#endif
+
static _Unwind_Reason_Code
callback (struct _Unwind_Context *ctx, void *arg)
{
return _URC_NO_REASON;
}
-int
-main (void)
+static void *
+func (void *a)
{
/* 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. */
+ _Unwind_Backtrace is able to reach the start routine. */
alarm (DEFAULT_TIMEOUT);
_Unwind_Backtrace (callback, 0);
+ return a;
+}
+
+int
+main (void)
+{
+#if USE_PTHREADS
+ pthread_t thr;
+ int rc = pthread_create (&thr, NULL, &func, NULL);
+ if (rc)
+ error (1, rc, "pthread_create");
+ rc = pthread_join (thr, NULL);
+ if (rc)
+ error (1, rc, "pthread_join");
+#else
+ func (NULL);
+#endif
}
Index: glibc-2.29/nptl/Makefile
===================================================================
--- glibc-2.29.orig/nptl/Makefile
+++ glibc-2.29/nptl/Makefile
@@ -320,7 +320,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 ts
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-rwlock-pwn \
- tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall
+ tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall \
+ tst-unwind-thread
tests-internal := tst-rwlock19 tst-rwlock20 \
tst-sem11 tst-sem12 tst-sem13 \
@@ -710,6 +711,8 @@ $(objpfx)tst-audit-threads: $(objpfx)tst
$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so
tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so
+CFLAGS-tst-unwind-thread.c += -funwind-tables
+
# The tests here better do not run in parallel
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
.NOTPARALLEL:
Index: glibc-2.29/nptl/tst-unwind-thread.c
===================================================================
--- /dev/null
+++ glibc-2.29/nptl/tst-unwind-thread.c
@@ -0,0 +1,2 @@
+#define USE_PTHREADS 1
+#include "../elf/tst-unwind-main.c"
Index: glibc-2.29/sysdeps/unix/sysv/linux/riscv/clone.S
===================================================================
--- glibc-2.29.orig/sysdeps/unix/sysv/linux/riscv/clone.S
+++ glibc-2.29/sysdeps/unix/sysv/linux/riscv/clone.S
@@ -69,6 +69,11 @@ L (error):
ENTRY (__thread_start)
L (thread_start):
+ /* Terminate call stack by noting ra is undefined. Use a dummy
+ .cfi_label to force starting the FDE. */
+ .cfi_label .Ldummy
+ cfi_undefined (ra)
+
/* Restore the arg for user's function. */
REG_L a1,0(sp) /* Function pointer. */
REG_L a0,SZREG(sp) /* Argument pointer. */

View File

@ -1,19 +0,0 @@
2019-03-21 Stefan Liebler <stli@linux.ibm.com>
* sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT):
Add HWCAP_S390_VX and HWCAP_S390_VXE.
Index: glibc-2.29/sysdeps/s390/dl-procinfo.h
===================================================================
--- glibc-2.29.orig/sysdeps/s390/dl-procinfo.h
+++ glibc-2.29/sysdeps/s390/dl-procinfo.h
@@ -57,7 +57,8 @@ enum
};
#define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
- | HWCAP_S390_EIMM | HWCAP_S390_DFP)
+ | HWCAP_S390_EIMM | HWCAP_S390_DFP \
+ | HWCAP_S390_VX | HWCAP_S390_VXE)
/* We cannot provide a general printing function. */
#define _dl_procinfo(type, word) -1

View File

@ -1,19 +0,0 @@
2019-03-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
[BZ #24162]
* localedata/locales/ja_JP (LC_TIME): Change the offset for Taisho
gan-nen from 2 to 1. Problem reported by Morimitsu, Junji.
Index: glibc-2.29/localedata/locales/ja_JP
===================================================================
--- glibc-2.29.orig/localedata/locales/ja_JP
+++ glibc-2.29/localedata/locales/ja_JP
@@ -14953,7 +14953,7 @@ era "+:2:2020//01//01:+*:<U4EE4><U548C>:
"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
"+:2:1913//01//01:1926//12//24:<U5927><U6B63>:%EC%Ey<U5E74>";/
- "+:2:1912//07//30:1912//12//31:<U5927><U6B63>:%EC<U5143><U5E74>";/
+ "+:1:1912//07//30:1912//12//31:<U5927><U6B63>:%EC<U5143><U5E74>";/
"+:6:1873//01//01:1912//07//29:<U660E><U6CBB>:%EC%Ey<U5E74>";/
"+:1:0001//01//01:1872//12//31:<U897F><U66A6>:%EC%Ey<U5E74>";/
"+:1:-0001//12//31:-*:<U7D00><U5143><U524D>:%EC%Ey<U5E74>"

View File

@ -1,100 +0,0 @@
2019-05-15 Andreas Schwab <schwab@suse.de>
[BZ #20568]
* libio/wfileops.c (_IO_wfile_sync): Correct last argument to
__codecvt_do_length.
* libio/Makefile (tests): Add tst-wfile-sync.
($(objpfx)tst-wfile-sync.out): Depend on $(gen-locales).
* libio/tst-wfile-sync.c: New file.
* libio/tst-wfile-sync.input: New file.
Index: glibc-2.29/libio/Makefile
===================================================================
--- glibc-2.29.orig/libio/Makefile
+++ glibc-2.29/libio/Makefile
@@ -65,7 +65,7 @@ tests = tst_swprintf tst_wprintf tst_sws
tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
- tst-sprintf-ub tst-sprintf-chk-ub
+ tst-sprintf-ub tst-sprintf-chk-ub tst-wfile-sync
tests-internal = tst-vtables tst-vtables-interposed tst-readline
@@ -212,6 +212,7 @@ $(objpfx)tst-ungetwc1.out: $(gen-locales
$(objpfx)tst-ungetwc2.out: $(gen-locales)
$(objpfx)tst-widetext.out: $(gen-locales)
$(objpfx)tst_wprintf2.out: $(gen-locales)
+$(objpfx)tst-wfile-sync.out: $(gen-locales)
endif
$(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen
Index: glibc-2.29/libio/tst-wfile-sync.c
===================================================================
--- /dev/null
+++ glibc-2.29/libio/tst-wfile-sync.c
@@ -0,0 +1,39 @@
+/* Test that _IO_wfile_sync does not crash (bug 20568).
+ Copyright (C) 2019 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 <locale.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+
+static int
+do_test (void)
+{
+ TEST_VERIFY_EXIT (setlocale (LC_ALL, "de_DE.UTF-8") != NULL);
+ /* Fill the stdio buffer and advance the read pointer. */
+ TEST_VERIFY_EXIT (fgetwc (stdin) != WEOF);
+ /* This calls _IO_wfile_sync, it should not crash. */
+ TEST_VERIFY_EXIT (setvbuf (stdin, NULL, _IONBF, 0) == 0);
+ /* Verify that the external file offset has been synchronized. */
+ TEST_COMPARE (xlseek (0, 0, SEEK_CUR), 1);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
Index: glibc-2.29/libio/tst-wfile-sync.input
===================================================================
--- /dev/null
+++ glibc-2.29/libio/tst-wfile-sync.input
@@ -0,0 +1 @@
+This is a test of _IO_wfile_sync.
Index: glibc-2.29/libio/wfileops.c
===================================================================
--- glibc-2.29.orig/libio/wfileops.c
+++ glibc-2.29/libio/wfileops.c
@@ -508,11 +508,12 @@ _IO_wfile_sync (FILE *fp)
generate the wide characters up to the current reading
position. */
int nread;
-
+ size_t wnread = (fp->_wide_data->_IO_read_ptr
+ - fp->_wide_data->_IO_read_base);
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
fp->_IO_read_base,
- fp->_IO_read_end, delta);
+ fp->_IO_read_end, wnread);
fp->_IO_read_ptr = fp->_IO_read_base + nread;
delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
}