ports/core (3.4): [notify] glibc: updated to 2.24-10. Fix for CVE-2018-1000001
commit 9a5975b0aaed19d3c06f69dd46e36c7c23f3fe69 Author: Fredrik Rinnestam <fredrik@crux.nu> Date: Fri Jan 19 15:05:14 2018 +0100 [notify] glibc: updated to 2.24-10. Fix for CVE-2018-1000001 diff --git a/glibc/.md5sum b/glibc/.md5sum index 757ebc60..c6cb1113 100644 --- a/glibc/.md5sum +++ b/glibc/.md5sum @@ -1,6 +1,5 @@ -bcfb2cb7f1cb0b4ecce27fcd5d5d2b21 0001-CVE-2017-15670-glob-Fix-one-byte-overflow-BZ-22320.patch aaad345ff18993dafe3e44ac947f7157 glibc-2.20-multilib-dirs.patch -cb9c54c9d22b3ab597a69d05420b5e80 glibc-2.24.8.patch +4382c5b030a4995a9a4649dd735f6685 glibc-2.24-10.patch 97dc5517f92016f3d70d83e3162ad318 glibc-2.24.tar.xz 96156bec8e05de67384dc93e72bdc313 host.conf fbbc215a9b15ba4846f326cc88108057 hosts diff --git a/glibc/.signature b/glibc/.signature index e37cfd3e..05d98733 100644 --- a/glibc/.signature +++ b/glibc/.signature @@ -1,6 +1,6 @@ untrusted comment: verify with /etc/ports/core.pub -RWRJc1FUaeVeqgAZOOo9pTZ8Kkhyn33vUDz6ZScBxuUJQ6SeGXgbji+1Hk8NhAeXhzpTxD/z+samesI/MdBUnJ7FWpznMnezQgk= -SHA256 (Pkgfile) = 5d3c266de36bc04680358a4a7231bd7de49ead7e44da17d6a7edcb2a8d4cc3b5 +RWRJc1FUaeVeqsBKjyM8wdd/C2rlJ/gFfK8cx67MV3xb/bI841ZYrLyS3oFcfaUv3weOhVQjgQpN8ToKwmEykQRHEtqCvlfzgA8= +SHA256 (Pkgfile) = 4edcaa1db1ba626fa4970327676b6623d925ab76831a5bcaac4ec5a6be4184fc SHA256 (.footprint) = 9bfd444359441e61174162207102b96597aa3a7051b4c5d8401d9d0e2713ec81 SHA256 (glibc-2.24.tar.xz) = 99d4a3e8efd144d71488e478f62587578c0f4e1fa0b4eed47ee3d4975ebeb5d3 SHA256 (kernel-headers-4.9.5.tar.xz) = 5783ad8f668ee71561fae370fbcdc477aaa6df249bd85635b87a8c204aeb4aa9 @@ -10,5 +10,4 @@ SHA256 (resolv.conf) = 72ccb58768a72a771ec37142bc361a18478a07ec9de6e925a20760794 SHA256 (nsswitch.conf) = 859b8984e5e90aff3cce8f9779996ae4033b280d2122840e9411e2f44a1c2e61 SHA256 (host.conf) = 1bffc6575eb6204458758c34656cd44d87e7d89f545055f8857dd8906b7fb277 SHA256 (ld.so.conf) = 441a37924864b5b063208922ea04a926cd9654e74ed3f160b9d455b56d23387f -SHA256 (glibc-2.24.8.patch) = 314fe8ec41042a85991e830a002abf2ff0b98dc4467afa238d8bb369d3be7cca -SHA256 (0001-CVE-2017-15670-glob-Fix-one-byte-overflow-BZ-22320.patch) = 3f634bf301eb8bab57e5ea552de3f694fb063ab45af3cc91990e1bc24f280ddd +SHA256 (glibc-2.24-10.patch) = 166d8a11ef5e616e65f5f626ad0a47b881712865ceef6e78bb4bc9bdc8af2c55 diff --git a/glibc/0001-CVE-2017-15670-glob-Fix-one-byte-overflow-BZ-22320.patch b/glibc/0001-CVE-2017-15670-glob-Fix-one-byte-overflow-BZ-22320.patch deleted file mode 100644 index bc410b26..00000000 --- a/glibc/0001-CVE-2017-15670-glob-Fix-one-byte-overflow-BZ-22320.patch +++ /dev/null @@ -1,765 +0,0 @@ -From b9911eb529e51ebe7c5daa3b4f17e2caf7ddb9a4 Mon Sep 17 00:00:00 2001 -From: Fredrik Rinnestam <fredrik@crux.nu> -Date: Sun, 22 Oct 2017 16:18:40 +0200 -Subject: [PATCH] CVE-2017-15670: glob: Fix one-byte overflow [BZ #22320] - ---- - ChangeLog | 10 + - NEWS | 701 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - posix/glob.c | 2 +- - 3 files changed, 712 insertions(+), 1 deletion(-) - -diff --git a/ChangeLog b/ChangeLog -index 84189ec762..1fb38cb7ee 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,4 @@ -+<<<<<<< HEAD - 2017-10-19 H.J. Lu <hongjiu.lu@intel.com> - - * sysdeps/x86_64/Makefile (tests): Add tst-sse, tst-avx and -@@ -20,6 +21,15 @@ - * sysdeps/x86_64/tst-avxmod.c: Likewise. - * sysdeps/x86_64/tst-sse.c: Likewise. - * sysdeps/x86_64/tst-ssemod.c: Likewise. -+======= -+2017-10-20 Paul Eggert <eggert@cs.ucla.edu> -+ -+ [BZ #22320] -+ CVE-2017-15670 -+ * posix/glob.c (__glob): Fix one-byte overflow. -+ -+2017-10-20 Wilco Dijkstra <wdijkstr@arm.com> -+>>>>>>> c369d66e54... CVE-2017-15670: glob: Fix one-byte overflow [BZ #22320] - - 2017-10-19 H.J. Lu <hongjiu.lu@intel.com> - -diff --git a/NEWS b/NEWS -index 4831542023..90cae42eee 100644 ---- a/NEWS -+++ b/NEWS -@@ -5,7 +5,708 @@ See the end for copying conditions. - Please send GNU C library bug reports via <http://sourceware.org/bugzilla/> - using `glibc' in the "product" field. - -+<<<<<<< HEAD - Version 2.24.1 -+======= -+Version 2.27 -+ -+Major new features: -+ -+* Optimized x86-64 asin, atan2, exp, expf, log, pow, atan, sin and tan -+ with FMA, contributed by Arjan van de Ven and H.J. Lu from Intel. -+ -+* Optimized x86-64 trunc and truncf for processors with SSE4.1. -+ -+* Optimized generic expf, exp2f, logf, log2f and powf. -+ -+* In order to support faster and safer process termination the malloc API -+ family of functions will no longer print a failure address and stack -+ backtrace after detecting heap corruption. The goal is to minimize the -+ amount of work done after corruption is detected and to avoid potential -+ security issues in continued process execution. Reducing shutdown time -+ leads to lower overall process restart latency, so there is benefit both -+ from a security and performance perspective. -+ -+* The abort function terminates the process immediately, without flushing -+ stdio streams. Previous glibc versions used to flush streams, resulting -+ in deadlocks and further data corruption. This change also affects -+ process aborts as the result of assertion failures. -+ -+* On platforms where long double has the IEEE binary128 format (aarch64, -+ alpha, mips64, s390 and sparc), the math library now implements _Float128 -+ interfaces for that type, as defined by ISO/IEC TS 18661-3:2015. These -+ are the same interfaces added in version 2.26 for some platforms where -+ this format is supported but is not the format of long double. -+ -+Deprecated and removed features, and other changes affecting compatibility: -+ -+* On GNU/Linux, the obsolete Linux constant PTRACE_SEIZE_DEVEL is no longer -+ defined by <sys/ptrace.h>. -+ -+* libm no longer supports SVID error handling (calling a user-provided -+ matherr function on error) or the _LIB_VERSION variable to control error -+ handling. (SVID error handling and the _LIB_VERSION variable still work -+ for binaries linked against older versions of the GNU C Library.) The -+ libieee.a library is no longer provided. math.h no longer defines struct -+ exception, or the macros X_TLOSS, DOMAIN, SING, OVERFLOW, UNDERFLOW, -+ TLOSS, PLOSS and HUGE. -+ -+* The libm functions pow10, pow10f and pow10l are no longer supported for -+ new programs. Programs should use the standard names exp10, exp10f and -+ exp10l for these functions instead. -+ -+* The mcontext_t type is no longer the same as struct sigcontext. On -+ platforms where it was previously the same, this changes the C++ name -+ mangling for interfaces involving this type. -+ -+* The add-ons mechanism for building additional packages at the same time as -+ glibc has been removed. The --enable-add-ons configure option is now -+ ignored. -+ -+Changes to build and runtime requirements: -+ -+ [Add changes to build and runtime requirements here] -+ -+Security related changes: -+ -+ CVE-2009-5064: The ldd script would sometimes run the program under -+ examination directly, without preventing code execution through the -+ dynamic linker. (The glibc project disputes that this is a security -+ vulnerability; only trusted binaries must be examined using the ldd -+ script.) -+ -+ CVE-2017-15670: The glob function, when invoked with GLOB_TILDE, suffered -+ from a one-byte overflow during ~ operator processing (either on the stack -+ or the heap, depending on the length of the user name). -+ -+The following bugs are resolved with this release: -+ -+ [The release manager will add the list generated by -+ scripts/list-fixed-bugs.py just before the release.] -+ -+ -+Version 2.26 -+ -+Major new features: -+ -+* A per-thread cache has been added to malloc. Access to the cache requires -+ no locks and therefore significantly accelerates the fast path to allocate -+ and free small amounts of memory. Refilling an empty cache requires locking -+ the underlying arena. Performance measurements show significant gains in a -+ wide variety of user workloads. Workloads were captured using a special -+ instrumented malloc and analyzed with a malloc simulator. Contributed by -+ DJ Delorie with the help of Florian Weimer, and Carlos O'Donell. -+ -+* Unicode 10.0.0 Support: Character encoding, character type info, and -+ transliteration tables are all updated to Unicode 10.0.0, using -+ generator scripts contributed by Mike FABIAN (Red Hat). -+ These updates cause user visible changes, especially the changes in -+ wcwidth for many emoji characters cause problems when emoji sequences -+ are rendered with pango, see for example: -+ https://bugzilla.gnome.org/show_bug.cgi?id=780669#c5 -+ -+* Collation of Hungarian has been overhauled and is now consistent with "The -+ Rules of Hungarian Orthography, 12th edition" (Bug 18934). Contributed by -+ Egmont Koblinger. -+ -+* Improvements to the DNS stub resolver, contributed by Florian Weimer: -+ -+ - The GNU C Library will now detect when /etc/resolv.conf has been -+ modified and reload the changed configuration. The new resolver option -+ “no-reload” (RES_NORELOAD) disables this behavior. -+ -+ - The GNU C Library now supports an arbitrary number of search domains -+ (configured using the “search” directive in /etc/resolv.conf); -+ previously, there was a hard limit of six domains. For backward -+ compatibility, applications that directly modify the ‘_res’ global -+ object are still limited to six search domains. -+ -+ - When the “rotate” (RES_ROTATE) resolver option is active, the GNU C -+ Library will now randomly pick a name server from the configuration as a -+ starting point. (Previously, the second name server was always used.) -+ -+* The tunables feature is now enabled by default. This allows users to tweak -+ behavior of the GNU C Library using the GLIBC_TUNABLES environment variable. -+ -+* New function reallocarray, which resizes an allocated block (like realloc) -+ to the product of two sizes, with a guaranteed clean failure upon integer -+ overflow in the multiplication. Originally from OpenBSD, contributed by -+ Dennis Wölfing and Rüdiger Sonderfeld. -+ -+* New wrappers for the Linux-specific system calls preadv2 and pwritev2. -+ These are extended versions of preadv and pwritev, respectively, taking an -+ additional flags argument. The set of supported flags depends on the -+ running kernel; full support currently requires kernel 4.7 or later. -+ -+* posix_spawnattr_setflags now supports the flag POSIX_SPAWN_SETSID, to -+ create a new session ID for the spawned process. This feature is -+ scheduled to be added to the next major revision of POSIX; for the time -+ being, it is available under _GNU_SOURCE. -+ -+* errno.h is now safe to use from C-preprocessed assembly language on all -+ supported operating systems. In this context, it will only define the -+ Exxxx constants, as preprocessor macros expanding to integer literals. -+ -+* On ia64, powerpc64le, x86-32, and x86-64, the math library now implements -+ 128-bit floating point as defined by ISO/IEC/IEEE 60559:2011 (IEEE -+ 754-2008) and ISO/IEC TS 18661-3:2015. Contributed by Paul E. Murphy, -+ Gabriel F. T. Gomes, Tulio Magno Quites Machado Filho, and Joseph Myers. -+ -+ To compile programs that use this feature, the compiler must support -+ 128-bit floating point with the type name _Float128 (as defined by TS -+ 18661-3) or __float128 (the nonstandard name used by GCC for C++, and for -+ C prior to version 7). _GNU_SOURCE or __STDC_WANT_IEC_60559_TYPES_EXT__ -+ must be defined to make the new interfaces visible. -+ -+ The new functions and macros correspond to those present for other -+ floating-point types (except for a few obsolescent interfaces not -+ supported for the new type), with F128 or f128 suffixes; for example, -+ strtof128, HUGE_VAL_F128 and cosf128. Following TS 18661-3, there are no -+ printf or scanf formats for the new type; the strfromf128 and strtof128 -+ interfaces should be used instead. -+ -+Deprecated and removed features, and other changes affecting compatibility: -+ -+* The synchronization that pthread_spin_unlock performs has been changed to -+ now be equivalent to a C11 atomic store with release memory order to the -+ spin lock's memory location. Previously, several (but not all) -+ architectures used stronger synchronization (e.g., containing what is -+ often called a full barrier). This change can improve performance, but -+ may affect odd fringe uses of spin locks that depend on the previous -+ behavior (e.g., using spin locks as atomic variables to try to implement -+ Dekker's mutual exclusion algorithm). -+ -+* The port to Native Client running on ARMv7-A (--host=arm-nacl) has been -+ removed. -+ -+* Sun RPC is deprecated. The rpcgen program, librpcsvc, and Sun RPC headers -+ will only be built and installed when the GNU C Library is configured with -+ --enable-obsolete-rpc. This allows alternative RPC implementations, such -+ as TIRPC or rpcsvc-proto, to be used. -+ -+* The NIS(+) name service modules, libnss_nis, libnss_nisplus, and -+ libnss_compat, are deprecated, and will not be built or installed by -+ default. -+ -+ The NIS(+) support library, libnsl, is also deprecated. By default, a -+ compatibility shared library will be built and installed, but not headers -+ or development libraries. Only a few NIS-related programs require this -+ library. (In particular, the GNU C Library has never required programs -+ that use 'gethostbyname' to be linked with libnsl.) -+ -+ Replacement implementations based on TIRPC, which additionally support -+ IPv6, are available from <https://github.com/thkukuk/>. The configure -+ option --enable-obsolete-nsl will cause libnsl's headers, and the NIS(+) -+ name service modules, to be built and installed. -+ -+* The DNS stub resolver no longer performs EDNS fallback. If EDNS or DNSSEC -+ support is enabled, the configured recursive resolver must support EDNS. -+ (Responding to EDNS-enabled queries with responses which are not -+ EDNS-enabled is fine, but FORMERR responses are not.) -+ -+* res_mkquery and res_nmkquery no longer support the IQUERY opcode. DNS -+ servers have not supported this opcode for a long time. -+ -+* The _res_opcodes variable has been removed from libresolv. It had been -+ exported by accident. -+ -+* <string.h> no longer includes inline versions of any string functions, -+ as this kind of optimization is better done by the compiler. The macros -+ __USE_STRING_INLINES and __NO_STRING_INLINES no longer have any effect. -+ -+* The nonstandard header <xlocale.h> has been removed. Most programs should -+ use <locale.h> instead. If you have a specific need for the definition of -+ locale_t with no other declarations, please contact -+ libc-alpha@sourceware.org and explain. -+ -+* The obsolete header <sys/ultrasound.h> has been removed. -+ -+* The obsolete signal constant SIGUNUSED is no longer defined by <signal.h>. -+ -+* The obsolete function cfree has been removed. Applications should use -+ free instead. -+ -+* The stack_t type no longer has the name struct sigaltstack. This changes -+ the C++ name mangling for interfaces involving this type. -+ -+* The ucontext_t type no longer has the name struct ucontext. This changes -+ the C++ name mangling for interfaces involving this type. -+ -+* On M68k GNU/Linux and MIPS GNU/Linux, the fpregset_t type no longer has -+ the name struct fpregset. On Nios II GNU/Linux, the mcontext_t type no -+ longer has the name struct mcontext. On SPARC GNU/Linux, the struct -+ mc_fq, struct rwindow, struct fpq and struct fq types are no longer -+ defined in sys/ucontext.h, the mc_fpu_t type no longer has the name struct -+ mc_fpu, the gwindows_t type no longer has the name struct gwindows and the -+ fpregset_t type no longer has the name struct fpu. This changes the C++ -+ name mangling for interfaces involving those types. -+ -+* On S/390 GNU/Linux, the constants defined by <sys/ptrace.h> have been -+ synced with the kernel: -+ -+ - PTRACE_GETREGS, PTRACE_SETREGS, PTRACE_GETFPREGS and PTRACE_SETFPREGS -+ are not supported on this architecture and have been removed. -+ -+ - PTRACE_SINGLEBLOCK, PTRACE_SECCOMP_GET_FILTER, PTRACE_PEEKUSR_AREA, -+ PTRACE_POKEUSR_AREA, PTRACE_GET_LAST_BREAK, PTRACE_ENABLE_TE, -+ PTRACE_DISABLE_TE and PTRACE_TE_ABORT_RAND have been added. -+ -+ Programs that assume the GET/SETREGS ptrace requests are universally -+ available will now fail to build, instead of malfunctioning at runtime. -+ -+Changes to build and runtime requirements: -+ -+* Linux kernel 3.2 or later is required at runtime, on all architectures -+ supported by that kernel. (This is a change from version 2.25 only for -+ x86-32 and x86-64.) -+ -+* GNU Binutils 2.25 or later is now required to build the GNU C Library. -+ -+* On most architectures, GCC 4.9 or later is required to build the GNU C -+ Library. On powerpc64le, GCC 6.2 or later is required. -+ -+ Older GCC versions and non-GNU compilers are still supported when -+ compiling programs that use the GNU C Library. (We do not know exactly -+ how old, and some GNU extensions to C may be _de facto_ required. If you -+ are interested in helping us make this statement less vague, please -+ contact libc-alpha@sourceware.org.) -+ -+Security related changes: -+ -+* The DNS stub resolver limits the advertised UDP buffer size to 1200 bytes, -+ to avoid fragmentation-based spoofing attacks (CVE-2017-12132). -+ -+* LD_LIBRARY_PATH is now ignored in binaries running in privileged AT_SECURE -+ mode to guard against local privilege escalation attacks (CVE-2017-1000366). -+ -+* Avoid printing a backtrace from the __stack_chk_fail function since it is -+ called on a corrupt stack and a backtrace is unreliable on a corrupt stack -+ (CVE-2010-3192). -+ -+* A use-after-free vulnerability in clntudp_call in the Sun RPC system has been -+ fixed (CVE-2017-12133). -+ -+The following bugs are resolved with this release: -+ -+ [984] network: Respond to changed resolv.conf in gethostbyname -+ [5010] network: sunrpc service cleanup causes unwanted port mapper traffic -+ [12068] localedata: sc_IT: misspelled yesexpr/day/abday/mon/abmon/date_fmt -+ fields -+ [12189] libc: __stack_chk_fail should not attempt a backtrace -+ (CVE-2010-3192) -+ [14096] time: Race condition on timezone/tst-timezone.out -+ [14172] localedata: az_IR: new locale -+ [14995] build: glibc fails to build if gold is the default linker, even if -+ ld.bfd is available -+ [15998] build: [powerpc] Set arch_minimum_kernel for powerpc LE -+ [16637] network: inet_pton function is accepting IPv6 with bad format -+ [16640] string: string/strtok.c: undefined behaviour inconsistent between -+ x86 and other generic code -+ [16875] localedata: ko_KR: fix lang_name -+ [17225] localedata: ar_SY: localized month names for May and June are -+ incorrect -+ [17297] localedata: da_DK: wrong date_fmt string -+ [18907] stdio: Incorrect order of __wur __THROW in <printf.h> -+ [18934] localedata: hu_HU: collate: fix multiple bugs and add tests -+ [18988] nptl: pthread wastes memory with mlockall(MCL_FUTURE) -+ [19066] localedata: ar_SA abbreviated day and month names are in English -+ [19569] network: resolv: Support an arbitrary number of search domains -+ [19570] network: Implement random DNS server selection in the stub -+ resolver -+ [19838] locale: localedef fails on PA-RISC -+ [19919] localedata: iso14651_t1_common: Correct the Malayalam sorting -+ order of 0D36 and 0D37 -+ [19922] localedata: iso14651_t1_common: Define collation for Malayalam -+ chillu characters -+ [20098] libc: FAIL: debug/backtrace-tst on hppa -+ [20257] network: sunrpc: clntudp_call does not enforce timeout when -+ receiving data -+ [20275] localedata: locale day/abday/mon/abmon should not have trailing -+ whitespace -+ [20313] localedata: Update locale data to Unicode 9.0 -+ [20424] manual: Document how to provide a malloc replacement -+ [20496] localedata: agr_PE: new language locale Awajún / Aguaruna (agr) -+ for Peru -+ [20686] locale: Add el_GR@euro to SUPPORTED. -+ [20831] dynamic-link: _dl_map_segments does not test for __mprotect -+ failures consistently -+ [21015] dynamic-link: Document and fix --enable-bind-now -+ [21016] nptl: pthread_cond support is broken on hppa -+ [21029] libc: glibc-2.23 (and later) fails to compile with -fno-omit- -+ frame-pointer on i386 -+ [21049] libc: segfault in longjmp_chk() due to clobbered processor -+ register -+ [21075] libc: unused assigment to %g4 in sparc/sparc{64,32}/clone.S -+ [21088] libc: Build fails with --enable-static-nss -+ [21094] math: cosf(1.57079697) has 3 ulp error on targets where the -+ generic c code is used -+ [21109] libc: Tunables broken on big-endian -+ [21112] math: powf has large ulp errors with base close to 1 and exponent -+ around 4000 -+ [21115] network: sunrpc: Use-after-free in error path in clntudp_call -+ (CVE-2017-12133) -+ [21120] malloc: glibc malloc is incompatible with GCC 7 -+ [21130] math: Incorrect return from y0l (-inf) and y1l (-inf) when linking -+ with -lieee -+ [21134] math: Exception (divide by zero) not set for y0/y1 (0.0) and y0/y1 -+ (-0.0) when linking with -lieee -+ [21171] math: log10, log2 and lgamma return incorrect results -+ [21179] libc: handle R_SPARC_DISP64 and R_SPARC_REGISTER relocs -+ [21182] libc: __memchr_sse2: regression in glibc-2.25 on i686 -+ [21207] localedata: ce_RU: update weekdays from CLDR -+ [21209] dynamic-link: LD_HWCAP_MASK read in setuid binaries -+ [21217] localedata: Update months from CLDR-31 -+ [21232] libc: miss posix_fadvise64 on MIPS64 when static linking -+ [21243] libc: support_delete_temp_file should issue warning for failed -+ remove() -+ [21244] libc: support resolv_test_start() socket fd close should be -+ checked for errors. -+ [21253] libc: localedef randomly segfaults when using -fstack-check due to -+ new posix_spawn implementation -+ [21258] dynamic-link: Branch predication in _dl_runtime_resolve_avx512_opt -+ leads to lower CPU frequency -+ [21259] libc: [alpha] termios.h missing IXANY for POSIX -+ [21261] libc: [sparc64] bits/setjmp.h namespace -+ [21267] network: [mips] bits/socket.h IOC* namespace -+ [21268] libc: [alpha] termios.h NL2, NL3 namespace -+ [21270] libc: mmap64 silently truncates large offset values -+ [21275] libc: posix_spawn always crashes on ia64 now -+ [21277] libc: [alpha] termios.h missing IUCLC for UNIX98 and older -+ [21280] math: [powerpc] logbl for POWER7 return incorrect results -+ [21289] libc: Incorrect declaration for 32-bit platforms with -+ _FILE_OFFSET_BITS=64 causes build error -+ [21295] network: GETAI(AF_UNSPEC) drops IPv6 addresses if nss module does -+ not support gethostbyname4_r -+ [21298] nptl: rwlock can deadlock on frequent reader/writer phase -+ switching -+ [21338] malloc: mallopt M_ARENA_MAX doesn't set the maximum number of -+ arenas -+ [21340] libc: Support POSIX_SPAWN_SETSID -+ [21357] libc: unwind-dw2-fde deadlock when using AddressSanitizer -+ [21359] network: ns_name_pack needs additional byte in destination buffer -+ [21361] network: resolv: Reduce advertised EDNS0 buffer size to guard -+ against fragmentation attacks (CVE-2017-12132) -+ [21369] network: resolv: Remove EDNS fallback -+ [21371] libc: Missing timespec definition when compiled with _XOPEN_SOURCE -+ and _POSIX_C_SOURCE -+ [21386] nptl: Assertion in fork for distinct parent PID is incorrect -+ [21391] dynamic-link: x86: Set dl_platform and dl_hwcap from CPU features -+ [21393] stdio: Missing dup3 error check in freopen, freopen64 -+ [21396] libc: Use AVX2 memcpy/memset on Skylake server -+ [21399] localedata: Bad description for U00EC in -+ localedata/charmaps/CP1254 -+ [21411] malloc: realloc documentation error -+ [21426] network: sys/socket.h uio.h namespace -+ [21428] libc: [aarch64] tst-backtrace5 testsuite failure -+ [21445] libc: signal.h bsd_signal namespace -+ [21455] network: Network headers stdint.h namespace -+ [21474] network: resolv: res_init does not use RES_DFLRETRY (2) but 4 for -+ retry value -+ [21475] network: resolv: Overlong search path is truncated mid-label -+ [21511] libc: sigstack namespace -+ [21512] libc: clone() ends up calling exit_group() through _exit() wrapper -+ [21514] libc: sysdeps/unix/sysv/linux/sys/syscall.h:31:27: fatal error: -+ bits/syscall.h: No such file or directory -+ [21517] libc: struct sigaltstack namespace -+ [21528] dynamic-link: Duplicated minimal strtoul implementations in ld.so -+ [21533] localedata: Update locale data to Unicode 10.0 -+ [21537] libc: -+ ../sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S:44: Error: -+ junk at end of line, first unrecognized character is `@' -+ [21538] libc: SIG_HOLD missing for XPG4 -+ [21539] libc: S390: Mismatch between kernel and glibc ptrace.h with -+ request 12: PTRACE_SINGLEBLOCK vs PTRACE_GETREGS. -+ [21542] libc: Use conservative default for sysconf (_SC_NPROCESSORS_ONLN) -+ [21543] libc: sigevent namespace -+ [21548] libc: [mips] get/set/make/swap context for MIPS O32 assume wrong -+ size for general purpose registers in mcontext_t structure -+ [21550] libc: sigwait namespace -+ [21552] libc: XPG4 bsd_signal namespace -+ [21554] libc: sigpause namespace -+ [21560] libc: sys/wait.h signal.h namespace -+ [21561] libc: waitid namespace -+ [21573] nptl: GCC 7: /usr/bin/install: cannot remove -+ '/usr/include/stdlib.h': Permission denied -+ [21575] libc: sys/wait.h missing struct rusage definition -+ [21584] libc: sigaltstack etc namespace -+ [21597] libc: siginterrupt namespace -+ [21607] math: hppa: FAIL: math/test-tgmath -+ [21609] dynamic-link: Incomplete workaround for GCC __tls_get_addr ABI -+ issue on x86-64 -+ [21622] libc: [tile] missing SA_* for POSIX.1:2008 -+ [21624] dynamic-link: ld.so: Unsafe alloca allows local attackers to alias -+ stack and heap (CVE-2017-1000366) -+ [21625] libc: wait3 namespace -+ [21654] nss: Incorrect pointer alignment in NSS group merge result -+ construction -+ [21657] network: Parse interface zone id for node-local multicast -+ [21662] string: memcmp-avx2-movbe.S lacks saturating subtraction for -+ between_2_3 -+ [21666] libc: .symver is used on common symbol -+ [21668] network: resolv: res_init cross-thread broadcast introduces race -+ conditions -+ [21687] math: tgmath.h totalorder, totalordermag return type -+ [21694] locale: Current Glibc Locale Does Not Support Tok-Pisin and Fiji -+ Hindi Locale -+ [21696] libc: Incorrect assumption of of __cpu_mask in -+ posix/sched_cpucount.c -+ [21697] libc: sysdeps/posix/spawni.c: 2 * suspicious condition ? -+ [21706] localedata: yesstr and nostr are missing for Breton [LC_MESSAGES] -+ locale -+ [21707] math: ppc64le: Invalid IFUNC resolver from libgcc calls getauxval, -+ leading to relocation crash -+ [21709] libc: resolv_conf.c:552: update_from_conf: Assertion -+ `resolv_conf_matches (resp, conf)' failed. -+ [21710] localedata: Added Samoan language locale for Samoa -+ [21711] localedata: Pashto yesstr/nostr locale are missing -+ [21715] nptl: sysdeps/nptl/bits/pthreadtypes.h: typedef guard -+ __have_pthread_attr_t can cause redefinition of typedef ‘pthread_attr_t’ -+ [21721] localedata: Incorrect Full Weekday names for ks_IN@devanagari -+ [21723] localedata: yesstr/nostr missing for Chinese language locale -+ [21724] localedata: yesstr and nostr are missing for Xhosa [LC_MESSAGES] -+ locale -+ [21727] localedata: yesstr and nostr are missing for Tsonga [LC_MESSAGES] -+ locale -+ [21728] localedata: New Locale for Tongan language -+ [21729] localedata: incorrect LC_NAME fields for hi_IN -+ [21733] localedata: yesstr and nostr are missing for zh_HK -+ [21734] localedata: Missing yesstr and nostr are for kw_GB -+ [21738] libc: misc/tst-preadvwritev2 and misc/tst-preadvwritev64v2 fail -+ [21741] libc: Undefined __memmove_chk_XXX and __memset_chk_XXX in libc.a -+ [21742] libc: _dl_num_cache_relocations is undefined in libc.a -+ [21743] localedata: ks_IN@devanagari: abday strings mismatch the day -+ strings -+ [21744] libc: Tests failing on --enable-tunables --enable-stack- -+ protector=all -+ [21749] localedata: Wrong abbreviated day name (“abday”) for -+ ar_JO/ar_LB/ar_SY -+ [21756] localedata: missing yesstr, nostr for nds_DE and nds_NL -+ [21757] localedata: missing yesstr, nostr for pap_AW and pap_CW -+ [21759] localedata: missing yesstr and nostr for Tigrinya -+ [21760] localedata: Fix LC_MESSAGES and LC_ADDRESS for anp_IN -+ [21766] localedata: Wrong LC_MESSAGES for om_ET Locale -+ [21767] localedata: Missing Bislama locales -+ [21768] localedata: Missing yesstr and nostr for aa_ET -+ [21770] localedata: Missing Field in li_NL -+ [21778] nptl: Robust mutex may deadlock -+ [21779] libc: MicroBlaze segfaults when loading libpthread -+ [21783] localedata: Fix int_select international_call_prefixes -+ [21784] localedata: Inconsistency in country_isbn -+ [21788] localedata: Missing Country Postal Abbreviations -+ [21794] localedata: Added-country_isbn-for-Italy -+ [21795] localedata: Add/Fix country_isbn for France -+ [21796] localedata: Added country_isbn for Republic of Korea -+ [21797] localedata: Fix inconsistency in country_isbn and missing prefixes -+ [21799] localedata: Added int_select international_call_prefixes -+ [21801] localedata: Added int_select international_call_prefixes -+ [21804] nptl: Double semicolon in thread-shared-types.h -+ [21807] localedata: LC_ADDRESS fix for pap_CW -+ [21808] localedata: Fix LC_ADDRESS for pap_AW -+ [21821] localedata: Added country_name in mai_IN -+ [21822] localedata: Fix LC_TIME for mai_IN -+ [21823] localedata: missing yesstr, nostr for sa_IN -+ [21825] localedata: Fix name_mrs for mag_IN -+ [21828] localedata: 2.26 changelog should mention user visible changes -+ with unicode 9.0 -+ [21835] localedata: Added Maithili language locale for Nepal -+ [21838] localedata: Removed redundant data for the_NP -+ [21839] localedata: Fix LC_MONETARY for ta_LK -+ [21844] localedata: Fix Latin characters and Months Sequence. -+ [21848] localedata: Fix mai_NP Title Name -+ -+ -+Version 2.25 -+ -+* The feature test macro __STDC_WANT_LIB_EXT2__, from ISO/IEC TR -+ 24731-2:2010, is supported to enable declarations of functions from that -+ TR. Note that not all functions from that TR are supported by the GNU C -+ Library. -+ -+* The feature test macro __STDC_WANT_IEC_60559_BFP_EXT__, from ISO/IEC TS -+ 18661-1:2014, is supported to enable declarations of functions and macros -+ from that TS. Note that not all features from that TS are supported by -+ the GNU C Library. -+ -+* The feature test macro __STDC_WANT_IEC_60559_FUNCS_EXT__, from ISO/IEC TS -+ 18661-4:2015, is supported to enable declarations of functions and macros -+ from that TS. Note that most features from that TS are not supported by -+ the GNU C Library. -+ -+* The nonstandard feature selection macros _REENTRANT and _THREAD_SAFE are -+ now treated as compatibility synonyms for _POSIX_C_SOURCE=199506L. -+ Since the GNU C Library defaults to a much newer revision of POSIX, this -+ will only affect programs that specifically request an old conformance -+ mode. For instance, a program compiled with -std=c89 -D_REENTRANT will -+ see a change in the visible declarations, but a program compiled with -+ just -D_REENTRANT, or -std=c99 -D_POSIX_C_SOURCE=200809L -D_REENTRANT, -+ will not. -+ -+ Some C libraries once required _REENTRANT and/or _THREAD_SAFE to be -+ defined by all multithreaded code, but glibc has not required this for -+ many years. -+ -+* The inclusion of <sys/sysmacros.h> by <sys/types.h> is deprecated. This -+ means that in a future release, the macros “major”, “minor”, and “makedev” -+ will only be available from <sys/sysmacros.h>. -+ -+ These macros are not part of POSIX nor XSI, and their names frequently -+ collide with user code; see for instance glibc bug 19239 and Red Hat bug -+ 130601. <stdlib.h> includes <sys/types.h> under _GNU_SOURCE, and C++ code -+ presently cannot avoid being compiled under _GNU_SOURCE, exacerbating the -+ problem. -+ -+* New <fenv.h> features from TS 18661-1:2014 are added to libm: the -+ fesetexcept, fetestexceptflag, fegetmode and fesetmode functions, the -+ femode_t type and the FE_DFL_MODE and FE_SNANS_ALWAYS_SIGNAL macros. -+ -+* Integer width macros from TS 18661-1:2014 are added to <limits.h>: -+ CHAR_WIDTH, SCHAR_WIDTH, UCHAR_WIDTH, SHRT_WIDTH, USHRT_WIDTH, INT_WIDTH, -+ UINT_WIDTH, LONG_WIDTH, ULONG_WIDTH, LLONG_WIDTH, ULLONG_WIDTH; and to -+ <stdint.h>: INT8_WIDTH, UINT8_WIDTH, INT16_WIDTH, UINT16_WIDTH, -+ INT32_WIDTH, UINT32_WIDTH, INT64_WIDTH, UINT64_WIDTH, INT_LEAST8_WIDTH, -+ UINT_LEAST8_WIDTH, INT_LEAST16_WIDTH, UINT_LEAST16_WIDTH, -+ INT_LEAST32_WIDTH, UINT_LEAST32_WIDTH, INT_LEAST64_WIDTH, -+ UINT_LEAST64_WIDTH, INT_FAST8_WIDTH, UINT_FAST8_WIDTH, INT_FAST16_WIDTH, -+ UINT_FAST16_WIDTH, INT_FAST32_WIDTH, UINT_FAST32_WIDTH, INT_FAST64_WIDTH, -+ UINT_FAST64_WIDTH, INTPTR_WIDTH, UINTPTR_WIDTH, INTMAX_WIDTH, -+ UINTMAX_WIDTH, PTRDIFF_WIDTH, SIG_ATOMIC_WIDTH, SIZE_WIDTH, WCHAR_WIDTH, -+ WINT_WIDTH. -+ -+* New <math.h> features are added from TS 18661-1:2014: -+ -+ - Signaling NaN macros: SNANF, SNAN, SNANL. -+ -+ - Nearest integer functions: roundeven, roundevenf, roundevenl, fromfp, -+ fromfpf, fromfpl, ufromfp, ufromfpf, ufromfpl, fromfpx, fromfpxf, -+ fromfpxl, ufromfpx, ufromfpxf, ufromfpxl. -+ -+ - llogb functions: the llogb, llogbf and llogbl functions, and the -+ FP_LLOGB0 and FP_LLOGBNAN macros. -+ -+ - Max-min magnitude functions: fmaxmag, fmaxmagf, fmaxmagl, fminmag, -+ fminmagf, fminmagl. -+ -+ - Comparison macros: iseqsig. -+ -+ - Classification macros: iscanonical, issubnormal, iszero. -+ -+ - Total order functions: totalorder, totalorderf, totalorderl, -+ totalordermag, totalordermagf, totalordermagl. -+ -+ - Canonicalize functions: canonicalize, canonicalizef, canonicalizel. -+ -+ - NaN functions: getpayload, getpayloadf, getpayloadl, setpayload, -+ setpayloadf, setpayloadl, setpayloadsig, setpayloadsigf, setpayloadsigl. -+ -+* The functions strfromd, strfromf, and strfroml, from ISO/IEC TS 18661-1:2014, -+ are added to libc. They convert a floating-point number into string. -+ -+* Most of glibc can now be built with the stack smashing protector enabled. -+ It is recommended to build glibc with --enable-stack-protector=strong. -+ Implemented by Nick Alcock (Oracle). -+ -+* The function explicit_bzero, from OpenBSD, has been added to libc. It is -+ intended to be used instead of memset() to erase sensitive data after use; -+ the compiler will not optimize out calls to explicit_bzero even if they -+ are "unnecessary" (in the sense that no _correct_ program can observe the -+ effects of the memory clear). -+ -+* On ColdFire, MicroBlaze, Nios II and SH3, the float_t type is now defined -+ to float instead of double. This does not affect the ABI of any libraries -+ that are part of the GNU C Library, but may affect the ABI of other -+ libraries that use this type in their interfaces. -+ -+* On x86_64, when compiling with -mfpmath=387 or -mfpmath=sse+387, the -+ float_t and double_t types are now defined to long double instead of float -+ and double. These options are not the default, and this does not affect -+ the ABI of any libraries that are part of the GNU C Library, but it may -+ affect the ABI of other libraries that use this type in their interfaces, -+ if they are compiled or used with those options. -+ -+* The getentropy and getrandom functions, and the <sys/random.h> header file -+ have been added. -+ -+* The buffer size for byte-oriented stdio streams is now limited to 8192 -+ bytes by default. Previously, on Linux, the default buffer size on most -+ file systems was 4096 bytes (and thus remains unchanged), except on -+ network file systems, where the buffer size was unpredictable and could be -+ as large as several megabytes. -+ -+* The <sys/quota.h> header now includes the <linux/quota.h> header. Support -+ for the Linux quota interface which predates kernel version 2.4.22 has -+ been removed. -+ -+* The malloc_get_state and malloc_set_state functions have been removed. -+ Already-existing binaries that dynamically link to these functions will -+ get a hidden implementation in which malloc_get_state is a stub. As far -+ as we know, these functions are used only by GNU Emacs and this change -+ will not adversely affect already-built Emacs executables. Any undumped -+ Emacs executables, which normally exist only during an Emacs build, should -+ be rebuilt by re-running “./configure; make” in the Emacs build tree. -+ -+* The “ip6-dotint” and “no-ip6-dotint” resolver options, and the -+ corresponding RES_NOIP6DOTINT flag from <resolv.h> have been removed. -+ “no-ip6-dotint” had already been the default, and support for the -+ “ip6-dotint” option was removed from the Internet in 2006. -+ -+* The "ip6-bytestring" resolver option and the corresponding RES_USEBSTRING -+ flag from <resolv.h> have been removed. The option relied on a -+ backwards-incompatible DNS extension which was never deployed on the -+ Internet. -+ -+* The flags RES_AAONLY, RES_PRIMARY, RES_NOCHECKNAME, RES_KEEPTSIG, -+ RES_BLAST defined in the <resolv.h> header file have been deprecated. -+ They were already unimplemented. -+ -+* The "inet6" option in /etc/resolv.conf and the RES_USE_INET6 flag for -+ _res.flags are deprecated. The flag was standardized in RFC 2133, but -+ removed again from the IETF name lookup interface specification in RFC -+ 2553. Applications should use getaddrinfo instead. -+ -+* DNSSEC-related declarations and definitions have been removed from the -+ <arpa/nameser.h> header file, and libresolv will no longer attempt to -+ decode the data part of DNSSEC record types. Previous versions of glibc -+ only implemented minimal support for the previous version of DNSSEC, which -+ is incompatible with the currently deployed version. -+ -+* The resource record type classification macros ns_t_qt_p, ns_t_mrr_p, -+ ns_t_rr_p, ns_t_udp_p, ns_t_xfr_p have been removed from the -+ <arpa/nameser.h> header file because the distinction between RR types and -+ meta-RR types is not officially standardized, subject to revision, and -+ thus not suitable for encoding in a macro. -+ -+* The types res_sendhookact, res_send_qhook, re_send_rhook, and the qhook -+ and rhook members of the res_state type in <resolv.h> have been removed. -+ The glibc stub resolver did not support these hooks, but the header file -+ did not reflect that. -+ -+* For multi-arch support it is recommended to use a GCC which has -+ been built with support for GNU indirect functions. This ensures -+ that correct debugging information is generated for functions -+ selected by IFUNC resolvers. This support can either be enabled by -+ configuring GCC with '--enable-gnu-indirect-function', or by -+ enabling it by default by setting 'default_gnu_indirect_function' -+ variable for a particular architecture in the GCC source file -+ 'gcc/config.gcc'. -+ -+* GDB pretty printers have been added for mutex and condition variable -+ structures in POSIX Threads. When installed and loaded in gdb these pretty -+ printers show various pthread variables in human-readable form when read -+ using the 'print' or 'display' commands in gdb. -+ -+* Tunables feature added to allow tweaking of the runtime for an application -+ program. This feature can be enabled with the '--enable-tunables' configure -+ flag. The GNU C Library manual has details on usage and README.tunables has -+ instructions on adding new tunables to the library. -+ -+* A new version of condition variables functions have been implemented in -+ the NPTL implementation of POSIX Threads to provide stronger ordering -+ guarantees. -+ -+* A new version of pthread_rwlock functions have been implemented to use a more -+ scalable algorithm primarily through not using a critical section anymore to -+ make state changes. -+>>>>>>> c369d66e54... CVE-2017-15670: glob: Fix one-byte overflow [BZ #22320] - - Security related changes: - -diff --git a/posix/glob.c b/posix/glob.c -index ea4b0b61eb..08f240a1ff 100644 ---- a/posix/glob.c -+++ b/posix/glob.c -@@ -856,7 +856,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), - *p = '\0'; - } - else -- *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) -+ *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1)) - = '\0'; - user_name = newp; - } --- -2.14.2 - diff --git a/glibc/Pkgfile b/glibc/Pkgfile index d69230e5..85b9b03a 100644 --- a/glibc/Pkgfile +++ b/glibc/Pkgfile @@ -4,12 +4,12 @@ name=glibc version=2.24 -release=9 +release=10 source=(http://ftpmirror.gnu.org/gnu/glibc/glibc-2.24.tar.xz \ http://crux.nu/files/distfiles/kernel-headers-4.9.5.tar.xz \ $name-2.20-multilib-dirs.patch \ hosts resolv.conf nsswitch.conf host.conf ld.so.conf \ - glibc-2.24.8.patch 0001-CVE-2017-15670-glob-Fix-one-byte-overflow-BZ-22320.patch) + glibc-2.24-10.patch) build() { # install kernel headers @@ -17,9 +17,8 @@ build() { cp -r $SRC/kernel-headers-4.9.5/include $PKG/usr chown root:root $PKG/usr - patch -p1 -d $SRC/$name-${version:0:4} -i $SRC/glibc-2.24.8.patch + patch -p1 -d $SRC/$name-${version:0:4} -i $SRC/glibc-2.24-10.patch patch -p1 -d $SRC/$name-${version:0:4} -i $SRC/$name-2.20-multilib-dirs.patch - patch -p1 -d $SRC/$name-${version:0:4} -i $SRC/0001-CVE-2017-15670-glob-Fix-one-byte-overflow-BZ-22320.patch mkdir $SRC/build cd $SRC/build diff --git a/glibc/glibc-2.24.8.patch b/glibc/glibc-2.24-10.patch similarity index 83% rename from glibc/glibc-2.24.8.patch rename to glibc/glibc-2.24-10.patch index 4f1db10c..194691df 100644 --- a/glibc/glibc-2.24.8.patch +++ b/glibc/glibc-2.24-10.patch @@ -1,8 +1,210 @@ diff --git a/ChangeLog b/ChangeLog -index c44c926094..84189ec762 100644 +index c44c926094..cd499c5fe3 100644 --- a/ChangeLog +++ b/ChangeLog -@@ -1,3 +1,685 @@ +@@ -1,3 +1,887 @@ ++2018-01-12 Dmitry V. Levin <ldv@altlinux.org> ++ ++ [BZ #22679] ++ CVE-2018-1000001 ++ * sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Fall back to ++ generic_getcwd if the path returned by getcwd syscall is not absolute. ++ * io/tst-getcwd-abspath.c: New test. ++ * io/Makefile (tests): Add tst-getcwd-abspath. ++ ++ (gaih_inet): Likewise. ++ ++2017-12-30 Aurelien Jarno <aurelien@aurel32.net> ++ ++ [BZ #22625] ++ * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic ++ string token expansion. Check for NULL pointer or empty string possibly ++ returned by expand_dynamic_string_token. ++ (decompose_rpath): Check for empty path after dynamic string ++ token expansion. ++ ++2017-12-18 Dmitry V. Levin <ldv@altlinux.org> ++ ++ [BZ #22627] ++ * elf/dl-load.c (_dl_init_paths): Remove _dl_dst_substitute preparatory ++ code and invocation. ++ ++2017-12-14 Florian Weimer <fweimer@redhat.com> ++ ++ [BZ #22607] ++ CVE-2017-1000409 ++ * elf/dl-load.c (_dl_init_paths): Compute number of components in ++ the expanded path string. ++ ++2017-12-14 Florian Weimer <fweimer@redhat.com> ++ ++ [BZ #22606] ++ CVE-2017-1000408 ++ * elf/dl-load.c (system_dirs): Update comment. ++ (nsystem_dirs_len): Use array_length. ++ (_dl_init_paths): Use nsystem_dirs_len to compute the array size. ++ ++2017-11-02 Florian Weimer <fweimer@redhat.com> ++ ++ Add array_length and array_end macros. ++ * include/array_length.h: New file. ++ ++2017-11-02 Florian Weimer <fweimer@redhat.com> ++ ++ [BZ #22332] ++ * posix/tst-glob-tilde.c (do_noescape): New variable. ++ (one_test): Process it. ++ (do_test): Set do_noescape. Add unescaping test case. ++ ++2017-10-22 Paul Eggert <eggert@cs.ucla.edu> ++ ++ [BZ #22332] ++ * posix/glob.c (__glob): Fix buffer overflow during GLOB_TILDE ++ unescaping. ++ ++2017-10-21 Florian Weimer <fweimer@redhat.com> ++ ++ * posix/Makefile (tests): Add tst-glob-tilde. ++ (tests-special): Add tst-glob-tilde-mem.out ++ (tst-glob-tilde-ENV): Set MALLOC_TRACE. ++ (tst-glob-tilde-mem.out): Add mtrace check. ++ * posix/tst-glob-tilde.c: New file. ++ ++2017-10-20 Paul Eggert <eggert@cs.ucla.edu> ++ ++ [BZ #22320] ++ CVE-2017-15670 ++ * posix/glob.c (__glob): Fix one-byte overflow. ++ ++2017-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org> ++ ++ [BZ #1062] ++ CVE-2017-15671 ++ * posix/Makefile (routines): Add globfree, globfree64, and ++ glob_pattern_p. ++ * posix/flexmember.h: New file. ++ * posix/glob_internal.h: Likewise. ++ * posix/glob_pattern_p.c: Likewise. ++ * posix/globfree.c: Likewise. ++ * posix/globfree64.c: Likewise. ++ * sysdeps/gnu/globfree64.c: Likewise. ++ * sysdeps/unix/sysv/linux/alpha/globfree.c: Likewise. ++ * sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise. ++ * sysdeps/unix/sysv/linux/oldglob.c: Likewise. ++ * sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise. ++ * sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise. ++ * sysdeps/wordsize-64/globfree.c: Likewise. ++ * sysdeps/wordsize-64/globfree64.c: Likewise. ++ * posix/glob.c (HAVE_CONFIG_H): Use !_LIBC instead. ++ [NDEBUG): Remove comments. ++ (GLOB_ONLY_P, _AMIGA, VMS): Remove define. ++ (dirent_type): New type. Use uint_fast8_t not ++ uint8_t, as C99 does not require uint8_t. ++ (DT_UNKNOWN, DT_DIR, DT_LNK): New macros. ++ (struct readdir_result): Use dirent_type. Do not define skip_entry ++ unless it is needed; this saves a byte on platforms lacking d_ino. ++ (readdir_result_type, readdir_result_skip_entry): ++ New functions, replacing ... ++ (readdir_result_might_be_symlink, readdir_result_might_be_dir): ++ these functions, which were removed. This makes the callers ++ easier to read. All callers changed. ++ (D_INO_TO_RESULT): Now empty if there is no d_ino. ++ (size_add_wrapv, glob_use_alloca): New static functions. ++ (glob, glob_in_dir): Check for size_t overflow in several places, ++ and fix some size_t checks that were not quite right. ++ Remove old code using SHELL since Bash no longer ++ uses this. ++ (glob, prefix_array): Separate MS code better. ++ (glob_in_dir): Remove old Amiga and VMS code. ++ (globfree, __glob_pattern_type, __glob_pattern_p): Move to ++ separate files. ++ (glob_in_dir): Do not rely on undefined behavior in accessing ++ struct members beyond their bounds. Use a flexible array member ++ instead ++ (link_stat): Rename from link_exists2_p and return -1/0 instead of ++ 0/1. Caller changed. ++ (glob): Fix memory leaks. ++ * posix/glob64 (globfree64): Move to separate file. ++ * sysdeps/gnu/glob64.c (NO_GLOB_PATTERN_P): Remove define. ++ (globfree64): Remove hidden alias. ++ * sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Add ++ oldglob. ++ * sysdeps/unix/sysv/linux/alpha/glob.c (__new_globfree): Move to ++ separate file. ++ * sysdeps/unix/sysv/linux/i386/glob64.c (NO_GLOB_PATTERN_P): Remove ++ define. ++ Move compat code to separate file. ++ * sysdeps/wordsize-64/glob.c (globfree): Move definitions to ++ separate file. ++ ++2017-08-20 H.J. Lu <hongjiu.lu@intel.com> ++ ++ [BZ #18822] ++ * sysdeps/unix/sysv/linux/i386/glob64.c (__old_glob64): Add ++ libc_hidden_proto and libc_hidden_def. ++ ++2017-10-22 H.J. Lu <hongjiu.lu@intel.com> ++ ++ [BZ #21265] ++ * sysdeps/x86/cpu-features-offsets.sym (XSAVE_STATE_SIZE_OFFSET): ++ New. ++ * sysdeps/x86/cpu-features.c: Include <libc-internal.h>. ++ (get_common_indeces): Set xsave_state_size and ++ bit_arch_XSAVEC_Usable if needed. ++ (init_cpu_features): Remove bit_arch_Use_dl_runtime_resolve_slow ++ and bit_arch_Use_dl_runtime_resolve_opt. ++ * sysdeps/x86/cpu-features.h (bit_arch_Use_dl_runtime_resolve_opt): ++ Removed. ++ (bit_arch_Use_dl_runtime_resolve_slow): Likewise. ++ (bit_arch_Prefer_No_AVX512): Updated. ++ (bit_arch_MathVec_Prefer_No_AVX512): Likewise. ++ (bit_arch_XSAVEC_Usable): New. ++ (STATE_SAVE_OFFSET): Likewise. ++ (STATE_SAVE_MASK): Likewise. ++ [__ASSEMBLER__]: Include <cpu-features-offsets.h>. ++ (cpu_features): Add xsave_state_size. ++ (index_arch_Use_dl_runtime_resolve_opt): Removed. ++ (index_arch_Use_dl_runtime_resolve_slow): Likewise. ++ (index_arch_XSAVEC_Usable): New. ++ * sysdeps/x86_64/dl-machine.h (elf_machine_runtime_setup): ++ Replace _dl_runtime_resolve_sse, _dl_runtime_resolve_avx, ++ _dl_runtime_resolve_avx_slow, _dl_runtime_resolve_avx_opt, ++ _dl_runtime_resolve_avx512 and _dl_runtime_resolve_avx512_opt ++ with _dl_runtime_resolve_fxsave, _dl_runtime_resolve_xsave and ++ _dl_runtime_resolve_xsavec. ++ * sysdeps/x86_64/dl-trampoline.S (DL_RUNTIME_UNALIGNED_VEC_SIZE): ++ Removed. ++ (DL_RUNTIME_RESOLVE_REALIGN_STACK): Check STATE_SAVE_ALIGNMENT ++ instead of VEC_SIZE. ++ (REGISTER_SAVE_BND0): Removed. ++ (REGISTER_SAVE_BND1): Likewise. ++ (REGISTER_SAVE_BND3): Likewise. ++ (REGISTER_SAVE_RAX): Always defined to 0. ++ (VMOV): Removed. ++ (_dl_runtime_resolve_avx): Likewise. ++ (_dl_runtime_resolve_avx_slow): Likewise. ++ (_dl_runtime_resolve_avx_opt): Likewise. ++ (_dl_runtime_resolve_avx512): Likewise. ++ (_dl_runtime_resolve_avx512_opt): Likewise. ++ (_dl_runtime_resolve_sse): Likewise. ++ (_dl_runtime_resolve_sse_vex): Likewise. ++ (USE_FXSAVE): New. ++ (_dl_runtime_resolve_fxsave): Likewise. ++ (USE_XSAVE): Likewise. ++ (_dl_runtime_resolve_xsave): Likewise. ++ (USE_XSAVEC): Likewise. ++ (_dl_runtime_resolve_xsavec): Likewise. ++ * sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve_avx512): ++ Removed. ++ (_dl_runtime_resolve_avx512_opt): Likewise. ++ (_dl_runtime_resolve_avx): Likewise. ++ (_dl_runtime_resolve_avx_opt): Likewise. ++ (_dl_runtime_resolve_sse): Likewise. ++ (_dl_runtime_resolve_sse_vex): Likewise. ++ (_dl_runtime_resolve_fxsave): New. ++ (_dl_runtime_resolve_xsave): Likewise. ++ (_dl_runtime_resolve_xsavec): Likewise. ++ +2017-10-19 H.J. Lu <hongjiu.lu@intel.com> + + * sysdeps/x86_64/Makefile (tests): Add tst-sse, tst-avx and @@ -743,10 +945,10 @@ index 03fd89c13e..ee379f5852 100644 ifndef avoid-generated diff --git a/NEWS b/NEWS -index b0447e7169..4831542023 100644 +index b0447e7169..20e30028cf 100644 --- a/NEWS +++ b/NEWS -@@ -5,6 +5,33 @@ See the end for copying conditions. +@@ -5,6 +5,68 @@ See the end for copying conditions. Please send GNU C library bug reports via <http://sourceware.org/bugzilla/> using `glibc' in the "product" field. @@ -766,16 +968,51 @@ index b0447e7169..4831542023 100644 + question type which is outside the range of valid question type values. + (CVE-2015-5180) + ++* CVE-2017-15670: The glob function, when invoked with GLOB_TILDE, suffered ++ from a one-byte overflow during ~ operator processing (either on the stack ++ or the heap, depending on the length of the user name). ++ ++* CVE-2017-15671: The glob function, when invoked with GLOB_TILDE, ++ would sometimes fail to free memory allocated during ~ operator ++ processing, leading to a memory leak and, potentially, to a denial ++ of service. ++ ++* CVE-2017-15804: The glob function, when invoked with GLOB_TILDE and ++ without GLOB_NOESCAPE, could write past the end of a buffer while ++ unescaping user names. Reported by Tim Rühsen. ++ ++* CVE-2017-1000408: Incorrect array size computation in _dl_init_paths leads ++ to the allocation of too much memory. (This is not a security bug per se, ++ it is mentioned here only because of the CVE assignment.) Reported by ++ Qualys. ++ ++* CVE-2017-1000409: Buffer overflow in _dl_init_paths due to miscomputation ++ of the number of search path components. (This is not a security ++ vulnerability per se because no trust boundary is crossed if the fix for ++ CVE-2017-1000366 has been applied, but it is mentioned here only because ++ of the CVE assignment.) Reported by Qualys. ++ ++ CVE-2017-16997: Incorrect handling of RPATH or RUNPATH containing $ORIGIN ++ for AT_SECURE or SUID binaries could be used to load libraries from the ++ current directory. ++ ++ CVE-2018-1000001: Buffer underflow in realpath function when getcwd function ++ succeeds without returning an absolute path due to unexpected behaviour ++ of the Linux kernel getcwd syscall. Reported by halfdog. ++ +The following bugs are resolved with this release: + + [20790] Fix rpcgen buffer overrun + [20978] Fix strlen on null pointer in nss_nisplus + [21209] Ignore and remove LD_HWCAP_MASK for AT_SECURE programs ++ [21265] x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve + [21289] Fix symbol redirect for fts_set + [21386] Assertion in fork for distinct parent PID is incorrect + [21609] x86-64: Align the stack in __tls_get_addr + [21624] Unsafe alloca allows local attackers to alias stack and heap (CVE-2017-1000366) + [21654] nss: Fix invalid cast in group merging ++ [22679] getcwd(3) can succeed without returning an absolute path ++ (CVE-2018-1000001) + Version 2.24 @@ -1078,6 +1315,167 @@ index 687d7de874..9f93ab7628 100644 _dl_close_worker (map, false); +diff --git a/elf/dl-load.c b/elf/dl-load.c +index c0d6249373..1f774e139f 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -37,6 +37,7 @@ + #include <sysdep.h> + #include <stap-probe.h> + #include <libc-internal.h> ++#include <array_length.h> + + #include <dl-dst.h> + #include <dl-load.h> +@@ -103,7 +104,9 @@ static size_t ncapstr attribute_relro; + static size_t max_capstrlen attribute_relro; + + +-/* Get the generated information about the trusted directories. */ ++/* Get the generated information about the trusted directories. Use ++ an array of concatenated strings to avoid relocations. See ++ gen-trusted-dirs.awk. */ + #include "trusted-dirs.h" + + static const char system_dirs[] = SYSTEM_DIRS; +@@ -111,9 +114,7 @@ static const size_t system_dirs_len[] = + { + SYSTEM_DIRS_LEN + }; +-#define nsystem_dirs_len \ +- (sizeof (system_dirs_len) / sizeof (system_dirs_len[0])) +- ++#define nsystem_dirs_len array_length (system_dirs_len) + + static bool + is_trusted_path (const char *path, size_t len) +@@ -433,31 +434,40 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, + { + char *cp; + size_t nelems = 0; +- char *to_free; + + while ((cp = __strsep (&rpath, sep)) != NULL) + { + struct r_search_path_elem *dirp; ++ char *to_free = NULL; ++ size_t len = 0; + +- to_free = cp = expand_dynamic_string_token (l, cp, 1); ++ /* `strsep' can pass an empty string. */ ++ if (*cp != '\0') ++ { ++ to_free = cp = expand_dynamic_string_token (l, cp, 1); + +- size_t len = strlen (cp); ++ /* expand_dynamic_string_token can return NULL in case of empty ++ path or memory allocation failure. */ ++ if (cp == NULL) ++ continue; + +- /* `strsep' can pass an empty string. This has to be +- interpreted as `use the current directory'. */ +- if (len == 0) +- { +- static const char curwd[] = "./"; +- cp = (char *) curwd; +- } ++ /* Compute the length after dynamic string token expansion and ++ ignore empty paths. */ ++ len = strlen (cp); ++ if (len == 0) ++ { ++ free (to_free); ++ continue; ++ } + +- /* Remove trailing slashes (except for "/"). */ +- while (len > 1 && cp[len - 1] == '/') +- --len; ++ /* Remove trailing slashes (except for "/"). */ ++ while (len > 1 && cp[len - 1] == '/') ++ --len; + +- /* Now add one if there is none so far. */ +- if (len > 0 && cp[len - 1] != '/') +- cp[len++] = '/'; ++ /* Now add one if there is none so far. */ ++ if (len > 0 && cp[len - 1] != '/') ++ cp[len++] = '/'; ++ } + + /* Make sure we don't use untrusted directories if we run SUID. */ + if (__glibc_unlikely (check_trusted) && !is_trusted_path (cp, len)) +@@ -621,6 +631,14 @@ decompose_rpath (struct r_search_path_struct *sps, + necessary. */ + free (copy); + ++ /* There is no path after expansion. */ ++ if (result[0] == NULL) ++ { ++ free (result); ++ sps->dirs = (struct r_search_path_elem **) -1; ++ return false; ++ } ++ + sps->dirs = result; + /* The caller will change this value if we haven't used a real malloc. */ + sps->malloced = 1; +@@ -688,9 +706,8 @@ _dl_init_paths (const char *llp) + + ncapstr * sizeof (enum r_dir_status)) + / sizeof (struct r_search_path_elem)); + +- rtld_search_dirs.dirs[0] = (struct r_search_path_elem *) +- malloc ((sizeof (system_dirs) / sizeof (system_dirs[0])) +- * round_size * sizeof (struct r_search_path_elem)); ++ rtld_search_dirs.dirs[0] = malloc (nsystem_dirs_len * round_size ++ * sizeof (*rtld_search_dirs.dirs[0])); + if (rtld_search_dirs.dirs[0] == NULL) + { + errstring = N_("cannot create cache for search path"); +@@ -776,37 +793,14 @@ _dl_init_paths (const char *llp) + + if (llp != NULL && *llp != '\0') + { +- size_t nllp; +- const char *cp = llp; +- char *llp_tmp; +- +-#ifdef SHARED +- /* Expand DSTs. */ +- size_t cnt = DL_DST_COUNT (llp, 1); +- if (__glibc_likely (cnt == 0)) +- llp_tmp = strdupa (llp); +- else +- { +- /* Determine the length of the substituted string. */ +- size_t total = DL_DST_REQUIRED (l, llp, strlen (llp), cnt); +- +- /* Allocate the necessary memory. */ +- llp_tmp = (char *) alloca (total + 1); +- llp_tmp = _dl_dst_substitute (l, llp, llp_tmp, 1); +- } +-#else +- llp_tmp = strdupa (llp); +-#endif ++ char *llp_tmp = strdupa (llp); + + /* Decompose the LD_LIBRARY_PATH contents. First determine how many + elements it has. */ +- nllp = 1; +- while (*cp) +- { +- if (*cp == ':' || *cp == ';') +- ++nllp; +- ++cp; +- } ++ size_t nllp = 1; ++ for (const char *cp = llp_tmp; *cp != '\0'; ++cp) ++ if (*cp == ':' || *cp == ';') ++ ++nllp; + + env_path_list.dirs = (struct r_search_path_elem **) + malloc ((nllp + 1) * sizeof (struct r_search_path_elem *)); diff --git a/elf/rtld.c b/elf/rtld.c index 647661ca45..8f56d6edd3 100644 --- a/elf/rtld.c @@ -1664,6 +2062,62 @@ index 2e735ede4c..7c0deed9ae 100644 +#define T_QUERY_A_AND_AAAA 439963904 #endif +diff --git a/include/array_length.h b/include/array_length.h +new file mode 100644 +index 0000000000..cb4a8b2a56 +--- /dev/null ++++ b/include/array_length.h +@@ -0,0 +1,36 @@ ++/* The array_length and array_end macros. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#ifndef _ARRAY_LENGTH_H ++#define _ARRAY_LENGTH_H ++ ++/* array_length (VAR) is the number of elements in the array VAR. VAR ++ must evaluate to an array, not a pointer. */ ++#define array_length(var) \ ++ __extension__ ({ \ ++ _Static_assert (!__builtin_types_compatible_p \ ++ (__typeof (var), __typeof (&(var)[0])), \ ++ "argument must be an array"); \ ++ sizeof (var) / sizeof ((var)[0]); \ ++ }) ++ ++/* array_end (VAR) is a pointer one past the end of the array VAR. ++ VAR must evaluate to an array, not a pointer. */ ++#define array_end(var) (&(var)[array_length (var)]) ++ ++#endif /* _ARRAY_LENGTH_H */ +diff --git a/io/Makefile b/io/Makefile +index deb6100156..1128f4881f 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -71,7 +71,8 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-renameat tst-fchownat tst-fchmodat tst-faccessat \ + tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \ + tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \ +- tst-posix_fallocate tst-fts tst-fts-lfs ++ tst-posix_fallocate tst-posix_fallocate64 \ ++ tst-fts tst-fts-lfs tst-open-tmpfile tst-getcwd-abspath + + ifeq ($(run-built-tests),yes) + tests-special += $(objpfx)ftwtest.out diff --git a/io/fts.h b/io/fts.h index 127a0d2721..b6b45206c8 100644 --- a/io/fts.h @@ -1677,6 +2131,78 @@ index 127a0d2721..b6b45206c8 100644 # else # define fts_children fts64_children # define fts_close fts64_close +diff --git a/io/tst-getcwd-abspath.c b/io/tst-getcwd-abspath.c +new file mode 100644 +index 0000000000..3a3636f2ed +--- /dev/null ++++ b/io/tst-getcwd-abspath.c +@@ -0,0 +1,66 @@ ++/* BZ #22679 getcwd(3) should not succeed without returning an absolute path. ++ ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <errno.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <support/check.h> ++#include <support/namespace.h> ++#include <support/support.h> ++#include <support/temp_file.h> ++#include <support/test-driver.h> ++#include <support/xunistd.h> ++#include <unistd.h> ++ ++static char *chroot_dir; ++ ++/* The actual test. Run it in a subprocess, so that the test harness ++ can remove the temporary directory in --direct mode. */ ++static void ++getcwd_callback (void *closure) ++{ ++ xchroot (chroot_dir); ++ ++ errno = 0; ++ char *cwd = getcwd (NULL, 0); ++ TEST_COMPARE (errno, ENOENT); ++ TEST_VERIFY (cwd == NULL); ++ ++ errno = 0; ++ cwd = realpath (".", NULL); ++ TEST_COMPARE (errno, ENOENT); ++ TEST_VERIFY (cwd == NULL); ++ ++ _exit (0); ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ if (!support_can_chroot ()) ++ return EXIT_UNSUPPORTED; ++ ++ chroot_dir = support_create_temp_directory ("tst-getcwd-abspath-"); ++ support_isolate_in_subprocess (getcwd_callback, NULL); ++ ++ return 0; ++} ++ ++#include <support/test-driver.c> diff --git a/localedata/ChangeLog b/localedata/ChangeLog index 4be8afc110..a7688e3df6 100644 --- a/localedata/ChangeLog @@ -3208,6 +3734,51 @@ index 49d1f23904..e046577b08 100644 - -#~ msgid "cannot create internal descriptors" -#~ msgstr "kan inte skapa interna deskriptorer" +diff --git a/posix/Makefile b/posix/Makefile +index 5b0e298f75..82a4020c76 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -43,7 +43,7 @@ routines := \ + getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \ + getresuid getresgid setresuid setresgid \ + pathconf sysconf fpathconf \ +- glob glob64 fnmatch regex \ ++ glob glob64 globfree globfree64 glob_pattern_p fnmatch regex \ + confstr \ + getopt getopt1 getopt_init \ + sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \ +@@ -90,7 +90,7 @@ tests := tstgetopt testfnm runtests runptests \ + bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \ + tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \ + tst-fnmatch3 bug-regex36 tst-getaddrinfo5 \ +- tst-posix_spawn-fd ++ tst-posix_spawn-fd tst-glob-tilde + xtests := bug-ga2 + ifeq (yes,$(build-shared)) + test-srcs := globtest +@@ -133,7 +133,8 @@ tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \ + $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \ + $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \ + $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \ +- $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out ++ $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out \ ++ $(objpfx)tst-glob-tilde-mem.out + xtests-special += $(objpfx)bug-ga2-mem.out + endif + +@@ -340,6 +341,12 @@ $(objpfx)bug-glob2-mem.out: $(objpfx)bug-glob2.out + $(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \ + $(evaluate-test) + ++tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace ++ ++$(objpfx)tst-glob-tilde-mem.out: $(objpfx)tst-glob-tilde.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-glob-tilde.mtrace > $@; \ ++ $(evaluate-test) ++ + $(inst_libexecdir)/getconf: $(inst_bindir)/getconf \ + $(objpfx)getconf.speclist FORCE + $(addprefix $(..)./scripts/mkinstalldirs ,\ diff --git a/posix/execvpe.c b/posix/execvpe.c index d933f9c92a..7cdb06a611 100644 --- a/posix/execvpe.c @@ -3261,6 +3832,1881 @@ index d933f9c92a..7cdb06a611 100644 __execve (buffer, argv, envp); +diff --git a/posix/flexmember.h b/posix/flexmember.h +new file mode 100644 +index 0000000000..107c1f09e9 +--- /dev/null ++++ b/posix/flexmember.h +@@ -0,0 +1,45 @@ ++/* Sizes of structs with flexible array members. ++ ++ Copyright 2016-2017 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/>. ++ ++ Written by Paul Eggert. */ ++ ++#include <stddef.h> ++ ++/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below. ++ On older platforms without _Alignof, use a pessimistic bound that is ++ safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1. ++ On newer platforms, use _Alignof to get a tighter bound. */ ++ ++#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 ++# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1)) ++#else ++# define FLEXALIGNOF(type) _Alignof (type) ++#endif ++ ++/* Upper bound on the size of a struct of type TYPE with a flexible ++ array member named MEMBER that is followed by N bytes of other data. ++ This is not simply sizeof (TYPE) + N, since it may require ++ alignment on unusually picky C11 platforms, and ++ FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms. ++ Yield a value less than N if and only if arithmetic overflow occurs. */ ++ ++#define FLEXSIZEOF(type, member, n) \ ++ ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \ ++ & ~ (FLEXALIGNOF (type) - 1)) +diff --git a/posix/glob.c b/posix/glob.c +index ea4b0b61eb..f3fa807700 100644 +--- a/posix/glob.c ++++ b/posix/glob.c +@@ -15,7 +15,7 @@ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +-#ifdef HAVE_CONFIG_H ++#ifndef _LIBC + # include <config.h> + #endif + +@@ -27,29 +27,15 @@ + #include <stdbool.h> + #include <stddef.h> + #include <stdint.h> +- +-/* Outcomment the following line for production quality code. */ +-/* #define NDEBUG 1 */ + #include <assert.h> ++#include <unistd.h> + +-#include <stdio.h> /* Needed on stupid SunOS for assert. */ +- +-#if !defined _LIBC || !defined GLOB_ONLY_P +-#if defined HAVE_UNISTD_H || defined _LIBC +-# include <unistd.h> +-# ifndef POSIX +-# ifdef _POSIX_VERSION +-# define POSIX +-# endif +-# endif ++#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ ++# define WINDOWS32 + #endif + +-#include <pwd.h> +- +-#if defined HAVE_STDINT_H || defined _LIBC +-# include <stdint.h> +-#elif !defined UINTPTR_MAX +-# define UINTPTR_MAX (~((size_t) 0)) ++#ifndef WINDOWS32 ++# include <pwd.h> + #endif + + #include <errno.h> +@@ -57,24 +43,7 @@ + # define __set_errno(val) errno = (val) + #endif + +-#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ +-# include <dirent.h> +-#else +-# define dirent direct +-# ifdef HAVE_SYS_NDIR_H +-# include <sys/ndir.h> +-# endif +-# ifdef HAVE_SYS_DIR_H +-# include <sys/dir.h> +-# endif +-# ifdef HAVE_NDIR_H +-# include <ndir.h> +-# endif +-# ifdef HAVE_VMSDIR_H +-# include "vmsdir.h" +-# endif /* HAVE_VMSDIR_H */ +-#endif +- ++#include <dirent.h> + #include <stdlib.h> + #include <string.h> + #include <alloca.h> +@@ -87,27 +56,29 @@ + # define opendir(name) __opendir (name) + # define readdir(str) __readdir64 (str) + # define getpwnam_r(name, bufp, buf, len, res) \ +- __getpwnam_r (name, bufp, buf, len, res) ++ __getpwnam_r (name, bufp, buf, len, res) + # ifndef __stat64 + # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf) + # endif + # define struct_stat64 struct stat64 ++# define FLEXIBLE_ARRAY_MEMBER + #else /* !_LIBC */ +-# include "getlogin_r.h" +-# include "mempcpy.h" +-# include "stat-macros.h" +-# include "strdup.h" +-# define __stat64(fname, buf) stat (fname, buf) +-# define struct_stat64 struct stat +-# define __stat(fname, buf) stat (fname, buf) +-# define __alloca alloca +-# define __readdir readdir +-# define __readdir64 readdir64 +-# define __glob_pattern_p glob_pattern_p ++# define __getlogin_r(buf, len) getlogin_r (buf, len) ++# define __stat64(fname, buf) stat (fname, buf) ++# define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag) ++# define struct_stat64 struct stat ++# ifndef __MVS__ ++# define __alloca alloca ++# endif ++# define __readdir readdir ++# define COMPILE_GLOB64 + #endif /* _LIBC */ + + #include <fnmatch.h> + ++#include <flexmember.h> ++#include <glob_internal.h> ++ + #ifdef _SC_GETPW_R_SIZE_MAX + # define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX) + #else +@@ -121,61 +92,59 @@ + + static const char *next_brace_sub (const char *begin, int flags) __THROWNL; + ++typedef uint_fast8_t dirent_type; ++ ++#if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE ++/* Any distinct values will do here. ++ Undef any existing macros out of the way. */ ++# undef DT_UNKNOWN ++# undef DT_DIR ++# undef DT_LNK ++# define DT_UNKNOWN 0 ++# define DT_DIR 1 ++# define DT_LNK 2 ++#endif ++ + /* A representation of a directory entry which does not depend on the + layout of struct dirent, or the size of ino_t. */ + struct readdir_result + { + const char *name; +-# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE +- uint8_t type; +-# endif ++#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE ++ dirent_type type; ++#endif ++#if defined _LIBC || defined D_INO_IN_DIRENT + bool skip_entry; ++#endif + }; + +-# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE +-/* Initializer based on the d_type member of struct dirent. */ +-# define D_TYPE_TO_RESULT(source) (source)->d_type, +- +-/* True if the directory entry D might be a symbolic link. */ +-static bool +-readdir_result_might_be_symlink (struct readdir_result d) +-{ +- return d.type == DT_UNKNOWN || d.type == DT_LNK; +-} +- +-/* True if the directory entry D might be a directory. */ +-static bool +-readdir_result_might_be_dir (struct readdir_result d) +-{ +- return d.type == DT_DIR || readdir_result_might_be_symlink (d); +-} +-# else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */ +-# define D_TYPE_TO_RESULT(source) +- +-/* If we do not have type information, symbolic links and directories +- are always a possibility. */ +- +-static bool +-readdir_result_might_be_symlink (struct readdir_result d) ++/* Initialize and return type member of struct readdir_result. */ ++static dirent_type ++readdir_result_type (struct readdir_result d) + { +- return true; ++#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE ++# define D_TYPE_TO_RESULT(source) (source)->d_type, ++ return d.type; ++#else ++# define D_TYPE_TO_RESULT(source) ++ return DT_UNKNOWN; ++#endif + } + ++/* Initialize and return skip_entry member of struct readdir_result. */ + static bool +-readdir_result_might_be_dir (struct readdir_result d) ++readdir_result_skip_entry (struct readdir_result d) + { +- return true; +-} +- +-# endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */ +- +-# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ + /* Initializer for skip_entry. POSIX does not require that the d_ino + field be present, and some systems do not provide it. */ +-# define D_INO_TO_RESULT(source) false, +-# else +-# define D_INO_TO_RESULT(source) (source)->d_ino == 0, +-# endif ++#if defined _LIBC || defined D_INO_IN_DIRENT ++# define D_INO_TO_RESULT(source) (source)->d_ino == 0, ++ return d.skip_entry; ++#else ++# define D_INO_TO_RESULT(source) ++ return false; ++#endif ++} + + /* Construct an initializer for a struct readdir_result object from a + struct dirent *. No copy of the name is made. */ +@@ -186,8 +155,6 @@ readdir_result_might_be_dir (struct readdir_result d) + D_INO_TO_RESULT (source) \ + } + +-#endif /* !defined _LIBC || !defined GLOB_ONLY_P */ +- + /* Call gl_readdir on STREAM. This macro can be overridden to reduce + type safety if an old interface version needs to be supported. */ + #ifndef GL_READDIR +@@ -225,18 +192,55 @@ convert_dirent64 (const struct dirent64 *source) + } + #endif + ++#ifndef _LIBC ++/* The results of opendir() in this file are not used with dirfd and fchdir, ++ and we do not leak fds to any single-threaded code that could use stdio, ++ therefore save some unnecessary recursion in fchdir.c and opendir_safer.c. ++ FIXME - if the kernel ever adds support for multi-thread safety for ++ avoiding standard fds, then we should use opendir_safer. */ ++# ifdef GNULIB_defined_opendir ++# undef opendir ++# endif ++# ifdef GNULIB_defined_closedir ++# undef closedir ++# endif + +-#ifndef attribute_hidden +-# define attribute_hidden ++/* Just use malloc. */ ++# define __libc_use_alloca(n) false ++# define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0) ++# define extend_alloca_account(buf, len, newlen, avar) \ ++ ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0) + #endif + ++/* Set *R = A + B. Return true if the answer is mathematically ++ incorrect due to overflow; in this case, *R is the low order ++ bits of the correct answer. */ ++ ++static bool ++size_add_wrapv (size_t a, size_t b, size_t *r) ++{ ++#if 5 <= __GNUC__ && !defined __ICC ++ return __builtin_add_overflow (a, b, r); ++#else ++ *r = a + b; ++ return *r < a; ++#endif ++} ++ ++static bool ++glob_use_alloca (size_t alloca_used, size_t len) ++{ ++ size_t size; ++ return (!size_add_wrapv (alloca_used, len, &size) ++ && __libc_use_alloca (size)); ++} ++ + static int glob_in_dir (const char *pattern, const char *directory, + int flags, int (*errfunc) (const char *, int), + glob_t *pglob, size_t alloca_used); + extern int __glob_pattern_type (const char *pattern, int quote) + attribute_hidden; + +-#if !defined _LIBC || !defined GLOB_ONLY_P + static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL; + static int collated_compare (const void *, const void *) __THROWNL; + +@@ -265,16 +269,15 @@ next_brace_sub (const char *cp, int flags) + return *cp != '\0' ? cp : NULL; + } + +-#endif /* !defined _LIBC || !defined GLOB_ONLY_P */ + + /* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the +- `errno' value from the failing call; if it returns non-zero +- `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. ++ 'errno' value from the failing call; if it returns non-zero ++ 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. +- Otherwise, `glob' returns zero. */ ++ Otherwise, 'glob' returns zero. */ + int + #ifdef GLOB_ATTRIBUTE + GLOB_ATTRIBUTE +@@ -292,9 +295,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + int malloc_dirname = 0; + glob_t dirs; + int retval = 0; +-#ifdef _LIBC + size_t alloca_used = 0; +-#endif + + if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) + { +@@ -308,7 +309,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + flags |= GLOB_ONLYDIR; + + if (!(flags & GLOB_DOOFFS)) +- /* Have to do this so `globfree' knows where to start freeing. It ++ /* Have to do this so 'globfree' knows where to start freeing. It + also makes all the code that uses gl_offs simpler. */ + pglob->gl_offs = 0; + +@@ -350,14 +351,12 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + size_t rest_len; + char *onealt; + size_t pattern_len = strlen (pattern) - 1; +-#ifdef _LIBC +- int alloca_onealt = __libc_use_alloca (alloca_used + pattern_len); ++ int alloca_onealt = glob_use_alloca (alloca_used, pattern_len); + if (alloca_onealt) + onealt = alloca_account (pattern_len, alloca_used); + else +-#endif + { +- onealt = (char *) malloc (pattern_len); ++ onealt = malloc (pattern_len); + if (onealt == NULL) + { + if (!(flags & GLOB_APPEND)) +@@ -377,11 +376,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + next = next_brace_sub (begin + 1, flags); + if (next == NULL) + { +- /* It is an illegal expression. */ ++ /* It is an invalid expression. */ + illegal_brace: +-#ifdef _LIBC + if (__glibc_unlikely (!alloca_onealt)) +-#endif + free (onealt); + return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); + } +@@ -429,9 +426,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + /* If we got an error, return it. */ + if (result && result != GLOB_NOMATCH) + { +-#ifdef _LIBC + if (__glibc_unlikely (!alloca_onealt)) +-#endif + free (onealt); + if (!(flags & GLOB_APPEND)) + { +@@ -450,9 +445,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + assert (next != NULL); + } + +-#ifdef _LIBC + if (__glibc_unlikely (!alloca_onealt)) +-#endif + free (onealt); + + if (pglob->gl_pathc != firstc) +@@ -489,14 +482,16 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + + /* Find the filename. */ + filename = strrchr (pattern, '/'); ++ + #if defined __MSDOS__ || defined WINDOWS32 +- /* The case of "d:pattern". Since `:' is not allowed in ++ /* The case of "d:pattern". Since ':' is not allowed in + file names, we can safely assume that wherever it + happens in pattern, it signals the filename part. This + is so we could some day support patterns like "[a-z]:foo". */ + if (filename == NULL) + filename = strchr (pattern, ':'); + #endif /* __MSDOS__ || WINDOWS32 */ ++ + dirname_modified = 0; + if (filename == NULL) + { +@@ -521,11 +516,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + } + + filename = pattern; +-#ifdef _AMIGA +- dirname = (char *) ""; +-#else + dirname = (char *) "."; +-#endif + dirlen = 0; + } + } +@@ -549,22 +540,21 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + char *drive_spec; + + ++dirlen; +- drive_spec = (char *) __alloca (dirlen + 1); ++ drive_spec = __alloca (dirlen + 1); + *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; + /* For now, disallow wildcards in the drive spec, to + prevent infinite recursion in glob. */ + if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) + return GLOB_NOMATCH; +- /* If this is "d:pattern", we need to copy `:' to DIRNAME ++ /* If this is "d:pattern", we need to copy ':' to DIRNAME + as well. If it's "d:/pattern", don't remove the slash + from "d:/", since "d:" and "d:/" are not the same.*/ + } + #endif +-#ifdef _LIBC +- if (__libc_use_alloca (alloca_used + dirlen + 1)) ++ ++ if (glob_use_alloca (alloca_used, dirlen + 1)) + newp = alloca_account (dirlen + 1, alloca_used); + else +-#endif + { + newp = malloc (dirlen + 1); + if (newp == NULL) +@@ -575,14 +565,17 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + dirname = newp; + ++filename; + +- if (filename[0] == '\0' + #if defined __MSDOS__ || defined WINDOWS32 +- && dirname[dirlen - 1] != ':' +- && (dirlen < 3 || dirname[dirlen - 2] != ':' +- || dirname[dirlen - 1] != '/') ++ bool drive_root = (dirlen > 1 ++ && (dirname[dirlen - 1] == ':' ++ || (dirlen > 2 && dirname[dirlen - 2] == ':' ++ && dirname[dirlen - 1] == '/'))); ++#else ++ bool drive_root = false; + #endif +- && dirlen > 1) +- /* "pattern/". Expand "pattern", appending slashes. */ ++ ++ if (filename[0] == '\0' && dirlen > 1 && !drive_root) ++ /* "pattern/". Expand "pattern", appending slashes. */ + { + int orig_flags = flags; + if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\') +@@ -615,7 +608,6 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + } + } + +-#ifndef VMS + if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~') + { + if (dirname[1] == '\0' || dirname[1] == '/' +@@ -625,100 +617,127 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + /* Look up home directory. */ + char *home_dir = getenv ("HOME"); + int malloc_home_dir = 0; +-# ifdef _AMIGA +- if (home_dir == NULL || home_dir[0] == '\0') +- home_dir = "SYS:"; +-# else +-# ifdef WINDOWS32 +- if (home_dir == NULL || home_dir[0] == '\0') +- home_dir = "c:/users/default"; /* poor default */ +-# else + if (home_dir == NULL || home_dir[0] == '\0') + { ++#ifdef WINDOWS32 ++ /* Windows NT defines HOMEDRIVE and HOMEPATH. But give ++ preference to HOME, because the user can change HOME. */ ++ const char *home_drive = getenv ("HOMEDRIVE"); ++ const char *home_path = getenv ("HOMEPATH"); ++ ++ if (home_drive != NULL && home_path != NULL) ++ { ++ size_t home_drive_len = strlen (home_drive); ++ size_t home_path_len = strlen (home_path); ++ char *mem = alloca (home_drive_len + home_path_len + 1); ++ ++ memcpy (mem, home_drive, home_drive_len); ++ memcpy (mem + home_drive_len, home_path, home_path_len + 1); ++ home_dir = mem; ++ } ++ else ++ home_dir = "c:/users/default"; /* poor default */ ++#else + int success; + char *name; ++ int malloc_name = 0; + size_t buflen = GET_LOGIN_NAME_MAX () + 1; + + if (buflen == 0) +- /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try ++ /* 'sysconf' does not support _SC_LOGIN_NAME_MAX. Try + a moderate value. */ + buflen = 20; +- name = alloca_account (buflen, alloca_used); ++ if (glob_use_alloca (alloca_used, buflen)) ++ name = alloca_account (buflen, alloca_used); ++ else ++ { ++ name = malloc (buflen); ++ if (name == NULL) ++ { ++ retval = GLOB_NOSPACE; ++ goto out; ++ } ++ malloc_name = 1; ++ } + + success = __getlogin_r (name, buflen) == 0; + if (success) + { + struct passwd *p; +-# if defined HAVE_GETPWNAM_R || defined _LIBC +- long int pwbuflen = GETPW_R_SIZE_MAX (); ++ char *malloc_pwtmpbuf = NULL; + char *pwtmpbuf; ++# if defined HAVE_GETPWNAM_R || defined _LIBC ++ long int pwbuflenmax = GETPW_R_SIZE_MAX (); ++ size_t pwbuflen = pwbuflenmax; + struct passwd pwbuf; +- int malloc_pwtmpbuf = 0; + int save = errno; + +-# ifndef _LIBC +- if (pwbuflen == -1) +- /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. ++# ifndef _LIBC ++ if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX)) ++ /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. + Try a moderate value. */ + pwbuflen = 1024; +-# endif +- if (__libc_use_alloca (alloca_used + pwbuflen)) ++# endif ++ if (glob_use_alloca (alloca_used, pwbuflen)) + pwtmpbuf = alloca_account (pwbuflen, alloca_used); + else + { + pwtmpbuf = malloc (pwbuflen); + if (pwtmpbuf == NULL) + { ++ if (__glibc_unlikely (malloc_name)) ++ free (name); + retval = GLOB_NOSPACE; + goto out; + } +- malloc_pwtmpbuf = 1; ++ malloc_pwtmpbuf = pwtmpbuf; + } + + while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) + != 0) + { ++ size_t newlen; ++ bool v; + if (errno != ERANGE) + { + p = NULL; + break; + } +- +- if (!malloc_pwtmpbuf +- && __libc_use_alloca (alloca_used +- + 2 * pwbuflen)) ++ v = size_add_wrapv (pwbuflen, pwbuflen, &newlen); ++ if (!v && malloc_pwtmpbuf == NULL ++ && glob_use_alloca (alloca_used, newlen)) + pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen, +- 2 * pwbuflen, +- alloca_used); ++ newlen, alloca_used); + else + { +- char *newp = realloc (malloc_pwtmpbuf +- ? pwtmpbuf : NULL, +- 2 * pwbuflen); ++ char *newp = (v ? NULL ++ : realloc (malloc_pwtmpbuf, newlen)); + if (newp == NULL) + { +- if (__glibc_unlikely (malloc_pwtmpbuf)) +- free (pwtmpbuf); ++ free (malloc_pwtmpbuf); ++ if (__glibc_unlikely (malloc_name)) ++ free (name); + retval = GLOB_NOSPACE; + goto out; + } +- pwtmpbuf = newp; +- pwbuflen = 2 * pwbuflen; +- malloc_pwtmpbuf = 1; ++ malloc_pwtmpbuf = pwtmpbuf = newp; + } ++ pwbuflen = newlen; + __set_errno (save); + } +-# else ++# else + p = getpwnam (name); +-# endif ++# endif ++ if (__glibc_unlikely (malloc_name)) ++ free (name); + if (p != NULL) + { +- if (!malloc_pwtmpbuf) ++ if (malloc_pwtmpbuf == NULL) + home_dir = p->pw_dir; + else + { + size_t home_dir_len = strlen (p->pw_dir) + 1; +- if (__libc_use_alloca (alloca_used + home_dir_len)) ++ if (glob_use_alloca (alloca_used, home_dir_len)) + home_dir = alloca_account (home_dir_len, + alloca_used); + else +@@ -733,26 +752,32 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + malloc_home_dir = 1; + } + memcpy (home_dir, p->pw_dir, home_dir_len); +- +- free (pwtmpbuf); + } + } ++ free (malloc_pwtmpbuf); + } ++ else ++ { ++ if (__glibc_unlikely (malloc_name)) ++ free (name); ++ } ++#endif /* WINDOWS32 */ + } + if (home_dir == NULL || home_dir[0] == '\0') + { ++ if (__glibc_unlikely (malloc_home_dir)) ++ free (home_dir); + if (flags & GLOB_TILDE_CHECK) + { +- if (__glibc_unlikely (malloc_home_dir)) +- free (home_dir); + retval = GLOB_NOMATCH; + goto out; + } + else +- home_dir = (char *) "~"; /* No luck. */ ++ { ++ home_dir = (char *) "~"; /* No luck. */ ++ malloc_home_dir = 0; ++ } + } +-# endif /* WINDOWS32 */ +-# endif + /* Now construct the full directory. */ + if (dirname[1] == '\0') + { +@@ -767,8 +792,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + { + char *newp; + size_t home_len = strlen (home_dir); +- int use_alloca = __libc_use_alloca (alloca_used +- + home_len + dirlen); ++ int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen); + if (use_alloca) + newp = alloca_account (home_len + dirlen, alloca_used); + else +@@ -792,12 +816,15 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + dirname = newp; + dirlen += home_len - 1; + malloc_dirname = !use_alloca; ++ ++ if (__glibc_unlikely (malloc_home_dir)) ++ free (home_dir); + } + dirname_modified = 1; + } +-# if !defined _AMIGA && !defined WINDOWS32 + else + { ++#ifndef WINDOWS32 + char *end_name = strchr (dirname, '/'); + char *user_name; + int malloc_user_name = 0; +@@ -819,7 +846,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + else + { + char *newp; +- if (__libc_use_alloca (alloca_used + (end_name - dirname))) ++ if (glob_use_alloca (alloca_used, end_name - dirname)) + newp = alloca_account (end_name - dirname, alloca_used); + else + { +@@ -836,11 +863,11 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + char *p = mempcpy (newp, dirname + 1, + unescape - dirname - 1); + char *q = unescape; +- while (*q != '\0') ++ while (q != end_name) + { + if (*q == '\\') + { +- if (q[1] == '\0') ++ if (q + 1 == end_name) + { + /* "~fo\\o\\" unescape to user_name "foo\\", + but "~fo\\o\\/" unescape to user_name +@@ -856,7 +883,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + *p = '\0'; + } + else +- *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) ++ *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1)) + = '\0'; + user_name = newp; + } +@@ -864,20 +891,21 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + /* Look up specific user's home directory. */ + { + struct passwd *p; ++ char *malloc_pwtmpbuf = NULL; + # if defined HAVE_GETPWNAM_R || defined _LIBC +- long int buflen = GETPW_R_SIZE_MAX (); ++ long int buflenmax = GETPW_R_SIZE_MAX (); ++ size_t buflen = buflenmax; + char *pwtmpbuf; +- int malloc_pwtmpbuf = 0; + struct passwd pwbuf; + int save = errno; + + # ifndef _LIBC +- if (buflen == -1) +- /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a ++ if (! (0 <= buflenmax && buflenmax <= SIZE_MAX)) ++ /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a + moderate value. */ + buflen = 1024; + # endif +- if (__libc_use_alloca (alloca_used + buflen)) ++ if (glob_use_alloca (alloca_used, buflen)) + pwtmpbuf = alloca_account (buflen, alloca_used); + else + { +@@ -890,32 +918,32 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + retval = GLOB_NOSPACE; + goto out; + } +- malloc_pwtmpbuf = 1; ++ malloc_pwtmpbuf = pwtmpbuf; + } + + while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) + { ++ size_t newlen; ++ bool v; + if (errno != ERANGE) + { + p = NULL; + break; + } +- if (!malloc_pwtmpbuf +- && __libc_use_alloca (alloca_used + 2 * buflen)) ++ v = size_add_wrapv (buflen, buflen, &newlen); ++ if (!v && malloc_pwtmpbuf == NULL ++ && glob_use_alloca (alloca_used, newlen)) + pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen, +- 2 * buflen, alloca_used); ++ newlen, alloca_used); + else + { +- char *newp = realloc (malloc_pwtmpbuf ? pwtmpbuf : NULL, +- 2 * buflen); ++ char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen); + if (newp == NULL) + { +- if (__glibc_unlikely (malloc_pwtmpbuf)) +- free (pwtmpbuf); ++ free (malloc_pwtmpbuf); + goto nomem_getpw; + } +- pwtmpbuf = newp; +- malloc_pwtmpbuf = 1; ++ malloc_pwtmpbuf = pwtmpbuf = newp; + } + __set_errno (save); + } +@@ -936,7 +964,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + free (dirname); + malloc_dirname = 0; + +- if (__libc_use_alloca (alloca_used + home_len + rest_len + 1)) ++ if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) + dirname = alloca_account (home_len + rest_len + 1, + alloca_used); + else +@@ -944,8 +972,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + dirname = malloc (home_len + rest_len + 1); + if (dirname == NULL) + { +- if (__glibc_unlikely (malloc_pwtmpbuf)) +- free (pwtmpbuf); ++ free (malloc_pwtmpbuf); + retval = GLOB_NOSPACE; + goto out; + } +@@ -957,24 +984,24 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + dirlen = home_len + rest_len; + dirname_modified = 1; + +- if (__glibc_unlikely (malloc_pwtmpbuf)) +- free (pwtmpbuf); ++ free (malloc_pwtmpbuf); + } + else + { +- if (__glibc_unlikely (malloc_pwtmpbuf)) +- free (pwtmpbuf); ++ free (malloc_pwtmpbuf); + + if (flags & GLOB_TILDE_CHECK) +- /* We have to regard it as an error if we cannot find the +- home directory. */ +- return GLOB_NOMATCH; ++ { ++ /* We have to regard it as an error if we cannot find the ++ home directory. */ ++ retval = GLOB_NOMATCH; ++ goto out; ++ } + } + } ++#endif /* !WINDOWS32 */ + } +-# endif /* Not Amiga && not WINDOWS32. */ + } +-#endif /* Not VMS. */ + + /* Now test whether we looked for "~" or "~NAME". In this case we + can give the answer now. */ +@@ -993,19 +1020,18 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + size_t newcount = pglob->gl_pathc + pglob->gl_offs; + char **new_gl_pathv; + +- if (newcount > UINTPTR_MAX - (1 + 1) +- || newcount + 1 + 1 > ~((size_t) 0) / sizeof (char *)) ++ if (newcount > SIZE_MAX / sizeof (char *) - 2) + { + nospace: + free (pglob->gl_pathv); + pglob->gl_pathv = NULL; + pglob->gl_pathc = 0; +- return GLOB_NOSPACE; ++ retval = GLOB_NOSPACE; ++ goto out; + } + +- new_gl_pathv +- = (char **) realloc (pglob->gl_pathv, +- (newcount + 1 + 1) * sizeof (char *)); ++ new_gl_pathv = realloc (pglob->gl_pathv, ++ (newcount + 2) * sizeof (char *)); + if (new_gl_pathv == NULL) + goto nospace; + pglob->gl_pathv = new_gl_pathv; +@@ -1019,12 +1045,19 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen); + p[0] = '/'; + p[1] = '\0'; ++ if (__glibc_unlikely (malloc_dirname)) ++ free (dirname); + } + else + { +- pglob->gl_pathv[newcount] = strdup (dirname); +- if (pglob->gl_pathv[newcount] == NULL) +- goto nospace; ++ if (__glibc_unlikely (malloc_dirname)) ++ pglob->gl_pathv[newcount] = dirname; ++ else ++ { ++ pglob->gl_pathv[newcount] = strdup (dirname); ++ if (pglob->gl_pathv[newcount] == NULL) ++ goto nospace; ++ } + } + pglob->gl_pathv[++newcount] = NULL; + ++pglob->gl_pathc; +@@ -1034,7 +1067,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + } + + /* Not found. */ +- return GLOB_NOMATCH; ++ retval = GLOB_NOMATCH; ++ goto out; + } + + meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE)); +@@ -1080,7 +1114,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + if (status != 0) + { + if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH) +- return status; ++ { ++ retval = status; ++ goto out; ++ } + goto no_matches; + } + +@@ -1091,19 +1128,6 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + { + size_t old_pathc; + +-#ifdef SHELL +- { +- /* Make globbing interruptible in the bash shell. */ +- extern int interrupt_state; +- +- if (interrupt_state) +- { +- globfree (&dirs); +- return GLOB_ABORTED; +- } +- } +-#endif /* SHELL. */ +- + old_pathc = pglob->gl_pathc; + status = glob_in_dir (filename, dirs.gl_pathv[i], + ((flags | GLOB_APPEND) +@@ -1118,7 +1142,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + globfree (&dirs); + globfree (pglob); + pglob->gl_pathc = 0; +- return status; ++ retval = status; ++ goto out; + } + + /* Stick the directory on the front of each name. */ +@@ -1129,13 +1154,14 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + globfree (&dirs); + globfree (pglob); + pglob->gl_pathc = 0; +- return GLOB_NOSPACE; ++ retval = GLOB_NOSPACE; ++ goto out; + } + } + + flags |= GLOB_MAGCHAR; + +- /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls. ++ /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls. + But if we have not found any matching entry and the GLOB_NOCHECK + flag was set we must return the input pattern itself. */ + if (pglob->gl_pathc + pglob->gl_offs == oldcount) +@@ -1147,28 +1173,28 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + size_t newcount = pglob->gl_pathc + pglob->gl_offs; + char **new_gl_pathv; + +- if (newcount > UINTPTR_MAX - 2 +- || newcount + 2 > ~((size_t) 0) / sizeof (char *)) ++ if (newcount > SIZE_MAX / sizeof (char *) - 2) + { + nospace2: + globfree (&dirs); +- return GLOB_NOSPACE; ++ retval = GLOB_NOSPACE; ++ goto out; + } + +- new_gl_pathv = (char **) realloc (pglob->gl_pathv, +- (newcount + 2) +- * sizeof (char *)); ++ new_gl_pathv = realloc (pglob->gl_pathv, ++ (newcount + 2) * sizeof (char *)); + if (new_gl_pathv == NULL) + goto nospace2; + pglob->gl_pathv = new_gl_pathv; + +- pglob->gl_pathv[newcount] = __strdup (pattern); ++ pglob->gl_pathv[newcount] = strdup (pattern); + if (pglob->gl_pathv[newcount] == NULL) + { + globfree (&dirs); + globfree (pglob); + pglob->gl_pathc = 0; +- return GLOB_NOSPACE; ++ retval = GLOB_NOSPACE; ++ goto out; + } + + ++pglob->gl_pathc; +@@ -1180,7 +1206,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + else + { + globfree (&dirs); +- return GLOB_NOMATCH; ++ retval = GLOB_NOMATCH; ++ goto out; + } + } + +@@ -1226,7 +1253,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + flags = orig_flags; + goto no_matches; + } +- return status; ++ retval = status; ++ goto out; + } + + if (dirlen > 0) +@@ -1238,7 +1266,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + { + globfree (pglob); + pglob->gl_pathc = 0; +- return GLOB_NOSPACE; ++ retval = GLOB_NOSPACE; ++ goto out; + } + } + } +@@ -1263,7 +1292,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + { + globfree (pglob); + pglob->gl_pathc = 0; +- return GLOB_NOSPACE; ++ retval = GLOB_NOSPACE; ++ goto out; + } + strcpy (&new[len - 2], "/"); + pglob->gl_pathv[i] = new; +@@ -1289,32 +1319,12 @@ libc_hidden_def (glob) + #endif + + +-#if !defined _LIBC || !defined GLOB_ONLY_P +- +-/* Free storage allocated in PGLOB by a previous `glob' call. */ +-void +-globfree (glob_t *pglob) +-{ +- if (pglob->gl_pathv != NULL) +- { +- size_t i; +- for (i = 0; i < pglob->gl_pathc; ++i) +- free (pglob->gl_pathv[pglob->gl_offs + i]); +- free (pglob->gl_pathv); +- pglob->gl_pathv = NULL; +- } +-} +-#if defined _LIBC && !defined globfree +-libc_hidden_def (globfree) +-#endif +- +- + /* Do a collated comparison of A and B. */ + static int + collated_compare (const void *a, const void *b) + { +- const char *const s1 = *(const char *const * const) a; +- const char *const s2 = *(const char *const * const) b; ++ char *const *ps1 = a; char *s1 = *ps1; ++ char *const *ps2 = b; char *s2 = *ps2; + + if (s1 == s2) + return 0; +@@ -1335,28 +1345,24 @@ prefix_array (const char *dirname, char **array, size_t n) + { + size_t i; + size_t dirlen = strlen (dirname); +-#if defined __MSDOS__ || defined WINDOWS32 +- int sep_char = '/'; +-# define DIRSEP_CHAR sep_char +-#else +-# define DIRSEP_CHAR '/' +-#endif ++ char dirsep_char = '/'; + + if (dirlen == 1 && dirname[0] == '/') + /* DIRNAME is just "/", so normal prepending would get us "//foo". + We want "/foo" instead, so don't prepend any chars from DIRNAME. */ + dirlen = 0; ++ + #if defined __MSDOS__ || defined WINDOWS32 +- else if (dirlen > 1) ++ if (dirlen > 1) + { + if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':') + /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */ + --dirlen; + else if (dirname[dirlen - 1] == ':') + { +- /* DIRNAME is "d:". Use `:' instead of `/'. */ ++ /* DIRNAME is "d:". Use ':' instead of '/'. */ + --dirlen; +- sep_char = ':'; ++ dirsep_char = ':'; + } + } + #endif +@@ -1364,7 +1370,7 @@ prefix_array (const char *dirname, char **array, size_t n) + for (i = 0; i < n; ++i) + { + size_t eltlen = strlen (array[i]) + 1; +- char *new = (char *) malloc (dirlen + 1 + eltlen); ++ char *new = malloc (dirlen + 1 + eltlen); + if (new == NULL) + { + while (i > 0) +@@ -1374,7 +1380,7 @@ prefix_array (const char *dirname, char **array, size_t n) + + { + char *endp = mempcpy (new, dirname, dirlen); +- *endp++ = DIRSEP_CHAR; ++ *endp++ = dirsep_char; + mempcpy (endp, array[i], eltlen); + } + free (array[i]); +@@ -1384,103 +1390,57 @@ prefix_array (const char *dirname, char **array, size_t n) + return 0; + } + +- +-/* We must not compile this function twice. */ +-#if !defined _LIBC || !defined NO_GLOB_PATTERN_P +-int +-__glob_pattern_type (const char *pattern, int quote) +-{ +- const char *p; +- int ret = 0; +- +- for (p = pattern; *p != '\0'; ++p) +- switch (*p) +- { +- case '?': +- case '*': +- return 1; +- +- case '\\': +- if (quote) +- { +- if (p[1] != '\0') +- ++p; +- ret |= 2; +- } +- break; +- +- case '[': +- ret |= 4; +- break; +- +- case ']': +- if (ret & 4) +- return 1; +- break; +- } +- +- return ret; +-} +- +-/* Return nonzero if PATTERN contains any metacharacters. +- Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +-int +-__glob_pattern_p (const char *pattern, int quote) +-{ +- return __glob_pattern_type (pattern, quote) == 1; +-} +-# ifdef _LIBC +-weak_alias (__glob_pattern_p, glob_pattern_p) +-# endif +-#endif +- +-#endif /* !GLOB_ONLY_P */ +- +- + /* We put this in a separate function mainly to allow the memory + allocated with alloca to be recycled. */ +-#if !defined _LIBC || !defined GLOB_ONLY_P + static int + __attribute_noinline__ +-link_exists2_p (const char *dir, size_t dirlen, const char *fname, +- glob_t *pglob +-# ifndef _LIBC +- , int flags ++link_stat (const char *dir, size_t dirlen, const char *fname, ++ glob_t *pglob ++# if !defined _LIBC && !HAVE_FSTATAT ++ , int flags + # endif +- ) ++ ) + { + size_t fnamelen = strlen (fname); +- char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1); ++ char *fullname = __alloca (dirlen + 1 + fnamelen + 1); + struct stat st; +-# ifndef _LIBC +- struct_stat64 st64; +-# endif + + mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1), + fname, fnamelen + 1); + +-# ifdef _LIBC +- return (*pglob->gl_stat) (fullname, &st) == 0; +-# else +- return ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) +- ? (*pglob->gl_stat) (fullname, &st) +- : __stat64 (fullname, &st64)) == 0); ++# if !defined _LIBC && !HAVE_FSTATAT ++ if (__builtin_expect ((flags & GLOB_ALTDIRFUNC) == 0, 1)) ++ { ++ struct_stat64 st64; ++ return __stat64 (fullname, &st64); ++ } + # endif ++ return (*pglob->gl_stat) (fullname, &st); + } +-# ifdef _LIBC +-# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \ +- (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) \ +- ? link_exists2_p (dirname, dirnamelen, fname, pglob) \ +- : ({ struct stat64 st64; \ +- __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0; })) ++ ++/* Return true if DIR/FNAME exists. */ ++static int ++link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname, ++ glob_t *pglob, int flags) ++{ ++ int status; ++# if defined _LIBC || HAVE_FSTATAT ++ if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)) ++ status = link_stat (dir, dirlen, fname, pglob); ++ else ++ { ++ /* dfd cannot be -1 here, because dirfd never returns -1 on ++ glibc, or on hosts that have fstatat. */ ++ struct_stat64 st64; ++ status = __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0); ++ } + # else +-# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \ +- link_exists2_p (dirname, dirnamelen, fname, pglob, flags) ++ status = link_stat (dir, dirlen, fname, pglob, flags); + # endif +-#endif +- ++ return status == 0 || errno == EOVERFLOW; ++} + +-/* Like `glob', but PATTERN is a final pathname component, ++/* Like 'glob', but PATTERN is a final pathname component, + and matches are searched for in DIRECTORY. + The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. + The GLOB_APPEND flag is assumed to be set (always appends). */ +@@ -1491,25 +1451,25 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + { + size_t dirlen = strlen (directory); + void *stream = NULL; +- struct globnames +- { +- struct globnames *next; +- size_t count; +- char *name[64]; +- }; +-#define INITIAL_COUNT sizeof (init_names.name) / sizeof (init_names.name[0]) +- struct globnames init_names; +- struct globnames *names = &init_names; +- struct globnames *names_alloca = &init_names; ++# define GLOBNAMES_MEMBERS(nnames) \ ++ struct globnames *next; size_t count; char *name[nnames]; ++ struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) }; ++ struct { GLOBNAMES_MEMBERS (64) } init_names_buf; ++ struct globnames *init_names = (struct globnames *) &init_names_buf; ++ struct globnames *names = init_names; ++ struct globnames *names_alloca = init_names; + size_t nfound = 0; + size_t cur = 0; + int meta; + int save; ++ int result; + +- alloca_used += sizeof (init_names); ++ alloca_used += sizeof init_names_buf; + +- init_names.next = NULL; +- init_names.count = INITIAL_COUNT; ++ init_names->next = NULL; ++ init_names->count = ((sizeof init_names_buf ++ - offsetof (struct globnames, name)) ++ / sizeof init_names->name[0]); + + meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE)); + if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) +@@ -1529,14 +1489,16 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + struct_stat64 st64; + } ust; + size_t patlen = strlen (pattern); +- int alloca_fullname = __libc_use_alloca (alloca_used +- + dirlen + 1 + patlen + 1); ++ size_t fullsize; ++ bool alloca_fullname ++ = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize) ++ && glob_use_alloca (alloca_used, fullsize)); + char *fullname; + if (alloca_fullname) +- fullname = alloca_account (dirlen + 1 + patlen + 1, alloca_used); ++ fullname = alloca_account (fullsize, alloca_used); + else + { +- fullname = malloc (dirlen + 1 + patlen + 1); ++ fullname = malloc (fullsize); + if (fullname == NULL) + return GLOB_NOSPACE; + } +@@ -1544,9 +1506,11 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), + "/", 1), + pattern, patlen + 1); +- if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ++ if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) + ? (*pglob->gl_stat) (fullname, &ust.st) +- : __stat64 (fullname, &ust.st64)) == 0) ++ : __stat64 (fullname, &ust.st64)) ++ == 0) ++ || errno == EOVERFLOW) + /* We found this file to be existing. Now tell the rest + of the function to copy this name into the result. */ + flags |= GLOB_NOCHECK; +@@ -1568,16 +1532,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + } + else + { +-#ifdef _LIBC + int dfd = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) + ? -1 : dirfd ((DIR *) stream)); +-#endif + int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) +- | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) +-#if defined _AMIGA || defined VMS +- | FNM_CASEFOLD +-#endif +- ); ++ | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)); + flags |= GLOB_MAGCHAR; + + while (1) +@@ -1597,19 +1555,24 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + } + if (d.name == NULL) + break; +- if (d.skip_entry) ++ if (readdir_result_skip_entry (d)) + continue; + + /* If we shall match only directories use the information + provided by the dirent call if possible. */ +- if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d)) +- continue; ++ if (flags & GLOB_ONLYDIR) ++ switch (readdir_result_type (d)) ++ { ++ case DT_DIR: case DT_LNK: case DT_UNKNOWN: break; ++ default: continue; ++ } + + if (fnmatch (pattern, d.name, fnm_flags) == 0) + { + /* If the file we found is a symlink we have to + make sure the target file exists. */ +- if (!readdir_result_might_be_symlink (d) ++ dirent_type type = readdir_result_type (d); ++ if (! (type == DT_LNK || type == DT_UNKNOWN) + || link_exists_p (dfd, directory, dirlen, d.name, + pglob, flags)) + { +@@ -1617,10 +1580,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + { + struct globnames *newnames; + size_t count = names->count * 2; +- size_t size = (sizeof (struct globnames) +- + ((count - INITIAL_COUNT) +- * sizeof (char *))); +- if (__libc_use_alloca (alloca_used + size)) ++ size_t nameoff = offsetof (struct globnames, name); ++ size_t size = FLEXSIZEOF (struct globnames, name, ++ count * sizeof (char *)); ++ if ((SIZE_MAX - nameoff) / 2 / sizeof (char *) ++ < names->count) ++ goto memory_error; ++ if (glob_use_alloca (alloca_used, size)) + newnames = names_alloca + = alloca_account (size, alloca_used); + else if ((newnames = malloc (size)) +@@ -1636,6 +1602,8 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + goto memory_error; + ++cur; + ++nfound; ++ if (SIZE_MAX - pglob->gl_offs <= nfound) ++ goto memory_error; + } + } + } +@@ -1646,29 +1614,27 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + { + size_t len = strlen (pattern); + nfound = 1; +- names->name[cur] = (char *) malloc (len + 1); ++ names->name[cur] = malloc (len + 1); + if (names->name[cur] == NULL) + goto memory_error; + *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0'; + } + +- int result = GLOB_NOMATCH; ++ result = GLOB_NOMATCH; + if (nfound != 0) + { ++ char **new_gl_pathv; + result = 0; + +- if (pglob->gl_pathc > UINTPTR_MAX - pglob->gl_offs +- || pglob->gl_pathc + pglob->gl_offs > UINTPTR_MAX - nfound +- || pglob->gl_pathc + pglob->gl_offs + nfound > UINTPTR_MAX - 1 +- || (pglob->gl_pathc + pglob->gl_offs + nfound + 1 +- > UINTPTR_MAX / sizeof (char *))) ++ if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc ++ < pglob->gl_offs + nfound + 1) + goto memory_error; + +- char **new_gl_pathv; + new_gl_pathv +- = (char **) realloc (pglob->gl_pathv, +- (pglob->gl_pathc + pglob->gl_offs + nfound + 1) +- * sizeof (char *)); ++ = realloc (pglob->gl_pathv, ++ (pglob->gl_pathc + pglob->gl_offs + nfound + 1) ++ * sizeof (char *)); ++ + if (new_gl_pathv == NULL) + { + memory_error: +@@ -1684,7 +1650,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + and this is the block assigned to OLD here. */ + if (names == NULL) + { +- assert (old == &init_names); ++ assert (old == init_names); + break; + } + cur = names->count; +@@ -1710,7 +1676,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, + and this is the block assigned to OLD here. */ + if (names == NULL) + { +- assert (old == &init_names); ++ assert (old == init_names); + break; + } + cur = names->count; +diff --git a/posix/glob64.c b/posix/glob64.c +index a5f5a7f9e2..39e54afe8b 100644 +--- a/posix/glob64.c ++++ b/posix/glob64.c +@@ -43,10 +43,4 @@ glob64 (const char *pattern, int flags, + } + libc_hidden_def (glob64) + +-void +-globfree64 (glob64_t *pglob) +-{ +-} +-libc_hidden_def (globfree64) +- + stub_warning (glob64) +diff --git a/posix/glob_internal.h b/posix/glob_internal.h +new file mode 100644 +index 0000000000..12c93660b7 +--- /dev/null ++++ b/posix/glob_internal.h +@@ -0,0 +1,57 @@ ++/* Shared definition for glob and glob_pattern_p. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#ifndef GLOB_INTERNAL_H ++# define GLOB_INTERNAL_H ++ ++static inline int ++__glob_pattern_type (const char *pattern, int quote) ++{ ++ const char *p; ++ int ret = 0; ++ ++ for (p = pattern; *p != '\0'; ++p) ++ switch (*p) ++ { ++ case '?': ++ case '*': ++ return 1; ++ ++ case '\\': ++ if (quote) ++ { ++ if (p[1] != '\0') ++ ++p; ++ ret |= 2; ++ } ++ break; ++ ++ case '[': ++ ret |= 4; ++ break; ++ ++ case ']': ++ if (ret & 4) ++ return 1; ++ break; ++ } ++ ++ return ret; ++} ++ ++#endif /* GLOB_INTERNAL_H */ +diff --git a/posix/glob_pattern_p.c b/posix/glob_pattern_p.c +new file mode 100644 +index 0000000000..a17d337182 +--- /dev/null ++++ b/posix/glob_pattern_p.c +@@ -0,0 +1,33 @@ ++/* Return nonzero if PATTERN contains any metacharacters. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#ifndef _LIBC ++# include <config.h> ++#endif ++ ++#include <glob.h> ++#include "glob_internal.h" ++ ++/* Return nonzero if PATTERN contains any metacharacters. ++ Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ ++int ++__glob_pattern_p (const char *pattern, int quote) ++{ ++ return __glob_pattern_type (pattern, quote) == 1; ++} ++weak_alias (__glob_pattern_p, glob_pattern_p) +diff --git a/posix/globfree.c b/posix/globfree.c +new file mode 100644 +index 0000000000..042e29d9b0 +--- /dev/null ++++ b/posix/globfree.c +@@ -0,0 +1,41 @@ ++/* Frees the dynamically allocated storage from an earlier call to glob. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#ifndef _LIBC ++# include <config.h> ++#endif ++ ++#include <glob.h> ++#include <stdlib.h> ++ ++/* Free storage allocated in PGLOB by a previous `glob' call. */ ++void ++globfree (glob_t *pglob) ++{ ++ if (pglob->gl_pathv != NULL) ++ { ++ size_t i; ++ for (i = 0; i < pglob->gl_pathc; ++i) ++ free (pglob->gl_pathv[pglob->gl_offs + i]); ++ free (pglob->gl_pathv); ++ pglob->gl_pathv = NULL; ++ } ++} ++#ifndef globfree ++libc_hidden_def (globfree) ++#endif +diff --git a/sysdeps/unix/sysv/linux/sh/pread.c b/posix/globfree64.c +similarity index 68% +rename from sysdeps/unix/sysv/linux/sh/pread.c +rename to posix/globfree64.c +index d3f99f35db..c9f8908a4e 100644 +--- a/sysdeps/unix/sysv/linux/sh/pread.c ++++ b/posix/globfree64.c +@@ -1,6 +1,6 @@ +-/* Copyright (C) 1997-2016 Free Software Foundation, Inc. ++/* Frees the dynamically allocated storage from an earlier call to glob. ++ Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. +- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public +@@ -16,8 +16,16 @@ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +-/* SH4 ABI does not really require argument alignment for 64-bits, but +- the kernel interface for pread adds a dummy long argument before the +- offset. */ +-#define __ALIGNMENT_ARG +-#include <sysdeps/unix/sysv/linux/pread.c> ++#ifndef _LIBC ++# include <config.h> ++#endif ++ ++#include <glob.h> ++#include <stdlib.h> ++ ++/* Free storage allocated in PGLOB by a previous `glob' call. */ ++void ++globfree64 (glob64_t *pglob) ++{ ++} ++libc_hidden_def (globfree64) +diff --git a/posix/tst-glob-tilde.c b/posix/tst-glob-tilde.c +new file mode 100644 +index 0000000000..6886f4371f +--- /dev/null ++++ b/posix/tst-glob-tilde.c +@@ -0,0 +1,143 @@ ++/* Check for GLOB_TIDLE heap allocation issues (bugs 22320, 22325, 22332). ++ Copyright (C) 2017 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 <glob.h> ++#include <mcheck.h> ++#include <nss.h> ++#include <pwd.h> ++#include <stdlib.h> ++#include <string.h> ++#include <support/check.h> ++#include <support/support.h> ++ ++/* Flag which indicates whether to pass the GLOB_ONLYDIR flag. */ ++static int do_onlydir; ++ ++/* Flag which indicates whether to pass the GLOB_NOCHECK flag. */ ++static int do_nocheck; ++ ++/* Flag which indicates whether to pass the GLOB_MARK flag. */ ++static int do_mark; ++ ++/* Flag which indicates whether to pass the GLOB_NOESCAPE flag. */ ++static int do_noescape; ++ ++static void ++one_test (const char *prefix, const char *middle, const char *suffix) ++{ ++ char *pattern = xasprintf ("%s%s%s", prefix, middle, suffix); ++ int flags = GLOB_TILDE; ++ if (do_onlydir) ++ flags |= GLOB_ONLYDIR; ++ if (do_nocheck) ++ flags |= GLOB_NOCHECK; ++ if (do_mark) ++ flags |= GLOB_MARK; ++ if (do_noescape) ++ flags |= GLOB_NOESCAPE; ++ glob_t gl; ++ /* This glob call might result in crashes or memory leaks. */ ++ if (glob (pattern, flags, NULL, &gl) == 0) ++ globfree (&gl); ++ free (pattern); ++} ++ ++enum ++ { ++ /* The largest base being tested. */ ++ largest_base_size = 500000, ++ ++ /* The actual size is the base size plus a variable whose absolute ++ value is not greater than this. This helps malloc to trigger ++ overflows. */ ++ max_size_skew = 16, ++ ++ /* The maximum string length supported by repeating_string ++ below. */ ++ repeat_size = largest_base_size + max_size_skew, ++ }; ++ ++/* Used to construct strings which repeat a single character 'x'. */ ++static char *repeat; ++ ++/* Return a string of SIZE characters. */ ++const char * ++repeating_string (int size) ++{ ++ TEST_VERIFY (size >= 0); ++ TEST_VERIFY (size <= repeat_size); ++ const char *repeated_shifted = repeat + repeat_size - size; ++ TEST_VERIFY (strlen (repeated_shifted) == size); ++ return repeated_shifted; ++} ++ ++static int ++do_test (void) ++{ ++ /* Avoid network-based NSS modules and initialize nss_files with a ++ dummy lookup. This has to come before mtrace because NSS does ++ not free all memory. */ ++ __nss_configure_lookup ("passwd", "files"); ++ (void) getpwnam ("root"); ++ ++ mtrace (); ++ ++ repeat = xmalloc (repeat_size + 1); ++ memset (repeat, 'x', repeat_size); ++ repeat[repeat_size] = '\0'; ++ ++ /* These numbers control the size of the user name. The values ++ cover the minimum (0), a typical size (8), a large ++ stack-allocated size (100000), and a somewhat large ++ heap-allocated size (largest_base_size). */ ++ static const int base_sizes[] = { 0, 8, 100, 100000, largest_base_size, -1 }; ++ ++ for (do_onlydir = 0; do_onlydir < 2; ++do_onlydir) ++ for (do_nocheck = 0; do_nocheck < 2; ++do_nocheck) ++ for (do_mark = 0; do_mark < 2; ++do_mark) ++ for (do_noescape = 0; do_noescape < 2; ++do_noescape) ++ for (int base_idx = 0; base_sizes[base_idx] >= 0; ++base_idx) ++ { ++ for (int size_skew = -max_size_skew; size_skew <= max_size_skew; ++ ++size_skew) ++ { ++ int size = base_sizes[base_idx] + size_skew; ++ if (size < 0) ++ continue; ++ ++ const char *user_name = repeating_string (size); ++ one_test ("~", user_name, "/a/b"); ++ one_test ("~", user_name, "x\\x\\x////x\\a"); ++ } ++ ++ const char *user_name = repeating_string (base_sizes[base_idx]); ++ one_test ("~", user_name, ""); ++ one_test ("~", user_name, "/"); ++ one_test ("~", user_name, "/a"); ++ one_test ("~", user_name, "/*/*"); ++ one_test ("~", user_name, "\\/"); ++ one_test ("/~", user_name, ""); ++ one_test ("*/~", user_name, "/a/b"); ++ } ++ ++ free (repeat); ++ ++ return 0; ++} ++ ++#include <support/test-driver.c> diff --git a/resolv/Makefile b/resolv/Makefile index 8be41d3ae1..a4c86b9762 100644 --- a/resolv/Makefile @@ -9482,12 +11928,12 @@ index 0000000000..cfc6dd8fa8 + if (bind (fd, sa, sa_len) != 0) + FAIL_EXIT1 ("bind (%d), family %d: %m", fd, sa->sa_family); +} -diff --git a/sysdeps/unix/sysv/linux/sh/pread.c b/support/xcalloc.c -similarity index 68% -rename from sysdeps/unix/sysv/linux/sh/pread.c +diff --git a/sysdeps/unix/sysv/linux/sh/pread64.c b/support/xcalloc.c +similarity index 67% +rename from sysdeps/unix/sysv/linux/sh/pread64.c rename to support/xcalloc.c -index d3f99f35db..135f42dab2 100644 ---- a/sysdeps/unix/sysv/linux/sh/pread.c +index b2e8a25788..135f42dab2 100644 +--- a/sysdeps/unix/sysv/linux/sh/pread64.c +++ b/support/xcalloc.c @@ -1,6 +1,6 @@ -/* Copyright (C) 1997-2016 Free Software Foundation, Inc. @@ -9506,7 +11952,7 @@ index d3f99f35db..135f42dab2 100644 - the kernel interface for pread adds a dummy long argument before the - offset. */ -#define __ALIGNMENT_ARG --#include <sysdeps/unix/sysv/linux/pread.c> +-#include <sysdeps/unix/sysv/linux/pread64.c> +#include <support/support.h> + +#include <stdarg.h> @@ -9523,31 +11969,30 @@ index d3f99f35db..135f42dab2 100644 + oom_error ("calloc", n * s); + return p; +} -diff --git a/sysdeps/unix/sysv/linux/sh/pread64.c b/support/xchroot.c -similarity index 67% -rename from sysdeps/unix/sysv/linux/sh/pread64.c -rename to support/xchroot.c -index b2e8a25788..abcc299e00 100644 ---- a/sysdeps/unix/sysv/linux/sh/pread64.c +diff --git a/support/xchroot.c b/support/xchroot.c +new file mode 100644 +index 0000000000..abcc299e00 +--- /dev/null +++ b/support/xchroot.c -@@ -1,6 +1,6 @@ --/* Copyright (C) 1997-2016 Free Software Foundation, Inc. +@@ -0,0 +1,28 @@ +/* chroot with error checking. + Copyright (C) 2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. -- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public -@@ -16,8 +16,13 @@ - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - --/* SH4 ABI does not really require argument alignment for 64-bits, but -- the kernel interface for pread adds a dummy long argument before the -- offset. */ --#define __ALIGNMENT_ARG --#include <sysdeps/unix/sysv/linux/pread64.c> ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ +#include <support/check.h> +#include <support/xunistd.h> +#include <sys/stat.h> @@ -11998,6 +14443,38 @@ index d5b8119c9c..ac57bd5db0 100644 "LD_LIBRARY_PATH\0" \ "LD_ORIGIN_PATH\0" \ "LD_PRELOAD\0" \ +diff --git a/sysdeps/gnu/glob64.c b/sysdeps/gnu/glob64.c +index d1e4e6f0d5..52e97e2f6a 100644 +--- a/sysdeps/gnu/glob64.c ++++ b/sysdeps/gnu/glob64.c +@@ -15,11 +15,8 @@ + #undef __stat + #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf) + +-#define NO_GLOB_PATTERN_P 1 +- + #define COMPILE_GLOB64 1 + + #include <posix/glob.c> + + libc_hidden_def (glob64) +-libc_hidden_def (globfree64) +diff --git a/sysdeps/gnu/globfree64.c b/sysdeps/gnu/globfree64.c +new file mode 100644 +index 0000000000..f092d0bf8b +--- /dev/null ++++ b/sysdeps/gnu/globfree64.c +@@ -0,0 +1,10 @@ ++#include <dirent.h> ++#include <glob.h> ++#include <sys/stat.h> ++ ++#define glob_t glob64_t ++#define globfree(pglob) globfree64 (pglob) ++ ++#include <posix/globfree.c> ++ ++libc_hidden_def (globfree64) diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h index 9404211819..01bd5bf197 100644 --- a/sysdeps/hppa/dl-machine.h @@ -13053,6 +15530,19 @@ index 94a2ce0e37..38c2432002 100644 LIBC_CANCEL_RESET (sc_cancel_oldtype); \ } \ sc_ret; \ +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 35e1ed48d2..32beaa67d0 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -140,7 +140,7 @@ endif + ifeq ($(subdir),posix) + sysdep_headers += bits/initspin.h + +-sysdep_routines += sched_getcpu ++sysdep_routines += sched_getcpu oldglob + + tests += tst-affinity tst-affinity-pid + diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S index 76baa7a698..96482e53c0 100644 --- a/sysdeps/unix/sysv/linux/aarch64/clone.S @@ -13150,6 +15640,64 @@ index 6a3154f9a7..2757bf20c3 100644 cfi_endproc .end thread_start +diff --git a/sysdeps/unix/sysv/linux/alpha/glob.c b/sysdeps/unix/sysv/linux/alpha/glob.c +index c5dfb85468..19eb9b1c07 100644 +--- a/sysdeps/unix/sysv/linux/alpha/glob.c ++++ b/sysdeps/unix/sysv/linux/alpha/glob.c +@@ -42,10 +42,6 @@ extern void __new_globfree (glob_t *__pglob); + #undef globfree64 + + versioned_symbol (libc, __new_glob, glob, GLIBC_2_1); +-versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1); + libc_hidden_ver (__new_glob, glob) +-libc_hidden_ver (__new_globfree, globfree) + + weak_alias (__new_glob, glob64) +-weak_alias (__new_globfree, globfree64) +-libc_hidden_ver (__new_globfree, globfree64) +diff --git a/sysdeps/unix/sysv/linux/alpha/globfree.c b/sysdeps/unix/sysv/linux/alpha/globfree.c +new file mode 100644 +index 0000000000..98cf1c200b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/alpha/globfree.c +@@ -0,0 +1,37 @@ ++/* Compat globfree. Linux/alpha version. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#define globfree64 __no_globfree64_decl ++#include <sys/types.h> ++#include <glob.h> ++#include <shlib-compat.h> ++ ++#define globfree(pglob) \ ++ __new_globfree (pglob) ++ ++extern void __new_globfree (glob_t *__pglob); ++ ++#include <posix/globfree.c> ++ ++#undef globfree64 ++ ++versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1); ++libc_hidden_ver (__new_globfree, globfree) ++ ++weak_alias (__new_globfree, globfree64) ++libc_hidden_ver (__new_globfree, globfree64) diff --git a/sysdeps/unix/sysv/linux/alpha/vfork.S b/sysdeps/unix/sysv/linux/alpha/vfork.S index 9fc199ac41..e5f7ed0661 100644 --- a/sysdeps/unix/sysv/linux/alpha/vfork.S @@ -13275,6 +15823,33 @@ index 6d32cece48..ec86f50814 100644 return INTERNAL_SYSCALL_ERRNO (res, err); } +diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c +index 3f21ae743f..d0b2c38c17 100644 +--- a/sysdeps/unix/sysv/linux/getcwd.c ++++ b/sysdeps/unix/sysv/linux/getcwd.c +@@ -76,7 +76,7 @@ __getcwd (char *buf, size_t size) + int retval; + + retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size); +- if (retval >= 0) ++ if (retval > 0 && path[0] == '/') + { + #ifndef NO_ALLOCATION + if (buf == NULL && size == 0) +@@ -92,10 +92,10 @@ __getcwd (char *buf, size_t size) + return buf; + } + +- /* The system call cannot handle paths longer than a page. +- Neither can the magic symlink in /proc/self. Just use the ++ /* The system call either cannot handle paths longer than a page ++ or can succeed without returning an absolute path. Just use the + generic implementation right away. */ +- if (errno == ENAMETOOLONG) ++ if (retval >= 0 || errno == ENAMETOOLONG) + { + #ifndef NO_ALLOCATION + if (buf == NULL && size == 0) diff --git a/sysdeps/unix/sysv/linux/getpid.c b/sysdeps/unix/sysv/linux/getpid.c deleted file mode 100644 index 1124549326..0000000000 @@ -13473,6 +16048,63 @@ index 25f2a9c340..feae504ce6 100644 PSEUDO_END (__clone) libc_hidden_def (__clone) +diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/i386/glob64.c +index 802c957d6c..c2cc85741f 100644 +--- a/sysdeps/unix/sysv/linux/i386/glob64.c ++++ b/sysdeps/unix/sysv/linux/i386/glob64.c +@@ -19,6 +19,7 @@ + #include <dirent.h> + #include <glob.h> + #include <sys/stat.h> ++#include <shlib-compat.h> + + #define dirent dirent64 + #define __readdir(dirp) __readdir64 (dirp) +@@ -33,44 +34,9 @@ + #undef __stat + #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf) + +-#define NO_GLOB_PATTERN_P 1 +- + #define COMPILE_GLOB64 1 + + #include <posix/glob.c> + +-#include "shlib-compat.h" +- +-libc_hidden_def (globfree64) +- + versioned_symbol (libc, __glob64, glob64, GLIBC_2_2); + libc_hidden_ver (__glob64, glob64) +- +-#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) +- +-#include <sysdeps/unix/sysv/linux/i386/olddirent.h> +- +-int __old_glob64 (const char *__pattern, int __flags, +- int (*__errfunc) (const char *, int), +- glob64_t *__pglob); +- +-#undef dirent +-#define dirent __old_dirent64 +-#undef GL_READDIR +-# define GL_READDIR(pglob, stream) \ +- ((struct __old_dirent64 *) (pglob)->gl_readdir (stream)) +-#undef __readdir +-#define __readdir(dirp) __old_readdir64 (dirp) +-#undef glob +-#define glob(pattern, flags, errfunc, pglob) \ +- __old_glob64 (pattern, flags, errfunc, pglob) +-#define convert_dirent __old_convert_dirent +-#define glob_in_dir __old_glob_in_dir +-#define GLOB_ATTRIBUTE attribute_compat_text_section +- +-#define GLOB_ONLY_P 1 +- +-#include <posix/glob.c> +- +-compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1); +-#endif diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S index 7a1d3373bb..a865de2201 100644 --- a/sysdeps/unix/sysv/linux/i386/vfork.S @@ -13689,6 +16321,13 @@ index 39634c5cf0..7ae65ef723 100644 END(__thread_start) libc_hidden_def (__clone) +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c b/sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c +new file mode 100644 +index 0000000000..abc35fdd2b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c +@@ -0,0 +1 @@ ++/* glob64 is in globfree64.c */ diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/syscalls.list b/sysdeps/unix/sysv/linux/mips/mips64/n64/syscalls.list index 890a74494a..26ab6d0b75 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/syscalls.list @@ -13783,6 +16422,54 @@ index c1bb9c7134..8997269199 100644 bne r7, zero, SYSCALL_ERROR_LABEL ret +diff --git a/sysdeps/unix/sysv/linux/oldglob.c b/sysdeps/unix/sysv/linux/oldglob.c +new file mode 100644 +index 0000000000..8233e57ce9 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/oldglob.c +@@ -0,0 +1,42 @@ ++#include <shlib-compat.h> ++ ++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) ++ ++#include <dirent.h> ++#include <glob.h> ++#include <sys/stat.h> ++ ++#include <sysdeps/unix/sysv/linux/i386/olddirent.h> ++ ++int __old_glob64 (const char *__pattern, int __flags, ++ int (*__errfunc) (const char *, int), ++ glob64_t *__pglob); ++libc_hidden_proto (__old_glob64); ++ ++#define dirent __old_dirent64 ++#define GL_READDIR(pglob, stream) \ ++ ((struct __old_dirent64 *) (pglob)->gl_readdir (stream)) ++#undef __readdir ++#define __readdir(dirp) __old_readdir64 (dirp) ++ ++#define glob_t glob64_t ++#define glob(pattern, flags, errfunc, pglob) \ ++ __old_glob64 (pattern, flags, errfunc, pglob) ++#define globfree(pglob) globfree64(pglob) ++ ++#define convert_dirent __old_convert_dirent ++#define glob_in_dir __old_glob_in_dir ++ ++#undef stat ++#define stat stat64 ++#undef __stat ++#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf) ++ ++#define GLOB_ATTRIBUTE attribute_compat_text_section ++ ++#include <posix/glob.c> ++ ++libc_hidden_def (__old_glob64); ++ ++compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1); ++#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile index c89ed9ec7d..2cfb46eca3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/Makefile @@ -15053,6 +17740,14 @@ index 68a7e6d6e2..1472311947 100644 -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include <support/test-driver.c> +diff --git a/sysdeps/unix/sysv/linux/wordsize-64/globfree64.c b/sysdeps/unix/sysv/linux/wordsize-64/globfree64.c +new file mode 100644 +index 0000000000..af035e1514 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/wordsize-64/globfree64.c +@@ -0,0 +1,2 @@ ++/* This file is here so sysdeps/gnu/glob64.c doesn't take precedence. */ ++#include <sysdeps/wordsize-64/globfree64.c> diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S index 66f4b11490..5629aed395 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -15108,11 +17803,138 @@ index 8332ade9fb..cdd2dea32a 100644 cmpl $-4095, %eax jae SYSCALL_ERROR_LABEL /* Branch forward if it failed. */ +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/globfree.c b/sysdeps/unix/sysv/linux/x86_64/x32/globfree.c +new file mode 100644 +index 0000000000..b76a761c17 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/globfree.c +@@ -0,0 +1 @@ ++#include <sysdeps/wordsize-64/globfree.c> +diff --git a/sysdeps/wordsize-64/glob.c b/sysdeps/wordsize-64/glob.c +index 082faf1c70..954e8d37e2 100644 +--- a/sysdeps/wordsize-64/glob.c ++++ b/sysdeps/wordsize-64/glob.c +@@ -4,5 +4,3 @@ + #undef glob64 + #undef globfree64 + weak_alias (glob, glob64) +-weak_alias (globfree, globfree64) +-libc_hidden_ver (globfree, globfree64) +diff --git a/sysdeps/wordsize-64/globfree.c b/sysdeps/wordsize-64/globfree.c +new file mode 100644 +index 0000000000..ec8c35b489 +--- /dev/null ++++ b/sysdeps/wordsize-64/globfree.c +@@ -0,0 +1,5 @@ ++#define globfree64 __no_globfree64_decl ++#include <posix/globfree.c> ++#undef globfree64 ++weak_alias (globfree, globfree64) ++libc_hidden_ver (globfree, globfree64) +diff --git a/sysdeps/wordsize-64/globfree64.c b/sysdeps/wordsize-64/globfree64.c +new file mode 100644 +index 0000000000..a0f57ff4b3 +--- /dev/null ++++ b/sysdeps/wordsize-64/globfree64.c +@@ -0,0 +1 @@ ++/* globfree64 is in globfree.c */ +diff --git a/sysdeps/x86/cpu-features-offsets.sym b/sysdeps/x86/cpu-features-offsets.sym +index f6739fae81..33dd094e37 100644 +--- a/sysdeps/x86/cpu-features-offsets.sym ++++ b/sysdeps/x86/cpu-features-offsets.sym +@@ -15,6 +15,7 @@ CPUID_ECX_OFFSET offsetof (struct cpuid_registers, ecx) + CPUID_EDX_OFFSET offsetof (struct cpuid_registers, edx) + FAMILY_OFFSET offsetof (struct cpu_features, family) + MODEL_OFFSET offsetof (struct cpu_features, model) ++XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size) + FEATURE_OFFSET offsetof (struct cpu_features, feature) + FEATURE_SIZE sizeof (unsigned int) + diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c -index 9ce4b495a5..508ad2ae7b 100644 +index 9ce4b495a5..9eca98817d 100644 --- a/sysdeps/x86/cpu-features.c +++ b/sysdeps/x86/cpu-features.c -@@ -133,8 +133,6 @@ init_cpu_features (struct cpu_features *cpu_features) +@@ -18,6 +18,7 @@ + + #include <cpuid.h> + #include <cpu-features.h> ++#include <libc-internal.h> + + static void + get_common_indeces (struct cpu_features *cpu_features, +@@ -88,6 +89,71 @@ get_common_indeces (struct cpu_features *cpu_features, + cpu_features->feature[index_arch_FMA_Usable] + |= bit_arch_FMA_Usable; + } ++ ++ /* For _dl_runtime_resolve, set xsave_state_size to xsave area ++ size + integer register save size and align it to 64 bytes. */ ++ if (cpu_features->max_cpuid >= 0xd) ++ { ++ unsigned int eax, ebx, ecx, edx; ++ ++ __cpuid_count (0xd, 0, eax, ebx, ecx, edx); ++ if (ebx != 0) ++ { ++ cpu_features->xsave_state_size ++ = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64); ++ ++ __cpuid_count (0xd, 1, eax, ebx, ecx, edx); ++ ++ /* Check if XSAVEC is available. */ ++ if ((eax & (1 << 1)) != 0) ++ { ++ unsigned int xstate_comp_offsets[32]; ++ unsigned int xstate_comp_sizes[32]; ++ unsigned int i; ++ ++ xstate_comp_offsets[0] = 0; ++ xstate_comp_offsets[1] = 160; ++ xstate_comp_offsets[2] = 576; ++ xstate_comp_sizes[0] = 160; ++ xstate_comp_sizes[1] = 256; ++ ++ for (i = 2; i < 32; i++) ++ { ++ if ((STATE_SAVE_MASK & (1 << i)) != 0) ++ { ++ __cpuid_count (0xd, i, eax, ebx, ecx, edx); ++ xstate_comp_sizes[i] = eax; ++ } ++ else ++ { ++ ecx = 0; ++ xstate_comp_sizes[i] = 0; ++ } ++ ++ if (i > 2) ++ { ++ xstate_comp_offsets[i] ++ = (xstate_comp_offsets[i - 1] ++ + xstate_comp_sizes[i -1]); ++ if ((ecx & (1 << 1)) != 0) ++ xstate_comp_offsets[i] ++ = ALIGN_UP (xstate_comp_offsets[i], 64); ++ } ++ } ++ ++ /* Use XSAVEC. */ ++ unsigned int size ++ = xstate_comp_offsets[31] + xstate_comp_sizes[31]; ++ if (size) ++ { ++ cpu_features->xsave_state_size ++ = ALIGN_UP (size + STATE_SAVE_OFFSET, 64); ++ cpu_features->feature[index_arch_XSAVEC_Usable] ++ |= bit_arch_XSAVEC_Usable; ++ } ++ } ++ } ++ } + } + } + +@@ -133,8 +199,6 @@ init_cpu_features (struct cpu_features *cpu_features) case 0x57: /* Knights Landing. Enable Silvermont optimizations. */ @@ -15121,7 +17943,7 @@ index 9ce4b495a5..508ad2ae7b 100644 case 0x5c: case 0x5f: -@@ -205,6 +203,33 @@ init_cpu_features (struct cpu_features *cpu_features) +@@ -205,6 +269,16 @@ init_cpu_features (struct cpu_features *cpu_features) if (CPU_FEATURES_ARCH_P (cpu_features, AVX2_Usable)) cpu_features->feature[index_arch_AVX_Fast_Unaligned_Load] |= bit_arch_AVX_Fast_Unaligned_Load; @@ -15135,41 +17957,23 @@ index 9ce4b495a5..508ad2ae7b 100644 + else + cpu_features->feature[index_arch_Prefer_No_AVX512] + |= bit_arch_Prefer_No_AVX512; -+ -+ /* To avoid SSE transition penalty, use _dl_runtime_resolve_slow. -+ If XGETBV suports ECX == 1, use _dl_runtime_resolve_opt. -+ Use _dl_runtime_resolve_opt only with AVX512F since it is -+ slower than _dl_runtime_resolve_slow with AVX. */ -+ cpu_features->feature[index_arch_Use_dl_runtime_resolve_slow] -+ |= bit_arch_Use_dl_runtime_resolve_slow; -+ if (CPU_FEATURES_ARCH_P (cpu_features, AVX512F_Usable) -+ && cpu_features->max_cpuid >= 0xd) -+ { -+ unsigned int eax; -+ -+ __cpuid_count (0xd, 1, eax, ebx, ecx, edx); -+ if ((eax & (1 << 2)) != 0) -+ cpu_features->feature[index_arch_Use_dl_runtime_resolve_opt] -+ |= bit_arch_Use_dl_runtime_resolve_opt; -+ } } /* This spells out "AuthenticAMD". */ else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h -index 97ffe765f4..2609ac0999 100644 +index 97ffe765f4..507a141414 100644 --- a/sysdeps/x86/cpu-features.h +++ b/sysdeps/x86/cpu-features.h -@@ -37,6 +37,9 @@ +@@ -37,6 +37,8 @@ #define bit_arch_Prefer_No_VZEROUPPER (1 << 17) #define bit_arch_Fast_Unaligned_Copy (1 << 18) #define bit_arch_Prefer_ERMS (1 << 19) -+#define bit_arch_Use_dl_runtime_resolve_opt (1 << 20) -+#define bit_arch_Use_dl_runtime_resolve_slow (1 << 21) -+#define bit_arch_Prefer_No_AVX512 (1 << 22) ++#define bit_arch_Prefer_No_AVX512 (1 << 20) ++#define bit_arch_XSAVEC_Usable (1 << 21) /* CPUID Feature flags. */ -@@ -60,6 +63,11 @@ +@@ -60,6 +62,11 @@ #define bit_cpu_AVX2 (1 << 5) #define bit_cpu_AVX512F (1 << 16) #define bit_cpu_AVX512DQ (1 << 17) @@ -15181,7 +17985,23 @@ index 97ffe765f4..2609ac0999 100644 /* XCR0 Feature flags. */ #define bit_XMM_state (1 << 1) -@@ -107,6 +115,9 @@ +@@ -74,6 +81,15 @@ + /* The current maximum size of the feature integer bit array. */ + #define FEATURE_INDEX_MAX 1 + ++/* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need ++ space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be ++ aligned to 16 bytes for fxsave and 64 bytes for xsave. */ ++#define STATE_SAVE_OFFSET (8 * 7 + 8) ++ ++/* Save SSE, AVX, AVX512, mask and bound registers. */ ++#define STATE_SAVE_MASK \ ++ ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7)) ++ + #ifdef __ASSEMBLER__ + + # include <cpu-features-offsets.h> +@@ -107,6 +123,9 @@ # define index_arch_Prefer_No_VZEROUPPER FEATURE_INDEX_1*FEATURE_SIZE # define index_arch_Fast_Unaligned_Copy FEATURE_INDEX_1*FEATURE_SIZE # define index_arch_Prefer_ERMS FEATURE_INDEX_1*FEATURE_SIZE @@ -15191,7 +18011,20 @@ index 97ffe765f4..2609ac0999 100644 # if defined (_LIBC) && !IS_IN (nonlib) -@@ -232,6 +243,11 @@ extern const struct cpu_features *__get_cpu_features (void) +@@ -195,6 +214,12 @@ struct cpu_features + } cpuid[COMMON_CPUID_INDEX_MAX]; + unsigned int family; + unsigned int model; ++ /* The type must be unsigned long int so that we use ++ ++ sub xsave_state_size_offset(%rip) %RSP_LP ++ ++ in _dl_runtime_resolve. */ ++ unsigned long int xsave_state_size; + unsigned int feature[FEATURE_INDEX_MAX]; + }; + +@@ -232,6 +257,11 @@ extern const struct cpu_features *__get_cpu_features (void) # define index_cpu_AVX2 COMMON_CPUID_INDEX_7 # define index_cpu_AVX512F COMMON_CPUID_INDEX_7 # define index_cpu_AVX512DQ COMMON_CPUID_INDEX_7 @@ -15203,7 +18036,7 @@ index 97ffe765f4..2609ac0999 100644 # define index_cpu_ERMS COMMON_CPUID_INDEX_7 # define index_cpu_RTM COMMON_CPUID_INDEX_7 # define index_cpu_FMA COMMON_CPUID_INDEX_1 -@@ -250,6 +266,11 @@ extern const struct cpu_features *__get_cpu_features (void) +@@ -250,6 +280,11 @@ extern const struct cpu_features *__get_cpu_features (void) # define reg_AVX2 ebx # define reg_AVX512F ebx # define reg_AVX512DQ ebx @@ -15215,13 +18048,12 @@ index 97ffe765f4..2609ac0999 100644 # define reg_ERMS ebx # define reg_RTM ebx # define reg_FMA ecx -@@ -277,6 +298,9 @@ extern const struct cpu_features *__get_cpu_features (void) +@@ -277,6 +312,8 @@ extern const struct cpu_features *__get_cpu_features (void) # define index_arch_Prefer_No_VZEROUPPER FEATURE_INDEX_1 # define index_arch_Fast_Unaligned_Copy FEATURE_INDEX_1 # define index_arch_Prefer_ERMS FEATURE_INDEX_1 -+# define index_arch_Use_dl_runtime_resolve_opt FEATURE_INDEX_1 -+# define index_arch_Use_dl_runtime_resolve_slow FEATURE_INDEX_1 +# define index_arch_Prefer_No_AVX512 FEATURE_INDEX_1 ++# define index_arch_XSAVEC_Usable FEATURE_INDEX_1 #endif /* !__ASSEMBLER__ */ @@ -15296,49 +18128,42 @@ index 6d99284cd0..cc990a9685 100644 +gen-as-const-headers += tlsdesc.sym rtld-offsets.sym endif diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h -index ed0c1a8efd..c0f0fa16a2 100644 +index ed0c1a8efd..8355432dfc 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h -@@ -68,7 +68,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +@@ -66,9 +66,9 @@ static inline int __attribute__ ((unused, always_inline)) + elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + { Elf64_Addr *got; - extern void _dl_runtime_resolve_sse (ElfW(Word)) attribute_hidden; - extern void _dl_runtime_resolve_avx (ElfW(Word)) attribute_hidden; -+ extern void _dl_runtime_resolve_avx_slow (ElfW(Word)) attribute_hidden; -+ extern void _dl_runtime_resolve_avx_opt (ElfW(Word)) attribute_hidden; - extern void _dl_runtime_resolve_avx512 (ElfW(Word)) attribute_hidden; -+ extern void _dl_runtime_resolve_avx512_opt (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_sse (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_avx (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_avx512 (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_xsave (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_xsavec (ElfW(Word)) attribute_hidden; extern void _dl_runtime_profile_sse (ElfW(Word)) attribute_hidden; extern void _dl_runtime_profile_avx (ElfW(Word)) attribute_hidden; extern void _dl_runtime_profile_avx512 (ElfW(Word)) attribute_hidden; -@@ -118,9 +121,26 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +@@ -117,12 +117,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + /* This function will get called to fix up the GOT entry indicated by the offset on the stack, and then jump to the resolved address. */ - if (HAS_ARCH_FEATURE (AVX512F_Usable)) +- if (HAS_ARCH_FEATURE (AVX512F_Usable)) - *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve_avx512; -+ { -+ if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt)) -+ *(ElfW(Addr) *) (got + 2) -+ = (ElfW(Addr)) &_dl_runtime_resolve_avx512_opt; -+ else -+ *(ElfW(Addr) *) (got + 2) -+ = (ElfW(Addr)) &_dl_runtime_resolve_avx512; -+ } - else if (HAS_ARCH_FEATURE (AVX_Usable)) +- else if (HAS_ARCH_FEATURE (AVX_Usable)) - *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve_avx; -+ { -+ if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt)) -+ *(ElfW(Addr) *) (got + 2) -+ = (ElfW(Addr)) &_dl_runtime_resolve_avx_opt; -+ else if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_slow)) -+ *(ElfW(Addr) *) (got + 2) -+ = (ElfW(Addr)) &_dl_runtime_resolve_avx_slow; -+ else -+ *(ElfW(Addr) *) (got + 2) -+ = (ElfW(Addr)) &_dl_runtime_resolve_avx; -+ } ++ if (GLRO(dl_x86_cpu_features).xsave_state_size != 0) ++ *(ElfW(Addr) *) (got + 2) ++ = (HAS_ARCH_FEATURE (XSAVEC_Usable) ++ ? (ElfW(Addr)) &_dl_runtime_resolve_xsavec ++ : (ElfW(Addr)) &_dl_runtime_resolve_xsave); else - *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve_sse; +- *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve_sse; ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) &_dl_runtime_resolve_fxsave; } + } + diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c new file mode 100644 index 0000000000..3584805c8e @@ -15419,7 +18244,7 @@ index cf6c107f54..fa5bf6cd93 100644 + +#endif /* _X86_64_DL_TLS_H */ diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S -index 12f1a5cf84..50b23633e3 100644 +index 12f1a5cf84..b4cda0f535 100644 --- a/sysdeps/x86_64/dl-trampoline.S +++ b/sysdeps/x86_64/dl-trampoline.S @@ -18,6 +18,7 @@ @@ -15430,167 +18255,364 @@ index 12f1a5cf84..50b23633e3 100644 #include <link-defines.h> #ifndef DL_STACK_ALIGNMENT -@@ -104,9 +105,11 @@ +@@ -33,41 +34,24 @@ + # define DL_STACK_ALIGNMENT 8 + #endif + +-#ifndef DL_RUNTIME_UNALIGNED_VEC_SIZE +-/* The maximum size in bytes of unaligned vector load and store in the +- dynamic linker. Since SSE optimized memory/string functions with +- aligned SSE register load and store are used in the dynamic linker, +- we must set this to 8 so that _dl_runtime_resolve_sse will align the +- stack before calling _dl_fixup. */ +-# define DL_RUNTIME_UNALIGNED_VEC_SIZE 8 +-#endif +- +-/* True if _dl_runtime_resolve should align stack to VEC_SIZE bytes. */ ++/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align ++ stack to 16 bytes before calling _dl_fixup. */ + #define DL_RUNTIME_RESOLVE_REALIGN_STACK \ +- (VEC_SIZE > DL_STACK_ALIGNMENT \ +- && VEC_SIZE > DL_RUNTIME_UNALIGNED_VEC_SIZE) +- +-/* Align vector register save area to 16 bytes. */ +-#define REGISTER_SAVE_VEC_OFF 0 ++ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ ++ || 16 > DL_STACK_ALIGNMENT) + + /* Area on stack to save and restore registers used for parameter + passing when calling _dl_fixup. */ + #ifdef __ILP32__ +-# define REGISTER_SAVE_RAX (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8) + # define PRESERVE_BND_REGS_PREFIX + #else +-/* Align bound register save area to 16 bytes. */ +-# define REGISTER_SAVE_BND0 (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8) +-# define REGISTER_SAVE_BND1 (REGISTER_SAVE_BND0 + 16) +-# define REGISTER_SAVE_BND2 (REGISTER_SAVE_BND1 + 16) +-# define REGISTER_SAVE_BND3 (REGISTER_SAVE_BND2 + 16) +-# define REGISTER_SAVE_RAX (REGISTER_SAVE_BND3 + 16) + # ifdef HAVE_MPX_SUPPORT + # define PRESERVE_BND_REGS_PREFIX bnd + # else + # define PRESERVE_BND_REGS_PREFIX .byte 0xf2 + # endif #endif ++#define REGISTER_SAVE_RAX 0 + #define REGISTER_SAVE_RCX (REGISTER_SAVE_RAX + 8) + #define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8) + #define REGISTER_SAVE_RSI (REGISTER_SAVE_RDX + 8) +@@ -79,50 +63,56 @@ + + #define VEC_SIZE 64 + #define VMOVA vmovdqa64 +-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT +-# define VMOV vmovdqa64 +-#else +-# define VMOV vmovdqu64 +-#endif + #define VEC(i) zmm##i +-#define _dl_runtime_resolve _dl_runtime_resolve_avx512 + #define _dl_runtime_profile _dl_runtime_profile_avx512 + #include "dl-trampoline.h" +-#undef _dl_runtime_resolve + #undef _dl_runtime_profile + #undef VEC +-#undef VMOV + #undef VMOVA + #undef VEC_SIZE + + #define VEC_SIZE 32 + #define VMOVA vmovdqa +-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT +-# define VMOV vmovdqa +-#else +-# define VMOV vmovdqu +-#endif #define VEC(i) ymm##i - #define _dl_runtime_resolve _dl_runtime_resolve_avx -+#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx_opt +-#define _dl_runtime_resolve _dl_runtime_resolve_avx #define _dl_runtime_profile _dl_runtime_profile_avx #include "dl-trampoline.h" - #undef _dl_runtime_resolve -+#undef _dl_runtime_resolve_opt +-#undef _dl_runtime_resolve #undef _dl_runtime_profile #undef VEC - #undef VMOV -@@ -126,3 +129,19 @@ +-#undef VMOV + #undef VMOVA + #undef VEC_SIZE + + /* movaps/movups is 1-byte shorter. */ + #define VEC_SIZE 16 + #define VMOVA movaps +-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT +-# define VMOV movaps +-#else +-# define VMOV movups +-#endif + #define VEC(i) xmm##i +-#define _dl_runtime_resolve _dl_runtime_resolve_sse #define _dl_runtime_profile _dl_runtime_profile_sse #undef RESTORE_AVX #include "dl-trampoline.h" -+#undef _dl_runtime_resolve +#undef _dl_runtime_profile -+#undef VMOV ++#undef VEC +#undef VMOVA ++#undef VEC_SIZE + -+/* Used by _dl_runtime_resolve_avx_opt/_dl_runtime_resolve_avx512_opt -+ to preserve the full vector registers with zero upper bits. */ -+#define VMOVA vmovdqa -+#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT -+# define VMOV vmovdqa -+#else -+# define VMOV vmovdqu -+#endif -+#define _dl_runtime_resolve _dl_runtime_resolve_sse_vex -+#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx512_opt ++#define USE_FXSAVE ++#define STATE_SAVE_ALIGNMENT 16 ++#define _dl_runtime_resolve _dl_runtime_resolve_fxsave ++#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef USE_FXSAVE ++#undef STATE_SAVE_ALIGNMENT ++ ++#define USE_XSAVE ++#define STATE_SAVE_ALIGNMENT 64 ++#define _dl_runtime_resolve _dl_runtime_resolve_xsave ++#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef USE_XSAVE ++#undef STATE_SAVE_ALIGNMENT ++ ++#define USE_XSAVEC ++#define STATE_SAVE_ALIGNMENT 64 ++#define _dl_runtime_resolve _dl_runtime_resolve_xsavec +#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef USE_XSAVEC ++#undef STATE_SAVE_ALIGNMENT diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h -index b90836ab13..d21c5a987a 100644 +index b90836ab13..b9c2f1796f 100644 --- a/sysdeps/x86_64/dl-trampoline.h +++ b/sysdeps/x86_64/dl-trampoline.h -@@ -50,6 +50,106 @@ - #endif +@@ -16,40 +16,47 @@ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ - .text -+#ifdef _dl_runtime_resolve_opt -+/* Use the smallest vector registers to preserve the full YMM/ZMM -+ registers to avoid SSE transition penalty. */ -+ -+# if VEC_SIZE == 32 -+/* Check if the upper 128 bits in %ymm0 - %ymm7 registers are non-zero -+ and preserve %xmm0 - %xmm7 registers with the zero upper bits. Since -+ there is no SSE transition penalty on AVX512 processors which don't -+ support XGETBV with ECX == 1, _dl_runtime_resolve_avx512_slow isn't -+ provided. */ -+ .globl _dl_runtime_resolve_avx_slow -+ .hidden _dl_runtime_resolve_avx_slow -+ .type _dl_runtime_resolve_avx_slow, @function -+ .align 16 -+_dl_runtime_resolve_avx_slow: -+ cfi_startproc -+ cfi_adjust_cfa_offset(16) # Incorporate PLT -+ vorpd %ymm0, %ymm1, %ymm8 -+ vorpd %ymm2, %ymm3, %ymm9 -+ vorpd %ymm4, %ymm5, %ymm10 -+ vorpd %ymm6, %ymm7, %ymm11 -+ vorpd %ymm8, %ymm9, %ymm9 -+ vorpd %ymm10, %ymm11, %ymm10 -+ vpcmpeqd %xmm8, %xmm8, %xmm8 -+ vorpd %ymm9, %ymm10, %ymm10 -+ vptest %ymm10, %ymm8 -+ # Preserve %ymm0 - %ymm7 registers if the upper 128 bits of any -+ # %ymm0 - %ymm7 registers aren't zero. -+ PRESERVE_BND_REGS_PREFIX -+ jnc _dl_runtime_resolve_avx -+ # Use vzeroupper to avoid SSE transition penalty. -+ vzeroupper -+ # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits -+ # when the upper 128 bits of %ymm0 - %ymm7 registers are zero. -+ PRESERVE_BND_REGS_PREFIX -+ jmp _dl_runtime_resolve_sse_vex -+ cfi_adjust_cfa_offset(-16) # Restore PLT adjustment -+ cfi_endproc -+ .size _dl_runtime_resolve_avx_slow, .-_dl_runtime_resolve_avx_slow +-#undef REGISTER_SAVE_AREA_RAW +-#ifdef __ILP32__ +-/* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as VEC0 to +- VEC7. */ +-# define REGISTER_SAVE_AREA_RAW (8 * 7 + VEC_SIZE * 8) +-#else +-/* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as +- BND0, BND1, BND2, BND3 and VEC0 to VEC7. */ +-# define REGISTER_SAVE_AREA_RAW (8 * 7 + 16 * 4 + VEC_SIZE * 8) +-#endif ++ .text ++#ifdef _dl_runtime_resolve + +-#undef REGISTER_SAVE_AREA +-#undef LOCAL_STORAGE_AREA +-#undef BASE +-#if DL_RUNTIME_RESOLVE_REALIGN_STACK +-# define REGISTER_SAVE_AREA (REGISTER_SAVE_AREA_RAW + 8) +-/* Local stack area before jumping to function address: RBX. */ +-# define LOCAL_STORAGE_AREA 8 +-# define BASE rbx +-# if (REGISTER_SAVE_AREA % VEC_SIZE) != 0 +-# error REGISTER_SAVE_AREA must be multples of VEC_SIZE ++# undef REGISTER_SAVE_AREA ++# undef LOCAL_STORAGE_AREA ++# undef BASE ++ ++# if (STATE_SAVE_ALIGNMENT % 16) != 0 ++# error STATE_SAVE_ALIGNMENT must be multples of 16 + # endif +-#else +-# define REGISTER_SAVE_AREA REGISTER_SAVE_AREA_RAW ++ ++# if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0 ++# error STATE_SAVE_OFFSET must be multples of STATE_SAVE_ALIGNMENT +# endif + -+/* Use XGETBV with ECX == 1 to check which bits in vector registers are -+ non-zero and only preserve the non-zero lower bits with zero upper -+ bits. */ -+ .globl _dl_runtime_resolve_opt -+ .hidden _dl_runtime_resolve_opt -+ .type _dl_runtime_resolve_opt, @function -+ .align 16 -+_dl_runtime_resolve_opt: -+ cfi_startproc -+ cfi_adjust_cfa_offset(16) # Incorporate PLT -+ pushq %rax -+ cfi_adjust_cfa_offset(8) -+ cfi_rel_offset(%rax, 0) -+ pushq %rcx -+ cfi_adjust_cfa_offset(8) -+ cfi_rel_offset(%rcx, 0) -+ pushq %rdx -+ cfi_adjust_cfa_offset(8) -+ cfi_rel_offset(%rdx, 0) -+ movl $1, %ecx -+ xgetbv -+ movl %eax, %r11d -+ popq %rdx -+ cfi_adjust_cfa_offset(-8) -+ cfi_restore (%rdx) -+ popq %rcx -+ cfi_adjust_cfa_offset(-8) -+ cfi_restore (%rcx) -+ popq %rax -+ cfi_adjust_cfa_offset(-8) -+ cfi_restore (%rax) -+# if VEC_SIZE == 32 -+ # For YMM registers, check if YMM state is in use. -+ andl $bit_YMM_state, %r11d -+ # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits if -+ # YMM state isn't in use. -+ PRESERVE_BND_REGS_PREFIX -+ jz _dl_runtime_resolve_sse_vex -+# elif VEC_SIZE == 16 -+ # For ZMM registers, check if YMM state and ZMM state are in -+ # use. -+ andl $(bit_YMM_state | bit_ZMM0_15_state), %r11d -+ cmpl $bit_YMM_state, %r11d -+ # Preserve %zmm0 - %zmm7 registers if ZMM state is in use. -+ PRESERVE_BND_REGS_PREFIX -+ jg _dl_runtime_resolve_avx512 -+ # Preserve %ymm0 - %ymm7 registers with the zero upper 256 bits if -+ # ZMM state isn't in use. -+ PRESERVE_BND_REGS_PREFIX -+ je _dl_runtime_resolve_avx -+ # Preserve %xmm0 - %xmm7 registers with the zero upper 384 bits if -+ # neither YMM state nor ZMM state are in use. ++# if DL_RUNTIME_RESOLVE_REALIGN_STACK ++/* Local stack area before jumping to function address: RBX. */ ++# define LOCAL_STORAGE_AREA 8 ++# define BASE rbx ++# ifdef USE_FXSAVE ++/* Use fxsave to save XMM registers. */ ++# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET) ++# if (REGISTER_SAVE_AREA % 16) != 0 ++# error REGISTER_SAVE_AREA must be multples of 16 ++# endif ++# endif +# else -+# error Unsupported VEC_SIZE! -+# endif -+ cfi_adjust_cfa_offset(-16) # Restore PLT adjustment -+ cfi_endproc -+ .size _dl_runtime_resolve_opt, .-_dl_runtime_resolve_opt -+#endif ++# ifndef USE_FXSAVE ++# error USE_FXSAVE must be defined ++# endif ++/* Use fxsave to save XMM registers. */ ++# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8) + /* Local stack area before jumping to function address: All saved + registers. */ +-# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA +-# define BASE rsp +-# if (REGISTER_SAVE_AREA % 16) != 8 +-# error REGISTER_SAVE_AREA must be odd multples of 8 ++# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA ++# define BASE rsp ++# if (REGISTER_SAVE_AREA % 16) != 8 ++# error REGISTER_SAVE_AREA must be odd multples of 8 ++# endif + # endif +-#endif + +- .text .globl _dl_runtime_resolve .hidden _dl_runtime_resolve .type _dl_runtime_resolve, @function -@@ -69,7 +169,9 @@ _dl_runtime_resolve: - and $-VEC_SIZE, %RSP_LP - #endif +@@ -57,19 +64,30 @@ + cfi_startproc + _dl_runtime_resolve: + cfi_adjust_cfa_offset(16) # Incorporate PLT +-#if DL_RUNTIME_RESOLVE_REALIGN_STACK +-# if LOCAL_STORAGE_AREA != 8 +-# error LOCAL_STORAGE_AREA must be 8 +-# endif ++# if DL_RUNTIME_RESOLVE_REALIGN_STACK ++# if LOCAL_STORAGE_AREA != 8 ++# error LOCAL_STORAGE_AREA must be 8 ++# endif + pushq %rbx # push subtracts stack by 8. + cfi_adjust_cfa_offset(8) + cfi_rel_offset(%rbx, 0) + mov %RSP_LP, %RBX_LP + cfi_def_cfa_register(%rbx) +- and $-VEC_SIZE, %RSP_LP +-#endif ++ and $-STATE_SAVE_ALIGNMENT, %RSP_LP ++# endif ++# ifdef REGISTER_SAVE_AREA sub $REGISTER_SAVE_AREA, %RSP_LP -+#if !DL_RUNTIME_RESOLVE_REALIGN_STACK ++# if !DL_RUNTIME_RESOLVE_REALIGN_STACK cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) -+#endif ++# endif ++# else ++ # Allocate stack space of the required size to save the state. ++# if IS_IN (rtld) ++ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP ++# else ++ sub _dl_x86_cpu_features+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP ++# endif ++# endif # Preserve registers otherwise clobbered. movq %rax, REGISTER_SAVE_RAX(%rsp) movq %rcx, REGISTER_SAVE_RCX(%rsp) -@@ -162,7 +264,10 @@ _dl_runtime_resolve: +@@ -78,59 +96,42 @@ _dl_runtime_resolve: + movq %rdi, REGISTER_SAVE_RDI(%rsp) + movq %r8, REGISTER_SAVE_R8(%rsp) + movq %r9, REGISTER_SAVE_R9(%rsp) +- VMOV %VEC(0), (REGISTER_SAVE_VEC_OFF)(%rsp) +- VMOV %VEC(1), (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp) +- VMOV %VEC(2), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp) +- VMOV %VEC(3), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp) +- VMOV %VEC(4), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp) +- VMOV %VEC(5), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp) +- VMOV %VEC(6), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp) +- VMOV %VEC(7), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp) +-#ifndef __ILP32__ +- # We also have to preserve bound registers. These are nops if +- # Intel MPX isn't available or disabled. +-# ifdef HAVE_MPX_SUPPORT +- bndmov %bnd0, REGISTER_SAVE_BND0(%rsp) +- bndmov %bnd1, REGISTER_SAVE_BND1(%rsp) +- bndmov %bnd2, REGISTER_SAVE_BND2(%rsp) +- bndmov %bnd3, REGISTER_SAVE_BND3(%rsp) ++# ifdef USE_FXSAVE ++ fxsave STATE_SAVE_OFFSET(%rsp) + # else +-# if REGISTER_SAVE_BND0 == 0 +- .byte 0x66,0x0f,0x1b,0x04,0x24 ++ movl $STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ # Clear the XSAVE Header. ++# ifdef USE_XSAVE ++ movq %rdx, (STATE_SAVE_OFFSET + 512)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8)(%rsp) ++# endif ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 2)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 3)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 4)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 5)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 6)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 7)(%rsp) ++# ifdef USE_XSAVE ++ xsave STATE_SAVE_OFFSET(%rsp) + # else +- .byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0 ++ xsavec STATE_SAVE_OFFSET(%rsp) + # endif +- .byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1 +- .byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2 +- .byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3 + # endif +-#endif + # Copy args pushed by PLT in register. + # %rdi: link_map, %rsi: reloc_index + mov (LOCAL_STORAGE_AREA + 8)(%BASE), %RSI_LP + mov LOCAL_STORAGE_AREA(%BASE), %RDI_LP + call _dl_fixup # Call resolver. + mov %RAX_LP, %R11_LP # Save return value +-#ifndef __ILP32__ +- # Restore bound registers. These are nops if Intel MPX isn't +- # avaiable or disabled. +-# ifdef HAVE_MPX_SUPPORT +- bndmov REGISTER_SAVE_BND3(%rsp), %bnd3 +- bndmov REGISTER_SAVE_BND2(%rsp), %bnd2 +- bndmov REGISTER_SAVE_BND1(%rsp), %bnd1 +- bndmov REGISTER_SAVE_BND0(%rsp), %bnd0 ++ # Get register content back. ++# ifdef USE_FXSAVE ++ fxrstor STATE_SAVE_OFFSET(%rsp) + # else +- .byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3 +- .byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2 +- .byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1 +-# if REGISTER_SAVE_BND0 == 0 +- .byte 0x66,0x0f,0x1a,0x04,0x24 +-# else +- .byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0 +-# endif ++ movl $STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ xrstor STATE_SAVE_OFFSET(%rsp) + # endif +-#endif +- # Get register content back. + movq REGISTER_SAVE_R9(%rsp), %r9 + movq REGISTER_SAVE_R8(%rsp), %r8 + movq REGISTER_SAVE_RDI(%rsp), %rdi +@@ -138,20 +139,12 @@ _dl_runtime_resolve: + movq REGISTER_SAVE_RDX(%rsp), %rdx + movq REGISTER_SAVE_RCX(%rsp), %rcx + movq REGISTER_SAVE_RAX(%rsp), %rax +- VMOV (REGISTER_SAVE_VEC_OFF)(%rsp), %VEC(0) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp), %VEC(1) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp), %VEC(2) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp), %VEC(3) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp), %VEC(4) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp), %VEC(5) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp), %VEC(6) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp), %VEC(7) +-#if DL_RUNTIME_RESOLVE_REALIGN_STACK ++# if DL_RUNTIME_RESOLVE_REALIGN_STACK + mov %RBX_LP, %RSP_LP + cfi_def_cfa_register(%rsp) + movq (%rsp), %rbx + cfi_restore(%rbx) +-#endif ++# endif + # Adjust stack(PLT did 2 pushes) + add $(LOCAL_STORAGE_AREA + 16), %RSP_LP + cfi_adjust_cfa_offset(-(LOCAL_STORAGE_AREA + 16)) +@@ -160,9 +153,10 @@ _dl_runtime_resolve: + jmp *%r11 # Jump to function address. + cfi_endproc .size _dl_runtime_resolve, .-_dl_runtime_resolve ++#endif -#ifndef PROF -+/* To preserve %xmm0 - %xmm7 registers, dl-trampoline.h is included -+ twice, for _dl_runtime_resolve_sse and _dl_runtime_resolve_sse_vex. -+ But we don't need another _dl_runtime_profile for XMM registers. */ +#if !defined PROF && defined _dl_runtime_profile # if (LR_VECTOR_OFFSET % VEC_SIZE) != 0 # error LR_VECTOR_OFFSET must be multples of VEC_SIZE
participants (1)
-
crux@crux.nu