Compare commits

...
Author SHA1 Message Date
Tulio Magno Quites Machado Filho 6869471f35 Merge branch release/2.26/master into ibm/2.26/master 2020-03-20 18:24:51 -03:00
Andreas Schwab 263e617599 Fix use-after-free in glob when expanding ~user (bug 25414)
The value of `end_name' points into the value of `dirname', thus don't
deallocate the latter before the last use of the former.

(cherry picked from commit ddc650e9b3 with
 changes from commit d711a00f93)
2020-03-20 17:49:04 -03:00
Andreas Schwab 37db4539dd Fix array overflow in backtrace on PowerPC (bug 25423)
When unwinding through a signal frame the backtrace function on PowerPC
didn't check array bounds when storing the frame address.  Fixes commit
d400dcac5e ("PowerPC: fix backtrace to handle signal trampolines").

(cherry picked from commit d937694059)
2020-03-20 15:32:44 -03:00
Matheus Castanho fe5012e474 Merge branch release/2.26/master into ibm/2.26/master 2020-03-03 17:34:21 -03:00
Florian Weimer 2dc2d678e9 libio: Disable vtable validation for pre-2.1 interposed handles [BZ #25203]
Commit c402355dfa ("libio: Disable
vtable validation in case of interposition [BZ #23313]") only covered
the interposable glibc 2.1 handles, in libio/stdfiles.c.  The
parallel code in libio/oldstdfiles.c needs similar detection logic.

Fixes (again) commit db3476aff1
("libio: Implement vtable verification [BZ #20191]").

Change-Id: Ief6f9f17e91d1f7263421c56a7dc018f4f595c21
(cherry picked from commit cb61630ed7)
2019-11-28 14:44:48 +01:00
Marcin Kościelnicki bc42e3bd44 rtld: Check __libc_enable_secure before honoring LD_PREFER_MAP_32BIT_EXEC (CVE-2019-19126) [BZ #25204]
The problem was introduced in glibc 2.23, in commit
b9eb92ab05
("Add Prefer_MAP_32BIT_EXEC to map executable pages with MAP_32BIT").

(cherry picked from commit d5dfad4326)
2019-11-22 13:49:18 +01:00
Dragan Mladjenovic aaf2f25b61 mips: Force RWX stack for hard-float builds that can run on pre-4.8 kernels
Linux/Mips kernels prior to 4.8 could potentially crash the user
process when doing FPU emulation while running on non-executable
user stack.

Currently, gcc doesn't emit .note.GNU-stack for mips, but that will
change in the future. To ensure that glibc can be used with such
future gcc, without silently resulting in binaries that might crash
in runtime, this patch forces RWX stack for all built objects if
configured to run against minimum kernel version less than 4.8.

	* sysdeps/unix/sysv/linux/mips/Makefile
	(test-xfail-check-execstack):
	Move under mips-has-gnustack != yes.
	(CFLAGS-.o*, ASFLAGS-.o*): New rules.
	Apply -Wa,-execstack if mips-force-execstack == yes.
	* sysdeps/unix/sysv/linux/mips/configure: Regenerated.
	* sysdeps/unix/sysv/linux/mips/configure.ac
	(mips-force-execstack): New var.
	Set to yes for hard-float builds with minimum_kernel < 4.8.0
	or minimum_kernel not set at all.
	(mips-has-gnustack): New var.
	Use value of libc_cv_as_noexecstack
	if mips-force-execstack != yes, otherwise set to no.

(cherry picked from commit 33bc9efd91)
2019-11-05 13:56:52 -03:00
Wilco Dijkstra 612fba2fe9 Improve performance of memmem
This patch significantly improves performance of memmem using a novel
modified Horspool algorithm.  Needles up to size 256 use a bad-character
table indexed by hashed pairs of characters to quickly skip past mismatches.
Long needles use a self-adapting filtering step to avoid comparing the whole
needle repeatedly.

By limiting the needle length to 256, the shift table only requires 8 bits
per entry, lowering preprocessing overhead and minimizing cache effects.
This limit also implies worst-case performance is linear.

Small needles up to size 2 use a dedicated linear search.  Very long needles
use the Two-Way algorithm (to avoid increasing stack size or slowing down
the common case, inlining is disabled).

The performance gain is 6.6 times on English text on AArch64 using random
needles with average size 8.

Tested against GLIBC testsuite and randomized tests.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>

	* string/memmem.c (__memmem): Rewrite to improve performance.

(cherry picked from commit 680942b016)
2019-09-13 16:41:34 +01:00
Wilco Dijkstra 796c5ee030 Improve performance of strstr
This patch significantly improves performance of strstr using a novel
modified Horspool algorithm.  Needles up to size 256 use a bad-character
table indexed by hashed pairs of characters to quickly skip past mismatches.
Long needles use a self-adapting filtering step to avoid comparing the whole
needle repeatedly.

By limiting the needle length to 256, the shift table only requires 8 bits
per entry, lowering preprocessing overhead and minimizing cache effects.
This limit also implies worst-case performance is linear.

Small needles up to size 3 use a dedicated linear search.  Very long needles
use the Two-Way algorithm.

The performance gain using the improved bench-strstr on Cortex-A72 is 5.8
times basic_strstr and 3.7 times twoway_strstr.

Tested against GLIBC testsuite, randomized tests and the GNULIB strstr test
(https://git.savannah.gnu.org/cgit/gnulib.git/tree/tests/test-strstr.c).

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>

	* string/str-two-way.h (two_way_short_needle): Add inline to avoid
	warning.
	(two_way_long_needle): Block inlining.
	* string/strstr.c (strstr2): Add new function.
	(strstr3): Likewise.
	(STRSTR): Completely rewrite strstr to improve performance.

(cherry picked from commit 5e0a7ecb66)
2019-09-13 16:41:26 +01:00
Wilco Dijkstra cd3487afa2 Fix strstr bug with huge needles (bug 23637)
The generic strstr in GLIBC 2.28 fails to match huge needles.  The optimized
AVAILABLE macro reads ahead a large fixed amount to reduce the overhead of
repeatedly checking for the end of the string.  However if the needle length
is larger than this, two_way_long_needle may confuse this as meaning the end
of the string and return NULL.  This is fixed by adding the needle length to
the amount to read ahead.

	[BZ #23637]
	* string/test-strstr.c (pr23637): New function.
	(test_main): Add tests with longer needles.
	* string/strcasestr.c (AVAILABLE): Fix readahead distance.
	* string/strstr.c (AVAILABLE): Likewise.

(cherry picked from commit 83a552b0bb)
2019-09-13 16:40:59 +01:00
Rajalakshmi Srinivasaraghavan ceeba1d73c Speedup first memmem match
As done in commit 284f42bc77, memcmp
can be used after memchr to avoid the initialization overhead of the
two-way algorithm for the first match.  This has shown improvement
>40% for first match.

(cherry picked from commit c8dd67e7c9)
2019-09-13 16:40:20 +01:00
Wilco Dijkstra c60bf879b2 Simplify and speedup strstr/strcasestr first match
Looking at the benchtests, both strstr and strcasestr spend a lot of time
in a slow initialization loop handling one character per iteration.
This can be simplified and use the much faster strlen/strnlen/strchr/memcmp.
Read ahead a few cachelines to reduce the number of strnlen calls, which
improves performance by ~3-4%.  This patch improves the time taken for the
full strstr benchtest by >40%.

	* string/strcasestr.c (STRCASESTR): Simplify and speedup first match.
	* string/strstr.c (AVAILABLE): Likewise.

(cherry picked from commit 284f42bc77)
2019-09-13 16:39:42 +01:00
Wilco Dijkstra 55a280689e Improve strstr performance
Improve strstr performance.  Strstr tends to be slow because it uses
many calls to memchr and a slow byte loop to scan for the next match.
Performance is significantly improved by using strnlen on larger blocks
and using strchr to search for the next matching character.  strcasestr
can also use strnlen to scan ahead, and memmem can use memchr to check
for the next match.

On the GLIBC bench tests the performance gains on Cortex-A72 are:
strstr: +25%
strcasestr: +4.3%
memmem: +18%

On a 256KB dataset strstr performance improves by 67%, strcasestr by 47%.

    Reviewd-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

(cherry picked from commit 3ae725dfb6)
2019-09-13 16:39:12 +01:00
Wilco Dijkstra d6613ad24f [AArch64] Add ifunc support for Ares
Add Ares to the midr_el0 list and support ifunc dispatch.  Since Ares
supports 2 128-bit loads/stores, use Neon registers for memcpy by
selecting __memcpy_falkor by default (we should rename this to
__memcpy_simd or similar).

	* manual/tunables.texi (glibc.cpu.name): Add ares tunable.
	* sysdeps/aarch64/multiarch/memcpy.c (__libc_memcpy): Use
	__memcpy_falkor for ares.
	* sysdeps/unix/sysv/linux/aarch64/cpu-features.h (IS_ARES):
	Add new define.
	* sysdeps/unix/sysv/linux/aarch64/cpu-features.c (cpu_list):
	Add ares cpu.

(cherry picked from commit 02f440c1ef)
2019-09-06 18:58:34 +01:00
Siddhesh Poyarekar ad64510e5c aarch64,falkor: Use vector registers for memcpy
Vector registers perform better than scalar register pairs for copying
data so prefer them instead.  This results in a time reduction of over
50% (i.e. 2x speed improvemnet) for some smaller sizes for memcpy-walk.
Larger sizes show improvements of around 1% to 2%.  memcpy-random shows
a very small improvement, in the range of 1-2%.

	* sysdeps/aarch64/multiarch/memcpy_falkor.S (__memcpy_falkor):
	Use vector registers.

(cherry picked from commit 0aec4c1d18)
2019-09-06 18:42:14 +01:00
Siddhesh Poyarekar d3c05bfffa aarch64,falkor: Ignore prefetcher tagging for smaller copies
For smaller and medium sized copies, the effect of hardware
prefetching are not as dominant as instruction level parallelism.
Hence it makes more sense to load data into multiple registers than to
try and route them to the same prefetch unit.  This is also the case
for the loop exit where we are unable to latch on to the same prefetch
unit anyway so it makes more sense to have data loaded in parallel.

The performance results are a bit mixed with memcpy-random, with
numbers jumping between -1% and +3%, i.e. the numbers don't seem
repeatable.  memcpy-walk sees a 70% improvement (i.e. > 2x) for 128
bytes and that improvement reduces down as the impact of the tail copy
decreases in comparison to the loop.

	* sysdeps/aarch64/multiarch/memcpy_falkor.S (__memcpy_falkor):
	Use multiple registers to copy data in loop tail.

(cherry picked from commit db725a458e)
2019-09-06 18:41:04 +01:00
Siddhesh Poyarekar e3c35100d3 aarch64/strncmp: Use lsr instead of mov+lsr
A lsr can do what the mov and lsr did.

(cherry picked from commit b47c3e7637)
2019-09-06 17:15:27 +01:00
Siddhesh Poyarekar 00fd3acde1 aarch64/strncmp: Unbreak builds with old binutils
Binutils 2.26.* and older do not support moves with shifted registers,
so use a separate shift instruction instead.

(cherry picked from commit d46f84de74)
2019-09-06 17:14:47 +01:00
Siddhesh Poyarekar af9381b734 aarch64: Improve strncmp for mutually misaligned inputs
The mutually misaligned inputs on aarch64 are compared with a simple
byte copy, which is not very efficient.  Enhance the comparison
similar to strcmp by loading a double-word at a time.  The peak
performance improvement (i.e. 4k maxlen comparisons) due to this on
the strncmp microbenchmark is as follows:

falkor: 3.5x (up to 72% time reduction)
cortex-a73: 3.5x (up to 71% time reduction)
cortex-a53: 3.5x (up to 71% time reduction)

All mutually misaligned inputs from 16 bytes maxlen onwards show
upwards of 15% improvement and there is no measurable effect on the
performance of aligned/mutually aligned inputs.

	* sysdeps/aarch64/strncmp.S (count): New macro.
	(strncmp): Store misaligned length in SRC1 in COUNT.
	(mutual_align): Adjust.
	(misaligned8): Load dword at a time when it is safe.

(cherry picked from commit 7108f1f944)
2019-09-06 17:14:05 +01:00
Siddhesh Poyarekar 01de24dbca aarch64/strcmp: fix misaligned loop jump target
I accidentally set the loop jump back label as misaligned8 instead of
do_misaligned.  The typo is harmless but it's always nice to not have
to unnecessarily execute those two instructions.

	* sysdeps/aarch64/strcmp.S (do_misaligned): Jump back to
	do_misaligned, not misaligned8.

(cherry picked from commit 6ca24c4348)
2019-09-06 17:13:34 +01:00
Siddhesh Poyarekar 4e75091d6c aarch64: Improve strcmp unaligned performance
Replace the simple byte-wise compare in the misaligned case with a
dword compare with page boundary checks in place.  For simplicity I've
chosen a 4K page boundary so that we don't have to query the actual
page size on the system.

This results in up to 3x improvement in performance in the unaligned
case on falkor and about 2.5x improvement on mustang as measured using
bench-strcmp.

	* sysdeps/aarch64/strcmp.S (misaligned8): Compare dword at a
	time whenever possible.

(cherry picked from commit 2bce01ebba)
2019-09-06 17:13:02 +01:00
Siddhesh Poyarekar 8569357e11 aarch64: Fix branch target to loop16
I goofed up when changing the loop8 name to loop16 and missed on out
the branch instance.  Fixed and actually build tested this time.

	* sysdeps/aarch64/memcmp.S (more16): Fix branch target loop16.

(cherry picked from commit 4e54d91863)
2019-09-06 16:33:12 +01:00
Siddhesh Poyarekar ec4512194f aarch64: Optimized memcmp for medium to large sizes
This improved memcmp provides a fast path for compares up to 16 bytes
and then compares 16 bytes at a time, thus optimizing loads from both
sources.  The glibc memcmp microbenchmark retains performance (with an
error of ~1ns) for smaller compare sizes and reduces up to 31% of
execution time for compares up to 4K on the APM Mustang.  On Qualcomm
Falkor this improves to almost 48%, i.e. it is almost 2x improvement
for sizes of 2K and above.

	* sysdeps/aarch64/memcmp.S: Widen comparison to 16 bytes at a
	time.

(cherry picked from commit 30a81dae5b)
2019-09-06 16:33:04 +01:00
Siddhesh Poyarekar 600e4e866c aarch64: Use the L() macro for labels in memcmp
The L() macro makes the assembly a bit more readable.

	* sysdeps/aarch64/memcmp.S: Use L() macro for labels.

(cherry picked from commit 84c94d2fd9)
2019-09-06 16:31:36 +01:00
Wilco Dijkstra 1896de3d92 [AArch64] Optimized memcmp.
This is an optimized memcmp for AArch64.  This is a complete rewrite
using a different algorithm.  The previous version split into cases
where both inputs were aligned, the inputs were mutually aligned and
unaligned using a byte loop.  The new version combines all these cases,
while small inputs of less than 8 bytes are handled separately.

This allows the main code to be sped up using unaligned loads since
there are now at least 8 bytes to be compared.  After the first 8 bytes,
align the first input.  This ensures each iteration does at most one
unaligned access and mutually aligned inputs behave as aligned.
After the main loop, process the last 8 bytes using unaligned accesses.

This improves performance of (mutually) aligned cases by 25% and
unaligned by >500% (yes >6 times faster) on large inputs.

	* sysdeps/aarch64/memcmp.S (memcmp):
	Rewrite of optimized memcmp.

(cherry picked from commit 922369032c)
2019-09-06 16:30:10 +01:00
Adhemerval Zanella 54194d8b4d posix: Fix large mmap64 offset for mips64n32 (BZ#24699)
The fix for BZ#21270 (commit 158d5fa0e1) added a mask to avoid offset larger
than 1^44 to be used along __NR_mmap2.  However mips64n32 users __NR_mmap,
as mips64n64, but still defines off_t as old non-LFS type (other ILP32, such
x32, defines off_t being equal to off64_t).  This leads to use the same
mask meant only for __NR_mmap2 call for __NR_mmap, thus limiting the maximum
offset it can use with mmap64.

This patch fixes by setting the high mask only for __NR_mmap2 usage. The
posix/tst-mmap-offset.c already tests it and also fails for mips64n32. The
patch also change the test to check for an arch-specific header that defines
the maximum supported offset.

Checked on x86_64-linux-gnu, i686-linux-gnu, and I also tests tst-mmap-offset
on qemu simulated mips64 with kernel 3.2.0 kernel for both mips-linux-gnu and
mips64-n32-linux-gnu.

	[BZ #24699]
	* posix/tst-mmap-offset.c: Mention BZ #24699.
	(do_test_bz21270): Rename to do_test_large_offset and use
	mmap64_maximum_offset to check for maximum expected offset value.
	* sysdeps/generic/mmap_info.h: New file.
	* sysdeps/unix/sysv/linux/mips/mmap_info.h: Likewise.
	* sysdeps/unix/sysv/linux/mmap64.c (MMAP_OFF_HIGH_MASK): Define iff
	__NR_mmap2 is used.

(cherry picked from commit a008c76b56)
2019-07-12 19:02:04 +00:00
Szabolcs Nagy f2f501ff39 aarch64: handle STO_AARCH64_VARIANT_PCS
Backport of commit 82bc69c012
and commit 30ba037546
without using DT_AARCH64_VARIANT_PCS for optimizing the symbol table check.
This is needed so the internal abi between ld.so and libc.so is unchanged.

Avoid lazy binding of symbols that may follow a variant PCS with different
register usage convention from the base PCS.

Currently the lazy binding entry code does not preserve all the registers
required for AdvSIMD and SVE vector calls.  Saving and restoring all
registers unconditionally may break existing binaries, even if they never
use vector calls, because of the larger stack requirement for lazy
resolution, which can be significant on an SVE system.

The solution is to mark all symbols in the symbol table that may follow
a variant PCS so the dynamic linker can handle them specially.  In this
patch such symbols are always resolved at load time, not lazily.

So currently LD_AUDIT for variant PCS symbols are not supported, for that
the _dl_runtime_profile entry needs to be changed e.g. to unconditionally
save/restore all registers (but pass down arg and retval registers to
pltentry/exit callbacks according to the base PCS).

This patch also removes a __builtin_expect from the modified code because
the branch prediction hint did not seem useful.

	* sysdeps/aarch64/dl-machine.h (elf_machine_lazy_rel): Check
	STO_AARCH64_VARIANT_PCS and bind such symbols at load time.
2019-07-12 10:50:17 +01:00
Szabolcs Nagy 71c2578a9b aarch64: add STO_AARCH64_VARIANT_PCS and DT_AARCH64_VARIANT_PCS
STO_AARCH64_VARIANT_PCS is a non-visibility st_other flag for marking
symbols that reference functions that may follow a variant PCS with
different register usage convention from the base PCS.

DT_AARCH64_VARIANT_PCS is a dynamic tag that marks ELF modules that
have R_*_JUMP_SLOT relocations for symbols marked with
STO_AARCH64_VARIANT_PCS (i.e. have variant PCS calls via a PLT).

	* elf/elf.h (STO_AARCH64_VARIANT_PCS): Define.
	(DT_AARCH64_VARIANT_PCS): Define.
2019-07-12 10:50:12 +01:00
Wilco Dijkstra ac92c66821 Fix tcache count maximum (BZ #24531)
The tcache counts[] array is a char, which has a very small range and thus
may overflow.  When setting tcache_count tunable, there is no overflow check.
However the tunable must not be larger than the maximum value of the tcache
counts[] array, otherwise it can overflow when filling the tcache.

	[BZ #24531]
	* malloc/malloc.c (MAX_TCACHE_COUNT): New define.
	(do_set_tcache_count): Only update if count is small enough.
	* manual/tunables.texi (glibc.malloc.tcache_count): Document max value.

(cherry picked from commit 5ad533e8e6)
2019-05-22 15:41:24 +01:00
Andreas Schwab 4385ec1d8a Fix crash in _IO_wfile_sync (bug 20568)
When computing the length of the converted part of the stdio buffer, use
the number of consumed wide characters, not the (negative) distance to the
end of the wide buffer.

(cherry picked from commit 32ff397533)
2019-05-16 10:10:04 +02:00
Stefan Liebler c165427d55 Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock. [BZ #24180]
While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and
Heiko Carstens found a bug in pthread_mutex_trylock due to misordered
instructions:
140:   a5 1b 00 01             oill    %r1,1
144:   e5 48 a0 f0 00 00       mvghi   240(%r10),0   <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
14a:   e3 10 a0 e0 00 24       stg     %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI

vs (with compiler barriers):
140:   a5 1b 00 01             oill    %r1,1
144:   e3 10 a0 e0 00 24       stg     %r1,224(%r10)
14a:   e5 48 a0 f0 00 00       mvghi   240(%r10),0

Please have a look at the discussion:
"Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede"
(https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/)

This patch is introducing the same compiler barriers and comments
for pthread_mutex_trylock as introduced for pthread_mutex_lock and
pthread_mutex_timedlock by commit 8f9450a0b7
"Add compiler barriers around modifications of the robust mutex list."

ChangeLog:

	[BZ #24180]
	* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock):
	Add compiler barriers and comments.

(cherry picked from commit 823624bdc4)
2019-02-07 15:49:36 +01:00
H.J. Lu 04e767b59b x86-64 memcmp: Use unsigned Jcc instructions on size [BZ #24155]
Since the size argument is unsigned. we should use unsigned Jcc
instructions, instead of signed, to check size.

Tested on x86-64 and x32, with and without --disable-multi-arch.

	[BZ #24155]
	CVE-2019-7309
	* NEWS: Updated for CVE-2019-7309.
	* sysdeps/x86_64/memcmp.S: Use RDX_LP for size.  Clear the
	upper 32 bits of RDX register for x32.  Use unsigned Jcc
	instructions, instead of signed.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcmp-2.
	* sysdeps/x86_64/x32/tst-size_t-memcmp-2.c: New test.

(cherry picked from commit 3f635fb433)
2019-02-04 10:27:37 -08:00
H.J. Lu dc968f5573 x86-64 strnlen/wcsnlen: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes strnlen/wcsnlen for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/strlen-avx2.S: Use RSI_LP for length.
	Clear the upper 32 bits of RSI register.
	* sysdeps/x86_64/strlen.S: Use RSI_LP for length.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-strnlen
	and tst-size_t-wcsnlen.
	* sysdeps/x86_64/x32/tst-size_t-strnlen.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-wcsnlen.c: Likewise.

(cherry picked from commit 5165de69c0)
2019-02-01 15:35:22 -08:00
H.J. Lu 40575878cd x86-64 strncpy: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes strncpy for x32.  Tested on x86-64 and x32.  On x86-64,
libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: Use RDX_LP
	for length.
	* sysdeps/x86_64/multiarch/strcpy-ssse3.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-strncpy.
	* sysdeps/x86_64/x32/tst-size_t-strncpy.c: New file.

(cherry picked from commit c7c54f65b0)
2019-02-01 15:35:00 -08:00
H.J. Lu 15ce2f62f6 x86-64 strncmp family: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes the strncmp family for x32.  Tested on x86-64 and x32.
On x86-64, libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/strcmp-sse42.S: Use RDX_LP for length.
	* sysdeps/x86_64/strcmp.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-strncasecmp,
	tst-size_t-strncmp and tst-size_t-wcsncmp.
	* sysdeps/x86_64/x32/tst-size_t-strncasecmp.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-strncmp.c: Likewise.
	* sysdeps/x86_64/x32/tst-size_t-wcsncmp.c: Likewise.

(cherry picked from commit ee915088a0)
2019-02-01 15:34:41 -08:00
H.J. Lu 885e4af2ac x86-64 memset/wmemset: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memset/wmemset for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S: Use
	RDX_LP for length.  Clear the upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-wmemset.
	* sysdeps/x86_64/x32/tst-size_t-memset.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-wmemset.c: Likewise.

(cherry picked from commit 82d0b4a4d7)
2019-02-01 15:34:29 -08:00
H.J. Lu c9ea2e82d4 x86-64 memrchr: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memrchr for x32.  Tested on x86-64 and x32.  On x86-64,
libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/memrchr.S: Use RDX_LP for length.
	* sysdeps/x86_64/multiarch/memrchr-avx2.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memrchr.
	* sysdeps/x86_64/x32/tst-size_t-memrchr.c: New file.

(cherry picked from commit ecd8b842cf)
2019-02-01 15:34:17 -08:00
H.J. Lu 94b88894b1 x86-64 memcpy: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memcpy for x32.  Tested on x86-64 and x32.  On x86-64,
libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: Use RDX_LP for
	length.  Clear the upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memcpy-ssse3.S: Likewise.
	* sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S:
	Likewise.
	* sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:
	Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcpy.
	tst-size_t-wmemchr.
	* sysdeps/x86_64/x32/tst-size_t-memcpy.c: New file.

(cherry picked from commit 231c56760c)
2019-02-01 15:34:04 -08:00
H.J. Lu 232a7628f0 x86-64 memcmp/wmemcmp: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memcmp/wmemcmp for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S: Use RDX_LP for
	length.  Clear the upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memcmp-sse4.S: Likewise.
	* sysdeps/x86_64/multiarch/memcmp-ssse3.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcmp and
	tst-size_t-wmemcmp.
	* sysdeps/x86_64/x32/tst-size_t-memcmp.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-wmemcmp.c: Likewise.

(cherry picked from commit b304fc201d)
2019-02-01 15:33:50 -08:00
H.J. Lu bff8346b01 x86-64 memchr/wmemchr: Properly handle the length parameter [BZ #24097]
On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memchr/wmemchr for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ #24097]
	CVE-2019-6488
	* sysdeps/x86_64/memchr.S: Use RDX_LP for length.  Clear the
	upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memchr-avx2.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memchr and
	tst-size_t-wmemchr.
	* sysdeps/x86_64/x32/test-size_t.h: New file.
	* sysdeps/x86_64/x32/tst-size_t-memchr.c: Likewise.
	* sysdeps/x86_64/x32/tst-size_t-wmemchr.c: Likewise.

(cherry picked from commit 97700a34f3)
2019-02-01 15:32:53 -08:00
Tulio Magno Quites Machado Filho c49ad9bdc9 Merge branch 'release/2.26/master' into ibm/2.26/master 2019-01-11 14:20:21 -02:00
Gabriel F. T. Gomes 7ab39c6a3c powerpc: Regenerate ULPs
On POWER9, cbrtf128 fails by 1 ULP.

	* sysdeps/powerpc/fpu/libm-test-ulps: Regenerate.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
(cherry picked from commit 428fc49eaa)
2019-01-11 14:14:10 -02:00
Tulio Magno Quites Machado Filho d851e9199e [BZ #21745] powerpc: build some IFUNC math functions for libc and libm
Some math functions have to be distributed in libc because they're
required by printf.
libc and libm require their own builds of these functions, e.g. libc
functions have to call __stack_chk_fail_local in order to bypass the
PLT, while libm functions have to call __stack_chk_fail.

While math/Makefile treat the generic cases, i.e. s_isinff, the
multiarch Makefile has to treat its own files, i.e. s_isinff-ppc64.

	[BZ #21745]
	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile:
	[$(subdir) = math] (sysdep_calls): New variable.  Has the
	previous contents of sysdep_routines, but re-sorted..
	[$(subdir) = math] (sysdep_routines): Re-use the contents from
	sysdep_calls.
	[$(subdir) = math] (libm-sysdep_routines): Remove the functions
	defined in sysdep_calls and replace by the respective m_* names.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S:
	(compat_symbol): Undefine to avoid duplicated compat symbols in
	libc.

(cherry picked from commit 61c45f2505)
2019-01-11 14:14:10 -02:00
Florian Weimer a5bd0ba192 intl: Do not return NULL on asprintf failure in gettext [BZ #24018]
Fixes commit 9695dd0c93 ("DCIGETTEXT:
Use getcwd, asprintf to construct absolute pathname").

(cherry picked from commit 8c1aafc1f3)
2019-01-02 20:01:05 +01:00
Florian Weimer 94417f6c26 malloc: Always call memcpy in _int_realloc [BZ #24027]
This commit removes the custom memcpy implementation from _int_realloc
for small chunk sizes.  The ncopies variable has the wrong type, and
an integer wraparound could cause the existing code to copy too few
elements (leaving the new memory region mostly uninitialized).
Therefore, removing this code fixes bug 24027.

(cherry picked from commit b50dd3bc8c)
2019-01-01 11:07:26 +01:00
Florian Weimer a0bc5dd3be CVE-2018-19591: if_nametoindex: Fix descriptor for overlong name [BZ #23927]
(cherry picked from commit d527c860f5)
2018-11-27 21:35:31 +01:00
Alexandra Hájková 27e46f5836 Add an additional test to resolv/tst-resolv-network.c
Test for the infinite loop in getnetbyname, bug #17630.

(cherry picked from commit ac8060265b)
2018-11-09 14:43:45 +01:00
Andreas Schwab fcd86c6253 libanl: properly cleanup if first helper thread creation failed (bug 22927)
(cherry picked from commit bd3b0fbae3)
2018-11-06 17:12:07 +01:00
Adhemerval Zanella dc40423dba x86: Fix Haswell CPU string flags (BZ#23709)
Th commit 'Disable TSX on some Haswell processors.' (2702856bf4) changed the
default flags for Haswell models.  Previously, new models were handled by the
default switch path, which assumed a Core i3/i5/i7 if AVX is available. After
the patch, Haswell models (0x3f, 0x3c, 0x45, 0x46) do not set the flags
Fast_Rep_String, Fast_Unaligned_Load, Fast_Unaligned_Copy, and
Prefer_PMINUB_for_stringop (only the TSX one).

This patch fixes it by disentangle the TSX flag handling from the memory
optimization ones.  The strstr case cited on patch now selects the
__strstr_sse2_unaligned as expected for the Haswell cpu.

Checked on x86_64-linux-gnu.

	[BZ #23709]
	* sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
	independently of other flags.

(cherry picked from commit c3d8dc45c9)
2018-11-02 11:14:05 +01:00
Joseph Myers 33f5de7a79 Disable -Wrestrict for two nptl/tst-attr3.c tests.
nptl/tst-attr3 fails to build with GCC mainline because of
(deliberate) aliasing between the second (attributes) and fourth
(argument to thread start routine) arguments to pthread_create.

Although both those arguments are restrict-qualified in POSIX,
pthread_create does not actually dereference its fourth argument; it's
an opaque pointer passed to the thread start routine.  Thus, the
aliasing is actually valid in this case, and it's deliberate in the
test.  So this patch makes the test disable -Wrestrict for the two
pthread_create calls in question.  (-Wrestrict was added in GCC 7,
hence the __GNUC_PREREQ conditions, but the particular warning in
question is new in GCC 8.)

Tested compilation with build-many-glibcs.py for aarch64-linux-gnu.

	* nptl/tst-attr3.c: Include <libc-diag.h>.
	(do_test) [__GNUC_PREREQ (7, 0)]: Ignore -Wrestrict for two tests.

(cherry picked from commit 40c4162df6)
2018-10-22 14:20:23 +02:00
Joseph Myers 6ae2ca620a Fix string/bug-strncat1.c build with GCC 8.
GCC 8 warns about strncat calls with truncated output.
string/bug-strncat1.c tests such a call; this patch disables the
warning for it.

Tested (compilation) with GCC 8 for x86_64-linux-gnu with
build-many-glibcs.py (in conjunction with Martin's patch to allow
glibc to build).

	* string/bug-strncat1.c: Include <libc-diag.h>.
	(main): Disable -Wstringop-truncation for strncat call for GCC 8.

(cherry picked from commit ec72135e5f)
2018-10-22 14:16:02 +02:00
Joseph Myers fe5978e1a5 Ignore -Wrestrict for one strncat test.
With current GCC mainline, one strncat test involving a size close to
SIZE_MAX results in a -Wrestrict warning that that buffer size would
imply that the two buffers must overlap.  This patch fixes the build
by adding disabling of -Wrestrict (for GCC versions supporting that
option) to the already-present disabling of -Wstringop-overflow= and
-Warray-bounds for this test.

Tested with build-many-glibcs.py that this restores the testsuite
build with GCC mainline for aarch64-linux-gnu.

	* string/tester.c (test_strncat) [__GNUC_PREREQ (7, 0)]: Also
	ignore -Wrestrict for one test.

(cherry picked from commit 35ebb6b0c4)
2018-10-22 14:15:29 +02:00
Joseph Myers 70e810a30c Disable strncat test array-bounds warnings for GCC 8.
Some strncat tests fail to build with GCC 8 because of -Warray-bounds
warnings.  These tests are deliberately test over-large size arguments
passed to strncat, and already disable -Wstringop-overflow warnings,
but now the warnings for these tests come under -Warray-bounds so that
option needs disabling for them as well, which this patch does (with
an update on the comments; the DIAG_IGNORE_NEEDS_COMMENT call for
-Warray-bounds doesn't need to be conditional itself, because that
option is supported by all versions of GCC that can build glibc).

Tested compilation with build-many-glibcs.py for aarch64-linux-gnu.

	* string/tester.c (test_strncat): Also disable -Warray-bounds
	warnings for two tests.

(cherry picked from commit 1421f39b7e)
2018-10-22 14:15:29 +02:00
Joseph Myers dd03d15e28 Fix string/tester.c build with GCC 8.
GCC 8 warns about more cases of string functions truncating their
output or not copying a trailing NUL byte.

This patch fixes testsuite build failures caused by such warnings in
string/tester.c.  In general, the warnings are disabled around the
relevant calls using DIAG_* macros, since the relevant cases are being
deliberately tested.  In one case, the warning is with
-Wstringop-overflow= instead of -Wstringop-truncation; in that case,
the conditional is __GNUC_PREREQ (7, 0) (being the version where
-Wstringop-overflow= was introduced), to allow the conditional to be
removed sooner, since it's harmless to disable the warning for a
GCC version where it doesn't actually occur.  In the case of warnings
for strncpy calls in test_memcmp, the calls in question are changed to
use memcpy, as they don't copy a trailing NUL and the point of that
code is to test memcmp rather than strncpy.

Tested (compilation) with GCC 8 for x86_64-linux-gnu with
build-many-glibcs.py (in conjunction with Martin's patch to allow
glibc to build).

	* string/tester.c (test_stpncpy): Disable -Wstringop-truncation
	for stpncpy calls for GCC 8.
	(test_strncat): Disable -Wstringop-truncation warning for strncat
	calls for GCC 8.  Disable -Wstringop-overflow= warning for one
	strncat call for GCC 7.
	(test_strncpy): Disable -Wstringop-truncation warning for strncpy
	calls for GCC 8.
	(test_memcmp): Use memcpy instead of strncpy for calls not copying
	trailing NUL.

(cherry picked from commit 2e64ec9c9e)
2018-10-22 14:15:28 +02:00
Joseph Myers 935cecfe9a Fix nscd readlink argument aliasing (bug 22446).
Current GCC mainline detects that nscd calls readlink with the same
buffer for both input and output, which is not valid (those arguments
are both restrict-qualified in POSIX).  This patch makes it use a
separate buffer for readlink's input (with a size that is sufficient
to avoid truncation, so there should be no problems with warnings
about possible truncation, though not strictly minimal, but much
smaller than the buffer for output) to avoid this problem.

Tested compilation for aarch64-linux-gnu with build-many-glibcs.py.

	[BZ #22446]
	* nscd/connections.c (handle_request) [SO_PEERCRED]: Use separate
	buffers for readlink input and output.

(cherry picked from commit 49b036bce9)
2018-10-22 14:08:12 +02:00
Steve Ellcey 3fb525c103 Increase buffer size due to warning from ToT GCC
* nscd/dbg_log.c (dbg_log): Increase msg buffer size.

(cherry picked from commit a7e3edf4f2)
2018-10-22 14:00:39 +02:00
Joseph Myers 636f49ba92 Fix p_secstodate overflow handling (bug 22463).
The resolv/res_debug.c function p_secstodate (which is a public
function exported from libresolv, taking an unsigned long argument)
does:

        struct tm timebuf;
        time = __gmtime_r(&clock, &timebuf);
        time->tm_year += 1900;
        time->tm_mon += 1;
        sprintf(output, "%04d%02d%02d%02d%02d%02d",
                time->tm_year, time->tm_mon, time->tm_mday,
                time->tm_hour, time->tm_min, time->tm_sec);

If __gmtime_r returns NULL (because the year overflows the range of
int), this will dereference a null pointer.  Otherwise, if the
computed year does not fit in four characters, this will cause a
buffer overrun of the fixed-size 15-byte buffer.  With current GCC
mainline, there is a compilation failure because of the possible
buffer overrun.

I couldn't find a specification for how this function is meant to
behave, but Paul pointed to RFC 4034 as relevant to the cases where
this function is called from within glibc.  The function's interface
is inherently problematic when dates beyond Y2038 might be involved,
because of the ambiguity in how to interpret 32-bit timestamps as such
dates (the RFC suggests interpreting times as being within 68 years of
the present date, which would mean some kind of interface whose
behavior depends on the present date).

This patch works on the basis of making a minimal fix in preparation
for obsoleting the function.  The function is made to handle times in
the interval [0, 0x7fffffff] only, on all platforms, with <overflow>
used as the output string in other cases (and errno set to EOVERFLOW
in such cases).  This seems to be a reasonable state for the function
to be in when made a compat symbol by a future patch, being compatible
with any existing uses for existing timestamps without trying to work
for later timestamps.  Results independent of the range of time_t also
simplify the testcase.

I couldn't persuade GCC to recognize the ranges of the struct tm
fields by adding explicit range checks with a call to
__builtin_unreachable if outside the range (this looks similar to
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80776>), so having added
a range check on the input, this patch then disables the
-Wformat-overflow= warning for the sprintf call (I prefer that to the
use of strftime, as being more transparently correct without knowing
what each of %m and %M etc. is).

I do not know why this build failure should be new with mainline GCC
(that is, I don't know what GCC change might have introduced it, when
the basic functionality for such warnings was already in GCC 7).

I do not know if this is a security issue (that is, if there are
plausible ways in which a date before -999 or after 9999 from an
untrusted source might end up in this function).  The system clock is
arguably an untrusted source (in that e.g. NTP is insecure), but
probably not to that extent (NTP can't communicate such wild
timestamps), and uses from within glibc are limited to 32-bit inputs.

Tested with build-many-glibcs.py that this restores the build for arm
with yesterday's mainline GCC.  Also tested for x86_64 and x86.

	[BZ #22463]
	* resolv/res_debug.c: Include <libc-diag.h>.
	(p_secstodate): Assert time_t at least as wide as u_long.  On
	overflow, use integer seconds since the epoch as output, or use
	"<overflow>" as output and set errno to EOVERFLOW if integer
	seconds since the epoch would be 14 or more characters.
	(p_secstodate) [__GNUC_PREREQ (7, 0)]: Disable -Wformat-overflow=
	for sprintf call.
	* resolv/tst-p_secstodate.c: New file.
	* resolv/Makefile (tests): Add tst-p_secstodate.
	($(objpfx)tst-p_secstodate): Depend on $(objpfx)libresolv.so.

(cherry picked from commit f120cda607)
2018-10-22 14:00:17 +02:00
Paul Eggert d161b294e1 timezone: pacify GCC -Wstringop-truncation
Problem reported by Martin Sebor in:
https://sourceware.org/ml/libc-alpha/2017-11/msg00336.html
* timezone/zic.c (writezone): Use memcpy, not strncpy.

(cherry picked from commit e69897bf20)
2018-10-22 14:00:17 +02:00
Martin Sebor e37ec9c813 utmp: Avoid -Wstringop-truncation warning
The -Wstringop-truncation option new in GCC 8 detects common misuses
of the strncat and strncpy function that may result in truncating
the copied string before the terminating NUL.  To avoid false positive
warnings for correct code that intentionally creates sequences of
characters that aren't guaranteed to be NUL-terminated, arrays that
are intended to store such sequences should be decorated with a new
nonstring attribute.  This change add this attribute to Glibc and
uses it to suppress such false positives.

ChangeLog:
	* misc/sys/cdefs.h (__attribute_nonstring__): New macro.
	* sysdeps/gnu/bits/utmp.h (struct utmp): Use it.
	* sysdeps/unix/sysv/linux/s390/bits/utmp.h (struct utmp): Same.

(cherry picked from commit 7532837d7b)
2018-10-22 14:00:13 +02:00
Joseph Myers 27611fd05b Avoid use of strlen in getlogin_r (bug 22447).
Building glibc with current mainline GCC fails, among other reasons,
because of an error for use of strlen on the nonstring ut_user field.
This patch changes the problem code in getlogin_r to use __strnlen
instead.  It also needs to set the trailing NUL byte of the result
explicitly, because of the case where ut_user does not have such a
trailing NUL byte (but the result should always have one).

Tested for x86_64.  Also tested that, in conjunction with
<https://sourceware.org/ml/libc-alpha/2017-11/msg00797.html>, it fixes
the build for arm with mainline GCC.

	[BZ #22447]
	* sysdeps/unix/getlogin_r.c (__getlogin_r): Use __strnlen not
	strlen to compute length of ut_user and set trailing NUL byte of
	result explicitly.

(cherry picked from commit 4bae615022)
2018-10-22 13:58:39 +02:00
Ilya Yu. Malakhov 48bef587bf signal: Use correct type for si_band in siginfo_t [BZ #23562]
(cherry picked from commit f997b4be18)
2018-10-22 13:43:59 +02:00
Adhemerval Zanella 202d08db40 Fix misreported errno on preadv2/pwritev2 (BZ#23579)
The fallback code of Linux wrapper for preadv2/pwritev2 executes
regardless of the errno code for preadv2, instead of the case where
the syscall is not supported.

This fixes it by calling the fallback code iff errno is ENOSYS. The
patch also adds tests for both invalid file descriptor and invalid
iov_len and vector count.

The only discrepancy between preadv2 and fallback code regarding
error reporting is when an invalid flags are used.  The fallback code
bails out earlier with ENOTSUP instead of EINVAL/EBADF when the syscall
is used.

Checked on x86_64-linux-gnu on a 4.4.0 and 4.15.0 kernel.

	[BZ #23579]
	* misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd): New
	test.
	* misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test):
	Call do_test_with_invalid_fd.
	* sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff
	errno is ENOSYS.
	* sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
	* sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
	* sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.

(cherry picked from commit 7a16bdbb9f)
2018-09-28 15:16:04 -03:00
Florian Weimer 3022a296bd preadv2/pwritev2: Handle offset == -1 [BZ #22753]
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

(cherry picked from commit d4b4a00a46)
2018-09-28 15:16:02 -03:00
Stefan Liebler c5c90b480e Fix segfault in maybe_script_execute.
If glibc is built with gcc 8 and -march=z900,
the testcase posix/tst-spawn4-compat crashes with a segfault.

In function maybe_script_execute, the new_argv array is dynamically
initialized on stack with (argc + 1) elements.
The function wants to add _PATH_BSHELL as the first argument
and writes out of bounds of new_argv.
There is an off-by-one because maybe_script_execute fails to count
the terminating NULL when sizing new_argv.

ChangeLog:

	* sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
	Increment size of new_argv by one.

(cherry picked from commit 28669f86f6)
2018-09-10 14:27:40 +02:00
Martin Kuchta 174709d879 pthread_cond_broadcast: Fix waiters-after-spinning case [BZ #23538]
(cherry picked from commit 99ea93ca31)
2018-08-27 19:14:58 +02:00
H.J. Lu c9570bd2f5 x86: Populate COMMON_CPUID_INDEX_80000001 for Intel CPUs [BZ #23459]
Reviewed-by: Carlos O'Donell <carlos@redhat.com>

	[BZ #23459]
	* sysdeps/x86/cpu-features.c (get_extended_indices): New
	function.
	(init_cpu_features): Call get_extended_indices for both Intel
	and AMD CPUs.
	* sysdeps/x86/cpu-features.h (COMMON_CPUID_INDEX_80000001):
	Remove "for AMD" comment.

(cherry picked from commit be525a69a6)
2018-07-29 06:28:50 -07:00
H.J. Lu 86e0996b1a x86: Correct index_cpu_LZCNT [BZ #23456]
cpu-features.h has

 #define bit_cpu_LZCNT		(1 << 5)
 #define index_cpu_LZCNT	COMMON_CPUID_INDEX_1
 #define reg_LZCNT

But the LZCNT feature bit is in COMMON_CPUID_INDEX_80000001:

Initial EAX Value: 80000001H
ECX Extended Processor Signature and Feature Bits:
Bit 05: LZCNT available

index_cpu_LZCNT should be COMMON_CPUID_INDEX_80000001, not
COMMON_CPUID_INDEX_1.  The VMX feature bit is in COMMON_CPUID_INDEX_1:

Initial EAX Value: 01H
Feature Information Returned in the ECX Register:
5 VMX

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

	[BZ #23456]
	* sysdeps/x86/cpu-features.h (index_cpu_LZCNT): Set to
	COMMON_CPUID_INDEX_80000001.

(cherry picked from commit 65d87ade1e)
2018-07-29 06:26:35 -07:00
Florian Weimer cf6deb084b conform/conformtest.pl: Escape literal braces in regular expressions
This suppresses Perl warnings like these:

Unescaped left brace in regex is deprecated here (and will be fatal in
Perl 5.32), passed through in regex; marked by <-- HERE in m/^element
*({ <-- HERE ([^}]*)}|([^{ ]*)) *({([^}]*)}|([^{ ]*)) *([A-Za-z0-9_]*)
*(.*)/ at conformtest.pl line 370.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit ddb3c626b0)
2018-07-06 16:41:11 +02:00
Florian Weimer b12bed3e06 stdio-common/tst-printf.c: Remove part under a non-free license [BZ #23363]
The license does not allow modification.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 5a35750665)
2018-07-03 18:34:26 +02:00
Florian Weimer 20dc7a909a libio: Add tst-vtables, tst-vtables-interposed
(cherry picked from commit 29055464a0)

Some adjustments were needed for a tricky multi-inclusion issue related
to libioP.h.
2018-07-03 18:13:58 +02:00
Florian Weimer 4b10e69b1f Synchronize support/ infrastructure with master
This commit updates the support/ subdirectory to
commit 5c0202af4b
on the master branch.
2018-07-03 18:13:05 +02:00
Florian Weimer 762e9d63d5 NEWS: Reorder out-of-order bugs 2018-07-03 15:58:48 +02:00
Florian Weimer 2781bd5a86 libio: Disable vtable validation in case of interposition [BZ #23313]
(cherry picked from commit c402355dfa)
2018-07-03 15:57:55 +02:00
Steve Ellcey 74d16a57a3 Check length of ifname before copying it into to ifreq structure.
[BZ #22442]
	* sysdeps/unix/sysv/linux/if_index.c (__if_nametoindex):
	Check if ifname is too long.

(cherry picked from commit 2180fee114)
2018-06-29 17:32:23 +02:00
Daniel Alvarez 3aaf8bda00 getifaddrs: Don't return ifa entries with NULL names [BZ #21812]
A lookup operation in map_newlink could turn into an insert because of
holes in the interface part of the map.  This leads to incorrectly set
the name of the interface to NULL when the interface is not present
for the address being processed (most likely because the interface was
added between the RTM_GETLINK and RTM_GETADDR calls to the kernel).
When such changes are detected by the kernel, it'll mark the dump as
"inconsistent" by setting NLM_F_DUMP_INTR flag on the next netlink
message.

This patch checks this condition and retries the whole operation.
Hopes are that next time the interface corresponding to the address
entry is present in the list and correct name is returned.

(cherry picked from commit c1f86a33ca)
2018-06-29 17:23:13 +02:00
Florian Weimer f958b45d52 Use _STRUCT_TIMESPEC as guard in <bits/types/struct_timespec.h> [BZ #23349]
After commit d76d370355 ("Fix missing
timespec definition for sys/stat.h (BZ #21371)") in combination with
kernel UAPI changes, GCC sanitizer builds start to fail due to a
conflicting definition of struct timespec in <linux/time.h>.  Use
_STRUCT_TIMESPEC as the header file inclusion guard, which is already
checked in the kernel header, to support including <linux/time.h> and
<sys/stat.h> in the same translation unit.

(cherry picked from commit c1c2848b57)
2018-06-28 13:22:34 +02:00
Gabriel F. T. Gomes 81b994bd83 Fix parameter type in C++ version of iseqsig (bug 23171)
The commit

  commit c85e54ac6c
  Author: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
  Date:   Fri Nov 3 10:44:36 2017 -0200

      Provide a C++ version of iseqsig (bug 22377)

mistakenly used double parameters in the long double version of iseqsig,
thus causing spurious conversions to double, as reported on bug 23171.

Tested for powerpc64le and x86_64.

(cherry picked from commit fb0e10b8eb)
2018-06-19 14:16:36 -03:00
Florian Weimer 7b52c8ae05 libio: Avoid _allocate_buffer, _free_buffer function pointers [BZ #23236]
These unmangled function pointers reside on the heap and could
be targeted by exploit writers, effectively bypassing libio vtable
validation.  Instead, we ignore these pointers and always call
malloc or free.

In theory, this is a backwards-incompatible change, but using the
global heap instead of the user-supplied callback functions should
have little application impact.  (The old libstdc++ implementation
exposed this functionality via a public, undocumented constructor
in its strstreambuf class.)

(cherry picked from commit 4e8a6346cd)
2018-06-01 11:24:58 +02:00
Florian Weimer 4df8479e6b Add NEWS entry for CVE-2018-11236 2018-05-24 16:27:38 +02:00
Florian Weimer a5bc5ec967 Add references to CVE-2018-11236, CVE-2017-18269 2018-05-24 15:49:32 +02:00
H.J. Lu 58ad5f8a64 Add a test case for [BZ #23196]
[BZ #23196]
	* string/test-memcpy.c (do_test1): New function.
	(test_main): Call it.

(cherry picked from commit ed983107bb)
2018-05-24 15:47:22 +02:00
Andreas Schwab 6b4362f2cb Don't write beyond destination in __mempcpy_avx512_no_vzeroupper (bug 23196)
When compiled as mempcpy, the return value is the end of the destination
buffer, thus it cannot be used to refer to the start of it.

(cherry picked from commit 9aaaab7c6e)
2018-05-24 15:47:12 +02:00
Paul Pluzhnikov af7519f7b3 Fix path length overflow in realpath [BZ #22786]
Integer addition overflow may cause stack buffer overflow
when realpath() input length is close to SSIZE_MAX.

2018-05-09  Paul Pluzhnikov  <ppluzhnikov@google.com>

	[BZ #22786]
	* stdlib/canonicalize.c (__realpath): Fix overflow in path length
	computation.
	* stdlib/Makefile (test-bz22786): New test.
	* stdlib/test-bz22786.c: New test.

(cherry picked from commit 5460617d15)
2018-05-17 14:10:16 +02:00
Paul Pluzhnikov 365722ace6 Fix stack overflow with huge PT_NOTE segment [BZ #20419]
A PT_NOTE in a binary could be arbitratily large, so using alloca
for it may cause stack overflow.  If the note is larger than
__MAX_ALLOCA_CUTOFF, use dynamically allocated memory to read it in.

2018-05-05  Paul Pluzhnikov  <ppluzhnikov@google.com>

	[BZ #20419]
	* elf/dl-load.c (open_verify): Fix stack overflow.
	* elf/Makefile (tst-big-note): New test.
	* elf/tst-big-note-lib.S: New.
	* elf/tst-big-note.c: New.

(cherry picked from commit 0065aaaaae)
2018-05-17 14:08:37 +02:00
Stefan Liebler be056fae3b Fix blocking pthread_join. [BZ #23137]
On s390 (31bit) if glibc is build with -Os, pthread_join sometimes
blocks indefinitely. This is e.g. observable with
testcase intl/tst-gettext6.

pthread_join is calling lll_wait_tid(tid), which performs the futex-wait
syscall in a loop as long as tid != 0 (thread is alive).

On s390 (and build with -Os), tid is loaded from memory before
comparing against zero and then the tid is loaded a second time
in order to pass it to the futex-wait-syscall.
If the thread exits in between, then the futex-wait-syscall is
called with the value zero and it waits until a futex-wake occurs.
As the thread is already exited, there won't be a futex-wake.

In lll_wait_tid, the tid is stored to the local variable __tid,
which is then used as argument for the futex-wait-syscall.
But unfortunately the compiler is allowed to reload the value
from memory.

With this patch, the tid is loaded with atomic_load_acquire.
Then the compiler is not allowed to reload the value for __tid from memory.

ChangeLog:

	[BZ #23137]
	* sysdeps/nptl/lowlevellock.h (lll_wait_tid):
	Use atomic_load_acquire to load __tid.

(cherry picked from commit 1660901840)
2018-05-17 14:05:51 +02:00
Joseph Myers 02f0dd83a4 Fix signed integer overflow in random_r (bug 17343).
Bug 17343 reports that stdlib/random_r.c has code with undefined
behavior because of signed integer overflow on int32_t.  This patch
changes the code so that the possibly overflowing computations use
unsigned arithmetic instead.

Note that the bug report refers to "Most code" in that file.  The
places changed in this patch are the only ones I found where I think
such overflow can occur.

Tested for x86_64 and x86.

	[BZ #17343]
	* stdlib/random_r.c (__random_r): Use unsigned arithmetic for
	possibly overflowing computations.

(cherry picked from commit 8a07b0c43c)
2018-05-17 14:04:58 +02:00
Adhemerval Zanella 3241353ab2 i386: Fix i386 sigaction sa_restorer initialization (BZ#21269)
This patch fixes the i386 sa_restorer field initialization for sigaction
syscall for kernel with vDSO.  As described in bug report, i386 Linux
(and compat on x86_64) interprets SA_RESTORER clear with nonzero
sa_restorer as a request for stack switching if the SS segment is 'funny'.
This means that anything that tries to mix glibc's signal handling with
segmentation (for instance through modify_ldt syscall) is randomly broken
depending on what values lands in sa_restorer.

The testcase added  is based on Linux test tools/testing/selftests/x86/ldt_gdt.c,
more specifically in do_multicpu_tests function.  The main changes are:

  - C11 atomics instead of plain access.

  - Remove x86_64 support which simplifies the syscall handling and fallbacks.

  - Replicate only the test required to trigger the issue.

Checked on i686-linux-gnu.

	[BZ #21269]
	* sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269.
	* sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear
	sa_restorer for vDSO case.
	* sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file.

(cherry picked from commit 68448be208)
2018-05-17 14:01:57 +02:00
DJ Delorie 677e6d13e0 [BZ #22342] Fix netgroup cache keys.
Unlike other nscd caches, the netgroup cache contains two types of
records - those for "iterate through a netgroup" (i.e. setnetgrent())
and those for "is this user in this netgroup" (i.e. innetgr()),
i.e. full and partial records.  The timeout code assumes these records
have the same key for the group name, so that the collection of records
that is "this netgroup" can be expired as a unit.

However, the keys are not the same, as the in-netgroup key is generated
by nscd rather than being passed to it from elsewhere, and is generated
without the trailing NUL.  All other keys have the trailing NUL, and as
noted in the linked BZ, debug statements confirm that two keys for the
same netgroup are added to the cache with two different lengths.

The result of this is that as records in the cache expire, the purge
code only cleans out one of the two types of entries, resulting in
stale, possibly incorrect, and possibly inconsistent cache data.

The patch simply includes the existing NUL in the computation for the
key length ('key' points to the char after the NUL, and 'group' to the
first char of the group, so 'key-group' includes the first char to the
NUL, inclusive).

	[BZ #22342]
	* nscd/netgroupcache.c (addinnetgrX): Include trailing NUL in
	key value.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 1c81d55fc4)
2018-05-17 14:00:28 +02:00
Andrew Senkevich 71d339cb86 Fix i386 memmove issue (bug 22644).
[BZ #22644]
	* sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: Fixed
	branch conditions.
	* string/test-memmove.c (do_test2): New testcase.

(cherry picked from commit cd66c0e584)
2018-05-17 13:58:22 +02:00
Andreas Schwab 31e2d15b80 Fix crash in resolver on memory allocation failure (bug 23005)
(cherry picked from commit f178e59fa5)
2018-05-17 13:57:29 +02:00
Jesse Hathaway 1f7c4748d6 getlogin_r: return early when linux sentinel value is set
When there is no login uid Linux sets /proc/self/loginid to the sentinel
value of, (uid_t) -1. If this is set we can return early and avoid
needlessly looking up the sentinel value in any configured nss
databases.

Checked on aarch64-linux-gnu.

	* sysdeps/unix/sysv/linux/getlogin_r.c (__getlogin_r_loginuid): Return
	early when linux sentinel value is set.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit cc8a1620eb)
2018-05-17 13:56:33 +02:00
Florian Weimer 7e7a5f0bcd resolv: Fully initialize struct mmsghdr in send_dg [BZ #23037]
(cherry picked from commit 583a27d525)
2018-05-17 13:54:45 +02:00
Arjun Shankar d300041c53 Update NEWS for bug 22343 and bug 22774 2018-02-08 17:04:17 +01:00
Arjun Shankar 01ba6f5076 Fix integer overflows in internal memalign and malloc [BZ #22343] [BZ #22774]
When posix_memalign is called with an alignment less than MALLOC_ALIGNMENT
and a requested size close to SIZE_MAX, it falls back to malloc code
(because the alignment of a block returned by malloc is sufficient to
satisfy the call).  In this case, an integer overflow in _int_malloc leads
to posix_memalign incorrectly returning successfully.

Upon fixing this and writing a somewhat thorough regression test, it was
discovered that when posix_memalign is called with an alignment larger than
MALLOC_ALIGNMENT (so it uses _int_memalign instead) and a requested size
close to SIZE_MAX, a different integer overflow in _int_memalign leads to
posix_memalign incorrectly returning successfully.

Both integer overflows affect other memory allocation functions that use
_int_malloc (one affected malloc in x86) or _int_memalign as well.

This commit fixes both integer overflows.  In addition to this, it adds a
regression test to guard against false successful allocations by the
following memory allocation functions when called with too-large allocation
sizes and, where relevant, various valid alignments:
malloc, realloc, calloc, reallocarray, memalign, posix_memalign,
aligned_alloc, valloc, and pvalloc.

(cherry picked from commit 8e448310d7)
2018-02-08 15:47:05 +01:00
Tulio Magno Quites Machado Filho 400747ec4f Merge branch 'release/2.26/master' into ibm/2.26/master 2018-02-02 15:18:56 -02:00
Tulio Magno Quites Machado Filho bbabb868cd powerpc: Fix syscalls during early process initialization [BZ #22685]
The tunables framework needs to execute syscall early in process
initialization, before the TCB is available for consumption.  This
behavior conflicts with powerpc{|64|64le}'s lock elision code, that
checks the TCB before trying to abort transactions immediately before
executing a syscall.

This patch adds a powerpc-specific implementation of __access_noerrno
that does not abort transactions before the executing syscall.

Tested on powerpc{|64|64le}.

	[BZ #22685]
	* sysdeps/powerpc/powerpc32/sysdep.h (ABORT_TRANSACTION_IMPL): Renamed
	from ABORT_TRANSACTION.
	(ABORT_TRANSACTION): Redirect to ABORT_TRANSACTION_IMPL.
	* sysdeps/powerpc/powerpc64/sysdep.h (ABORT_TRANSACTION,
	ABORT_TRANSACTION_IMPL): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/not-errno.h: New file.  Reuse
	Linux code, but remove the code that aborts transactions.

Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
Tested-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 4612268a0a)
2018-01-29 14:50:19 -02:00
Gabriel F. T. Gomes 38e08dc3e0 Provide a C++ version of iseqsig (bug 22377)
In C++ mode, __MATH_TG cannot be used for defining iseqsig, because
__MATH_TG relies on __builtin_types_compatible_p, which is a C-only
builtin.  This is true when float128 is provided as an ABI-distinct type
from long double.

Moreover, the comparison macros from ISO C take two floating-point
arguments, which need not have the same type.  Choosing what underlying
function to call requires evaluating the formats of the arguments, then
selecting which is wider.  The macro __MATH_EVAL_FMT2 provides this
information, however, only the type of the macro expansion is relevant
(actually evaluating the expression would be incorrect).

This patch provides a C++ version of iseqsig, in which only the type of
__MATH_EVAL_FMT2 (__typeof or decltype) is used as a template parameter
for __iseqsig_type.  This function calls the appropriate underlying
function.

Tested for powerpc64le and x86_64.

	[BZ #22377]
	* math/Makefile [C++] (tests): Add test for iseqsig.
	* math/math.h [C++] (iseqsig): New implementation, which does
	not rely on __MATH_TG/__builtin_types_compatible_p.
	* math/test-math-iseqsig.cc: New file.
	* sysdeps/powerpc/powerpc64le/Makefile
	(CFLAGS-test-math-iseqsig.cc): New variable.

(cherry picked from commit c85e54ac6c)
2018-01-29 14:50:18 -02:00
Szabolcs Nagy a5db85df69 [AARCH64] Rewrite elf_machine_load_address using _DYNAMIC symbol
This patch rewrites aarch64 elf_machine_load_address to use special _DYNAMIC
symbol instead of _dl_start.

The static address of _DYNAMIC symbol is stored in the first GOT entry.
Here is the change which makes this solution work (part of binutils 2.24):
https://sourceware.org/ml/binutils/2013-06/msg00248.html

i386, x86_64 targets use the same method to do this as well.

The original implementation relies on a trick that R_AARCH64_ABS32 relocation
being resolved at link time and the static address fits in the 32bits.
However, in LP64, normally, the address is defined to be 64 bit.

Here is the C version one which should be portable in all cases.

	* sysdeps/aarch64/dl-machine.h (elf_machine_load_address): Use
	_DYNAMIC symbol to calculate load address.

(cherry picked from commit a68ba2f3cd)
2018-01-26 12:03:49 +01:00
H.J. Lu 51600b0fd7 NEWS: Add an entry for [BZ #22715] 2018-01-19 09:46:16 -08:00
H.J. Lu 0bd4b39247 x86-64: Properly align La_x86_64_retval to VEC_SIZE [BZ #22715]
_dl_runtime_profile calls _dl_call_pltexit, passing a pointer to
La_x86_64_retval which is allocated on stack.  The lrv_vector0
field in La_x86_64_retval must be aligned to size of vector register.
When allocating stack space for La_x86_64_retval, we need to make sure
that the address of La_x86_64_retval + RV_VECTOR0_OFFSET is aligned to
VEC_SIZE.  This patch checks the alignment of the lrv_vector0 field
and pads the stack space if needed.

Tested with x32 and x86-64 on SSE4, AVX and AVX512 machines.  It fixed

FAIL: elf/tst-audit10
FAIL: elf/tst-audit4
FAIL: elf/tst-audit5
FAIL: elf/tst-audit6
FAIL: elf/tst-audit7

on x32 AVX512 machine.

(cherry picked from commit 207a72e298)

	[BZ #22715]
	* sysdeps/x86_64/dl-trampoline.h (_dl_runtime_profile): Properly
	align La_x86_64_retval to VEC_SIZE.
2018-01-19 09:41:51 -08:00
Florian Weimer de51f431ed nptl/tst-thread-exit-clobber: Run with any C++ compiler
We do not need thread_local support in the C++11 comiler, and the
minimum GCC version for glibc has C++11 support (if it has C++ support).

(cherry picked from commit 10d200dbac)
2018-01-17 10:32:14 +01:00
Florian Weimer 6311c54e3a nptl/tst-minstack-throw: Compile in C++11 mode with GNU extensions
(cherry picked from commit b725132d2b)
2018-01-16 08:08:38 +01:00
Florian Weimer 247c1ddd30 nptl: Add PTHREAD_MIN_STACK C++ throw test [BZ #22636]
(cherry picked from commit 860b0240a5)
2018-01-15 16:06:36 +01:00
Florian Weimer 3feefa1cc8 nptl: Add tst-minstack-cancel, tst-minstack-exit [BZ #22636]
I verified that without the guard accounting change in commit
630f4cc3aa (Fix stack guard size
accounting) and RTLD_NOW for libgcc_s introduced by commit
f993b87540 (nptl: Open libgcc.so with
RTLD_NOW during pthread_cancel), the tst-minstack-cancel test fails on
an AVX-512F machine.  tst-minstack-exit still passes, and either of
the mentioned commit by itself frees sufficient stack space to make
tst-minstack-cancel pass, too.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit d8b778907e)
2018-01-15 16:06:35 +01:00
Florian Weimer 89d6a65833 nptl: Open libgcc.so with RTLD_NOW during pthread_cancel [BZ #22636]
Disabling lazy binding reduces stack usage during unwinding.

Note that RTLD_NOW only makes a difference if libgcc.so has not
already been loaded, so this is only a partial fix.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit f993b87540)
2018-01-15 16:06:35 +01:00
Szabolcs Nagy 0b5cdd80c1 [BZ #22637] Fix stack guard size accounting
Previously if user requested S stack and G guard when creating a
thread, the total mapping was S and the actual available stack was
S - G - static_tls, which is not what the user requested.

This patch fixes the guard size accounting by pretending the user
requested S+G stack.  This way all later logic works out except
when reporting the user requested stack size (pthread_getattr_np)
or when computing the minimal stack size (__pthread_get_minstack).

Normally this will increase thread stack allocations by one page.
TLS accounting is not affected, that will require a separate fix.

	[BZ #22637]
	* nptl/descr.h (stackblock, stackblock_size): Update comments.
	* nptl/allocatestack.c (allocate_stack): Add guardsize to stacksize.
	* nptl/nptl-init.c (__pthread_get_minstack): Remove guardsize from
	stacksize.
	* nptl/pthread_getattr_np.c (pthread_getattr_np): Likewise.

(cherry picked from commit 630f4cc3aa)
2018-01-15 16:06:32 +01:00
Florian Weimer 477cd2b183 nptl: Add test for callee-saved register restore in pthread_exit
GCC PR 83641 results in a miscompilation of libpthread, which
causes pthread_exit not to restore callee-saved registers before
running destructors for objects on the stack.  This test detects
this situation:

info: unsigned int, direct pthread_exit call
tst-thread-exit-clobber.cc:80: numeric comparison failure
   left: 4148288912 (0xf741dd90); from: value
  right: 1600833940 (0x5f6ac994); from: magic_values.v2
info: double, direct pthread_exit call
info: unsigned int, indirect pthread_exit call
info: double, indirect pthread_exit call
error: 1 test failures

(cherry picked from commit 579396ee08)
2018-01-15 15:24:38 +01:00
Florian Weimer c247c53665 Synchronize support/ infrastructure with master
This commit updates the support/ subdirectory to
commit 1a51e46e4a
on the master branch.
2018-01-15 15:23:35 +01:00
Dmitry V. Levin fabef2edbc linux: make getcwd(3) fail if it cannot obtain an absolute path [BZ #22679]
Currently getcwd(3) can succeed without returning an absolute path
because the underlying getcwd syscall, starting with linux commit
v2.6.36-rc1~96^2~2, may succeed without returning an absolute path.

This is a conformance issue because "The getcwd() function shall
place an absolute pathname of the current working directory
in the array pointed to by buf, and return buf".

This is also a security issue because a non-absolute path returned
by getcwd(3) causes a buffer underflow in realpath(3).

Fix this by checking the path returned by getcwd syscall and falling
back to generic_getcwd if the path is not absolute, effectively making
getcwd(3) fail with ENOENT.  The error code is chosen for consistency
with the case when the current directory is unlinked.

[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.

(cherry picked from commit 52a713fdd0)
2018-01-12 14:49:49 +00:00
Florian Weimer 7d2672a47b Add missing reference to bug 20532 2018-01-12 13:32:51 +01:00
Adhemerval Zanella 268bd5f053 ia64: Fix memchr for large input sizes (BZ #22603)
Current optimized ia64 memchr uses a strategy to check for last address
by adding the input one with expected size.  However it does not take
care for possible overflow.

It was triggered by 3038145ca2 where default rawmemchr now uses memchr
(p, c, (size_t)-1).

This patch fixes it by implement a satured addition where overflows
sets the maximum pointer size to UINTPTR_MAX.

Checked on ia64-linux-gnu where it fixes both stratcliff and
test-rawmemchr failures.

	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
	James Clarke <jrtc27@jrtc27.com>

	[BZ #22603]
	* sysdeps/ia64/memchr.S (__memchr): Avoid overflow in pointer
	addition.

(cherry picked from commit 3bb1ef58b9)
2018-01-10 21:56:05 +01:00
Dmitry V. Levin 989f59db39 tst-ttyname: skip the test when /dev/ptmx is not available
* sysdeps/unix/sysv/linux/tst-ttyname.c (do_in_chroot_1): Skip the
test instead of failing in case of ENOENT returned by posix_openpt.

(cherry picked from commit d7ff3f11b6)
2018-01-08 22:02:53 +00:00
Florian Weimer bfda785841 Mention CVE-2017-16997 in ChangeLog 2018-01-04 13:41:27 +01:00
Aurelien Jarno 7a64940a59 tst-realloc: do not check for errno on success [BZ #22611]
POSIX explicitly says that applications should check errno only after
failure, so the errno value can be clobbered on success as long as it
is not set to zero.

Changelog:
	[BZ #22611]
	* malloc/tst-realloc.c (do_test): Remove the test checking that errno
	is unchanged on success.
(cherry picked from commit f8aa69be44)
2017-12-31 21:21:27 +01:00
Aurelien Jarno 4ebd0c4191 elf: Check for empty tokens before dynamic string token expansion [BZ #22625]
The fillin_rpath function in elf/dl-load.c loops over each RPATH or
RUNPATH tokens and interprets empty tokens as the current directory
("./"). In practice the check for empty token is done *after* the
dynamic string token expansion. The expansion process can return an
empty string for the $ORIGIN token if __libc_enable_secure is set
or if the path of the binary can not be determined (/proc not mounted).

Fix that by moving the check for empty tokens before the dynamic string
token expansion. In addition, check for NULL pointer or empty strings
return by expand_dynamic_string_token.

The above changes highlighted a bug in decompose_rpath, an empty array
is represented by the first element being NULL at the fillin_rpath
level, but by using a -1 pointer in decompose_rpath and other functions.

Changelog:
	[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.
(cherry picked from commit 3e3c904dae)
2017-12-30 22:07:01 +01:00
Dmitry V. Levin 98f244e245 elf: do not substitute dst in $LD_LIBRARY_PATH twice [BZ #22627]
Starting with commit
glibc-2.18.90-470-g2a939a7e6d81f109d49306bc2e10b4ac9ceed8f9 that
introduced substitution of dynamic string tokens in fillin_rpath,
_dl_init_paths invokes _dl_dst_substitute for $LD_LIBRARY_PATH twice:
the first time it's called directly, the second time the result
is passed on to fillin_rpath which calls expand_dynamic_string_token
which in turn calls _dl_dst_substitute, leading to the following
behaviour:

$ mkdir -p /tmp/'$ORIGIN' && cd /tmp/'$ORIGIN' &&
  echo 'int main(){}' |gcc -xc - &&
  strace -qq -E LD_LIBRARY_PATH='$ORIGIN' -e /open ./a.out
open("/tmp//tmp/$ORIGIN/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/tmp//tmp/$ORIGIN/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/tmp//tmp/$ORIGIN/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/tmp//tmp/$ORIGIN/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3

Fix this by removing the direct _dl_dst_substitute invocation.

* elf/dl-load.c (_dl_init_paths): Remove _dl_dst_substitute preparatory
code and invocation.

(cherry picked from commit bb195224ac)
2017-12-22 14:56:36 +00:00
Florian Weimer 069c3dd05a tst-ttyname: Fix namespace setup for Fedora
On Fedora, the previous initialization sequence did not work and
resulted in failures like:

info:  entering chroot 1
info:    testcase: basic smoketest
info:      ttyname: PASS {name="/dev/pts/5", errno=0}
info:      ttyname_r: PASS {name="/dev/pts/5", ret=0, errno=0}
error: ../sysdeps/unix/sysv/linux/tst-ttyname.c:122: write (setroups, "deny"): Operation not permitted
info:  entering chroot 2
error: ../sysdeps/unix/sysv/linux/tst-ttyname.c:122: write (setroups, "deny"): Operation not permitted
error: 2 test failures

Reviewed-by: Christian Brauner <christian.brauner@ubuntu.com>
(cherry picked from commit 8db7f48cb7)
2017-12-22 15:28:08 +01:00
Luke Shumaker 89e75d5eda linux ttyname{_r}: Add tests
Add a new tst-ttyname test that includes several named sub-testcases.

This patch is ordered after the patches with the fixes that it tests for (to
avoid breaking `git bisect`), but for reference, here's how each relevant change
so far affected the testcases in this commit, starting with
15e9a4f378:

  |                                 | before  |         | make checks | don't |
  |                                 | 15e9a4f | 15e9a4f | consistent  | bail  |
  |---------------------------------+---------+---------+-------------+-------|
  | basic smoketest                 | PASS    | PASS    | PASS        | PASS  |
  | no conflict, no match           | PASS[1] | PASS    | PASS        | PASS  |
  | no conflict, console            | PASS    | FAIL!   | FAIL        | PASS! |
  | conflict, no match              | FAIL    | PASS!   | PASS        | PASS  |
  | conflict, console               | FAIL    | FAIL    | FAIL        | PASS! |
  | with readlink target            | PASS    | PASS    | PASS        | PASS  |
  | with readlink trap; fallback    | FAIL    | FAIL    | FAIL        | PASS! |
  | with readlink trap; no fallback | FAIL    | PASS!   | PASS        | PASS  |
  | with search-path trap           | FAIL    | FAIL    | PASS!       | PASS  |
  |---------------------------------+---------+---------+-------------+-------|
  |                                 | 4/9     | 5/9     | 6/9         | 9/9   |

  [1]: 15e9a4f introduced a semantic that, under certain failure
       conditions, ttyname sets errno=ENODEV, where previously it didn't
       set errno; it's not quite fair to hold "before 15e9a4f" ttyname to
       those new semantics.  This testcase actually fails, but would have
       passed if we tested for the old the semantics.

Each of the failing tests before 15e9a4f are all essentially the same bug: that
it returns a PTY slave with the correct minor device number, but from the wrong
devpts filesystem instance.

15e9a4f sought to fix this, but missed several of the cases that can cause this
to happen, and also broke the case where both the erroneous PTY and the correct
PTY exist.

Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
(cherry picked from commit d9611e3085)
2017-12-22 15:28:07 +01:00
Luke Shumaker 4f987759d1 linux ttyname{_r}: Don't bail prematurely [BZ #22145]
Commit 15e9a4f378 introduced logic for ttyname()
sending back ENODEV to signal that we can't get a name for the TTY because we
inherited it from a different mount namespace.

However, just because we inherited it from a different mount namespace and it
isn't available at its original path, doesn't mean that its name is unknowable;
we can still try to find it by allowing the normal fall back on iterating
through devices.

An example scenario where this happens is with "/dev/console" in containers.
It's a common practice among container managers to allocate a PTY master/slave
pair in the host's mount namespace (the slave having a path like "/dev/pty/$X"),
bind mount the slave to "/dev/console" in the container's mount namespace, and
send the slave FD to a process in the container. Inside of the
container, the slave-end isn't available at its original path ("/dev/pts/$X"),
since the container mount namespace has a separate devpts instance from the host
(that path may or may not exist in the container; if it does exist, it's not the
 same PTY slave device). Currently ttyname{_r} sees that the file at the
original "/dev/pts/$X" path doesn't match the FD passed to it, and fails early
and gives up, even though if it kept searching it would find the TTY at
"/dev/console". Fix that; don't have the ENODEV path force an early return
inhibiting the fall-back search.

This change is based on the previous patch that adds use of is_mytty in
getttyname and getttyname_r. Without that change, this effectively reverts
15e9a4f, which made us disregard the false similarity of file pointed to by
"/proc/self/fd/$Y", because if it doesn't bail prematurely then that file
("/dev/pts/$X") will just come up again anyway in the fall-back search.

Reviewed-by: Christian Brauner <christian.brauner@ubuntu.com>
(cherry picked from commit a09dfc19ed)
2017-12-22 15:28:07 +01:00
Luke Shumaker f43ead291c linux ttyname{_r}: Make tty checks consistent
In the ttyname and ttyname_r routines on Linux, at several points it needs to
check if a given TTY is the TTY we are looking for. It used to be that this
check was (to see if `maybe` is `mytty`):

       __xstat64(_STAT_VER, maybe_filename, &maybe) == 0
    #ifdef _STATBUF_ST_RDEV
       && S_ISCHR(maybe.st_mode) && maybe.st_rdev == mytty.st_rdev
    #else
       && maybe.st_ino == mytty.st_ino && maybe.st_dev == mytty.st_dev
    #endif

This check appears in several places.

Then, one of the changes made in commit 15e9a4f378
was to change that check to:

       __xstat64(_STAT_VER, maybe_filename, &maybe) == 0
    #ifdef _STATBUF_ST_RDEV
       && S_ISCHR(maybe.st_mode) && maybe.st_rdev == mytty.st_rdev
    #endif
       && maybe.st_ino == mytty.st_ino && maybe.st_dev == mytty.st_dev

That is, it made the st_ino and st_dev parts of the check happen even if we have
the st_rdev member. This is an important change, because the kernel allows
multiple devpts filesystem instances to be created; a device file in one devpts
instance may share the same st_rdev with a file in another devpts instance, but
they aren't the same file.

This check appears twice in each file (ttyname.c and ttyname_r.c), once (in
ttyname and __ttyname_r) to check if a candidate file found by inspecting /proc
is the desired TTY, and once (in getttyname and getttyname_r) to check if a
candidate file found by searching /dev is the desired TTY. However, 15e9a4f
only updated the checks for files found via /proc; but the concern about
collisions between devpts instances is just as valid for files found via /dev.

So, update all 4 occurrences the check to be consistent with the version of the
check introduced in 15e9a4f. Make it easy to keep all 4 occurrences of the
check consistent by pulling it in to a static inline function, is_mytty.

Reviewed-by: Christian Brauner <christian.brauner@ubuntu.com>
(cherry picked from commit 2fbce9c203)
2017-12-22 15:27:57 +01:00
Luke Shumaker bd81a9d1e9 linux ttyname: Change return type of is_pty from int to bool
is_pty returning a bool is fine since there's no possible outcome other than
true or false, and bool is used throughout the codebase.

Reviewed-by: Christian Brauner <christian.brauner@ubuntu.com>
(cherry picked from commit d10d6cab16)
2017-12-22 15:23:52 +01:00
Luke Shumaker 1f0ba053ed linux ttyname: Update a reference to kernel docs for kernel 4.10
Linux 4.10 moved many of the documentation files around.

4.10 came out between the time the patch adding the comment (commit
15e9a4f378) was submitted and the time
it was applied (in February, January, and March 2017; respectively).

Reviewed-by: Christian Brauner <christian.brauner@ubuntu.com>
(cherry picked from commit 9b5a87502d)
2017-12-22 15:23:41 +01:00
Luke Shumaker 58a63062a0 manual: Update to mention ENODEV for ttyname and ttyname_r
Commit 15e9a4f378 introduced ENODEV as a possible
error condition for ttyname and ttyname_r. Update the manual to mention this GNU
extension.

Reviewed-by: Christian Brauner <christian.brauner@ubuntu.com>
(cherry picked from commit 495a56fdeb)
2017-12-22 15:23:29 +01:00
Florian Weimer 5da0de4de5 Synchronize support/ infrastructure with master
This commit updates the support/ subdirectory to
commit bad7a0c81f
on the master branch.
2017-12-22 15:22:17 +01:00
Florian Weimer 633e2f7f3d elf: Count components of the expanded path in _dl_init_path [BZ #22607]
(cherry picked from commit 3ff3dfa5af)
2017-12-16 12:58:10 +01:00
Florian Weimer 43b3cb59b2 elf: Compute correct array size in _dl_init_paths [BZ #22606]
(cherry picked from commit 8a0b17e48b)
2017-12-16 12:58:02 +01:00
Florian Weimer bda48606ee <array_length.h>: New array_length and array_end macros
(cherry picked from commit c94a5688fb)
2017-12-16 12:57:38 +01:00
H.J. Lu 5a2779f9bc i386: Regenerate libm-test-ulps for for gcc 7
Regenerate libm-test-ulps for gcc 7 with "-m32 -O2 -march=i586".

	* sysdeps/i386/fpu/libm-test-ulps: Regenerated for GCC 7 with
	"-O2 -march=i586".

(cherry picked from commit 63d3b468c1)
2017-12-14 13:46:39 +01:00
Adhemerval Zanella 828efe7842 Update IA64 libm-test-ulps
Ran on Itanium Processor 9020, GCC 7.2.1.

	* sysdeps/ia64/fpu/libm-test-ulps: Update.

Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2017-12-13 08:52:36 -02:00
Adhemerval Zanella 3a0b7d09db ia64: Fix thread stack allocation permission set (BZ #21672)
This patch fixes ia64 failures on thread exit by madvise the required
area taking in consideration its disjoing stacks
(NEED_SEPARATE_REGISTER_STACK).  Also the snippet that setup the
madvise call to advertise kernel the area won't be used anymore in
near future is reallocated in allocatestack.c (for consistency to
put all stack management function in one place).

Checked on x86_64-linux-gnu and i686-linux-gnu for sanity (since
it is not expected code changes for architecture that do not
define NEED_SEPARATE_REGISTER_STACK) and also got a report that
it fixes ia64-linux-gnu failures from Sergei Trofimovich
<slyfox@gentoo.org>.

	[BZ #21672]
	* nptl/allocatestack.c [_STACK_GROWS_DOWN] (setup_stack_prot):
	Set to use !NEED_SEPARATE_REGISTER_STACK as well.
	(advise_stack_range): New function.
	* nptl/pthread_create.c (START_THREAD_DEFN): Move logic to mark
	stack non required to advise_stack_range at allocatestack.c

(cherry pick from commit 01b87c656f)
2017-12-13 08:52:34 -02:00
Adhemerval Zanella d8b79b0eb1 posix: Fix mmap for m68k and ia64 (BZ#21908)
Default semantic for mmap2 syscall is to take the offset in 4096-byte
units.  However m68k and ia64 mmap2 implementation take in the
configured pageunit units and for both architecture it can be
different values.

This patch fixes the m68k runtime discover of mmap2 offset unit
and adds the ia64 definition to find it at runtime.

Checked the basic tst-mmap and tst-mmap-offset on m68k (the system
is configured with 4k, so current code is already passing on this
system) and a sanity check on x86_64-linux-gnu (which should not be
affected by this change).  Sergei also states that ia64 loader now
work correctly with this change.

	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
	Sergei Trofimovich  <slyfox@inbox.ru>

	* sysdeps/unix/sysv/linux/m68k/mmap_internal.h (MMAP2_PAGE_SHIFT):
	Rename to MMAP2_PAGE_UNIT.
	* sysdeps/unix/sysv/linux/mmap.c: Include mmap_internal iff
	__OFF_T_MATCHES_OFF64_T is not defined.
	* sysdeps/unix/sysv/linux/mmap_internal.h (page_unit): Declare as
	uint64_t.
	(MMAP2_PAGE_UNIT) [MMAP2_PAGE_UNIT == -1]: Redefine to page_unit.
	(page_unit) [MMAP2_PAGE_UNIT != -1]: Remove definition.

(cherry picked from commit 1f14d0c3dd)
2017-12-13 08:52:32 -02:00
James Clarke c48e2e558e ia64: Add ipc_priv.h header to set __IPC_64 to zero
When running strace, IPC_64 was set in the command, but ia64 is
an architecture where CONFIG_ARCH_WANT_IPC_PARSE_VERSION *isn't* set
in the kernel, so ipc_parse_version just returns IPC_64 without
clearing the IPC_64 bit in the command.

	* sysdeps/unix/sysv/linux/ia64/ipc_priv.h: New file defining
	__IPC_64 to 0 to avoid IPC_64 being set.

Signed-off-by: James Clarke <jrtc27@jrtc27.com>

(cherry picked from commit 89bd8016b3)
2017-12-12 19:43:00 +01:00
H.J. Lu 73a9236361 Silence -O3 -Wall warning in malloc/hooks.c with GCC 7 [BZ #22052]
realloc_check has

  unsigned char *magic_p;
...
  __libc_lock_lock (main_arena.mutex);
  const mchunkptr oldp = mem2chunk_check (oldmem, &magic_p);
  __libc_lock_unlock (main_arena.mutex);
  if (!oldp)
    malloc_printerr ("realloc(): invalid pointer");
...
  if (newmem == NULL)
    *magic_p ^= 0xFF;

with

static void malloc_printerr(const char *str) __attribute__ ((noreturn));

GCC 7 -O3 warns

hooks.c: In function ‘realloc_check’:
hooks.c:352:14: error: ‘magic_p’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
     *magic_p ^= 0xFF;

due to the GCC bug:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82090

This patch silences GCC 7 by using DIAG_IGNORE_NEEDS_COMMENT.

	[BZ #22052]
	* malloc/hooks.c (realloc_check): Use DIAG_IGNORE_NEEDS_COMMENT
	to silence -O3 -Wall warning with GCC 7.

(cherry picked from commit 8e57c9432a)
2017-12-06 16:15:47 +01:00
Arjun Shankar df8c219cb9 Fix integer overflow in malloc when tcache is enabled [BZ #22375]
When the per-thread cache is enabled, __libc_malloc uses request2size (which
does not perform an overflow check) to calculate the chunk size from the
requested allocation size. This leads to an integer overflow causing malloc
to incorrectly return the last successfully allocated block when called with
a very large size argument (close to SIZE_MAX).

This commit uses checked_request2size instead, removing the overflow.

(cherry picked from commit 34697694e8)
2017-12-06 07:44:51 +01:00
Aurelien Jarno 0890d5379c Update NEWS to add CVE-2017-15804 entry
(cherry picked from commit 15e84c63c0)
2017-12-01 21:56:32 +01:00
Florian Weimer a9f35ac127 posix/tst-glob-tilde.c: Add test for bug 22332
(cherry picked from commit 2fac6a6cd5)
2017-12-01 21:56:24 +01:00
Paul Eggert f1cf98b583 glob: Fix buffer overflow during GLOB_TILDE unescaping [BZ #22332]
(cherry picked from commit a159b53fa0)
2017-12-01 21:51:27 +01:00
Florian Weimer 6f9f307b5d Update NEWS and ChangeLog for CVE-2017-15671
(cherry picked from commit 914c9994d2)
2017-12-01 21:50:09 +01:00
Wilco Dijkstra f312f235d5 Add single-threaded path to _int_malloc
This patch adds single-threaded fast paths to _int_malloc.

	* malloc/malloc.c (_int_malloc): Add SINGLE_THREAD_P path.

(cherry-picked 905a7725e9)
2017-11-28 19:16:19 +05:30
Wilco Dijkstra 3664f34346 Add single-threaded path to malloc/realloc/calloc/memalloc
This patch adds a single-threaded fast path to malloc, realloc,
calloc and memalloc.  When we're single-threaded, we can bypass
arena_get (which always locks the arena it returns) and just use
the main arena.  Also avoid retrying a different arena since
there is just the main arena.

	* malloc/malloc.c (__libc_malloc): Add SINGLE_THREAD_P path.
	(__libc_realloc): Likewise.
	(_mid_memalign): Likewise.
	(__libc_calloc): Likewise.

(cherry-picked 3f6bb8a32e)
2017-11-28 19:15:59 +05:30
Wilco Dijkstra fe161827c5 Fix build issue with SINGLE_THREAD_P
Add sysdep-cancel.h include.

	* malloc/malloc.c (sysdep-cancel.h): Add include.

(cherry-picked 6d43de4b85)
2017-11-28 19:15:13 +05:30
Wilco Dijkstra e759c32364 Add single-threaded path to _int_free
This patch adds single-threaded fast paths to _int_free.
Bypass the explicit locking for larger allocations.

	* malloc/malloc.c (_int_free): Add SINGLE_THREAD_P fast paths.

(cherry-picked from a15d53e2de)
2017-11-28 19:14:48 +05:30
Wilco Dijkstra 0e24837040 Fix deadlock in _int_free consistency check
This patch fixes a deadlock in the fastbin consistency check.
If we fail the fast check due to concurrent modifications to
the next chunk or system_mem, we should not lock if we already
have the arena lock.  Simplify the check to make it obviously
correct.

	* malloc/malloc.c (_int_free): Fix deadlock bug in consistency check.

(cherry-pick d74e6f6c0d)
2017-11-28 19:13:49 +05:30
Florian Weimer 590b24e6e0 malloc: Resolve compilation failure in NDEBUG mode
In _int_free, the locked variable is not used if NDEBUG is defined.

(cherry-picked from 24cffce736)
2017-11-28 19:12:19 +05:30
Florian Weimer 533afac929 malloc: Change top_check return type to void
After commit ec2c1fcefb,
(malloc: Abort on heap corruption, without a backtrace), the function
always returns 0.

(cherry-picked from 5129873a8e)
2017-11-28 19:11:30 +05:30
Florian Weimer 675e8785dc malloc: Remove corrupt arena flag
This is no longer needed because we now abort immediately
once heap corruption is detected.

(cherry-picked from a9da0bb266)
2017-11-28 19:10:16 +05:30
Florian Weimer ee717ed23d malloc: Remove check_action variable [BZ #21754]
Clean up calls to malloc_printerr and trim its argument list.

This also removes a few bits of work done before calling
malloc_printerr (such as unlocking operations).

The tunable/environment variable still enables the lightweight
additional malloc checking, but mallopt (M_CHECK_ACTION)
no longer has any effect.

(cherry-picked from ac3ed168d0)
2017-11-28 19:09:25 +05:30
Florian Weimer 8788996793 malloc: Abort on heap corruption, without a backtrace [BZ #21754]
The stack trace printing caused deadlocks and has been itself been
targeted by code execution exploits.

(cherry-picked from ec2c1fcefb)
2017-11-28 19:07:55 +05:30
Tulio Magno Quites Machado Filho 962a4b638f Merge branch 'release/2.26/master' into ibm/2.26/master 2017-11-24 19:31:41 -02:00
Tulio Magno Quites Machado Filho aaa2eb83b8 powerpc: Update AT_HWCAP2 bits
Linux commit ID cba6ac4869e45cc93ac5497024d1d49576e82666 reserved a new
bit for a scenario where transactional memory is available, but the
suspended state is disabled.

	* sysdeps/powerpc/bits/hwcap.h (PPC_FEATURE2_HTM_NO_SUSPEND): New
	macro.

(cherry picked from commit df0c40ee3a)

Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
2017-11-24 18:30:11 -02:00
Andreas Schwab 71170eba2a Add test for bug 21041
(cherry picked from commit 40c06a3d04)
2017-11-21 20:09:49 +01:00
Andreas Schwab 4db8f362c1 Fix s390 version of pt-longjmp.c
(cherry picked from commit 5797b410a8)
2017-11-21 20:09:42 +01:00
Andreas Schwab 88758c4ad3 Don't use IFUNC resolver for longjmp or system in libpthread (bug 21041)
Unlike the vfork forwarder and like the fork forwarder as in bug 19861,
there won't be a problem when the compiler does not turn this into a tail
call.

(cherry picked from commit fc5ad7024c)
2017-11-21 20:09:34 +01:00
Rajalakshmi Srinivasaraghavan 6850e9c6ba powerpc: Replace lxvd2x/stxvd2x with lvx/stvx in P7's memcpy/memmove
POWER9 DD2.1 and earlier has an issue where some cache inhibited
vector load traps to the kernel, causing a performance degradation.  To
handle this in memcpy and memmove, lvx/stvx is used for aligned
addresses instead of lxvd2x/stxvd2x.

Reference: https://patchwork.ozlabs.org/patch/814059/

	* sysdeps/powerpc/powerpc64/power7/memcpy.S: Replace
	lxvd2x/stxvd2x with lvx/stvx.
	* sysdeps/powerpc/powerpc64/power7/memmove.S: Likewise.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

(cherry picked from commit 63da5cd4a0)
2017-11-21 22:32:20 +05:30
Florian Weimer 2767ebd8bc crypt: Adjust check-local-headers.sh for nspr4 include directory [BZ #17956]
(cherry picked from commit 11c4f5010c)
2017-11-18 19:27:03 +01:00
Guido Trentalancia 82b1663202 crypt: Use NSPR header files in addition to NSS header files [BZ #17956]
When configuring and building GNU libc using the Mozilla NSS library
for cryptography (--enable-nss-crypt option), also include the
NSPR header files along with the Mozilla NSS library header files.

Finally, when running the check-local-headers test, ignore the
Mozilla NSPR library header files (used by the Mozilla NSS library).

(cherry picked from commit 57b4af1955)
2017-11-18 19:26:57 +01:00
Wilco Dijkstra a546080d51 Fix build failure on tilepro due to unsupported atomics
* malloc/malloc.c (malloc_state): Use int for have_fastchunks since
        not all targets support atomics on bool.

(cherry-picked from 2c2245b92c)
2017-11-16 12:23:00 +05:30
Siddhesh Poyarekar aa5be982ea Use relaxed atomics for malloc have_fastchunks
Currently free typically uses 2 atomic operations per call.  The have_fastchunks
flag indicates whether there are recently freed blocks in the fastbins.  This
is purely an optimization to avoid calling malloc_consolidate too often and
avoiding the overhead of walking all fast bins even if all are empty during a
sequence of allocations.  However using catomic_or to update the flag is
completely unnecessary since it can be changed into a simple boolean and
accessed using relaxed atomics.  There is no change in multi-threaded behaviour
given the flag is already approximate (it may be set when there are no blocks in
any fast bins, or it may be clear when there are free blocks that could be
consolidated).

Performance of malloc/free improves by 27% on a simple benchmark on AArch64
(both single and multithreaded). The number of load/store exclusive instructions
is reduced by 33%. Bench-malloc-thread speeds up by ~3% in all cases.

	* malloc/malloc.c (FASTCHUNKS_BIT): Remove.
	(have_fastchunks): Remove.
	(clear_fastchunks): Remove.
	(set_fastchunks): Remove.
	(malloc_state): Add have_fastchunks.
	(malloc_init_state): Use have_fastchunks.
	(do_check_malloc_state): Remove incorrect invariant checks.
	(_int_malloc): Use have_fastchunks.
	(_int_free): Likewise.
	(malloc_consolidate): Likewise.

(cherry-picked from e956075a5a)
2017-11-16 12:21:27 +05:30
Wilco Dijkstra ade53e0df7 Inline tcache functions
The functions tcache_get and tcache_put show up in profiles as they
are a critical part of the tcache code.  Inline them to give tcache
a 16% performance gain.  Since this improves multi-threaded cases
as well, it helps offset any potential performance loss due to adding
single-threaded fast paths.

	* malloc/malloc.c (tcache_put): Inline.
	(tcache_get): Inline.

(cherry-picked from commit e4dd4ace56)
2017-11-16 12:14:30 +05:30
James Clarke 77f921dac1 Fix TLS relocations against local symbols on powerpc32, sparc32 and sparc64
Normally, TLS relocations against local symbols are optimised by the linker
to be absolute.  However, gold does not do this, and so it is possible to
end up with, for example, R_SPARC_TLS_DTPMOD64 referring to a local symbol.
Since sym_map is left as null in elf_machine_rela for the special local
symbol case, the relocation handling thinks it has nothing to do, and so
the module gets left as 0.  Havoc then ensues when the variable in question
is accessed.

Before this fix, the main_local_gold program would receive a SIGBUS on
sparc64, and SIGSEGV on powerpc32.  With this fix applied, that test now
passes like the rest of them.

	* sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela):
	Assign sym_map to be map for local symbols, as TLS relocations
	use sym_map to determine whether the symbol is defined and to
	extract the TLS information.
	* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise.

(cherry picked from commit 8644588807)
2017-11-14 21:07:52 +01:00
H.J. Lu 6a094c0ff1 x86-64: Regenerate libm-test-ulps for AVX512 mathvec tests
Update libm-test-ulps for AVX512 mathvec tests by running
“make regen-ulps” on Intel Xeon processor with AVX512.

	* sysdeps/x86_64/fpu/libm-test-ulps: Regenerated.

(cherry picked from commit fcaaca412f)
2017-11-13 13:31:18 +01:00
Adhemerval Zanella a81c1156c1 nptl: Define __PTHREAD_MUTEX_{NUSERS_AFTER_KIND,USE_UNION}
This patch adds two new internal defines to set the internal
pthread_mutex_t layout required by the supported ABIS:

  1. __PTHREAD_MUTEX_NUSERS_AFTER_KIND which control whether to define
     __nusers fields before or after __kind.  The preferred value for
     is 0 for new ports and it sets __nusers before __kind.

  2. __PTHREAD_MUTEX_USE_UNION which control whether internal __spins and
     __list members will be place inside an union for linuxthreads
     compatibility.  The preferred value is 0 for ports and it sets
     to not use an union to define both fields.

It fixes the wrong offsets value for __kind value on x86_64-linux-gnu-x32.
Checked with a make check run-built-tests=no on all afected ABIs.

	[BZ #22298]
	* nptl/allocatestack.c (allocate_stack): Check if
	__PTHREAD_MUTEX_HAVE_PREV is non-zero, instead if
	__PTHREAD_MUTEX_HAVE_PREV is defined.
	* nptl/descr.h (pthread): Likewise.
	* nptl/nptl-init.c (__pthread_initialize_minimal_internal):
	Likewise.
	* nptl/pthread_create.c (START_THREAD_DEFN): Likewise.
	* sysdeps/nptl/fork.c (__libc_fork): Likewise.
	* sysdeps/nptl/pthread.h (PTHREAD_MUTEX_INITIALIZER): Likewise.
	* sysdeps/nptl/bits/thread-shared-types.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION): New
	defines.
	(__pthread_internal_list): Check __PTHREAD_MUTEX_USE_UNION instead
	of __WORDSIZE for internal layout.
	(__pthread_mutex_s): Check __PTHREAD_MUTEX_NUSERS_AFTER_KIND instead
	of __WORDSIZE for internal __nusers layout and __PTHREAD_MUTEX_USE_UNION
	instead of __WORDSIZE whether to use an union for __spins and __list
	fields.
	(__PTHREAD_MUTEX_HAVE_PREV): Define also for __PTHREAD_MUTEX_USE_UNION
	case.
	* sysdeps/aarch64/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION): New
	defines.
	* sysdeps/alpha/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/arm/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/hppa/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/ia64/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/m68k/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/microblaze/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/mips/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/nios2/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/powerpc/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/s390/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/sh/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/sparc/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/tile/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.
	* sysdeps/x86/nptl/bits/pthreadtypes-arch.h
	(__PTHREAD_MUTEX_NUSERS_AFTER_KIND, __PTHREAD_MUTEX_USE_UNION):
	Likewise.

Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

(cherry picked from commit 06be6368da)
2017-11-07 11:03:01 -02:00
Adhemerval Zanella 5712f8db26 nptl: Add tests for internal pthread_mutex_t offsets
This patch adds a new build test to check for internal fields
offsets for user visible internal field.  Although currently
the only field which is statically initialized to a non zero value
is pthread_mutex_t.__data.__kind value, the tests also check the
offset of __kind, __spins, __elision (if supported), and __list
internal member.  A internal header (pthread-offset.h) is added
to each major ABI with the reference value.

Checked on x86_64-linux-gnu and with a build check for all affected
ABIs (aarch64-linux-gnu, alpha-linux-gnu, arm-linux-gnueabihf,
hppa-linux-gnu, i686-linux-gnu, ia64-linux-gnu, m68k-linux-gnu,
microblaze-linux-gnu, mips64-linux-gnu, mips64-n32-linux-gnu,
mips-linux-gnu, powerpc64le-linux-gnu, powerpc-linux-gnu,
s390-linux-gnu, s390x-linux-gnu, sh4-linux-gnu, sparc64-linux-gnu,
sparcv9-linux-gnu, tilegx-linux-gnu, tilegx-linux-gnu-x32,
tilepro-linux-gnu, x86_64-linux-gnu, and x86_64-linux-x32).

	* nptl/pthreadP.h (ASSERT_PTHREAD_STRING,
	ASSERT_PTHREAD_INTERNAL_OFFSET): New macro.
	* nptl/pthread_mutex_init.c (__pthread_mutex_init): Add build time
	checks for internal pthread_mutex_t offsets.
	* sysdeps/aarch64/nptl/pthread-offsets.h
	(__PTHREAD_MUTEX_NUSERS_OFFSET, __PTHREAD_MUTEX_KIND_OFFSET,
	__PTHREAD_MUTEX_SPINS_OFFSET, __PTHREAD_MUTEX_ELISION_OFFSET,
	__PTHREAD_MUTEX_LIST_OFFSET): New macro.
	* sysdeps/alpha/nptl/pthread-offsets.h: Likewise.
	* sysdeps/arm/nptl/pthread-offsets.h: Likewise.
	* sysdeps/hppa/nptl/pthread-offsets.h: Likewise.
	* sysdeps/i386/nptl/pthread-offsets.h: Likewise.
	* sysdeps/ia64/nptl/pthread-offsets.h: Likewise.
	* sysdeps/m68k/nptl/pthread-offsets.h: Likewise.
	* sysdeps/microblaze/nptl/pthread-offsets.h: Likewise.
	* sysdeps/mips/nptl/pthread-offsets.h: Likewise.
	* sysdeps/nios2/nptl/pthread-offsets.h: Likewise.
	* sysdeps/powerpc/nptl/pthread-offsets.h: Likewise.
	* sysdeps/s390/nptl/pthread-offsets.h: Likewise.
	* sysdeps/sh/nptl/pthread-offsets.h: Likewise.
	* sysdeps/sparc/nptl/pthread-offsets.h: Likewise.
	* sysdeps/tile/nptl/pthread-offsets.h: Likewise.
	* sysdeps/x86_64/nptl/pthread-offsets.h: Likewise.

Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

(cherry picked from commit dff91cd45e)
2017-11-07 10:57:49 -02:00
Adhemerval Zanella bfdb34f2f2 posix: Do not use WNOHANG in waitpid call for Linux posix_spawn
As shown in some buildbot issues on aarch64 and powerpc, calling
clone (VFORK) and waitpid (WNOHANG) does not guarantee the child
is ready to be collected.  This patch changes the call back to 0
as before fe05e1cb6d fix.

This change can lead to the scenario 4.3 described in the commit,
where the waitpid call can hang undefinitely on the call.  However
this is also a very unlikely and also undefinied situation where
both the caller is trying to terminate a pid before posix_spawn
returns and the race pid reuse is triggered.  I don't see how to
correct handle this specific situation within posix_spawn.

Checked on x86_64-linux-gnu, aarch64-linux-gnu and
powerpc64-linux-gnu.

	* sysdeps/unix/sysv/linux/spawni.c (__spawnix): Use 0 instead of
	WNOHANG in waitpid call.

(cherry picked from commit aa95a2414e)
2017-11-07 10:16:43 -02:00
Adhemerval Zanella f8ee700e89 posix: Fix improper assert in Linux posix_spawn (BZ#22273)
As noted by Florian Weimer, current Linux posix_spawn implementation
can trigger an assert if the auxiliary process is terminated before
actually setting the err member:

    340   /* Child must set args.err to something non-negative - we rely on
    341      the parent and child sharing VM.  */
    342   args.err = -1;
    [...]
    362   new_pid = CLONE (__spawni_child, STACK (stack, stack_size), stack_size,
    363                    CLONE_VM | CLONE_VFORK | SIGCHLD, &args);
    364
    365   if (new_pid > 0)
    366     {
    367       ec = args.err;
    368       assert (ec >= 0);

Another possible issue is killing the child between setting the err and
actually calling execve.  In this case the process will not ran, but
posix_spawn also will not report any error:

    269
    270   args->err = 0;
    271   args->exec (args->file, args->argv, args->envp);

As suggested by Andreas Schwab, this patch removes the faulty assert
and also handles any signal that happens before fork and execve as the
spawn was successful (and thus relaying the handling to the caller to
figure this out).  Different than Florian, I can not see why using
atomics to set err would help here, essentially the code runs
sequentially (due CLONE_VFORK) and I think it would not be legal the
compiler evaluate ec without checking for new_pid result (thus there
is no need to compiler barrier).

Summarizing the possible scenarios on posix_spawn execution, we
have:

  1. For default case with a success execution, args.err will be 0, pid
     will not be collected and it will be reported to caller.

  2. For default failure case, args.err will be positive and the it will
     be collected by the waitpid.  An error will be reported to the
     caller.

  3. For the unlikely case where the process was terminated and not
     collected by a caller signal handler, it will be reported as succeful
     execution and not be collected by posix_spawn (since args.err will
     be 0). The caller will need to actually handle this case.

  4. For the unlikely case where the process was terminated and collected
     by caller we have 3 other possible scenarios:

     4.1. The auxiliary process was terminated with args.err equal to 0:
	  it will handled as 1. (so it does not matter if we hit the pid
          reuse race since we won't possible collect an unexpected
          process).

     4.2. The auxiliary process was terminated after execve (due a failure
          in calling it) and before setting args.err to -1: it will also
          be handle as 1. but with the issue of not be able to report the
          caller a possible execve failures.

     4.3. The auxiliary process was terminated after args.err is set to -1:
          this is the case where it will be possible to hit the pid reuse
          case where we will need to collected the auxiliary pid but we
          can not be sure if it will be expected one.  I think for this
          case we need to actually change waitpid to use WNOHANG to avoid
          hanging indefinitely on the call and report an error to caller
          since we can't differentiate between a default failure as 2.
          and a possible pid reuse race issue.

Checked on x86_64-linux-gnu.

	* sysdeps/unix/sysv/linux/spawni.c (__spawnix): Handle the case where
	the auxiliary process is terminated by a signal before calling _exit
	or execve.

(cherry picked from commit fe05e1cb6d)
2017-11-07 10:15:45 -02:00
Adhemerval Zanella caa6857ec1 posix: Fix compat glob code on s390 and alpha
This patch fixes the compat glob implementation consolidation from
commit 116f1c64d with the following changes:

  - Add a compat implementation on s390 to avoid the architecture
    to build the symbols on default linux oldglob.c by setting
    GLOB_NO_OLD_VERSION.

  - Remove the duplicate rule to build oldglob on alpha.

Checked on s390-linux-gnu and alpha-linux-gnu using build-many-glibc.py.

	* sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c: New file.
	* sysdeps/unix/sysv/linux/alpha/Makefile
	[$(subdir) = csu] (sysdep_routines): Remove rule.

(cherry picked from commit 3ca622e4d6)
2017-10-30 11:49:40 +01:00
Adhemerval Zanella ee5bce43eb posix: Consolidate Linux glob implementation
This patch consolidates the glob implementation.  The main changes are:

  * On Linux all implementation now uses the default one at
    sysdeps/unix/sysv/linux/glob{free}{64}.c with the exception
    of alpha (which requires specific versioning) and s390-32 (which
    different than other 32 bits ports it does not add a compat one
    symbol for 2.1 version).

  * The default implementation uses XSTAT_IS_XSTAT64 to define whether
    both glob{free} and glob{free}64 should be different implementations.
    For archictures that define XSTAT_IS_XSTAT64, glob{free} is an alias
    to glob{free}64.

  * Move i386 olddirent.h header to Linux default directory, since it is
    the only header with this name and it is shared among different
    architectures (and used on compat glob symbol as well).

Checked on x86_64-linux-gnu and on a build using build-many-glibcs.py
for all major architectures.

	* sysdeps/unix/sysv/linux/arm/glob64.c: Remove file.
	* sysdeps/unix/sysv/linux/i386/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/m68k/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/wordsize-64/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/glob.c: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise.
	* sysdeps/wordsize-64/glob.c: Likewise.
	* sysdeps/wordsize-64/glob64.c: Likewise.
	* sysdeps/wordsize-64/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/glob.c: New file.
	* sysdeps/unix/sysv/linux/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/globfree.c: Likewise.
	* sysdeps/unix/sysv/linux/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/oldglob.c [SHLIB_COMPAT]: Also
	adds !GLOB_NO_OLD_VERSION as an extra condition.
	* sysdeps/unix/sysv/linux/i386/alphasort64.c: Include olddirent.h
	using relative path instead of absolute one.
	* sysdeps/unix/sysv/linux/i386/getdents64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/readdir64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/versionsort64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/olddirent.h: Move to ...
	* sysdeps/unix/sysv/linux//olddirent.h: ... here.

(cherry picked from commit 116f1c64d8)
2017-10-30 11:49:40 +01:00
H.J. Lu 4b692dffb9 x86-64: Don't set GLRO(dl_platform) to NULL [BZ #22299]
Since ld.so expands $PLATFORM with GLRO(dl_platform), don't set
GLRO(dl_platform) to NULL.

	[BZ #22299]
	* sysdeps/x86/cpu-features.c (init_cpu_features): Don't set
	GLRO(dl_platform) to NULL.
	* sysdeps/x86_64/Makefile (tests): Add tst-platform-1.
	(modules-names): Add tst-platformmod-1 and
	x86_64/tst-platformmod-2.
	(CFLAGS-tst-platform-1.c): New.
	(CFLAGS-tst-platformmod-1.c): Likewise.
	(CFLAGS-tst-platformmod-2.c): Likewise.
	(LDFLAGS-tst-platformmod-2.so): Likewise.
	($(objpfx)tst-platform-1): Likewise.
	($(objpfx)tst-platform-1.out): Likewise.
	(tst-platform-1-ENV): Likewise.
	($(objpfx)x86_64/tst-platformmod-2.os): Likewise.
	* sysdeps/x86_64/tst-platform-1.c: New file.
	* sysdeps/x86_64/tst-platformmod-1.c: Likewise.
	* sysdeps/x86_64/tst-platformmod-2.c: Likewise.

(cherry picked from commit 4d916f0f12)
2017-10-26 07:36:47 -07:00
Alexey Makhalov 77eea8950c Fix range check in do_tunable_update_val
Current implementation of tunables does not set arena_max and arena_test
values. Any value provided by glibc.malloc.arena_max and
glibc.malloc.arena_test parameters is ignored.

These tunables have minval value set to 1 (see elf/dl-tunables.list file)
and undefined maxval value. In that case default value (which is 0. see
scripts/gen-tunables.awk) is being used to set maxval.

For instance, generated tunable_list[] entry for arena_max is:
(gdb) p *cur
$1 = {name = 0x7ffff7df6217 "glibc.malloc.arena_max",
 type = {type_code = TUNABLE_TYPE_SIZE_T, min = 1, max = 0},
  val = {numval = 0, strval = 0x0}, initialized = false,
   security_level = TUNABLE_SECLEVEL_SXID_IGNORE,
    env_alias = 0x7ffff7df622e "MALLOC_ARENA_MAX"}

As a result, any value of glibc.malloc.arena_max is ignored by
TUNABLE_SET_VAL_IF_VALID_RANGE macro
  __type min = (__cur)->type.min;                    <- initialized to 1
  __type max = (__cur)->type.max;                    <- initialized to 0!
  if (min == max)                                    <- false
    {
      min = __default_min;
      max = __default_max;
    }
  if ((__type) (__val) >= min && (__type) (val) <= max)  <- false
    {
      (__cur)->val.numval = val;
      (__cur)->initialized = true;
    }

Assigning correct min/max values at a build time fixes a problem.
Plus, a bit of optimization: Setting of default min/max values for the
given type at a run time might be eliminated.

	* elf/dl-tunables.c (do_tunable_update_val): Range checking fix.
	* scripts/gen-tunables.awk: Set unspecified minval and/or maxval
	values to correct default value for given type.
2017-10-23 21:27:46 +05:30
Joseph Myers 04acd59794 Install correct bits/long-double.h for MIPS64 (bug 22322).
Similar to bug 21987 for SPARC, MIPS64 wrongly installs the ldbl-128
version of bits/long-double.h, meaning incorrect results when using
headers installed from a 64-bit installation for a 32-bit build.  (I
haven't actually seen this cause build failures before its interaction
with bits/floatn.h did so - installed headers wrongly expecting
_Float128 to be available in a 32-bit configuration.)

This patch fixes the bug by moving the MIPS header to
sysdeps/mips/ieee754, which comes before sysdeps/ieee754/ldbl-128 in
the sysdeps directory ordering.  (bits/floatn.h will need a similar
fix - duplicating the ldbl-128 version for MIPS will suffice - for
headers from a 32-bit installation to be correct for 64-bit builds.)

Tested with build-many-glibcs.py (compilers build for
mips64-linux-gnu, where there was previously a libstdc++ build failure
as at
<https://sourceware.org/ml/libc-testresults/2017-q4/msg00130.html>).

	[BZ #22322]
	* sysdeps/mips/bits/long-double.h: Move to ....
	* sysdeps/mips/ieee754/bits/long-double.h: ... here.

(cherry picked from commit 37bb78cb8c)
2017-10-23 15:46:38 +00:00
Gabriel F. T. Gomes febbdd6731 Merge branch 'release/2.26/master' into ibm/2.26/master 2017-10-22 22:53:18 -02:00
Gabriel F. T. Gomes b1b8d8aa95 Add missing bug fixes to NEWS 2017-10-22 22:35:42 -02:00
Romain Naour f8279a4b3c Let signbit use the builtin in C++ mode with gcc < 6.x (bug 22296)
When using gcc < 6.x, signbit does not use the type-generic
__builtin_signbit builtin, instead it uses __MATH_TG.
However, when library support for float128 is available, __MATH_TG uses
__builtin_types_compatible_p, which is not available in C++ mode.

On the other hand, libstdc++ undefines (in cmath) many macros from
math.h, including signbit, so that it can provide its own functions.
However, during its configure tests, libstdc++ just tests for the
availability of the macros (it does not undefine them, nor does it
provide its own functions).

Finally, libstdc++ configure tests include math.h and get the definition
of signbit that uses __MATH_TG (and __builtin_types_compatible_p).
Since libstdc++ does not undefine the macros during its configure
tests, they fail.

This patch lets signbit use the builtin in C++ mode when gcc < 6.x is
used. This allows the configure test in libstdc++ to work.

Tested for x86_64.

	[BZ #22296]
	* math/math.h: Let signbit use the builtin in C++ mode with gcc
	< 6.x

Cc: Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
Cc: Joseph Myers <joseph@codesourcery.com>
(cherry picked from commit 386e1c26ac)
2017-10-22 20:53:43 -02:00
H.J. Lu f82a6fc223 x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve [BZ #21265]
In _dl_runtime_resolve, use fxsave/xsave/xsavec to preserve all vector,
mask and bound registers.  It simplifies _dl_runtime_resolve and supports
different calling conventions.  ld.so code size is reduced by more than
1 KB.  However, use fxsave/xsave/xsavec takes a little bit more cycles
than saving and restoring vector and bound registers individually.

Latency for _dl_runtime_resolve to lookup the function, foo, from one
shared library plus libc.so:

                             Before    After     Change

Westmere (SSE)/fxsave         345      866       151%
IvyBridge (AVX)/xsave         420      643       53%
Haswell (AVX)/xsave           713      1252      75%
Skylake (AVX+MPX)/xsavec      559      719       28%
Skylake (AVX512+MPX)/xsavec   145      272       87%
Ryzen (AVX)/xsavec            280      553       97%

This is the worst case where portion of time spent for saving and
restoring registers is bigger than majority of cases.  With smaller
_dl_runtime_resolve code size, overall performance impact is negligible.

On IvyBridge, differences in build and test time of binutils with lazy
binding GCC and binutils are noises.  On Westmere, differences in
bootstrap and "makc check" time of GCC 7 with lazy binding GCC and
binutils are also noises.

	[BZ #21265]
	* sysdeps/x86/cpu-features-offsets.sym (XSAVE_STATE_SIZE_OFFSET):
	New.
	* sysdeps/x86/cpu-features.c: Include <libc-pointer-arith.h>.
	(get_common_indeces): Set xsave_state_size, xsave_state_full_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 and xsave_state_full_size.
	(index_arch_Use_dl_runtime_resolve_opt): Removed.
	(index_arch_Use_dl_runtime_resolve_slow): Likewise.
	(index_arch_XSAVEC_Usable): New.
	* sysdeps/x86/cpu-tunables.c (TUNABLE_CALLBACK (set_hwcaps)):
	Support XSAVEC_Usable.  Remove Use_dl_runtime_resolve_slow.
	* sysdeps/x86_64/Makefile (tst-x86_64-1-ENV): New if tunables
	is enabled.
	* 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.

(cherry picked from commit b52b0d793d)
2017-10-22 07:41:00 -07:00
H.J. Lu b2c78ae69e x86: Add x86_64 to x86-64 HWCAP [BZ #22093]
Before glibc 2.26, ld.so set dl_platform to "x86_64" and searched the
"x86_64" subdirectory when loading a shared library.  ld.so in glibc
2.26 was changed to set dl_platform to "haswell" or "xeon_phi", based
on supported ISAs.  This led to shared library loading failure for
shared libraries placed under the "x86_64" subdirectory.

This patch adds "x86_64" to x86-64 dl_hwcap so that ld.so will always
search the "x86_64" subdirectory when loading a shared library.

NB: We can't set x86-64 dl_platform to "x86-64" since ld.so will skip
the "haswell" and "xeon_phi" subdirectories on "haswell" and "xeon_phi"
machines.

Tested on i686 and x86-64.

	[BZ #22093]
	* sysdeps/x86/cpu-features.c (init_cpu_features): Initialize
	GLRO(dl_hwcap) to HWCAP_X86_64 for x86-64.
	* sysdeps/x86/dl-hwcap.h (HWCAP_COUNT): Updated.
	(HWCAP_IMPORTANT): Likewise.
	(HWCAP_X86_64): New enum.
	(HWCAP_X86_AVX512_1): Updated.
	* sysdeps/x86/dl-procinfo.c (_dl_x86_hwcap_flags): Add "x86_64".
	* sysdeps/x86_64/Makefile (tests): Add tst-x86_64-1.
	(modules-names): Add x86_64/tst-x86_64mod-1.
	(LDFLAGS-tst-x86_64mod-1.so): New.
	($(objpfx)tst-x86_64-1): Likewise.
	($(objpfx)x86_64/tst-x86_64mod-1.os): Likewise.
	(tst-x86_64-1-clean): Likewise.
	* sysdeps/x86_64/tst-x86_64-1.c: New file.
	* sysdeps/x86_64/tst-x86_64mod-1.c: Likewise.

(cherry picked from commit 45ff34638f)
2017-10-22 04:16:39 -07:00
Florian Weimer 6182b3708b glob: Add new test tst-glob-tilde
The new test checks for memory leaks (see bug 22325) and attempts
to trigger the buffer overflow in bug 22320.

(cherry picked from commit e80fc1fc98)
2017-10-21 18:32:06 +02:00
Paul Eggert a76376df7c CVE-2017-15670: glob: Fix one-byte overflow [BZ #22320]
(cherry picked from commit c369d66e54)
2017-10-20 19:36:54 +02:00
Adhemerval Zanella 305f4f057d posix: Sync glob with gnulib [BZ #1062]
This patch syncs posix/glob.c implementation with gnulib version
b5ec983 (glob: simplify symlink detection).  The only difference
to gnulib code is

  * DT_UNKNOWN, DT_DIR, and DT_LNK definition in the case there
    were not already defined.  Gnulib code which uses
    HAVE_STRUCT_DIRENT_D_TYPE will redefine them wrongly because
    GLIBC does not define HAVE_STRUCT_DIRENT_D_TYPE.  Instead
    the patch check for each definition instead.

Also, the patch requires additional globfree and globfree64 files
for compatibility version on some architectures.  Also the code
simplification leads to not macro simplification (not need for
NO_GLOB_PATTERN_P anymore).

Checked on x86_64-linux-gnu and on a build using build-many-glibcs.py
for all major architectures.

	[BZ #1062]
	* 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.

(cherry picked from commit c66c908230)
2017-10-20 19:36:33 +02:00
H.J. Lu c96d7a646b i386: Hide __old_glob64 [BZ #18822]
Hide internal __old_glob64 function to allow direct access within
libc.so and libc.a without using GOT nor PLT.

	[BZ #18822]
	* sysdeps/unix/sysv/linux/i386/glob64.c (__old_glob64): Add
	libc_hidden_proto and libc_hidden_def.

(cherry picked from commit 2585d7b839)
2017-10-20 19:12:11 +02:00
Florian Weimer 2e78ea7a20 sysconf: Fix missing definition of UIO_MAXIOV on Linux [BZ #22321]
After commit 37f802f864 (Remove
__need_IOV_MAX and __need_FOPEN_MAX), UIO_MAXIOV is no longer supplied
(indirectly) through <bits/stdio_lim.h>, so sysdeps/posix/sysconf.c no
longer sees the definition.

(cherry picked from commit 63b4baa44e)
2017-10-20 04:23:26 +02:00
Florian Weimer 05155f0772 nss_files: Avoid large buffers with many host addresses [BZ #22078]
The previous implementation had at least a quadratic space
requirement in the number of host addresses and aliases.

(cherry picked from commit d8425e116c)
2017-10-19 10:44:31 +02:00
Florian Weimer 13728f56f0 nss_files: Use struct scratch_buffer for gethostbyname [BZ #18023]
(cherry picked from commit 78e806fd8c)
2017-10-19 10:43:40 +02:00
Florian Weimer 5ebb81e292 nss_files: Refactor gethostbyname3 multi case into separate function
This is in preparation of further cleanup work.

(cherry picked from commit 8ed70de2fa)
2017-10-19 10:43:32 +02:00
Gabriel F. T. Gomes f725563967 Remove conditional on LDBL_MANT_DIG from e_lgammal_r.c
The IEEE 754 implementation of lgammal in sysdeps/ieee754/ldbl-128/ used
to be shared by IBM's implementation in sysdeps/ieee754/ldbl-128ibm/ (by
an inclusion of the source file).  In order for the algorithm to work
for IBM's implementation, a check for LDBL_MANT_DIG was required. Since
the source file is no longer shared, the requirement for the check is
gone.  This patch removes the conditionals.

Tested for powerpc64le and s390x.

	* sysdeps/ieee754/ldbl-128/e_lgammal_r.c (__ieee754_lgammal_r):
	Remove conditionals on LDBL_MANT_DIG.
	* sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c
	(__ieee754_lgammal_r): Likewise.

(cherry picked from commit 9ac3c68218)
2017-10-10 10:15:16 -03:00
Gabriel F. T. Gomes d50b9bf1cc ldbl-128ibm: Automatic replacing of _Float128 and L()
The ldbl-128ibm implementation of j0l, j1l, lgammal_r, and cbrtl, as
well as the tables used by expl were copied from ldbl-128.  However, the
original files used _Float128 for the type and L() for the literal
suffix.  This patch uses the following sed command to rewrite _Float128
as long double and L(x) as xL (for e_expl.c, e_j0l.c, e_j1l.c,
e_lgammal_r.c, and t_expl.h):

  sed -i <filename> \
    -e "/^#define _Float128 long double/d" \
    -e "/^#define L(x) x ## L/d" \
    -e "/L(/s/)/L/" \
    -e "/L(/s/L(//" \
    -e "s/_Float128/long double/g"

For sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c, this sed command incorrectly
replaces a few occurrences of L(), so the following command is used
instead:

  sed -i sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c \
    -e "/^#define _Float128 long double/d" \
    -e "/^#define L(x) x ## L/d" \
    -e "s/L(0\.3\{40\})/0.3333333333333333333333333333333333333333L/" \
    -e "s/L(3\.7568280825958912391243e-1)/3.7568280825958912391243e-1L/" \
    -e "/L(/s/)/L/" \
    -e "/L(/s/L(//" \
    -e "s/_Float128/long double/g"

Tested for powerpc64le with patched [1] and unpatched gcc.

[1] https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01028.html

	* sysdeps/ieee754/ldbl-128ibm/e_expl.c: Remove definitions of
	_Float128 and L().
	* sysdeps/ieee754/ldbl-128ibm/e_j0l.c: Remove definitions of
	_Float128 and L(). Replace _Float128 with long double and L(x)
	with xL, throughout the file.
	* sysdeps/ieee754/ldbl-128ibm/e_j1l.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/t_expl.h: Likewise.

(cherry picked from commit d2f0ed09f8)
2017-10-10 10:15:16 -03:00
Gabriel F. T. Gomes 4f11fe97c3 ldbl-128ibm: Copy implementations from ldbl-128 instead of including them
Some files under sysdeps/ieee754/ldbl-128ibm/ are able to reuse the
implementation in sysdeps/ieee754/ldbl-128/ by defining _Float128 to
long double.  This relied on compiler support for _Float128 being
disabled.  On powerpc, such support was disabled by default, however, it
got enabled by default [1] in GCC 8.

This patch copies the implementations from ldbl-128 to ldbl-128ibm.  The
uses of _Float128 and L() are kept intact in this patch and are replaced
with a script in a subsequent patch.

[1] https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01028.html

Tested for powerpc64 and powerpc64le.

	* sysdeps/ieee754/ldbl-128ibm/e_expl.c: Include tables from
	sysdeps/ieee754/ldbl-128ibm.
	* sysdeps/ieee754/ldbl-128ibm/e_j0l.c: Copy contents from the
	equivalent implementation in sysdeps/ieee754/ldbl-128/ instead
	of including it.  Keep _Float128 and L() intact.  These will be
	reviewed by a separate patch.
	* sysdeps/ieee754/ldbl-128ibm/e_j1l.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/e_lgammal_r.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_cbrtl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/t_expl.h: Likewise.

(cherry picked from commit c5c2e667bf)
2017-10-10 10:15:15 -03:00
Gabriel F. T. Gomes c9163eeb6e powerpc: Add redirection for finitef128, isinf128, and isnanf128
On powerpc64le, compiler support for float128 is not enabled by default
on gcc.  To enable it, the flag -mfloat128 must be passed as a command
line option to the compiler.  This means that only the few files that
actively have -mfloat128 passed as an argument get compiler support for
float128, whereas all other files don't.

When -mfloat128 becomes enabled by default on powerpc [1], all the files
that do not currently have compiler support for float128 enabled during
their compilation, will start to have it.  This will lead to build
errors in s_finite.c, s_isinf.c, and s_isnan.c.

The errors are due to the unintended macro expansion of __finitef128 to
__redirect_finitef128 in math/bits/mathcalls-helper-functions.h.  In
that header, __MATHDECL_1 takes '__finite' and 'f128' as arguments and
concatenates them.  However, since '__finite' has been redefined in
s_finite.c, the function declaration becomes __redirect_finitef128:

    extern int __redirect___finitef128 (_Float128 __value) __attribute__ ((__nothrow__ )) __attribute__ ((__const__));

This declaration itself is OK.  The problem arises when include/math.h
creates the hidden prototype ('hidden_proto (__finitef128)'), which
expands to:

    extern __typeof (__finitef128) __finitef128 __attribute__ ((visibility ("hidden")));

Since __finitef128 is not declared, __typeof fails.  This effect was
already true for the 'float' and 'long double' versions and is now true
for float128.  Likewise for isinsff128 and isnanf128.

This patch defines __finitef128 as __redirect___finitef128 in
sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c, similarly to what's
done for the float and long double versions of these functions, to get
rid of the build error.  Likewise for isinff128 and isnanf128.

[1] https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01028.html

Tested for powerpc64 and powerpc64le.

	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
	(__finitef128): Define to __redirect___finitef128.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
	(__isinff128): Define to __redirect___isinff128.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
	(__isnanf128): Define to __redirect___isnanf128.

(cherry picked from commit e010deb231)
2017-10-10 10:15:15 -03:00
Gabriel F. T. Gomes 356a2df52a powerpc64le: Add -mfloat128 to tst-strtod-nan-locale testcase
On powerpc64le, not all files can have the flag -mfloat128 passed as an
option on the compile command, since that could conflict with other
flags, such as -mno-vsx.  Each file that needs the flag, gets it through
a CFLAGS-filename variable on sysdeps/powerpc/powerpc64le/Makefile.

The test cases tst-strtod-nan-locale and tst-wcstod-nan-locale are
missing this flag.

Tested for powerpc64le.

	* sysdeps/powerpc/powerpc64le/Makefile
	(CFLAGS-tst-strtod-nan-locale.c): New variable.
	(CFLAGS-tst-wcstod-nan-locale.c): New variable.

(cherry picked from commit ffa448041b)
2017-10-10 10:15:15 -03:00
Steve Ellcey 1f1239c389 Fix glibc.tune.cpu tunable handling
* sysdeps/unix/sysv/linux/aarch64/cpu-features.c (get_midr_from_mcpu):
	Use strcmp instead of tunable_is_name.
2017-10-10 15:53:55 +05:30
Siddhesh Poyarekar 290ba1089e aarch64: Optimized implementation of memmove for Qualcomm Falkor
This is an optimized memmove implementation for the Qualcomm Falkor
processor core.  Due to the way the falkor memcpy needs to be written,
code cannot be easily shared between memmove and memcpy like in case
of other aarch64 memcpy implementations due to which this routine is
separate.  The underlying principle is the same as that of memcpy
where it tries to use registers with the same lower 4 bits for
fetching the same stream, thus optimizing hardware prefetcher
performance.

The memcpy copy loop copies 64 bytes at a time using the same register
pair since that's the way to train the hardware prefetcher on the
falkor core.  memmove cannot quite do that since it needs to avoid
overlaps, so it does the next best thing, i.e. has a 32 byte loop with
a 32 byte end (prefetch a loop ahead to account for overlapping
locations) with register pairs that alias so that they hit the same
prefetcher.  Due to this difference in loop size, they have to
currently be separate implementations but efforts are on to try and
get memmove to fall back into memcpy whenever it can without simply
duplicating all of the code.

Performance:

The routine fares around 20-25% better than the generic memmove for
most medium to large sizes (i.e. > 128 bytes) for the new walking
memmove benchmark (memmove-walk) with an unexplained regression
between 1K and 2K.  The minor regression is something worth looking
into for us, but the remaining gains are significant enough that we
would like this included upstream as we looking into the cause for the
regression.  Here is a snippet of the numbers as generated from the
microbenchmark by the compare_strings script.  Comparisons are against
__memmove_generic:

Function: memmove
Variant: walk
                                    __memmove_thunderx	__memmove_falkor	__memmove_generic
========================================================================================================================
<snip>
                        length=16384:  12508800.00 (  6.09%)	 11486800.00 ( 13.76%)	 13319600.00
                        length=16400:  13614200.00 ( -0.67%)	 11585000.00 ( 14.33%)	 13523600.00
                        length=16385:  13448400.00 (  0.10%)	 11732700.00 ( 12.84%)	 13461200.00
                        length=16399:  13594100.00 ( -0.22%)	 11859600.00 ( 12.57%)	 13564400.00
                        length=16386:  13211600.00 (  1.13%)	 11503800.00 ( 13.91%)	 13362400.00
                        length=16398:  13218600.00 (  2.12%)	 11573200.00 ( 14.30%)	 13504700.00
                        length=16387:  13510900.00 ( -0.37%)	 11744200.00 ( 12.76%)	 13461300.00
                        length=16397:  13603700.00 ( -0.15%)	 11878200.00 ( 12.55%)	 13583200.00
                        length=16388:  13461700.00 ( -0.13%)	 11558000.00 ( 14.03%)	 13444100.00
                        length=16396:  13517500.00 ( -0.03%)	 11561300.00 ( 14.45%)	 13513900.00
                        length=16389:  13534100.00 (  0.17%)	 11756800.00 ( 13.28%)	 13556900.00
                        length=16395:  13585600.00 (  0.11%)	 11791800.00 ( 13.30%)	 13601200.00
                        length=16390:  13480100.00 ( -0.13%)	 11685500.00 ( 13.20%)	 13462100.00
                        length=16394:  13529900.00 ( -0.23%)	 11549800.00 ( 14.43%)	 13498200.00
                        length=16391:  13595400.00 ( -0.26%)	 11768200.00 ( 13.22%)	 13560600.00
                        length=16393:  13567000.00 (  0.20%)	 11779700.00 ( 13.35%)	 13594700.00
                        length=32768:  71308800.00 ( -6.53%)	 50220800.00 ( 24.98%)	 66939200.00
                        length=32784:  72100800.00 (-11.55%)	 50114100.00 ( 22.47%)	 64636300.00
                        length=32769:  71767000.00 ( -7.10%)	 51238400.00 ( 23.54%)	 67010000.00
                        length=32783:  70113700.00 (-40.95%)	 51129000.00 ( -2.78%)	 49744400.00
                        length=32770:  71367600.00 ( -6.52%)	 50244700.00 ( 25.01%)	 67000900.00
                        length=32782:  64366700.00 (  4.71%)	 50101400.00 ( 25.83%)	 67545600.00
                        length=32771:  71440100.00 ( -6.51%)	 51263900.00 ( 23.57%)	 67074900.00
                        length=32781:  66993000.00 (  0.34%)	 51108300.00 ( 23.97%)	 67220300.00
                        length=32772:  71443900.00 (-60.50%)	 50062100.00 (-12.47%)	 44512600.00
                        length=32780:  71759100.00 ( -6.58%)	 50263200.00 ( 25.35%)	 67328600.00
                        length=32773:  71714900.00 (-33.21%)	 51076600.00 (  5.12%)	 53835400.00
                        length=32779:  71756900.00 ( -6.56%)	 51290800.00 ( 23.83%)	 67337800.00
                        length=32774:  59689300.00 (-34.55%)	 50068400.00 (-12.86%)	 44363300.00
                        length=32778:  71847500.00 (-18.20%)	 50084100.00 ( 17.61%)	 60786500.00
                        length=32775:  71599300.00 ( -6.54%)	 51278200.00 ( 23.70%)	 67204800.00
                        length=32777:  71862900.00 (-60.85%)	 51094000.00 (-14.36%)	 44677900.00
                        length=65536: 282848000.00 ( -6.60%)	199187000.00 ( 24.93%)	265325000.00
                        length=65552: 243285000.00 (-41.61%)	198512000.00 (-15.54%)	171805000.00
                        length=65537: 255415000.00 (-23.47%)	202499000.00 (  2.11%)	206858000.00
                        length=65551: 280122000.00 (-62.95%)	203349000.00 (-18.29%)	171911000.00
                        length=65538: 283676000.00 (-14.46%)	198368000.00 ( 19.96%)	247848000.00
                        length=65550: 275566000.00 (-51.76%)	198494000.00 ( -9.31%)	181581000.00
                        length=65539: 283699000.00 ( -6.58%)	203453000.00 ( 23.57%)	266195000.00
                        length=65549: 286572000.00 ( -6.65%)	202607000.00 ( 24.60%)	268712000.00
                        length=65540: 283710000.00 ( -6.59%)	199161000.00 ( 25.17%)	266160000.00
                        length=65548: 237573000.00 ( 11.48%)	198462000.00 ( 26.06%)	268395000.00
                        length=65541: 284150000.00 ( -6.58%)	203273000.00 ( 23.75%)	266600000.00
                        length=65547: 286250000.00 ( -6.70%)	202594000.00 ( 24.48%)	268263000.00
                        length=65542: 284167000.00 ( -6.60%)	199122000.00 ( 25.31%)	266584000.00
                        length=65546: 285656000.00 ( -6.59%)	198443000.00 ( 25.95%)	268002000.00
                        length=65543: 284600000.00 ( -6.58%)	203247000.00 ( 23.89%)	267030000.00
                        length=65545: 285665000.00 ( -6.40%)	202575000.00 ( 24.55%)	268472000.00
<snip>

	* sysdeps/aarch64/multiarch/Makefile (sysdep_routines): Add
	memmove_falkor.
	* sysdeps/aarch64/multiarch/ifunc-impl-list.c
	(__libc_ifunc_impl_list): Likewise.
	* sysdeps/aarch64/multiarch/memmove.c: Likewise.
	* sysdeps/aarch64/multiarch/memmove_falkor.S: New file.
2017-10-10 15:49:50 +05:30
Siddhesh Poyarekar de84fc77f8 Update translations 2017-10-10 15:47:10 +05:30
Siddhesh Poyarekar e39de9fa74 memcpy_falkor: Fix code style in comments 2017-10-10 15:45:09 +05:30
Siddhesh Poyarekar b21ec6c6b8 aarch64: Optimized memcpy for Qualcomm Falkor processor
This is an optimized implementation of the memcpy routine that gives a
significant gain in performance for all sizes of copies on the
Qualcomm Falkor processor.  A detailed rationale of the implementation
is written in a comment in the patch.

This implementation improves time for copies up to 128 bytes by up to
15% and for larger copies by up to 35% in the glibc
microbenchmark. The memcpy-random benchmark sees improvements in all
sizes in the range of 13%-18%.

Here are the full numbers extracted from the glibc microbenchmark
using the commands:

../benchtests/scripts/compare_strings.py benchtests/bench-memcpy.out \
		../benchtests/scripts/benchout_strings.schema.json \
		-base=__memcpy_generic length align1 align2

../benchtests/scripts/compare_strings.py benchtests/bench-memcpy-large.out \
		../benchtests/scripts/benchout_strings.schema.json \
		-base=__memcpy_generic length align1 align2

../benchtests/scripts/compare_strings.py benchtests/bench-memcpy-random.out \
		../benchtests/scripts/benchout_strings.schema.json \
		-base=__memcpy_generic max-size

Function: memcpy
__memcpy_thunderx       __memcpy_falkor __memcpy_generic
Variant: default
================================================================================
length=1,align1=0,align2=0:     33.59 (-115.00%)        15.62 (0.00%)   15.62
length=1,align1=0,align2=0:     16.41 (-10.53%) 14.06 (5.26%)   14.84
length=1,align1=0,align2=0:     14.84 (0.00%)   14.84 (0.00%)   14.84
length=1,align1=0,align2=0:     15.62 (-5.26%)  14.06 (5.26%)   14.84
length=2,align1=0,align2=0:     15.62 (-5.26%)  14.06 (5.26%)   14.84
length=2,align1=1,align2=0:     15.62 (-5.26%)  14.06 (5.26%)   14.84
length=2,align1=0,align2=1:     14.84 (0.00%)   14.06 (5.26%)   14.84
length=2,align1=1,align2=1:     14.84 (-5.56%)  14.06 (0.00%)   14.06
length=4,align1=0,align2=0:     14.06 (0.00%)   14.06 (0.00%)   14.06
length=4,align1=2,align2=0:     14.06 (-5.88%)  14.06 (-5.88%)  13.28
length=4,align1=0,align2=2:     14.06 (0.00%)   14.06 (0.00%)   14.06
length=4,align1=2,align2=2:     14.06 (-5.88%)  14.06 (-5.88%)  13.28
length=8,align1=0,align2=0:     14.84 (-5.56%)  13.28 (5.56%)   14.06
length=8,align1=3,align2=0:     14.06 (0.00%)   13.28 (5.56%)   14.06
length=8,align1=0,align2=3:     13.28 (0.00%)   13.28 (0.00%)   13.28
length=8,align1=3,align2=3:     13.28 (-6.25%)  13.28 (-6.25%)  12.50
length=16,align1=0,align2=0:    13.28 (0.00%)   13.28 (0.00%)   13.28
length=16,align1=4,align2=0:    13.28 (0.00%)   12.50 (5.88%)   13.28
length=16,align1=0,align2=4:    13.28 (0.00%)   13.28 (0.00%)   13.28
length=16,align1=4,align2=4:    13.28 (-6.25%)  12.50 (0.00%)   12.50
length=32,align1=0,align2=0:    14.06 (0.00%)   12.50 (11.11%)  14.06
length=32,align1=5,align2=0:    13.28 (0.00%)   12.50 (5.88%)   13.28
length=32,align1=0,align2=5:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=32,align1=5,align2=5:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=64,align1=0,align2=0:    14.06 (-5.88%)  13.28 (0.00%)   13.28
length=64,align1=6,align2=0:    13.28 (0.00%)   13.28 (0.00%)   13.28
length=64,align1=0,align2=6:    14.06 (5.26%)   14.06 (5.26%)   14.84
length=64,align1=6,align2=6:    14.84 (-11.77%) 14.06 (-5.88%)  13.28
length=128,align1=0,align2=0:   17.19 (-4.76%)  14.84 (9.52%)   16.41
length=128,align1=7,align2=0:   16.41 (4.55%)   15.62 (9.09%)   17.19
length=128,align1=0,align2=7:   16.41 (0.00%)   14.06 (14.29%)  16.41
length=128,align1=7,align2=7:   16.41 (4.55%)   15.62 (9.09%)   17.19
length=256,align1=0,align2=0:   21.88 (-3.70%)  21.09 (0.00%)   21.09
length=256,align1=8,align2=0:   21.09 (-3.85%)  21.09 (-3.85%)  20.31
length=256,align1=0,align2=8:   20.31 (-4.00%)  20.31 (-4.00%)  19.53
length=256,align1=8,align2=8:   21.88 (-7.69%)  20.31 (0.00%)   20.31
length=512,align1=0,align2=0:   28.91 (-2.78%)  28.91 (-2.78%)  28.12
length=512,align1=9,align2=0:   30.47 (-2.63%)  30.47 (-2.63%)  29.69
length=512,align1=0,align2=9:   29.69 (0.00%)   29.69 (0.00%)   29.69
length=512,align1=9,align2=9:   28.12 (-2.86%)  28.12 (-2.86%)  27.34
length=1024,align1=0,align2=0:  44.53 (0.00%)   44.53 (0.00%)   44.53
length=1024,align1=10,align2=0:         50.00 (0.00%)   50.00 (0.00%)   50.00
length=1024,align1=0,align2=10:         49.22 (1.56%)   50.78 (-1.56%)  50.00
length=1024,align1=10,align2=10:        44.53 (-1.79%)  43.75 (0.00%)   43.75
length=2048,align1=0,align2=0:  77.34 (-1.02%)  76.56 (0.00%)   76.56
length=2048,align1=11,align2=0:         89.84 (0.00%)   89.84 (0.00%)   89.84
length=2048,align1=0,align2=11:         89.84 (0.00%)   89.84 (0.00%)   89.84
length=2048,align1=11,align2=11:        75.78 (0.00%)   75.78 (0.00%)   75.78
length=4096,align1=0,align2=0:  141.41 (-0.56%) 140.62 (0.00%)  140.62
length=4096,align1=12,align2=0:         171.09 (-0.46%) 170.31 (0.00%)  170.31
length=4096,align1=0,align2=12:         170.31 (0.00%)  170.31 (0.00%)  170.31
length=4096,align1=12,align2=12:        140.62 (0.00%)  140.62 (0.00%)  140.62
length=8192,align1=0,align2=0:  278.91 (-0.28%) 275.78 (0.84%)  278.12
length=8192,align1=13,align2=0:         338.28 (0.23%)  335.94 (0.92%)  339.06
length=8192,align1=0,align2=13:         338.28 (0.00%)  455.47 (-34.64%)        338.28
length=8192,align1=13,align2=13:        278.12 (-0.28%) 275.78 (0.56%)  277.34
length=16384,align1=0,align2=0:         535.94 (-0.15%) 531.25 (0.73%)  535.16
length=16384,align1=14,align2=0:        659.38 (0.12%)  659.38 (0.12%)  660.16
length=16384,align1=0,align2=14:        659.38 (0.00%)  657.03 (0.36%)  659.38
length=16384,align1=14,align2=14:       535.16 (0.44%)  532.81 (0.87%)  537.50
length=32768,align1=0,align2=0:         1260.94 (10.68%)        1121.88 (20.53%)        1411.72
length=32768,align1=15,align2=0:        1368.75 (10.02%)        1376.56 (9.50%) 1521.09
length=32768,align1=0,align2=15:        1333.59 (10.91%)        1373.44 (8.25%) 1496.88
length=32768,align1=15,align2=15:       1256.25 (13.96%)        1125.78 (22.90%)        1460.16
length=65536,align1=0,align2=0:         2853.91 (30.11%)        2589.06 (36.60%)        4083.59
length=65536,align1=16,align2=0:        2850.00 (30.14%)        2589.84 (36.52%)        4079.69
length=65536,align1=0,align2=16:        2853.12 (30.60%)        2589.84 (37.00%)        4110.94
length=65536,align1=16,align2=16:       2850.78 (30.07%)        2589.06 (36.49%)        4076.56
length=0,align1=0,align2=0:     15.62 (-5.26%)  16.41 (-10.53%) 14.84
length=0,align1=0,align2=0:     14.84 (-5.56%)  14.84 (-5.56%)  14.06
length=0,align1=0,align2=0:     14.84 (0.00%)   14.84 (0.00%)   14.84
length=0,align1=0,align2=0:     16.41 (-16.67%) 14.84 (-5.56%)  14.06
length=1,align1=0,align2=0:     15.62 (4.76%)   15.62 (4.76%)   16.41
length=1,align1=1,align2=0:     15.62 (0.00%)   14.84 (5.00%)   15.62
length=1,align1=0,align2=1:     14.84 (0.00%)   14.84 (0.00%)   14.84
length=1,align1=1,align2=1:     14.84 (0.00%)   14.06 (5.26%)   14.84
length=2,align1=0,align2=0:     14.84 (0.00%)   14.06 (5.26%)   14.84
length=2,align1=2,align2=0:     14.84 (0.00%)   14.06 (5.26%)   14.84
length=2,align1=0,align2=2:     14.84 (-5.56%)  14.06 (0.00%)   14.06
length=2,align1=2,align2=2:     14.84 (0.00%)   14.06 (5.26%)   14.84
length=3,align1=0,align2=0:     14.84 (0.00%)   14.84 (0.00%)   14.84
length=3,align1=3,align2=0:     14.84 (-5.56%)  14.06 (0.00%)   14.06
length=3,align1=0,align2=3:     15.62 (-11.11%) 14.06 (0.00%)   14.06
length=3,align1=3,align2=3:     14.84 (0.00%)   14.06 (5.26%)   14.84
length=4,align1=0,align2=0:     17.97 (-27.78%) 14.06 (0.00%)   14.06
length=4,align1=4,align2=0:     13.28 (5.56%)   14.06 (0.00%)   14.06
length=4,align1=0,align2=4:     14.06 (0.00%)   13.28 (5.56%)   14.06
length=4,align1=4,align2=4:     13.28 (5.56%)   13.28 (5.56%)   14.06
length=5,align1=0,align2=0:     13.28 (5.56%)   13.28 (5.56%)   14.06
length=5,align1=5,align2=0:     14.06 (0.00%)   14.06 (0.00%)   14.06
length=5,align1=0,align2=5:     14.06 (0.00%)   13.28 (5.56%)   14.06
length=5,align1=5,align2=5:     14.06 (-5.88%)  14.06 (-5.88%)  13.28
length=6,align1=0,align2=0:     14.06 (-5.88%)  14.06 (-5.88%)  13.28
length=6,align1=6,align2=0:     14.06 (0.00%)   14.06 (0.00%)   14.06
length=6,align1=0,align2=6:     14.06 (0.00%)   13.28 (5.56%)   14.06
length=6,align1=6,align2=6:     14.06 (0.00%)   13.28 (5.56%)   14.06
length=7,align1=0,align2=0:     14.84 (-11.77%) 14.06 (-5.88%)  13.28
length=7,align1=7,align2=0:     13.28 (0.00%)   14.06 (-5.88%)  13.28
length=7,align1=0,align2=7:     14.06 (0.00%)   14.06 (0.00%)   14.06
length=7,align1=7,align2=7:     14.06 (0.00%)   14.06 (0.00%)   14.06
length=8,align1=0,align2=0:     14.06 (-5.88%)  13.28 (0.00%)   13.28
length=8,align1=8,align2=0:     14.06 (0.00%)   13.28 (5.56%)   14.06
length=8,align1=0,align2=8:     13.28 (0.00%)   13.28 (0.00%)   13.28
length=8,align1=8,align2=8:     14.06 (-5.88%)  13.28 (0.00%)   13.28
length=9,align1=0,align2=0:     13.28 (0.00%)   13.28 (0.00%)   13.28
length=9,align1=9,align2=0:     13.28 (0.00%)   13.28 (0.00%)   13.28
length=9,align1=0,align2=9:     13.28 (0.00%)   14.06 (-5.88%)  13.28
length=9,align1=9,align2=9:     14.06 (-5.88%)  13.28 (0.00%)   13.28
length=10,align1=0,align2=0:    14.06 (0.00%)   13.28 (5.56%)   14.06
length=10,align1=10,align2=0:   14.06 (-5.88%)  14.06 (-5.88%)  13.28
length=10,align1=0,align2=10:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=10,align1=10,align2=10:  14.06 (0.00%)   13.28 (5.56%)   14.06
length=11,align1=0,align2=0:    14.06 (-5.88%)  13.28 (0.00%)   13.28
length=11,align1=11,align2=0:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=11,align1=0,align2=11:   13.28 (0.00%)   13.28 (0.00%)   13.28
length=11,align1=11,align2=11:  13.28 (0.00%)   13.28 (0.00%)   13.28
length=12,align1=0,align2=0:    14.06 (-5.88%)  13.28 (0.00%)   13.28
length=12,align1=12,align2=0:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=12,align1=0,align2=12:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=12,align1=12,align2=12:  14.06 (0.00%)   13.28 (5.56%)   14.06
length=13,align1=0,align2=0:    14.06 (-5.88%)  13.28 (0.00%)   13.28
length=13,align1=13,align2=0:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=13,align1=0,align2=13:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=13,align1=13,align2=13:  13.28 (0.00%)   13.28 (0.00%)   13.28
length=14,align1=0,align2=0:    13.28 (0.00%)   13.28 (0.00%)   13.28
length=14,align1=14,align2=0:   13.28 (5.56%)   13.28 (5.56%)   14.06
length=14,align1=0,align2=14:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=14,align1=14,align2=14:  14.06 (-5.88%)  13.28 (0.00%)   13.28
length=15,align1=0,align2=0:    14.06 (-5.88%)  13.28 (0.00%)   13.28
length=15,align1=15,align2=0:   14.06 (-5.88%)  14.06 (-5.88%)  13.28
length=15,align1=0,align2=15:   13.28 (0.00%)   13.28 (0.00%)   13.28
length=15,align1=15,align2=15:  13.28 (0.00%)   14.06 (-5.88%)  13.28
length=16,align1=0,align2=0:    14.06 (-5.88%)  13.28 (0.00%)   13.28
length=16,align1=16,align2=0:   13.28 (5.56%)   14.06 (0.00%)   14.06
length=16,align1=0,align2=16:   14.84 (-11.77%) 13.28 (0.00%)   13.28
length=16,align1=16,align2=16:  13.28 (-6.25%)  12.50 (0.00%)   12.50
length=17,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=17,align1=17,align2=0:   14.84 (-11.77%) 12.50 (5.88%)   13.28
length=17,align1=0,align2=17:   14.84 (-5.56%)  12.50 (11.11%)  14.06
length=17,align1=17,align2=17:  14.84 (-11.77%) 12.50 (5.88%)   13.28
length=18,align1=0,align2=0:    14.06 (0.00%)   12.50 (11.11%)  14.06
length=18,align1=18,align2=0:   13.28 (5.56%)   12.50 (11.11%)  14.06
length=18,align1=0,align2=18:   14.06 (-5.88%)  12.50 (5.88%)   13.28
length=18,align1=18,align2=18:  14.06 (0.00%)   12.50 (11.11%)  14.06
length=19,align1=0,align2=0:    14.06 (-5.88%)  13.28 (0.00%)   13.28
length=19,align1=19,align2=0:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=19,align1=0,align2=19:   14.84 (-5.56%)  12.50 (11.11%)  14.06
length=19,align1=19,align2=19:  14.06 (-5.88%)  12.50 (5.88%)   13.28
length=20,align1=0,align2=0:    14.84 (-11.77%) 12.50 (5.88%)   13.28
length=20,align1=20,align2=0:   14.06 (0.00%)   12.50 (11.11%)  14.06
length=20,align1=0,align2=20:   14.06 (-5.88%)  12.50 (5.88%)   13.28
length=20,align1=20,align2=20:  14.06 (0.00%)   13.28 (5.56%)   14.06
length=21,align1=0,align2=0:    14.84 (-5.56%)  12.50 (11.11%)  14.06
length=21,align1=21,align2=0:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=21,align1=0,align2=21:   14.84 (-11.77%) 12.50 (5.88%)   13.28
length=21,align1=21,align2=21:  13.28 (5.56%)   13.28 (5.56%)   14.06
length=22,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=22,align1=22,align2=0:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=22,align1=0,align2=22:   14.06 (0.00%)   12.50 (11.11%)  14.06
length=22,align1=22,align2=22:  14.06 (0.00%)   12.50 (11.11%)  14.06
length=23,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=23,align1=23,align2=0:   14.06 (-5.88%)  13.28 (0.00%)   13.28
length=23,align1=0,align2=23:   14.06 (-5.88%)  12.50 (5.88%)   13.28
length=23,align1=23,align2=23:  14.06 (-5.88%)  13.28 (0.00%)   13.28
length=24,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=24,align1=24,align2=0:   14.06 (0.00%)   13.28 (5.56%)   14.06
length=24,align1=0,align2=24:   14.84 (-11.77%) 12.50 (5.88%)   13.28
length=24,align1=24,align2=24:  14.06 (-5.88%)  13.28 (0.00%)   13.28
length=25,align1=0,align2=0:    14.06 (0.00%)   12.50 (11.11%)  14.06
length=25,align1=25,align2=0:   14.06 (0.00%)   13.28 (5.56%)   14.06
length=25,align1=0,align2=25:   14.06 (0.00%)   12.50 (11.11%)  14.06
length=25,align1=25,align2=25:  13.28 (0.00%)   13.28 (0.00%)   13.28
length=26,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=26,align1=26,align2=0:   14.06 (0.00%)   13.28 (5.56%)   14.06
length=26,align1=0,align2=26:   14.06 (-5.88%)  12.50 (5.88%)   13.28
length=26,align1=26,align2=26:  14.06 (0.00%)   13.28 (5.56%)   14.06
length=27,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=27,align1=27,align2=0:   14.06 (-5.88%)  12.50 (5.88%)   13.28
length=27,align1=0,align2=27:   14.06 (-5.88%)  12.50 (5.88%)   13.28
length=27,align1=27,align2=27:  14.06 (0.00%)   12.50 (11.11%)  14.06
length=28,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=28,align1=28,align2=0:   14.06 (0.00%)   12.50 (11.11%)  14.06
length=28,align1=0,align2=28:   14.06 (0.00%)   12.50 (11.11%)  14.06
length=28,align1=28,align2=28:  14.84 (-11.77%) 13.28 (0.00%)   13.28
length=29,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=29,align1=29,align2=0:   13.28 (0.00%)   12.50 (5.88%)   13.28
length=29,align1=0,align2=29:   14.06 (0.00%)   12.50 (11.11%)  14.06
length=29,align1=29,align2=29:  13.28 (5.56%)   12.50 (11.11%)  14.06
length=30,align1=0,align2=0:    14.06 (-5.88%)  12.50 (5.88%)   13.28
length=30,align1=30,align2=0:   13.28 (5.56%)   12.50 (11.11%)  14.06
length=30,align1=0,align2=30:   14.06 (-5.88%)  12.50 (5.88%)   13.28
length=30,align1=30,align2=30:  13.28 (0.00%)   12.50 (5.88%)   13.28
length=31,align1=0,align2=0:    13.28 (0.00%)   12.50 (5.88%)   13.28
length=31,align1=31,align2=0:   14.06 (0.00%)   12.50 (11.11%)  14.06
length=31,align1=0,align2=31:   13.28 (0.00%)   12.50 (5.88%)   13.28
length=31,align1=31,align2=31:  14.06 (0.00%)   12.50 (11.11%)  14.06
length=48,align1=0,align2=0:    14.06 (0.00%)   14.06 (0.00%)   14.06
length=48,align1=3,align2=0:    14.06 (0.00%)   14.06 (0.00%)   14.06
length=48,align1=0,align2=3:    14.06 (-5.88%)  14.06 (-5.88%)  13.28
length=48,align1=3,align2=3:    13.28 (5.56%)   14.06 (0.00%)   14.06
length=80,align1=0,align2=0:    15.62 (-11.11%) 14.84 (-5.56%)  14.06
length=80,align1=5,align2=0:    15.62 (-11.11%) 16.41 (-16.67%) 14.06
length=80,align1=0,align2=5:    14.06 (0.00%)   15.62 (-11.11%) 14.06
length=80,align1=5,align2=5:    15.62 (-5.26%)  17.19 (-15.79%) 14.84
length=96,align1=0,align2=0:    14.06 (0.00%)   14.84 (-5.56%)  14.06
length=96,align1=6,align2=0:    14.84 (-5.56%)  16.41 (-16.67%) 14.06
length=96,align1=0,align2=6:    14.06 (0.00%)   14.84 (-5.56%)  14.06
length=96,align1=6,align2=6:    14.84 (-5.56%)  17.19 (-22.22%) 14.06
length=112,align1=0,align2=0:   17.19 (-4.76%)  14.06 (14.29%)  16.41
length=112,align1=7,align2=0:   17.19 (0.00%)   16.41 (4.55%)   17.19
length=112,align1=0,align2=7:   16.41 (0.00%)   14.84 (9.52%)   16.41
length=112,align1=7,align2=7:   17.19 (0.00%)   17.19 (0.00%)   17.19
length=144,align1=0,align2=0:   17.19 (-10.00%) 17.97 (-15.00%) 15.62
length=144,align1=9,align2=0:   17.19 (-4.76%)  18.75 (-14.29%) 16.41
length=144,align1=0,align2=9:   20.31 (-8.33%)  18.75 (0.00%)   18.75
length=144,align1=9,align2=9:   18.75 (-4.35%)  18.75 (-4.35%)  17.97
length=160,align1=0,align2=0:   18.75 (-4.35%)  17.97 (0.00%)   17.97
length=160,align1=10,align2=0:  18.75 (4.00%)   18.75 (4.00%)   19.53
length=160,align1=0,align2=10:  19.53 (-4.17%)  17.97 (4.17%)   18.75
length=160,align1=10,align2=10:         18.75 (-4.35%)  18.75 (-4.35%)  17.97
length=176,align1=0,align2=0:   18.75 (-4.35%)  17.19 (4.35%)   17.97
length=176,align1=11,align2=0:  19.53 (0.00%)   19.53 (0.00%)   19.53
length=176,align1=0,align2=11:  19.53 (-4.17%)  18.75 (0.00%)   18.75
length=176,align1=11,align2=11:         18.75 (0.00%)   17.97 (4.17%)   18.75
length=192,align1=0,align2=0:   18.75 (0.00%)   17.97 (4.17%)   18.75
length=192,align1=12,align2=0:  21.09 (-8.00%)  18.75 (4.00%)   19.53
length=192,align1=0,align2=12:  18.75 (0.00%)   18.75 (0.00%)   18.75
length=192,align1=12,align2=12:         18.75 (0.00%)   17.97 (4.17%)   18.75
length=208,align1=0,align2=0:   17.97 (0.00%)   20.31 (-13.04%) 17.97
length=208,align1=13,align2=0:  19.53 (7.41%)   21.09 (0.00%)   21.09
length=208,align1=0,align2=13:  23.44 (-11.11%) 21.09 (0.00%)   21.09
length=208,align1=13,align2=13:         21.09 (-3.85%)  21.09 (-3.85%)  20.31
length=224,align1=0,align2=0:   21.09 (-8.00%)  20.31 (-4.00%)  19.53
length=224,align1=14,align2=0:  23.44 (-11.11%) 20.31 (3.70%)   21.09
length=224,align1=0,align2=14:  21.09 (3.57%)   20.31 (7.14%)   21.88
length=224,align1=14,align2=14:         20.31 (0.00%)   19.53 (3.85%)   20.31
length=240,align1=0,align2=0:   20.31 (-4.00%)  19.53 (0.00%)   19.53
length=240,align1=15,align2=0:  22.66 (0.00%)   20.31 (10.34%)  22.66
length=240,align1=0,align2=15:  20.31 (-4.00%)  20.31 (-4.00%)  19.53
length=240,align1=15,align2=15:         21.88 (0.00%)   21.09 (3.57%)   21.88
length=272,align1=0,align2=0:   20.31 (0.00%)   28.12 (-38.46%) 20.31
length=272,align1=17,align2=0:  22.66 (0.00%)   27.34 (-20.69%) 22.66
length=272,align1=0,align2=17:  25.78 (-10.00%) 28.12 (-20.00%) 23.44
length=272,align1=17,align2=17:         22.66 (-3.57%)  27.34 (-25.00%) 21.88
length=288,align1=0,align2=0:   23.44 (-7.14%)  27.34 (-25.00%) 21.88
length=288,align1=18,align2=0:  22.66 (0.00%)   27.34 (-20.69%) 22.66
length=288,align1=0,align2=18:  23.44 (-3.45%)  25.00 (-10.35%) 22.66
length=288,align1=18,align2=18:         22.66 (-3.57%)  21.88 (0.00%)   21.88
length=304,align1=0,align2=0:   21.88 (0.00%)   21.88 (0.00%)   21.88
length=304,align1=19,align2=0:  23.44 (-3.45%)  22.66 (0.00%)   22.66
length=304,align1=0,align2=19:  22.66 (0.00%)   22.66 (0.00%)   22.66
length=304,align1=19,align2=19:         22.66 (-3.57%)  21.88 (0.00%)   21.88
length=320,align1=0,align2=0:   22.66 (-3.57%)  21.88 (0.00%)   21.88
length=320,align1=20,align2=0:  22.66 (0.00%)   22.66 (0.00%)   22.66
length=320,align1=0,align2=20:  22.66 (0.00%)   22.66 (0.00%)   22.66
length=320,align1=20,align2=20:         22.66 (-3.57%)  21.88 (0.00%)   21.88
length=336,align1=0,align2=0:   21.88 (0.00%)   24.22 (-10.71%) 21.88
length=336,align1=21,align2=0:  22.66 (0.00%)   25.00 (-10.35%) 22.66
length=336,align1=0,align2=21:  25.78 (0.00%)   25.00 (3.03%)   25.78
length=336,align1=21,align2=21:         25.00 (0.00%)   23.44 (6.25%)   25.00
length=352,align1=0,align2=0:   24.22 (0.00%)   24.22 (0.00%)   24.22
length=352,align1=22,align2=0:  25.00 (0.00%)   25.00 (0.00%)   25.00
length=352,align1=0,align2=22:  25.00 (-3.23%)  25.00 (-3.23%)  24.22
length=352,align1=22,align2=22:         25.00 (-3.23%)  24.22 (0.00%)   24.22
length=368,align1=0,align2=0:   25.00 (-3.23%)  23.44 (3.23%)   24.22
length=368,align1=23,align2=0:  25.00 (0.00%)   24.22 (3.12%)   25.00
length=368,align1=0,align2=23:  25.00 (-3.23%)  25.00 (-3.23%)  24.22
length=368,align1=23,align2=23:         25.00 (-6.67%)  23.44 (0.00%)   23.44
length=384,align1=0,align2=0:   24.22 (0.00%)   24.22 (0.00%)   24.22
length=384,align1=24,align2=0:  25.00 (0.00%)   24.22 (3.12%)   25.00
length=384,align1=0,align2=24:  25.00 (0.00%)   25.78 (-3.12%)  25.00
length=384,align1=24,align2=24:         24.22 (-3.33%)  23.44 (0.00%)   23.44
length=400,align1=0,align2=0:   25.00 (-3.23%)  26.56 (-9.68%)  24.22
length=400,align1=25,align2=0:  25.78 (-3.12%)  27.34 (-9.38%)  25.00
length=400,align1=0,align2=25:  27.34 (0.00%)   27.34 (0.00%)   27.34
length=400,align1=25,align2=25:         26.56 (0.00%)   25.78 (2.94%)   26.56
length=416,align1=0,align2=0:   26.56 (-3.03%)  25.78 (0.00%)   25.78
length=416,align1=26,align2=0:  28.12 (-2.86%)  27.34 (0.00%)   27.34
length=416,align1=0,align2=26:  27.34 (-2.94%)  28.12 (-5.88%)  26.56
length=416,align1=26,align2=26:         25.78 (0.00%)   26.56 (-3.03%)  25.78
length=432,align1=0,align2=0:   27.34 (-2.94%)  25.78 (2.94%)   26.56
length=432,align1=27,align2=0:  28.12 (-2.86%)  27.34 (0.00%)   27.34
length=432,align1=0,align2=27:  27.34 (0.00%)   28.12 (-2.86%)  27.34
length=432,align1=27,align2=27:         25.78 (0.00%)   25.78 (0.00%)   25.78
length=448,align1=0,align2=0:   26.56 (-3.03%)  25.78 (0.00%)   25.78
length=448,align1=28,align2=0:  27.34 (0.00%)   27.34 (0.00%)   27.34
length=448,align1=0,align2=28:  27.34 (0.00%)   28.12 (-2.86%)  27.34
length=448,align1=28,align2=28:         25.78 (0.00%)   25.78 (0.00%)   25.78
length=464,align1=0,align2=0:   25.78 (0.00%)   28.12 (-9.09%)  25.78
length=464,align1=29,align2=0:  28.12 (-2.86%)  29.69 (-8.57%)  27.34
length=464,align1=0,align2=29:  30.47 (0.00%)   30.47 (0.00%)   30.47
length=464,align1=29,align2=29:         28.12 (0.00%)   27.34 (2.78%)   28.12
length=480,align1=0,align2=0:   29.69 (-5.56%)  28.12 (0.00%)   28.12
length=480,align1=30,align2=0:  31.25 (-2.56%)  29.69 (2.56%)   30.47
length=480,align1=0,align2=30:  29.69 (0.00%)   30.47 (-2.63%)  29.69
length=480,align1=30,align2=30:         28.12 (0.00%)   28.12 (0.00%)   28.12
length=496,align1=0,align2=0:   28.12 (0.00%)   27.34 (2.78%)   28.12
length=496,align1=31,align2=0:  30.47 (-2.63%)  29.69 (0.00%)   29.69
length=496,align1=0,align2=31:  29.69 (0.00%)   30.47 (-2.63%)  29.69
length=496,align1=31,align2=31:         28.12 (-2.86%)  28.12 (-2.86%)  27.34
length=1024,align1=0,align2=0:  44.53 (0.00%)   44.53 (0.00%)   44.53
length=1024,align1=32,align2=0:         44.53 (-1.79%)  44.53 (-1.79%)  43.75
length=1024,align1=0,align2=32:         44.53 (-1.79%)  43.75 (0.00%)   43.75
length=1024,align1=32,align2=32:        43.75 (1.75%)   43.75 (1.75%)   44.53
length=1056,align1=0,align2=0:  46.88 (-1.69%)  46.88 (-1.69%)  46.09
length=1056,align1=33,align2=0:         53.12 (0.00%)   52.34 (1.47%)   53.12
length=1056,align1=0,align2=33:         52.34 (0.00%)   53.12 (-1.49%)  52.34
length=1056,align1=33,align2=33:        46.09 (0.00%)   46.88 (-1.69%)  46.09
length=1088,align1=0,align2=0:  46.88 (-1.69%)  46.09 (0.00%)   46.09
length=1088,align1=34,align2=0:         52.34 (0.00%)   52.34 (0.00%)   52.34
length=1088,align1=0,align2=34:         53.12 (-3.03%)  53.12 (-3.03%)  51.56
length=1088,align1=34,align2=34:        46.09 (0.00%)   46.88 (-1.69%)  46.09
length=1120,align1=0,align2=0:  49.22 (-1.61%)  48.44 (0.00%)   48.44
length=1120,align1=35,align2=0:         54.69 (1.41%)   55.47 (0.00%)   55.47
length=1120,align1=0,align2=35:         57.03 (0.00%)   55.47 (2.74%)   57.03
length=1120,align1=35,align2=35:        48.44 (0.00%)   49.22 (-1.61%)  48.44
length=1152,align1=0,align2=0:  47.66 (1.61%)   48.44 (0.00%)   48.44
length=1152,align1=36,align2=0:         55.47 (-1.43%)  55.47 (-1.43%)  54.69
length=1152,align1=0,align2=36:         58.59 (-1.35%)  55.47 (4.05%)   57.81
length=1152,align1=36,align2=36:        48.44 (0.00%)   49.22 (-1.61%)  48.44
length=1184,align1=0,align2=0:  53.12 (-3.03%)  50.78 (1.52%)   51.56
length=1184,align1=37,align2=0:         61.72 (-2.60%)  57.03 (5.19%)   60.16
length=1184,align1=0,align2=37:         62.50 (-1.27%)  57.03 (7.60%)   61.72
length=1184,align1=37,align2=37:        53.12 (-1.49%)  50.78 (2.99%)   52.34
length=1216,align1=0,align2=0:  53.91 (-4.55%)  50.78 (1.52%)   51.56
length=1216,align1=38,align2=0:         60.94 (0.00%)   57.03 (6.41%)   60.94
length=1216,align1=0,align2=38:         60.16 (0.00%)   57.81 (3.90%)   60.16
length=1216,align1=38,align2=38:        52.34 (-1.52%)  50.00 (3.03%)   51.56
length=1248,align1=0,align2=0:  54.69 (-2.94%)  53.12 (0.00%)   53.12
length=1248,align1=39,align2=0:         64.06 (-1.23%)  60.16 (4.94%)   63.28
length=1248,align1=0,align2=39:         60.94 (-2.63%)  60.16 (-1.32%)  59.38
length=1248,align1=39,align2=39:        53.12 (0.00%)   52.34 (1.47%)   53.12
length=1280,align1=0,align2=0:  52.34 (-1.52%)  52.34 (-1.52%)  51.56
length=1280,align1=40,align2=0:         61.72 (3.66%)   59.38 (7.32%)   64.06
length=1280,align1=0,align2=40:         60.94 (-2.63%)  60.16 (-1.32%)  59.38
length=1280,align1=40,align2=40:        52.34 (-1.52%)  52.34 (-1.52%)  51.56
length=1312,align1=0,align2=0:  54.69 (-1.45%)  55.47 (-2.90%)  53.91
length=1312,align1=41,align2=0:         63.28 (0.00%)   62.50 (1.23%)   63.28
length=1312,align1=0,align2=41:         62.50 (0.00%)   62.50 (0.00%)   62.50
length=1312,align1=41,align2=41:        53.91 (0.00%)   54.69 (-1.45%)  53.91
length=1344,align1=0,align2=0:  54.69 (0.00%)   54.69 (0.00%)   54.69
length=1344,align1=42,align2=0:         62.50 (0.00%)   62.50 (0.00%)   62.50
length=1344,align1=0,align2=42:         62.50 (-1.27%)  62.50 (-1.27%)  61.72
length=1344,align1=42,align2=42:        53.91 (0.00%)   53.91 (0.00%)   53.91
length=1376,align1=0,align2=0:  65.62 (-16.67%) 68.75 (-22.22%) 56.25
length=1376,align1=43,align2=0:         71.88 (-9.52%)  73.44 (-11.90%) 65.62
length=1376,align1=0,align2=43:         72.66 (-12.05%) 74.22 (-14.46%) 64.84
length=1376,align1=43,align2=43:        64.06 (-13.89%) 67.97 (-20.83%) 56.25
length=1408,align1=0,align2=0:  57.03 (-1.39%)  68.75 (-22.22%) 56.25
length=1408,align1=44,align2=0:         65.62 (-1.20%)  73.44 (-13.25%) 64.84
length=1408,align1=0,align2=44:         64.84 (0.00%)   74.22 (-14.46%) 64.84
length=1408,align1=44,align2=44:        56.25 (-1.41%)  68.75 (-23.94%) 55.47
length=1440,align1=0,align2=0:  67.97 (-14.47%) 64.84 (-9.21%)  59.38
length=1440,align1=45,align2=0:         74.22 (-10.47%) 68.75 (-2.33%)  67.19
length=1440,align1=0,align2=45:         72.66 (-6.90%)  69.53 (-2.30%)  67.97
length=1440,align1=45,align2=45:        65.62 (-13.51%) 58.59 (-1.35%)  57.81
length=1472,align1=0,align2=0:  66.41 (-14.86%) 58.59 (-1.35%)  57.81
length=1472,align1=46,align2=0:         73.44 (-9.30%)  67.19 (0.00%)   67.19
length=1472,align1=0,align2=46:         70.31 (-4.65%)  67.97 (-1.16%)  67.19
length=1472,align1=46,align2=46:        57.81 (0.00%)   58.59 (-1.35%)  57.81
length=1504,align1=0,align2=0:  60.94 (0.00%)   60.94 (0.00%)   60.94
length=1504,align1=47,align2=0:         71.09 (-1.11%)  70.31 (0.00%)   70.31
length=1504,align1=0,align2=47:         70.31 (-1.12%)  70.31 (-1.12%)  69.53
length=1504,align1=47,align2=47:        60.94 (-1.30%)  60.16 (0.00%)   60.16
length=1536,align1=0,align2=0:  62.50 (-3.90%)  60.16 (0.00%)   60.16
length=1536,align1=48,align2=0:         60.94 (-1.30%)  60.16 (0.00%)   60.16
length=1536,align1=0,align2=48:         61.72 (-3.95%)  60.16 (-1.32%)  59.38
length=1536,align1=48,align2=48:        60.94 (-1.30%)  60.16 (0.00%)   60.16
length=1568,align1=0,align2=0:  80.47 (-27.16%) 63.28 (0.00%)   63.28
length=1568,align1=49,align2=0:         86.72 (-18.09%) 72.66 (1.06%)   73.44
length=1568,align1=0,align2=49:         74.22 (-3.26%)  74.22 (-3.26%)  71.88
length=1568,align1=49,align2=49:        62.50 (0.00%)   61.72 (1.25%)   62.50
length=1600,align1=0,align2=0:  62.50 (-1.27%)  62.50 (-1.27%)  61.72
length=1600,align1=50,align2=0:         73.44 (0.00%)   71.88 (2.13%)   73.44
length=1600,align1=0,align2=50:         72.66 (0.00%)   73.44 (-1.08%)  72.66
length=1600,align1=50,align2=50:        62.50 (-1.27%)  62.50 (-1.27%)  61.72
length=1632,align1=0,align2=0:  64.84 (0.00%)   64.84 (0.00%)   64.84
length=1632,align1=51,align2=0:         75.78 (0.00%)   75.00 (1.03%)   75.78
length=1632,align1=0,align2=51:         78.91 (0.00%)   75.78 (3.96%)   78.91
length=1632,align1=51,align2=51:        64.84 (-2.47%)  64.84 (-2.47%)  63.28
length=1664,align1=0,align2=0:  64.84 (-1.22%)  64.84 (-1.22%)  64.06
length=1664,align1=52,align2=0:         75.78 (0.00%)   75.00 (1.03%)   75.78
length=1664,align1=0,align2=52:         80.47 (-0.98%)  75.78 (4.90%)   79.69
length=1664,align1=52,align2=52:        64.06 (-1.23%)  65.62 (-3.70%)  63.28
length=1696,align1=0,align2=0:  69.53 (-3.49%)  72.66 (-8.14%)  67.19
length=1696,align1=53,align2=0:         80.47 (-0.98%)  82.03 (-2.94%)  79.69
length=1696,align1=0,align2=53:         80.47 (0.96%)   82.03 (-0.96%)  81.25
length=1696,align1=53,align2=53:        68.75 (-2.33%)  72.66 (-8.14%)  67.19
length=1728,align1=0,align2=0:  67.97 (0.00%)   72.66 (-6.90%)  67.97
length=1728,align1=54,align2=0:         80.47 (-0.98%)  82.81 (-3.92%)  79.69
length=1728,align1=0,align2=54:         78.91 (-1.00%)  82.03 (-5.00%)  78.12
length=1728,align1=54,align2=54:        68.75 (0.00%)   72.66 (-5.68%)  68.75
length=1760,align1=0,align2=0:  77.34 (-12.50%) 68.75 (0.00%)   68.75
length=1760,align1=55,align2=0:         91.41 (-8.33%)  79.69 (5.56%)   84.38
length=1760,align1=0,align2=55:         88.28 (-10.78%) 80.47 (-0.98%)  79.69
length=1760,align1=55,align2=55:        77.34 (-11.24%) 68.75 (1.12%)   69.53
length=1792,align1=0,align2=0:  78.12 (-14.94%) 68.75 (-1.15%)  67.97
length=1792,align1=56,align2=0:         88.28 (-4.63%)  79.69 (5.56%)   84.38
length=1792,align1=0,align2=56:         88.28 (-9.71%)  80.47 (0.00%)   80.47
length=1792,align1=56,align2=56:        77.34 (-11.24%) 68.75 (1.12%)   69.53
length=1824,align1=0,align2=0:  72.66 (7.92%)   70.31 (10.89%)  78.91
length=1824,align1=57,align2=0:         85.94 (5.17%)   82.03 (9.48%)   90.62
length=1824,align1=0,align2=57:         82.03 (3.67%)   82.81 (2.75%)   85.16
length=1824,align1=57,align2=57:        70.31 (-1.12%)  70.31 (-1.12%)  69.53
length=1856,align1=0,align2=0:  70.31 (-1.12%)  70.31 (-1.12%)  69.53
length=1856,align1=58,align2=0:         83.59 (-0.94%)  82.03 (0.94%)   82.81
length=1856,align1=0,align2=58:         178.12 (-115.09%)       82.81 (0.00%)   82.81
length=1856,align1=58,align2=58:        70.31 (-1.12%)  70.31 (-1.12%)  69.53
length=1888,align1=0,align2=0:  73.44 (-1.08%)  78.91 (-8.60%)  72.66
length=1888,align1=59,align2=0:         85.94 (0.00%)   89.84 (-4.55%)  85.94
length=1888,align1=0,align2=59:         84.38 (0.00%)   89.06 (-5.56%)  84.38
length=1888,align1=59,align2=59:        72.66 (-1.09%)  78.12 (-8.70%)  71.88
length=1920,align1=0,align2=0:  72.66 (-1.09%)  78.12 (-8.70%)  71.88
length=1920,align1=60,align2=0:         85.94 (0.00%)   89.84 (-4.55%)  85.94
length=1920,align1=0,align2=60:         85.16 (0.00%)   89.06 (-4.59%)  85.16
length=1920,align1=60,align2=60:        72.66 (-1.09%)  78.91 (-9.78%)  71.88
length=1952,align1=0,align2=0:  75.00 (-1.05%)  75.00 (-1.05%)  74.22
length=1952,align1=61,align2=0:         88.28 (0.00%)   87.50 (0.88%)   88.28
length=1952,align1=0,align2=61:         87.50 (0.00%)   88.28 (-0.89%)  87.50
length=1952,align1=61,align2=61:        74.22 (0.00%)   74.22 (0.00%)   74.22
length=1984,align1=0,align2=0:  75.00 (-1.05%)  73.44 (1.05%)   74.22
length=1984,align1=62,align2=0:         89.06 (-0.89%)  87.50 (0.88%)   88.28
length=1984,align1=0,align2=62:         87.50 (0.00%)   88.28 (-0.89%)  87.50
length=1984,align1=62,align2=62:        74.22 (0.00%)   74.22 (0.00%)   74.22
length=2016,align1=0,align2=0:  77.34 (-1.02%)  76.56 (0.00%)   76.56
length=2016,align1=63,align2=0:         91.41 (-0.86%)  90.62 (0.00%)   90.62
length=2016,align1=0,align2=63:         89.84 (0.00%)   90.62 (-0.87%)  89.84
length=2016,align1=63,align2=63:        77.34 (-1.02%)  76.56 (0.00%)   76.56
length=4096,align1=0,align2=0:  141.41 (-0.56%) 146.88 (-4.44%) 140.62

Function: memcpy
__memcpy_thunderx       __memcpy_falkor __memcpy_generic
Variant: large
================================================================================
length=65543,align1=0,align2=0:         4018.75 (3.09%) 2634.38 (36.47%)        4146.88
length=65551,align1=0,align2=3:         4425.00 (-6.47%)        3134.38 (24.59%)        4156.25
length=65567,align1=3,align2=0:         2909.38 (29.95%)        3134.38 (24.53%)        4153.12
length=65599,align1=3,align2=5:         4415.62 (-6.16%)        3134.38 (24.64%)        4159.38
length=131079,align1=0,align2=0:        5765.62 (30.38%)        5240.62 (36.72%)        8281.25
length=131087,align1=0,align2=3:        8831.25 (-6.56%)        6271.88 (24.32%)        8287.50
length=131103,align1=3,align2=0:        5793.75 (29.05%)        6268.75 (23.23%)        8165.62
length=131135,align1=3,align2=5:        5806.25 (29.97%)        6259.38 (24.50%)        8290.62
length=262151,align1=0,align2=0:        11850.00 (28.91%)       10762.50 (35.43%)       16668.80
length=262159,align1=0,align2=3:        12043.80 (27.72%)       12700.00 (23.78%)       16662.50
length=262175,align1=3,align2=0:        12046.90 (27.90%)       12687.50 (24.07%)       16709.40
length=262207,align1=3,align2=5:        11984.40 (28.08%)       12678.10 (23.91%)       16662.50
length=524295,align1=0,align2=0:        24825.00 (25.00%)       24268.80 (27.34%)       33400.00
length=524303,align1=0,align2=3:        35731.20 (-6.53%)       25678.10 (23.44%)       33540.60
length=524319,align1=3,align2=0:        25893.80 (22.71%)       25725.00 (23.22%)       33503.10
length=524351,align1=3,align2=5:        25887.50 (22.86%)       25690.60 (23.45%)       33559.40
length=1048583,align1=0,align2=0:       50621.90 (0.30%)        50600.00 (0.34%)        50771.90
length=1048591,align1=0,align2=3:       53206.20 (0.54%)        51081.20 (4.51%)        53493.80
length=1048607,align1=3,align2=0:       53221.90 (0.32%)        51975.00 (2.66%)        53393.80
length=1048639,align1=3,align2=5:       53240.60 (0.36%)        51953.10 (2.77%)        53431.20
length=2097159,align1=0,align2=0:       103744.00 (-2.00%)      102447.00 (-1.00%)      102425.00
length=2097167,align1=0,align2=3:       108588.00 (-1.00%)      105159.00 (2.00%)       107606.00
length=2097183,align1=3,align2=0:       107678.00 (0.00%)       105250.00 (2.00%)       108125.00
length=2097215,align1=3,align2=5:       107906.00 (1.00%)       105841.00 (3.00%)       109475.00
length=4194311,align1=0,align2=0:       202994.00 (0.00%)       202500.00 (1.00%)       204809.00
length=4194319,align1=0,align2=3:       213350.00 (0.00%)       205997.00 (3.00%)       213384.00
length=4194335,align1=3,align2=0:       212653.00 (0.00%)       206444.00 (3.00%)       212900.00
length=4194367,align1=3,align2=5:       213044.00 (0.00%)       206084.00 (3.00%)       213847.00
length=8388615,align1=0,align2=0:       401294.00 (0.00%)       401231.00 (0.00%)       401944.00
length=8388623,align1=0,align2=3:       480872.00 (-14.00%)     406444.00 (3.00%)       422900.00
length=8388639,align1=3,align2=0:       422147.00 (0.00%)       407750.00 (3.00%)       422803.00
length=8388671,align1=3,align2=5:       442003.00 (-5.00%)      407125.00 (3.00%)       423509.00
length=16777223,align1=0,align2=0:      799809.00 (0.00%)       800000.00 (0.00%)       801756.00
length=16777231,align1=0,align2=3:      841184.00 (0.00%)       808525.00 (4.00%)       843775.00
length=16777247,align1=3,align2=0:      841166.00 (0.00%)       810147.00 (3.00%)       843147.00
length=16777279,align1=3,align2=5:      972569.00 (-16.00%)     808588.00 (4.00%)       843731.00
length=33554439,align1=0,align2=0:      1842240.00 (-0.01%)     1863590.00 (-1.17%)     1841990.00
length=33554447,align1=0,align2=3:      2103470.00 (-2.74%)     1919460.00 (6.25%)      2047440.00
length=33554463,align1=3,align2=0:      2075690.00 (-1.07%)     1930040.00 (6.02%)      2053720.00
length=33554495,align1=3,align2=5:      2110590.00 (-2.82%)     1924440.00 (6.25%)      2052650.00

Function: memcpy
__memcpy_thunderx       __memcpy_falkor __memcpy_generic
Variant: random
================================================================================
max-size=4096:  44061.90 (5.85%)        38568.20 (17.59%)       46799.90
max-size=8192:  42790.90 (5.27%)        38158.90 (15.52%)       45171.50
max-size=16384:         44912.10 (2.25%)        38710.40 (15.75%)       45945.00
max-size=32768:         43577.90 (1.23%)        37975.10 (13.93%)       44120.00
max-size=65536:         44375.50 (1.04%)        38474.20 (14.20%)       44840.60

	* manual/tunables.texi (Tunable glibc.tune.cpu): Add falkor.
	* sysdeps/aarch64/multiarch/Makefile (sysdep_routines): Add
	memcpy_falkor.
	* sysdeps/aarch64/multiarch/ifunc-impl-list.c (MAX_IFUNC):
	Bump.
	(__libc_ifunc_impl_list): Add __memcpy_falkor.
	* sysdeps/aarch64/multiarch/memcpy.c: Likewise.
	* sysdeps/aarch64/multiarch/memcpy_falkor.S: New file.
	* sysdeps/unix/sysv/linux/aarch64/cpu-features.c (cpu_list):
	Add falkor.
	* sysdeps/unix/sysv/linux/aarch64/cpu-features.h (IS_FALKOR):
	New macro.
2017-10-10 15:45:09 +05:30
Carlos O'Donell d5c6dea2d5 Update NEWS for bug 22111. 2017-10-06 13:31:05 -07:00
Carlos O'Donell 6e1ea21501 malloc: Fix tcache leak after thread destruction [BZ #22111]
The malloc tcache added in 2.26 will leak all of the elements remaining
in the cache and the cache structure itself when a thread exits. The
defect is that we do not set tcache_shutting_down early enough, and the
thread simply recreates the tcache and places the elements back onto a
new tcache which is subsequently lost as the thread exits (unfreed
memory). The fix is relatively simple, move the setting of
tcache_shutting_down earlier in tcache_thread_freeres. We add a test
case which uses mallinfo and some heuristics to look for unaccounted for
memory usage between the start and end of a thread start/join loop. It
is very reliable at detecting that there is a leak given the number of
iterations.  Without the fix the test will consume 122MiB of leaked
memory.

(cherry picked from commit 1e26d35193)
2017-10-06 10:35:30 -07:00
H.J. Lu dd3a7239fd test-math-iscanonical.cc: Replace bool with int
Fix GCC 7 compilation error:

test-math-iscanonical.cc: In function ‘void check_type()’:
test-math-iscanonical.cc:33:11: error: use of an operand of type ‘bool’ in ‘operator++’ is deprecated [-Werror=deprecated]
     errors++;
           ^~

Since not all non-zero error counts are errors, return errors != 0
instead.

	* math/test-math-iscanonical.cc (error): Replace bool with int.
	(do_test): Return errors != 0.

(cherry picked from commit cdd4155d6c and
 commit 758f1bfa2a)
2017-10-04 15:03:10 -07:00
Gabriel F. T. Gomes 3b10c5d2ab Add C++ versions of iscanonical for ldbl-96 and ldbl-128ibm (bug 22235)
All representations of floating-point numbers in types with IEC 60559
binary exchange format are canonical.  On the other hand, types with IEC
60559 extended formats, such as those implemented under ldbl-96 and
ldbl-128ibm, contain representations that are not canonical.

TS 18661-1 introduced the type-generic macro iscanonical, which returns
whether a floating-point value is canonical or not.  In Glibc, this
type-generic macro is implemented using the macro __MATH_TG, which, when
support for float128 is enabled, relies on __builtin_types_compatible_p
to select between floating-point types.  However, this use of
iscanonical breaks C++ applications, because the builtin is only
available in C mode.

This patch provides a C++ implementation of iscanonical that relies on
function overloading, rather than builtins, to select between
floating-point types.

Unlike the C++ implementations for iszero and issignaling, this
implementation ignores __NO_LONG_DOUBLE_MATH.  The double type always
matches IEC 60559 double format, which is always canonical.  Thus, when
double and long double are the same (__NO_LONG_DOUBLE_MATH), iscanonical
always returns 1 and is not implemented with __MATH_TG.

Tested for powerpc64, powerpc64le and x86_64.

	[BZ #22235]
	* math/math.h: Trivial fix for unbalanced parentheses in comment.
	* math/Makefile [CXX] (tests): Add test-math-iscanonical.cc.
	(CFLAGS-test-math-iscanonical.cc): New variable.
	* math/test-math-iscanonical.cc: New file.
	* sysdeps/ieee754/ldbl-96/bits/iscanonical.h (iscanonical):
	Provide a C++ implementation based on function overloading,
	rather than using __MATH_TG, which uses C-only builtins.
	* sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h (iscanonical):
	Likewise.
	* sysdeps/powerpc/powerpc64le/Makefile
	(CFLAGS-test-math-iscanonical.cc): New variable.

(cherry picked from commit aa0235dfde)
2017-10-03 16:26:05 -03:00
Joseph Myers 3f68c5c9b6 Fix sparc32 bits/long-double.h (bug 21987).
My refactoring of long double information

commit 0acb8a2a85
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Wed Dec 14 18:27:56 2016 +0000

    Refactor long double information into bits/long-double.h.

resulted in sparc32 configurations installing the ldbl-opt version of
bits/long-double.h instead of the intended
sysdeps/unix/sysv/linux/sparc version.

For sparc32 by itself, this is not a problem, since the ldbl-opt
version is correct for sparc32.  However, both sparc32 and sparc64 are
supposed to install sets of headers that work for both of them, so
that a single sysroot, whichever order the libraries are built and
installed in, works for both.  The effect of having the wrong version
installed is that you end up with a miscompiled sparc64 libstdc++
which fails glibc's configure tests for the C++ compiler.

This patch moves the header from sysdeps/unix/sysv/linux/sparc to
separate copies of the same file for sparc32 and sparc64, to ensure it
comes before ldbl-opt in the sysdeps directory ordering.

Tested with build-many-glibcs.py for sparc64-linux-gnu and
sparcv9-linux-gnu.

	[BZ #21987]
	* sysdeps/unix/sysv/linux/sparc/bits/long-double.h: Remove file
	and copy to ...
	* sysdeps/unix/sysv/linux/sparc/sparc32/bits/long-double.h:
	... here.
	* sysdeps/unix/sysv/linux/sparc/sparc64/bits/long-double.h:
	... and here.

(cherry picked from commit 80f91666fe)
2017-10-02 15:51:05 +00:00
Joseph Myers fdf58ebc60 Add missing bug fixes to list in NEWS file. 2017-09-30 00:48:07 +00:00
Joseph Myers 548cc83c38 Fix nearbyint arithmetic moved before feholdexcept (bug 22225).
In <https://sourceware.org/ml/libc-alpha/2013-05/msg00722.html> I
remarked on the possibility of arithmetic in various nearbyint
implementations being scheduled before feholdexcept calls, resulting
in spurious "inexact" exceptions.

I'm now actually observing this occurring in glibc built for ARM with
GCC 7 (in fact, both copies of the same addition/subtraction sequence
being combined and moved out before the conditionals and
feholdexcept/fesetenv pairs), resulting in test failures.

This patch makes the nearbyint implementations with this particular
feholdexcept / arithmetic / fesetenv pattern consistently use
math_opt_barrier on the function argument when first used in
arithmetic, and also consistently use math_force_eval before fesetenv
(the latter was generally already done, but the dbl-64/wordsize-64
implementation used math_opt_barrier instead, and as
math_opt_barrier's intended effect is through its output value being
used, such a use that doesn't use the return value is suspect).

Tested for x86_64 (--disable-multi-arch so more of these
implementations get used), and for ARM in a configuration where I saw
the problem scheduling.

	[BZ #22225]
	* sysdeps/ieee754/dbl-64/s_nearbyint.c (__nearbyint): Use
	math_opt_barrier on argument when doing arithmetic on it.
	* sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c (__nearbyint):
	Likewise.  Use math_force_eval not math_opt_barrier after
	arithmetic.
	* sysdeps/ieee754/flt-32/s_nearbyintf.c (__nearbyintf): Use
	math_opt_barrier on argument when doing arithmetic on it.
	* sysdeps/ieee754/ldbl-128/s_nearbyintl.c (__nearbyintl):
	Likewise.

(cherry picked from commit f124cb3811)
2017-09-28 02:03:21 +00:00
Gabriel F. T. Gomes d37c951fde Let fpclassify use the builtin when optimizing for size in C++ mode (bug 22146)
When optimization for size is on (-Os), fpclassify does not use the
type-generic __builtin_fpclassify builtin, instead it uses __MATH_TG.
However, when library support for float128 is available, __MATH_TG uses
__builtin_types_compatible_p, which is not available in C++ mode.

On the other hand, libstdc++ undefines (in cmath) many macros from
math.h, including fpclassify, so that it can provide its own functions.
However, during its configure tests, libstdc++ just tests for the
availability of the macros (it does not undefine them, nor does it
provide its own functions).

Finally, when libstdc++ is configured with optimization for size
enabled, its configure tests include math.h and get the definition of
fpclassify that uses __MATH_TG (and __builtin_types_compatible_p).
Since libstdc++ does not undefine the macros during its configure tests,
they fail.

This patch lets fpclassify use the builtin in C++ mode, even when
optimization for size is on.  This allows the configure test in
libstdc++ to work.

Tested for powerpc64le and x86_64.

	[BZ #22146]
	math/math.h: Let fpclassify use the builtin in C++ mode, even
	when optimazing for size.

(cherry picked from commit c5c4a62609)
2017-09-22 17:31:09 -03:00
Gabriel F. T. Gomes 37d4262a7a Fix remaining return type of ifunc resolver declaration
Since Martin Sebor's commit

commit ee4e992ebe
Author: Martin Sebor <msebor@redhat.com>
Date:   Tue Aug 22 09:35:23 2017 -0600

    Declare ifunc resolver to return a pointer to the same type as the target
    function to help GCC detect incompatibilities between the two when it's
    enhanced to do so.

builds for powerpc64le fail in the declaration of some ifunc resolvers,
because the ifunc is declared with unmatching return types.  One of the
declarations comes from the __ifunc_resolver macro, which was patched by
the aforementioned commit:

    /* Helper / base  macros for indirect function symbols.  */
    #define __ifunc_resolver(type_name, name, expr, arg, init, classifier) \
      classifier inhibit_stack_protector                                   \
      __typeof (type_name) *name##_ifunc (arg)                             \

whereas the other comes from the unpatched __ifunc macro when
HAVE_GCC_IFUNC is not defined:

    # define __ifunc(type_name, name, expr, arg, init)                     \
      extern __typeof (type_name) name;                                    \
      void *name##_ifunc (arg) __asm__ (#name);                            \

This patch changes the return type of the ifunc resolver in the __ifunc
macro, so that it matches the return type of the target function,
similarly to what the aforementioned commit does.

Tested for powerpc64le and s390x with unpatched GCC.

	* include/libc-symbols.h: [!defined HAVE_GCC_IFUNC] (__ifunc):
	Change the return type of the ifunc resolver to match the return
	type of the target function.

(cherry picked from commit b513da7e80)
2017-09-19 14:30:22 +02:00
Martin Sebor ac6113cb01 Declare ifunc resolver to return a pointer to the same type as the target
function to help GCC detect incompatibilities between the two when it's
enhanced to do so.

(cherry picked from commit ee4e992ebe)
2017-09-19 14:30:03 +02:00
Alan Modra 2422c6032f tst-tlsopt-powerpc as a shared lib
This makes the __tls_get_addr_opt test run as a shared library, and so
actually test that DTPMOD64/DTPREL64 pairs are processed by ld.so to
support the __tls_get_adfr_opt call stub fast return.  After a
2017-01-24 patch (binutils f0158f4416) ld.bfd no longer emitted
unnecessary dynamic relocations against local thread variables,
instead setting up the __tls_index GOT entries for the call stub fast
return.  This meant tst-tlsopt-powerpc passed but did not check ld.so
relocation support.  After a 2017-07-16 patch (binutils 676ee2b5fa)
ld.bfd no longer set up the __tls_index GOT entries for the call stub
fast return, and tst-tlsopt-powerpc failed.

Compiling mod-tlsopt-powerpc.c with -DSHARED exposed a bug in
powerpc64/tls-macros.h, which defines a __TLS_GET_ADDR macro that
clashes with one defined in dl-tls.h.  The tls-macros.h version is
only used in that file, so delete it and expand.

	* sysdeps/powerpc/mod-tlsopt-powerpc.c: Extract from
	tst-tlsopt-powerpc.c with function name change and no test harness.
	* sysdeps/powerpc/tst-tlsopt-powerpc.c: Remove body of test.
	Call tls_get_addr_opt_test.
	* sysdeps/powerpc/Makefile (LDFLAGS-tst-tlsopt-powerpc): Don't define.
	(modules-names): Add mod-tlsopt-powerpc.
	(mod-tlsopt-powerpc.so-no-z-defs): Define.
	(tst-tlsopt-powerpc): Depend on .so.
	* sysdeps/powerpc/powerpc64/tls-macros.h (__TLS_GET_ADDR): Don't
	define.  Expand use in TLS_GD and TLS_LD.

(cherry picked from commit e98c925fa4)
2017-09-18 18:30:53 +02:00
H.J. Lu 56ce01906e string/stratcliff.c: Replace int with size_t [BZ #21982]
Fix GCC 7 errors when string/stratcliff.c is compiled with -O3:

stratcliff.c: In function ‘do_test’:
cc1: error: assuming signed overflow does not occur when assuming that (X - c) <= X is always true [-Werror=strict-overflow]

	[BZ #21982]
	* string/stratcliff.c (do_test): Declare size, nchars, inner,
	middle and outer with size_t instead of int.  Repleace %d and
	%Zd with %zu in printf.  Update "MAX (0, nchars - 128)" and
	"MAX (outer, nchars - 64)" to support unsigned outer and
	nchars.  Also exit loop when outer == 0.

(cherry picked from commit 376b40a27a)
2017-09-11 08:48:28 -07:00
Markus Trippelsdorf 5f5532caf8 Update x86_64 ulps for AMD Ryzen.
* sysdeps/x86_64/fpu/libm-test-ulps: Update for AMD Ryzen.

(cherry picked from commit 4c03a69680)
2017-09-08 20:00:10 +00:00
H.J. Lu 86553be84d Use "static const char domain[] ="
* resolv/tst-resolv-qtypes.c (domain): Changed to
	"const char domain[] =".

(cherry picked from commit 78bfa877b3)
2017-09-07 13:59:46 -07:00
H.J. Lu dca8b177f6 Place $(elf-objpfx)sofini.os last [BZ #22051]
Since sofini.os terminates .eh_frame section, it should be placed last.

	[BZ #22051]
	* Makerules (build-module-helper-objlist): Filter out
	$(elf-objpfx)sofini.os.
	(build-shlib-objlist): Append $(elf-objpfx)sofini.os if it is
	needed.

(cherry picked from commit ecd0747df3)
2017-09-07 08:27:30 -07:00
Florian Weimer 8a1adb5939 dynarray: Set errno on overflow-induced allocation failure
This allows the caller to return directly on such an error, with an
appropriate errno value.

(cherry picked from commit 5898f4548e)
2017-09-06 16:13:53 +02:00
Florian Weimer d265b61291 __libc_dynarray_emplace_enlarge: Add missing else
Before, arrays of small elements received a starting allocation size of
8, not 16.
2017-09-06 16:09:05 +02:00
Florian Weimer 27233446a6 resolv: __resolv_conf_attach must not free passed conf object [BZ #22096]
(cherry picked from commit a830473081)
2017-09-06 15:47:27 +02:00
Florian Weimer 905a612914 resolv: Fix memory leak with OOM during resolv.conf parsing [BZ #22095]
(cherry picked from commit 5670c4ab25)
2017-09-06 15:46:54 +02:00
Florian Weimer 3005466abe nss_dns: Remove dead PTR IPv4-to-IPv6 mapping code
(cherry picked from commit c77eb96925)
2017-09-06 15:46:20 +02:00
Florian Weimer 85cfe50856 tst-res_use_inet6: Enhance test to cover IPv4-to-IPv6 address mapping
This requires more control over the response data, so it is now
determined by flags embedded in the query name.

(cherry picked from commit 5e9c4d17fe)
2017-09-06 15:46:15 +02:00
Florian Weimer a71a3374cd getaddrinfo: Fix error handling in gethosts [BZ #21915] [BZ #21922]
The old code uses errno as the primary indicator for success or
failure.  This is wrong because errno is only set for specific
combinations of the status return value and the h_errno variable.

(cherry picked from commit f4a6be2582)
2017-09-04 11:44:22 +02:00
Florian Weimer 7966331555 getaddrinfo: Return EAI_NODATA if gethostbyname2_r reports NO_DATA [BZ #21922]
(cherry picked from commit 5f8340f583)
2017-09-04 11:44:22 +02:00
Florian Weimer 7ab87bccb6 getaddrinfo: In gaih_inet, use h_errno for certain status values only
h_errno is not set for NSS_STATUS_SUCCESS, so its value might not be
accurate at this point.

(cherry picked from commit a2881ef014)
2017-09-04 11:44:21 +02:00
Florian Weimer 8f46c60524 getaddrinfo: Properly set errno for NSS function lookup failure
(cherry picked from commit ad816a5e00)
2017-09-04 11:44:21 +02:00
Florian Weimer 701f7873da getaddrinfo: Use &h_errno has the h_errno pointer
This simplifies the code because it is not necessary to propagate the
temporary h_errno value to the thread-local variable.  It also increases
compatibility with NSS modules which update only one of the two places.

(cherry picked from commit 53250a21b8)
2017-09-04 11:44:21 +02:00
Florian Weimer bdd8422cfb getaddrinfo: Use &errno has the errno pointer
Similar code in nss/getXXbyYY_r.c is already using &errno as the
argument.

(cherry picked from commit 924b121c59)
2017-09-04 11:44:21 +02:00
Florian Weimer 5253749232 Synchronize support/ infrastructure with master
This commit updates the support/ subdirectory to
commit 65329bd233
on the master branch.
2017-09-04 11:44:10 +02:00
Florian Weimer 4fdd75e446 getaddrinfo: Remove unreachable return statement from gaih_inet
(cherry picked from commit 0df595b23a)
2017-09-04 11:31:43 +02:00
Joseph Myers 947e2e0a94 Fix position of tests-unsupported definition in assert/Makefile.
tests-unsupported has to be defined before the inclusion of Rules in a
subdirectory Makefile; otherwise it is ineffective.  This patch fixes
the ordering in assert/Makefile, where a recent test addition put
tests-unsupported too late (resulting in build failures when the C++
compiler was missing or broken, and thereby showing up the unrelated
bug 21987).

Incidentally, I don't see why these tests depend on
$(have-cxx-thread_local) rather than just a working C++ compiler.

Tested in such a configuration (broken compiler/libstdc++) with
build-many-glibcs.py.

	* assert/Makefile [$(have-cxx-thread_local)]: Move conditional
	variable definitions above inclusion of ../Rules.

(cherry picked from commit 75dfe623df)
2017-09-04 11:31:43 +02:00
Gabriel F. T. Gomes 58270c0049 Provide a C++ version of iszero that does not use __MATH_TG (bug 21930)
When signaling nans are enabled (with -fsignaling-nans), the C++ version
of iszero uses the fpclassify macro, which is defined with __MATH_TG.
However, when support for float128 is available, __MATH_TG uses the
builtin __builtin_types_compatible_p, which is only available in C mode.

This patch refactors the C++ version of iszero so that it uses function
overloading to select between the floating-point types, instead of
relying on fpclassify and __MATH_TG.

Tested for powerpc64le, s390x, x86_64, and with build-many-glibcs.py.

	[BZ #21930]
	* math/math.h [defined __cplusplus && defined __SUPPORT_SNAN__]
	(iszero): New C++ implementation that does not use
	fpclassify/__MATH_TG/__builtin_types_compatible_p, when
	signaling nans are enabled, since __builtin_types_compatible_p
	is a C-only feature.
	* math/test-math-iszero.cc: When __HAVE_DISTINCT_FLOAT128 is
	defined, include ieee754_float128.h for access to the union and
	member ieee854_float128.ieee.
	[__HAVE_DISTINCT_FLOAT128] (do_test): Call check_float128.
	[__HAVE_DISTINCT_FLOAT128] (check_float128): New function.
	* sysdeps/powerpc/powerpc64le/Makefile [subdir == math]
	(CXXFLAGS-test-math-iszero.cc): Add -mfloat128 to the build
	options of test-math-zero on powerpc64le.

(cherry picked from commit 42496114ec)
2017-08-29 10:33:22 -03:00
Gabriel F. T. Gomes 35dded99a8 Fix the C++ version of issignaling when __NO_LONG_DOUBLE_MATH is defined
When __NO_LONG_DOUBLE_MATH is defined, __issignalingl is not available,
thus issignaling with long double argument should call __issignaling,
instead.

Tested for powerpc64le.

	* math/math.h [defined __cplusplus] (issignaling): In the long
	double case, call __issignalingl only if __NO_LONG_DOUBLE_MATH
	is not defined.  Call __issignaling, otherwise.

(cherry picked from commit 3d7b66f66c)
2017-08-29 10:32:34 -03:00
Gabriel F. T. Gomes ef8566d72a Provide a C++ version of issignaling that does not use __MATH_TG
The macro __MATH_TG contains the logic to select between long double and
_Float128, when these types are ABI-distinct.  This logic relies on
__builtin_types_compatible_p, which is not available in C++ mode.

On the other hand, C++ function overloading provides the means to
distinguish between the floating-point types.  The overloading
resolution will match the correct parameter regardless of type
qualifiers, i.e.: const and volatile.

Tested for powerpc64le, s390x, and x86_64.

	* math/math.h [defined __cplusplus] (issignaling): Provide a C++
	definition for issignaling that does not rely on __MATH_TG,
	since __MATH_TG uses __builtin_types_compatible_p, which is only
	available in C mode.
	(CFLAGS-test-math-issignaling.cc): New variable.
	* math/Makefile [CXX] (tests): Add test-math-issignaling.
	* math/test-math-issignaling.cc: New test for C++ implementation
	of type-generic issignaling.
	* sysdeps/powerpc/powerpc64le/Makefile [subdir == math]
	(CXXFLAGS-test-math-issignaling.cc): Add -mfloat128 to the build
	options of test-math-issignaling on powerpc64le.

(cherry picked from commit a16e8bc08e)
2017-08-29 10:32:29 -03:00
Andreas Schwab 6043d77a47 ldd: never run file directly
(cherry picked from commit eedca9772e)
2017-08-28 19:49:18 +02:00
Florian Weimer 77db8772bd __inet6_scopeid_pton: Remove attribute_hidden, internal_function
The hidden attribute was overridden by libc_hidden_proto on GNU/Linux.
It is incorrect because the function is used from nscd.

internal_function is not supposed to be used across DSO boundaries,
so this commit removes it (again, due to the use in nscd).

(cherry picked from commit f87cc2bfba)
2017-08-22 14:50:56 +02:00
Gabriel F. T. Gomes c9df582f3a Merge release/2.26/master into ibm/2.26/master 2017-08-21 16:29:58 -03:00
Gabriel F. T. Gomes 3aeab55ee1 Add missing bug fixes to NEWS 2017-08-21 15:45:57 -03:00
Florian Weimer fb9a781e9d assert: Support types without operator== (int) [BZ #21972]
(cherry picked from commit b5889d25e9)
2017-08-21 16:13:49 +02:00
Gabriel F. T. Gomes 5e989c3693 Do not use generic selection in C++ mode
The logic to protect the use of generic selection (_Generic) does not
check for C or C++ mode, however, generic selection is a C-only
feature.

Tested for powerpc64le.

	* misc/sys/cdefs.h (__HAVE_GENERIC_SELECTION): Define to 0, if
	in C++ mode.

(cherry picked from commit 6913ad65e0)
2017-08-21 14:24:18 +02:00
Gabriel F. T. Gomes c2921b17a3 Do not use __builtin_types_compatible_p in C++ mode (bug 21930)
The logic to define isinf for float128 depends on the availability of
__builtin_types_compatible_p, which is only available in C mode,
however, the conditionals do not check for C or C++ mode.  This lead to
an error in libstdc++ configure, as reported by bug 21930.

This patch adds a conditional for C mode in the definition of isinf for
float128.  No definition is provided in C++ mode, since libstdc++
headers undefine isinf.

Tested for powerpc64le (glibc test suite and libstdc++-v3 configure).

	[BZ #21930]
	* math/math.h (isinf): Check if in C or C++ mode before using
	__builtin_types_compatible_p, since this is a C mode feature.

(cherry picked from commit 47a67213a9)
2017-08-21 14:23:27 +02:00
Gabriel F. T. Gomes 645b7635ba powerpc: Restrict xssqrtqp operands to Vector Registers (bug 21941)
POWER ISA 3.0 introduces the xssqrtqp instructions, which expects
operands to be in Vector Registers (Altivec/VMX), even though this
instruction belongs to the Vector-Scalar Instruction Set.

In GCC's Extended Assembly for POWER, the 'wq' register constraint is
provided for use with IEEE 754 128-bit floating-point values.  However,
this constraint does not limit the register allocation to Vector
Registers (Altivec/VMX) and could assign a Vector-Scalar Register (VSX)
to the operands of the instruction.

This patch changes the register constraint used in sqrtf128 from 'wq' to
'v', in order to request a Vector Register (Altivec/VMX) for use with
the xssqrtqp instruction.

Tested for powerpc64le and --with-cpu=power9.

	[BZ #21941]
	* sysdeps/powerpc/fpu/math_private.h (__ieee754_sqrtf128): Since
	xssqrtqp requires operands to be in Vector Registers
	(Altivec/VMX), replace the register constraint 'wq' with 'v'.
	* sysdeps/powerpc/powerpc64le/power9/fpu/e_sqrtf128.c
	(__ieee754_sqrtf128): Likewise.

(cherry picked from commit 4d98ace9de)
2017-08-15 12:10:38 -03:00
Florian Weimer 2aa1a7a8f8 assert: Suppress pedantic warning caused by statement expression [BZ #21242]
(cherry picked from commit 8b2c63e4e2)
2017-08-11 15:48:14 +02:00
Florian Weimer c55ad6452e malloc: Avoid optimizer warning with GCC 7 and -O3
(cherry picked from commit eac43cbb8d)
2017-08-10 15:59:23 +02:00
Florian Weimer 302434688d nss: Call __resolv_context_put before early return in get*_r [BZ #21932]
This corrects an oversight introduced in commit
352f4ff9a2 (resolv: Introduce struct
resolv_context).

(cherry picked from commit 3016149819)
2017-08-10 09:10:36 +02:00
Adhemerval Zanella 82efa1ffd4 posix: Set p{read,write}v2 to return ENOTSUP (BZ#21780)
Different than other architectures hppa-linux-gnu define different values
for ENOTSUP and EOPNOTSUPP, where the later is a Linux specific one.
This leads to tst-preadwritev{64}v2 tests failures:

$ ./testrun.sh misc/tst-preadvwritev2
error: tst-preadvwritev2-common.c:35: preadv2 failure did not set errno to ENOTSUP (223)
error: 1 test failures

The straightforward fix is to return the POSIX defined ENOTSUP on all
p{read,write}v{64}v2 implementations instead of Linux specific one.

Checked on x86_64-linux-gnu and the tst-preadwritev{64}v2 on
hppa-linux-gnu (although due the installed kernel on my testing system
the pwritev{64}v2 with an invalid flag still fails due a known kernel
issue [1]).

	[BZ #21780]
	* sysdeps/posix/preadv2.c (preadv2): Use ENOTSUP instead of
	EOPNOTSUPP.
	* sysdeps/posix/preadv64v2.c (preadv64v2): Likewise.
	* sysdeps/posix/pwritev2.c (pwritev2): Likewise.
	* sysdeps/posix/pwritev64v2.c (pwritev64v2): Likewise.
	* sysdeps/unix/sysv/linux/preadv2.c (preadv2): Likewise.
	* sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
	* sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
	* sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.

[1] https://sourceware.org/ml/libc-alpha/2017-06/msg00726.html

Cherry-pick of 852d631207
2017-08-09 11:13:18 -03:00
H.J. Lu 799859f663 x86-64: Use _dl_runtime_resolve_opt only with AVX512F [BZ #21871]
On AVX machines with XGETBV (ECX == 1) like Skylake processors,

(gdb) disass _dl_runtime_resolve_avx_opt
Dump of assembler code for function _dl_runtime_resolve_avx_opt:
   0x0000000000015890 <+0>:	push   %rax
   0x0000000000015891 <+1>:	push   %rcx
   0x0000000000015892 <+2>:	push   %rdx
   0x0000000000015893 <+3>:	mov    $0x1,%ecx
   0x0000000000015898 <+8>:	xgetbv
   0x000000000001589b <+11>:	mov    %eax,%r11d
   0x000000000001589e <+14>:	pop    %rdx
   0x000000000001589f <+15>:	pop    %rcx
   0x00000000000158a0 <+16>:	pop    %rax
   0x00000000000158a1 <+17>:	and    $0x4,%r11d
   0x00000000000158a5 <+21>:	bnd je 0x16200 <_dl_runtime_resolve_sse_vex>
End of assembler dump.

is slower than:

(gdb) disass _dl_runtime_resolve_avx_slow
Dump of assembler code for function _dl_runtime_resolve_avx_slow:
   0x0000000000015850 <+0>:	vorpd  %ymm0,%ymm1,%ymm8
   0x0000000000015854 <+4>:	vorpd  %ymm2,%ymm3,%ymm9
   0x0000000000015858 <+8>:	vorpd  %ymm4,%ymm5,%ymm10
   0x000000000001585c <+12>:	vorpd  %ymm6,%ymm7,%ymm11
   0x0000000000015860 <+16>:	vorpd  %ymm8,%ymm9,%ymm9
   0x0000000000015865 <+21>:	vorpd  %ymm10,%ymm11,%ymm10
   0x000000000001586a <+26>:	vpcmpeqd %xmm8,%xmm8,%xmm8
   0x000000000001586f <+31>:	vorpd  %ymm9,%ymm10,%ymm10
   0x0000000000015874 <+36>:	vptest %ymm10,%ymm8
   0x0000000000015879 <+41>:	bnd jae 0x158b0 <_dl_runtime_resolve_avx>
   0x000000000001587c <+44>:	vzeroupper
   0x000000000001587f <+47>:	bnd jmpq 0x16200 <_dl_runtime_resolve_sse_vex>
End of assembler dump.
(gdb)

since xgetbv takes much more cycles than single cycle operations like
vpord/vvpcmpeq/ptest.  _dl_runtime_resolve_opt should be used only with
AVX512 where AVX512 instructions lead to lower CPU frequency on Skylake
server.

	[BZ #21871]
	* sysdeps/x86/cpu-features.c (init_cpu_features): Set
	bit_arch_Use_dl_runtime_resolve_opt only with AVX512F.

(cherry picked from commit d2cf37c0a2)
2017-08-06 10:44:44 -07:00
Aurelien Jarno a4e5aa1a44 Fix the return type of the getentropy stub
The return type of the getentropy stub is wrongly defined as ssize_t,
while both the <sys/random.h> header and the Linux implementation
define it as int. This patch fixes that.

Changelog:
	* stdlib/getentropy.c (getentropy): Change return type to int.
(cherry picked from commit 2b34e2716f)
2017-08-04 00:41:42 +02:00
Aurelien Jarno 665ce88d68 i686/multiarch: Regenerate ulps
This comes from running “make regen-ulps” on an AMD Opteron 2378 CPU.

Changelog:
	* sysdeps/i386/i686/fpu/multiarch/libm-test-ulps: Regenerated.
(cherry picked from commit 144bdab050)
2017-08-04 00:40:31 +02:00
Florian Weimer dc258ce62a getaddrinfo: Release resolver context on error in gethosts [BZ #21885]
(cherry picked from commit 964263bb8d)
2017-08-03 13:59:17 +02:00
Tulio Magno Quites Machado Filho 63efe9a47f Let ld.so have flags DT_RPATH and DT_RUNPATH
2015-02-20  Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>

	* elf/get-dynamic-info.h: Remove asserts that prevent ld.so from
          having the flags DT_RPATH and DT_RUNPATH.
2017-08-02 18:18:07 -03:00
512 changed files with 20350 additions and 3903 deletions
+1849
View File
File diff suppressed because it is too large Load Diff
-9
View File
@@ -441,15 +441,6 @@ Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
Part of stdio-common/tst-printf.c is copyright C E Chew:
(C) Copyright C E Chew
Feel free to copy, use and distribute this software provided:
1. you do not pretend that you wrote it
2. you leave this copyright notice intact.
Various long double libm functions are copyright Stephen L. Moshier:
Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+4 -1
View File
@@ -686,14 +686,17 @@ $(build-module-helper) -o $@ $(shlib-lds-flags) \
$(call after-link,$@)
endef
# sofini.os must be placed last since it terminates .eh_frame section.
build-module-helper-objlist = \
$(patsubst %_pic.a,$(whole-archive) %_pic.a $(no-whole-archive),\
$(filter-out %.lds $(map-file) $(+preinit) $(+postinit) \
$(elf-objpfx)sofini.os \
$(link-libc-deps),$^))
build-module-objlist = $(build-module-helper-objlist) $(LDLIBS-$(@F:%.so=%).so)
build-shlib-objlist = $(build-module-helper-objlist) \
$(LDLIBS-$(@F:lib%.so=%).so)
$(LDLIBS-$(@F:lib%.so=%).so) \
$(filter $(elf-objpfx)sofini.os,$^)
# Don't try to use -lc when making libc.so itself.
# Also omits crti.o and crtn.o, which we do not want
+192
View File
@@ -4,6 +4,194 @@ See the end for copying conditions.
Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
Version 2.26.1
Major new features:
* 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.
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).
Reported by Tim Rühsen.
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-17426: The malloc function, when called with an object size near
the value SIZE_MAX, would return a pointer to a buffer which is too small,
instead of NULL. This was a regression introduced with the new malloc
thread cache in glibc 2.26. Reported by Iain Buclaw.
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-2017-18269: An SSE2-based memmove implementation for the i386
architecture could corrupt memory. Reported by Max Horn.
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.
CVE-2018-6485: The posix_memalign and memalign functions, when called with
an object size near the value of SIZE_MAX, would return a pointer to a
buffer which is too small, instead of NULL. Reported by Jakub Wilk.
CVE-2018-6551: The malloc function, when called with an object size near
the value of SIZE_MAX, would return a pointer to a buffer which is too
small, instead of NULL.
CVE-2018-11236: Very long pathname arguments to realpath function could
result in an integer overflow and buffer overflow. Reported by Alexey
Izbyshev.
CVE-2018-11237: The mempcpy implementation for the Intel Xeon Phi
architecture could write beyond the target buffer, resulting in a buffer
overflow. Reported by Andreas Schwab.
CVE-2018-19591: A file descriptor leak in if_nametoindex can lead to a
denial of service due to resource exhaustion when processing getaddrinfo
calls with crafted host names. Reported by Guido Vranken.
CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
32 bits of a 64-bit register with with non-zero upper 32 bit. When it
happened, accessing the 32-bit size_t value as the full 64-bit register
in the assembly string/memory functions would cause a buffer overflow.
Reported by H.J. Lu.
CVE-2019-7309: x86-64 memcmp used signed Jcc instructions to check
size. For x86-64, memcmp on an object size larger than SSIZE_MAX
has undefined behavior. On x32, the size_t argument may be passed
in the lower 32 bits of the 64-bit RDX register with non-zero upper
32 bits. When it happened with the sign bit of RDX register set,
memcmp gave the wrong result since it treated the size argument as
zero. Reported by H.J. Lu.
CVE-2019-19126: ld.so failed to ignore the LD_PREFER_MAP_32BIT_EXEC
environment variable during program execution after a security
transition, allowing local attackers to restrict the possible mapping
addresses for loaded libraries and thus bypass ASLR for a setuid
program. Reported by Marcin Kościelnicki.
The following bugs are resolved with this release:
[16750] ldd: Never run file directly.
[17343] Fix signed integer overflow in random_r
[17956] crypt: Use NSPR header files in addition to NSS header files
[20419] elf: Fix stack overflow with huge PT_NOTE segment
[20532] getaddrinfo: More robust handling of dlopen failures
[20568] Fix crash in _IO_wfile_sync
[21242] assert: Suppress pedantic warning caused by statement expression
[21265] x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve
[21269] i386 sigaction sa_restorer handling is wrong
[21780] posix: Set p{read,write}v2 to return ENOTSUP
[21812] getifaddrs: Don't return ifa entries with NULL names
[21871] x86-64: Use _dl_runtime_resolve_opt only with AVX512F
[21885] getaddrinfo: Release resolver context on error in gethosts
[21915] getaddrinfo: incorrect result handling for NSS service modules
[21922] getaddrinfo with AF_INET(6) returns EAI_NONAME, not EAI_NODATA
[21930] Do not use __builtin_types_compatible_p in C++ mode
[21932] Unpaired __resolv_context_get in generic get*_r implementation
[21941] powerpc: Restrict xssqrtqp operands to Vector Registers
[21972] assert macro requires operator== (int) for its argument type
[21982] string: stratcliff.c: error: assuming signed overflow does not
occur with -O3
[21987] Fix sparc32 bits/long-double.h
[22051] libc: zero terminator in the middle of glibc's .eh_frame
[22052] malloc failed to compile with GCC 7 and -O3
[22078] nss_files performance issue in hosts multi mode
[22093] x86: Add x86_64 to x86-64 HWCAP
[22095] resolv: Fix memory leak with OOM during resolv.conf parsing
[22096] resolv: __resolv_conf_attach must not free passed conf object
[22111] malloc: per thread cache is not returned when thread exits
[22145] ttyname gives up too early in the face of namespaces
[22146] Let fpclassify use the builtin when optimizing for size in C++ mode
[22225] math: nearbyint arithmetic moved before feholdexcept
[22235] Add C++ versions of iscanonical for ldbl-96 and ldbl-128ibm
[22296] Let signbit use the builtin in C++ mode with gcc < 6.x
[22299] x86-64: Don't set GLRO(dl_platform) to NULL
[22320] glob: Fix one-byte overflow (CVE-2017-15670)
[22321] sysconf: Fix missing definition of UIO_MAXIOV on Linux
[22322] libc: [mips64] wrong bits/long-double.h installed
[22325] glibc: Memory leak in glob with GLOB_TILDE (CVE-2017-15671)
[22342] NSCD not properly caching netgroup
[22343] malloc: Integer overflow in posix_memalign (CVE-2018-6485)
[22375] malloc returns pointer from tcache instead of NULL (CVE-2017-17426)
[22377] Provide a C++ version of iseqsig
[22442] if_nametoindex: Check length of ifname before copying it
[22446] Fix nscd readlink argument aliasing
[22447] Avoid use of strlen in getlogin_r
[22463] Fix p_secstodate overflow handling
[22627] $ORIGIN in $LD_LIBRARY_PATH is substituted twice
[22636] PTHREAD_STACK_MIN is too small on x86-64
[22637] nptl: Fix stack guard size accounting
[22644] Fix i386 memmove issue
[22679] getcwd(3) can succeed without returning an absolute path
(CVE-2018-1000001)
[22685] powerpc: Fix syscalls during early process initialization
[22715] x86-64: Properly align La_x86_64_retval to VEC_SIZE
[22753] libc: preadv2/pwritev2 fallback code should handle offset=-1
[22774] malloc: Integer overflow in malloc (CVE-2018-6551)
[22786] Fix path length overflow in realpath
[22927] libanl: properly cleanup if first helper thread creation failed
[23005] resolv: Fix crash in resolver on memory allocation failure
[23024] getlogin_r: return early when linux sentinel value is set
[23037] resolv: Fully initialize struct mmsghdr in send_dg
[23137] s390: Fix blocking pthread_join
[23171] Fix parameter type in C++ version of iseqsig
[23196] __mempcpy_avx512_no_vzeroupper mishandles large copies
[23236] Harden function pointers in _IO_str_fields
[23313] libio: Disable vtable validation in case of interposition
[23349] Various glibc headers no longer compatible with <linux/time.h>
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
[23363] stdio-common/tst-printf.c has non-free license
[23456] Wrong index_cpu_LZCNT
[23459] COMMON_CPUID_INDEX_80000001 isn't populated for Intel processors
[23562] signal: Use correct type for si_band in siginfo_t
[23579] libc: Errors misreported in preadv2
[23709] Fix CPU string flags for Haswell-type CPUs
[23927] Linux if_nametoindex() does not close descriptor (CVE-2018-19591)
[24018] gettext may return NULL
[24027] malloc: Integer overflow in realloc
[24097] Can't use 64-bit register for size_t in assembly codes for x32 (CVE-2019-6488)
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
[25203] libio: Disable vtable validation for pre-2.1 interposed handles
[25204] Ignore LD_PREFER_MAP_32BIT_EXEC for SUID programs
[25423] Array overflow in backtrace on powerpc
Version 2.26
@@ -206,6 +394,9 @@ Security related changes:
* A use-after-free vulnerability in clntudp_call in the Sun RPC system has been
fixed (CVE-2017-12133).
* A use-after-free vulnerability in the glob function when expanding ~user has
been fixed (CVE-2020-1752).
The following bugs are resolved with this release:
[984] network: Respond to changed resolv.conf in gethostbyname
@@ -433,6 +624,7 @@ The following bugs are resolved with this release:
[21839] localedata: Fix LC_MONETARY for ta_LK
[21844] localedata: Fix Latin characters and Months Sequence.
[21848] localedata: Fix mai_NP Title Name
[25414] 'glob' use-after-free bug (CVE-2020-1752)
Version 2.25
+10 -1
View File
@@ -25,6 +25,15 @@ include ../Makeconfig
headers := assert.h
routines := assert assert-perr __assert
tests := test-assert test-assert-perr
tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++
ifeq ($(have-cxx-thread_local),yes)
CFLAGS-tst-assert-c++.o = -std=c++11
LDLIBS-tst-assert-c++ = -lstdc++
CFLAGS-tst-assert-g++.o = -std=gnu++11
LDLIBS-tst-assert-g++ = -lstdc++
else
tests-unsupported += tst-assert-c++ tst-assert-g++
endif
include ../Rules
+14 -4
View File
@@ -85,19 +85,29 @@ __END_DECLS
/* When possible, define assert so that it does not add extra
parentheses around EXPR. Otherwise, those added parentheses would
suppress warnings we'd expect to be detected by gcc's -Wparentheses. */
# if !defined __GNUC__ || defined __STRICT_ANSI__
# if defined __cplusplus
# define assert(expr) \
(static_cast <bool> (expr) \
? void (0) \
: __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
# elif !defined __GNUC__ || defined __STRICT_ANSI__
# define assert(expr) \
((expr) \
? __ASSERT_VOID_CAST (0) \
: __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
# else
/* The first occurrence of EXPR is not evaluated due to the sizeof,
but will trigger any pedantic warnings masked by the __extension__
for the second occurrence. The ternary operator is required to
support function pointers and bit fields in this context, and to
suppress the evaluation of variable length arrays. */
# define assert(expr) \
({ \
((void) sizeof ((expr) ? 1 : 0), __extension__ ({ \
if (expr) \
; /* empty */ \
else \
__assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION); \
})
}))
# endif
# ifdef __USE_GNU
@@ -113,7 +123,7 @@ __END_DECLS
C9x has a similar variable called __func__, but prefer the GCC one since
it demangles C++ function names. */
# if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4)
# define __ASSERT_FUNCTION __PRETTY_FUNCTION__
# define __ASSERT_FUNCTION __extension__ __PRETTY_FUNCTION__
# else
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
# define __ASSERT_FUNCTION __func__
+78
View File
@@ -0,0 +1,78 @@
/* Tests for interactions between C++ and assert.
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 <assert.h>
/* The C++ standard requires that if the assert argument is a constant
subexpression, then the assert itself is one, too. */
constexpr int
check_constexpr ()
{
return (assert (true), 1);
}
/* Objects of this class can be contextually converted to bool, but
cannot be compared to int. */
struct no_int
{
no_int () = default;
no_int (const no_int &) = delete;
explicit operator bool () const
{
return true;
}
bool operator! () const; /* No definition. */
template <class T> bool operator== (T) const; /* No definition. */
template <class T> bool operator!= (T) const; /* No definition. */
};
/* This class tests that operator== is not used by assert. */
struct bool_and_int
{
bool_and_int () = default;
bool_and_int (const no_int &) = delete;
explicit operator bool () const
{
return true;
}
bool operator! () const; /* No definition. */
template <class T> bool operator== (T) const; /* No definition. */
template <class T> bool operator!= (T) const; /* No definition. */
};
static int
do_test ()
{
{
no_int value;
assert (value);
}
{
bool_and_int value;
assert (value);
}
return 0;
}
#include <support/test-driver.c>
+19
View File
@@ -0,0 +1,19 @@
/* Tests for interactions between C++ and assert. GNU C++11 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/>. */
#include <tst-assert-c++.cc>
+1
View File
@@ -24,6 +24,7 @@
#define STRCASESTR simple_strcasestr
#define NO_ALIAS
#define __strncasecmp strncasecmp
#define __strnlen strnlen
#include "../string/strcasestr.c"
+3
View File
@@ -22,6 +22,9 @@
#define STRSTR simple_strstr
#undef libc_hidden_builtin_def
#define libc_hidden_builtin_def(X)
#define __strnlen strnlen
#include "../string/strstr.c"
Vendored
+5 -1
View File
@@ -3547,8 +3547,12 @@ if test x$nss_crypt = xyes; then
if test $? -ne 0; then
as_fn_error $? "cannot find include directory with nss-config" "$LINENO" 5
fi
nspr_includes=-I$(nspr-config --includedir 2>/dev/null)
if test $? -ne 0; then
as_fn_error $? "cannot find include directory with nspr-config" "$LINENO" 5
fi
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $nss_includes"
CFLAGS="$CFLAGS $nss_includes $nspr_includes"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+5 -1
View File
@@ -330,8 +330,12 @@ if test x$nss_crypt = xyes; then
if test $? -ne 0; then
AC_MSG_ERROR([cannot find include directory with nss-config])
fi
nspr_includes=-I$(nspr-config --includedir 2>/dev/null)
if test $? -ne 0; then
AC_MSG_ERROR([cannot find include directory with nspr-config])
fi
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $nss_includes"
CFLAGS="$CFLAGS $nss_includes $nspr_includes"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([typedef int PRBool;
#include <hasht.h>
#include <nsslowhash.h>
+13 -13
View File
@@ -367,7 +367,7 @@ while ($#headers >= 0) {
s/^optional-//;
$optional = 1;
}
if (/^element *({([^}]*)}|([^{ ]*)) *({([^}]*)}|([^{ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
if (/^element *(\{([^}]*)\}|([^{ ]*)) *(\{([^}]*)\}|([^{ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
my($struct) = "$2$3";
my($type) = "$5$6";
my($member) = "$7";
@@ -556,7 +556,7 @@ while ($#headers >= 0) {
"Symbol \"$symbol\" has not the right value.", $res,
$xfail);
}
} elsif (/^type *({([^}]*)|([a-zA-Z0-9_]*))/) {
} elsif (/^type *(\{([^}]*)|([a-zA-Z0-9_]*))/) {
my($type) = "$2$3";
my($maybe_opaque) = 0;
@@ -586,7 +586,7 @@ while ($#headers >= 0) {
? "NOT AVAILABLE"
: "Type \"$type\" not available."), $missing, $optional,
$xfail);
} elsif (/^tag *({([^}]*)|([a-zA-Z0-9_]*))/) {
} elsif (/^tag *(\{([^}]*)|([a-zA-Z0-9_]*))/) {
my($type) = "$2$3";
# Remember that this name is allowed.
@@ -607,7 +607,7 @@ while ($#headers >= 0) {
compiletest ($fnamebase, "Testing for type $type",
"Type \"$type\" not available.", $missing, 0, $xfail);
} elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
} elsif (/^function *(\{([^}]*)\}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
my($rettype) = "$2$3";
my($fname) = "$4";
my($args) = "$5";
@@ -644,7 +644,7 @@ while ($#headers >= 0) {
"Function \"$fname\" has incorrect type.", $res, 0,
$xfail);
}
} elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
} elsif (/^function *(\{([^}]*)\}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
my($rettype) = "$2$3";
my($fname) = "$4";
my($args) = "$5";
@@ -681,7 +681,7 @@ while ($#headers >= 0) {
"Function \"$fname\" has incorrect type.", $res, 0,
$xfail);
}
} elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) *(.*)/) {
} elsif (/^variable *(\{([^}]*)\}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) *(.*)/) {
my($type) = "$2$3";
my($vname) = "$4";
my($rest) = "$5";
@@ -713,7 +713,7 @@ while ($#headers >= 0) {
compiletest ($fnamebase, "Test for type of variable $fname",
"Variable \"$vname\" has incorrect type.", $res, 0, $xfail);
} elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
} elsif (/^macro-function *(\{([^}]*)\}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
my($rettype) = "$2$3";
my($fname) = "$4";
my($args) = "$5";
@@ -812,11 +812,11 @@ while ($#headers >= 0) {
s/^xfail(\[([^\]]*)\])?-//;
s/^optional-//;
if (/^element *({([^}]*)}|([^ ]*)) *({([^}]*)}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
if (/^element *(\{([^}]*)\}|([^ ]*)) *(\{([^}]*)\}|([^ ]*)) *([A-Za-z0-9_]*) *(.*)/) {
push @allow, $7;
} elsif (/^(macro|constant|macro-constant|macro-int-constant) +([a-zA-Z0-9_]*) *(?:{([^}]*)} *)?(?:([>=<!]+) ([A-Za-z0-9_-]*))?/) {
push @allow, $2;
} elsif (/^(type|tag) *({([^}]*)|([a-zA-Z0-9_]*))/) {
} elsif (/^(type|tag) *(\{([^}]*)|([a-zA-Z0-9_]*))/) {
my($type) = "$3$4";
# Remember that this name is allowed.
@@ -827,13 +827,13 @@ while ($#headers >= 0) {
} else {
push @allow, $type;
}
} elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
} elsif (/^function *(\{([^}]*)\}|([a-zA-Z0-9_]*)) [(][*]([a-zA-Z0-9_]*) ([(].*[)])/) {
push @allow, $4;
} elsif (/^function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
} elsif (/^function *(\{([^}]*)\}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
push @allow, $4;
} elsif (/^variable *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
} elsif (/^variable *(\{([^}]*)\}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*)/) {
push @allow, $4;
} elsif (/^macro-function *({([^}]*)}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
} elsif (/^macro-function *(\{([^}]*)\}|([a-zA-Z0-9_]*)) ([a-zA-Z0-9_]*) ([(].*[)])/) {
push @allow, $4;
} elsif (/^symbol *([a-zA-Z0-9_]*) *([A-Za-z0-9_-]*)?/) {
push @allow, $1;
+5 -3
View File
@@ -37,9 +37,11 @@ routines += $(libcrypt-routines)
endif
ifeq ($(nss-crypt),yes)
CPPFLAGS-sha256-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
CPPFLAGS-sha512-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
CPPFLAGS-md5-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
nss-cpp-flags := -DUSE_NSS \
-I$(shell nss-config --includedir) -I$(shell nspr-config --includedir)
CPPFLAGS-sha256-crypt.c = $(nss-cpp-flags)
CPPFLAGS-sha512-crypt.c = $(nss-cpp-flags)
CPPFLAGS-md5-crypt.c = $(nss-cpp-flags)
LDLIBS-crypt.so = -lfreebl3
else
libcrypt-routines += md5 sha256 sha512
+12
View File
@@ -88,6 +88,18 @@ handle_signal (int signum)
}
/* Symbol names are not available for static functions, so we do not
check do_test. */
/* Check that backtrace does not return more than what fits in the array
(bug 25423). */
for (int j = 0; j < NUM_FUNCTIONS; j++)
{
n = backtrace (addresses, j);
if (n > j)
{
FAIL ();
return;
}
}
}
NO_INLINE int
+2 -2
View File
@@ -55,8 +55,8 @@ __vasprintf_chk (char **result_ptr, int flags, const char *format,
_IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
_IO_str_init_static_internal (&sf, string, init_string_size, string);
sf._sbf._f._flags &= ~_IO_USER_BUF;
sf._s._allocate_buffer = (_IO_alloc_type) malloc;
sf._s._free_buffer = (_IO_free_type) free;
sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
sf._s._free_buffer_unused = (_IO_free_type) free;
/* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
can only come from read-only format strings. */
+7 -2
View File
@@ -179,7 +179,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose
tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
tst-big-note
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -263,7 +264,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin
tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
tst-big-note-lib
ifeq (yes,$(have-mtls-dialect-gnu2))
tests += tst-gnu2-tls1
modules-names += tst-gnu2-tls1mod
@@ -1410,3 +1413,5 @@ tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \
LD_HWCAP_MASK=0x1
tst-env-setuid-tunables-ENV = \
GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096
$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
+66 -55
View File
@@ -37,6 +37,7 @@
#include <sysdep.h>
#include <stap-probe.h>
#include <libc-pointer-arith.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,32 +434,41 @@ 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);
size_t len = strlen (cp);
/* `strsep' can pass an empty string. This has to be
interpreted as `use the current directory'. */
if (len == 0)
/* `strsep' can pass an empty string. */
if (*cp != '\0')
{
static const char curwd[] = "./";
cp = (char *) curwd;
to_free = cp = expand_dynamic_string_token (l, cp, 1);
/* expand_dynamic_string_token can return NULL in case of empty
path or memory allocation failure. */
if (cp == NULL)
continue;
/* 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;
/* Now add one if there is none so far. */
if (len > 0 && cp[len - 1] != '/')
cp[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++] = '/';
/* 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 *));
@@ -1526,6 +1520,7 @@ open_verify (const char *name, int fd,
ElfW(Ehdr) *ehdr;
ElfW(Phdr) *phdr, *ph;
ElfW(Word) *abi_note;
ElfW(Word) *abi_note_malloced = NULL;
unsigned int osversion;
size_t maplength;
@@ -1685,10 +1680,25 @@ open_verify (const char *name, int fd,
abi_note = (void *) (fbp->buf + ph->p_offset);
else
{
abi_note = alloca (size);
/* Note: __libc_use_alloca is not usable here, because
thread info may not have been set up yet. */
if (size < __MAX_ALLOCA_CUTOFF)
abi_note = alloca (size);
else
{
/* There could be multiple PT_NOTEs. */
abi_note_malloced = realloc (abi_note_malloced, size);
if (abi_note_malloced == NULL)
goto read_error;
abi_note = abi_note_malloced;
}
__lseek (fd, ph->p_offset, SEEK_SET);
if (__libc_read (fd, (void *) abi_note, size) != size)
goto read_error;
{
free (abi_note_malloced);
goto read_error;
}
}
while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
@@ -1724,6 +1734,7 @@ open_verify (const char *name, int fd,
break;
}
free (abi_note_malloced);
}
return fd;
+4 -11
View File
@@ -88,18 +88,11 @@ get_next_env (char **envp, char **name, size_t *namelen, char **val,
return NULL;
}
#define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type, __default_min, \
__default_max) \
#define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type) \
({ \
__type min = (__cur)->type.min; \
__type max = (__cur)->type.max; \
\
if (min == max) \
{ \
min = __default_min; \
max = __default_max; \
} \
\
if ((__type) (__val) >= min && (__type) (val) <= max) \
{ \
(__cur)->val.numval = val; \
@@ -119,17 +112,17 @@ do_tunable_update_val (tunable_t *cur, const void *valp)
{
case TUNABLE_TYPE_INT_32:
{
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t, INT32_MIN, INT32_MAX);
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t);
break;
}
case TUNABLE_TYPE_UINT_64:
{
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t, 0, UINT64_MAX);
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
break;
}
case TUNABLE_TYPE_SIZE_T:
{
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t, 0, SIZE_MAX);
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
break;
}
case TUNABLE_TYPE_STRING:
+7
View File
@@ -2759,6 +2759,13 @@ enum
#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */
/* AArch64 specific values for the Dyn d_tag field. */
#define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5)
#define DT_AARCH64_NUM 6
/* AArch64 specific values for the st_other field. */
#define STO_AARCH64_VARIANT_PCS 0x80
/* ARM relocs. */
#define R_ARM_NONE 0 /* No reloc */
-3
View File
@@ -141,9 +141,6 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|| (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
assert (info[DT_FLAGS] == NULL
|| (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
/* Flags must not be set for ld.so. */
assert (info[DT_RUNPATH] == NULL);
assert (info[DT_RPATH] == NULL);
#else
if (info[DT_FLAGS] != NULL)
{
+1 -13
View File
@@ -164,18 +164,6 @@ warning: you do not have execution permission for" "\`$file'" >&2
fi
done
case $ret in
0)
# If the program exits with exit code 5, it means the process has been
# invoked with __libc_enable_secure. Fall back to running it through
# the dynamic linker.
try_trace "$file"
rc=$?
if [ $rc = 5 ]; then
try_trace "$RTLD" "$file"
rc=$?
fi
[ $rc = 0 ] || result=1
;;
1)
# This can be a non-ELF binary or no binary at all.
nonelf "$file" || {
@@ -183,7 +171,7 @@ warning: you do not have execution permission for" "\`$file'" >&2
result=1
}
;;
2)
0|2)
try_trace "$RTLD" "$file" || result=1
;;
*)
+26
View File
@@ -0,0 +1,26 @@
/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This creates a .so with 8MiB PT_NOTE segment.
On a typical Linux system with 8MiB "ulimit -s", that was enough
to trigger stack overflow in open_verify. */
.pushsection .note.big,"a"
.balign 4
.fill 8*1024*1024, 1, 0
.popsection
+26
View File
@@ -0,0 +1,26 @@
/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This file must be run from within a directory called "elf". */
int main (int argc, char *argv[])
{
/* Nothing to do here: merely linking against tst-big-note-lib.so triggers
the bug. */
return 0;
}
+36
View File
@@ -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 */
+3 -2
View File
@@ -782,7 +782,8 @@ for linking")
/* Helper / base macros for indirect function symbols. */
#define __ifunc_resolver(type_name, name, expr, arg, init, classifier) \
classifier inhibit_stack_protector void *name##_ifunc (arg) \
classifier inhibit_stack_protector \
__typeof (type_name) *name##_ifunc (arg) \
{ \
init (); \
__typeof (type_name) *res = expr; \
@@ -809,7 +810,7 @@ for linking")
# define __ifunc(type_name, name, expr, arg, init) \
extern __typeof (type_name) name; \
void *name##_ifunc (arg) __asm__ (#name); \
__typeof (type_name) *name##_ifunc (arg) __asm__ (#name); \
__ifunc_resolver (type_name, name, expr, arg, init,) \
__asm__ (".type " #name ", %gnu_indirect_function");
+1 -1
View File
@@ -28,7 +28,7 @@
/* Parse SOURCE as a scope ID for ADDRESS. Return 0 on success and -1
on error. */
internal_function int
int
__inet6_scopeid_pton (const struct in6_addr *address, const char *scope,
uint32_t *result)
{
+1 -2
View File
@@ -25,8 +25,7 @@
#include <sys/time.h>
int __inet6_scopeid_pton (const struct in6_addr *address,
const char *scope, uint32_t *result)
internal_function attribute_hidden;
const char *scope, uint32_t *result);
libc_hidden_proto (__inet6_scopeid_pton)
+1 -1
View File
@@ -635,7 +635,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
int ret = __asprintf (&xdirname, "%s/%s", cwd, dirname);
free (cwd);
if (ret < 0)
return NULL;
goto return_untranslated;
dirname = xdirname;
}
#ifndef IN_LIBGLOCALE
+1 -1
View File
@@ -70,7 +70,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
tst-posix_fallocate tst-posix_fallocate64 \
tst-fts tst-fts-lfs tst-open-tmpfile
tst-fts tst-fts-lfs tst-open-tmpfile tst-getcwd-abspath
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)ftwtest.out
+66
View File
@@ -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>
+5 -1
View File
@@ -62,7 +62,10 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
bug-memstream1 bug-wmemstream1 \
tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
tst-ftell-append tst-fputws
tst-ftell-append tst-fputws tst-wfile-sync
tests-internal = tst-vtables tst-vtables-interposed
ifeq (yes,$(build-shared))
# Add test-fopenloc only if shared library is enabled since it depends on
# shared localedata objects.
@@ -199,6 +202,7 @@ $(objpfx)tst-ungetwc1.out: $(gen-locales)
$(objpfx)tst-ungetwc2.out: $(gen-locales)
$(objpfx)tst-widetext.out: $(gen-locales)
$(objpfx)tst_wprintf2.out: $(gen-locales)
$(objpfx)tst-wfile-sync.out: $(gen-locales)
endif
$(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen
+2 -2
View File
@@ -90,8 +90,8 @@ __open_memstream (char **bufloc, _IO_size_t *sizeloc)
_IO_JUMPS_FILE_plus (&new_f->fp._sf._sbf) = &_IO_mem_jumps;
_IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
new_f->fp.bufloc = bufloc;
new_f->fp.sizeloc = sizeloc;
+5
View File
@@ -87,6 +87,11 @@ _IO_check_libio (void)
stdout->_vtable_offset = stderr->_vtable_offset =
((int) sizeof (struct _IO_FILE)
- (int) sizeof (struct _IO_FILE_complete));
if (_IO_stdin_.vtable != &_IO_old_file_jumps
|| _IO_stdout_.vtable != &_IO_old_file_jumps
|| _IO_stderr_.vtable != &_IO_old_file_jumps)
IO_set_accept_foreign_vtables (&_IO_vtable_check);
}
}
+5 -6
View File
@@ -34,8 +34,11 @@ typedef void (*_IO_free_type) (void*);
struct _IO_str_fields
{
_IO_alloc_type _allocate_buffer;
_IO_free_type _free_buffer;
/* These members are preserved for ABI compatibility. The glibc
implementation always calls malloc/free for user buffers if
_IO_USER_BUF or _IO_FLAGS2_USER_WBUF are not set. */
_IO_alloc_type _allocate_buffer_unused;
_IO_free_type _free_buffer_unused;
};
/* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type,
@@ -55,10 +58,6 @@ typedef struct _IO_strfile_
struct _IO_str_fields _s;
} _IO_strfile;
/* dynamic: set when the array object is allocated (or reallocated) as
necessary to hold a character sequence that can change in length. */
#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0)
/* frozen: set when the program has requested that the array object not
be altered, reallocated, or freed. */
#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF)
+6 -8
View File
@@ -61,7 +61,7 @@ _IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size,
fp->_IO_read_end = end;
}
/* A null _allocate_buffer function flags the strfile as being static. */
sf->_s._allocate_buffer = (_IO_alloc_type) 0;
sf->_s._allocate_buffer_unused = (_IO_alloc_type) 0;
}
void
@@ -103,8 +103,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
_IO_size_t new_size = 2 * old_blen + 100;
if (new_size < old_blen)
return EOF;
new_buf
= (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
new_buf = malloc (new_size);
if (new_buf == NULL)
{
/* __ferror(fp) = 1; */
@@ -113,7 +112,7 @@ _IO_str_overflow (_IO_FILE *fp, int c)
if (old_buf)
{
memcpy (new_buf, old_buf, old_blen);
(*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
free (old_buf);
/* Make sure _IO_setb won't try to delete _IO_buf_base. */
fp->_IO_buf_base = NULL;
}
@@ -182,15 +181,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
_IO_size_t newsize = offset + 100;
char *oldbuf = fp->_IO_buf_base;
char *newbuf
= (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize);
char *newbuf = malloc (newsize);
if (newbuf == NULL)
return 1;
if (oldbuf != NULL)
{
memcpy (newbuf, oldbuf, _IO_blen (fp));
(*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
free (oldbuf);
/* Make sure _IO_setb won't try to delete
_IO_buf_base. */
fp->_IO_buf_base = NULL;
@@ -346,7 +344,7 @@ void
_IO_str_finish (_IO_FILE *fp, int dummy)
{
if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
(((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
free (fp->_IO_buf_base);
fp->_IO_buf_base = NULL;
_IO_default_finish (fp, 0);
+511
View File
@@ -0,0 +1,511 @@
/* Test for libio vtables and their validation. Common code.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This test provides some coverage for how various stdio functions
use the vtables in FILE * objects. The focus is mostly on which
functions call which methods, not so much on validating data
processing. An initial series of tests check that custom vtables
do not work without activation through _IO_init.
Note: libio vtables are deprecated feature. Do not use this test
as a documentation source for writing custom vtables. See
fopencookie for a different way of creating custom stdio
streams. */
#include <stdbool.h>
#include <string.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/namespace.h>
#include <support/support.h>
#include <support/test-driver.h>
#include <support/xunistd.h>
/* Data shared between the test subprocess and the test driver in the
parent. Note that *shared is reset at the start of the check_call
function. */
struct shared
{
/* Expected file pointer for method calls. */
FILE *fp;
/* If true, assume that a call to _IO_init is needed to enable
custom vtables. */
bool initially_disabled;
/* Requested return value for the methods which have one. */
int return_value;
/* A value (usually a character) recorded by some of the methods
below. */
int value;
/* Likewise, for some data. */
char buffer[16];
size_t buffer_length;
/* Total number of method calls. */
unsigned int calls;
/* Individual method call counts. */
unsigned int calls_finish;
unsigned int calls_overflow;
unsigned int calls_underflow;
unsigned int calls_uflow;
unsigned int calls_pbackfail;
unsigned int calls_xsputn;
unsigned int calls_xsgetn;
unsigned int calls_seekoff;
unsigned int calls_seekpos;
unsigned int calls_setbuf;
unsigned int calls_sync;
unsigned int calls_doallocate;
unsigned int calls_read;
unsigned int calls_write;
unsigned int calls_seek;
unsigned int calls_close;
unsigned int calls_stat;
unsigned int calls_showmanyc;
unsigned int calls_imbue;
} *shared;
/* Method implementations which increment the counters in *shared. */
static void
log_method (FILE *fp, const char *name)
{
if (test_verbose > 0)
printf ("info: %s (%p) called\n", name, fp);
}
static void
method_finish (FILE *fp, int dummy)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_finish;
}
static int
method_overflow (FILE *fp, int ch)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_overflow;
shared->value = ch;
return shared->return_value;
}
static int
method_underflow (FILE *fp)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_underflow;
return shared->return_value;
}
static int
method_uflow (FILE *fp)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_uflow;
return shared->return_value;
}
static int
method_pbackfail (FILE *fp, int ch)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_pbackfail;
shared->value = ch;
return shared->return_value;
}
static size_t
method_xsputn (FILE *fp, const void *data, size_t n)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_xsputn;
size_t to_copy = n;
if (n > sizeof (shared->buffer))
to_copy = sizeof (shared->buffer);
memcpy (shared->buffer, data, to_copy);
shared->buffer_length = to_copy;
return to_copy;
}
static size_t
method_xsgetn (FILE *fp, void *data, size_t n)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_xsgetn;
return 0;
}
static off64_t
method_seekoff (FILE *fp, off64_t offset, int dir, int mode)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_seekoff;
return shared->return_value;
}
static off64_t
method_seekpos (FILE *fp, off64_t offset, int mode)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_seekpos;
return shared->return_value;
}
static FILE *
method_setbuf (FILE *fp, char *buffer, ssize_t length)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_setbuf;
return fp;
}
static int
method_sync (FILE *fp)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_sync;
return shared->return_value;
}
static int
method_doallocate (FILE *fp)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_doallocate;
return shared->return_value;
}
static ssize_t
method_read (FILE *fp, void *data, ssize_t length)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_read;
return shared->return_value;
}
static ssize_t
method_write (FILE *fp, const void *data, ssize_t length)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_write;
return shared->return_value;
}
static off64_t
method_seek (FILE *fp, off64_t offset, int mode)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_seek;
return shared->return_value;
}
static int
method_close (FILE *fp)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_close;
return shared->return_value;
}
static int
method_stat (FILE *fp, void *buffer)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_stat;
return shared->return_value;
}
static int
method_showmanyc (FILE *fp)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_showmanyc;
return shared->return_value;
}
static void
method_imbue (FILE *fp, void *locale)
{
log_method (fp, __func__);
TEST_VERIFY (fp == shared->fp);
++shared->calls;
++shared->calls_imbue;
}
/* Our custom vtable. */
static const struct _IO_jump_t jumps =
{
JUMP_INIT_DUMMY,
JUMP_INIT (finish, method_finish),
JUMP_INIT (overflow, method_overflow),
JUMP_INIT (underflow, method_underflow),
JUMP_INIT (uflow, method_uflow),
JUMP_INIT (pbackfail, method_pbackfail),
JUMP_INIT (xsputn, method_xsputn),
JUMP_INIT (xsgetn, method_xsgetn),
JUMP_INIT (seekoff, method_seekoff),
JUMP_INIT (seekpos, method_seekpos),
JUMP_INIT (setbuf, method_setbuf),
JUMP_INIT (sync, method_sync),
JUMP_INIT (doallocate, method_doallocate),
JUMP_INIT (read, method_read),
JUMP_INIT (write, method_write),
JUMP_INIT (seek, method_seek),
JUMP_INIT (close, method_close),
JUMP_INIT (stat, method_stat),
JUMP_INIT (showmanyc, method_showmanyc),
JUMP_INIT (imbue, method_imbue)
};
/* Our file implementation. */
struct my_file
{
FILE f;
const struct _IO_jump_t *vtable;
};
struct my_file
my_file_create (void)
{
return (struct my_file)
{
/* Disable locking, so that we do not have to set up a lock
pointer. */
.f._flags = _IO_USER_LOCK,
/* Copy the offset from the an initialized handle, instead of
figuring it out from scratch. */
.f._vtable_offset = stdin->_vtable_offset,
.vtable = &jumps,
};
}
/* Initial tests which do not enable vtable compatibility. */
/* Inhibit GCC optimization of fprintf. */
typedef int (*fprintf_type) (FILE *, const char *, ...);
static const volatile fprintf_type fprintf_ptr = &fprintf;
static void
without_compatibility_fprintf (void *closure)
{
/* This call should abort. */
fprintf_ptr (shared->fp, " ");
_exit (1);
}
static void
without_compatibility_fputc (void *closure)
{
/* This call should abort. */
fputc (' ', shared->fp);
_exit (1);
}
static void
without_compatibility_fgetc (void *closure)
{
/* This call should abort. */
fgetc (shared->fp);
_exit (1);
}
static void
without_compatibility_fflush (void *closure)
{
/* This call should abort. */
fflush (shared->fp);
_exit (1);
}
/* Exit status after abnormal termination. */
static int termination_status;
static void
init_termination_status (void)
{
pid_t pid = xfork ();
if (pid == 0)
abort ();
xwaitpid (pid, &termination_status, 0);
TEST_VERIFY (WIFSIGNALED (termination_status));
TEST_COMPARE (WTERMSIG (termination_status), SIGABRT);
}
static void
check_for_termination (const char *name, void (*callback) (void *))
{
struct my_file file = my_file_create ();
shared->fp = &file.f;
shared->return_value = -1;
shared->calls = 0;
struct support_capture_subprocess proc
= support_capture_subprocess (callback, NULL);
support_capture_subprocess_check (&proc, name, termination_status,
sc_allow_stderr);
const char *message
= "Fatal error: glibc detected an invalid stdio handle\n";
TEST_COMPARE_BLOB (proc.err.buffer, proc.err.length,
message, strlen (message));
TEST_COMPARE (shared->calls, 0);
support_capture_subprocess_free (&proc);
}
/* The test with vtable validation disabled. */
/* This function does not have a prototype in libioP.h to prevent
accidental use from within the library (which would disable vtable
verification). */
void _IO_init (FILE *fp, int flags);
static void
with_compatibility_fprintf (void *closure)
{
TEST_COMPARE (fprintf_ptr (shared->fp, "A%sCD", "B"), 4);
TEST_COMPARE (shared->calls, 3);
TEST_COMPARE (shared->calls_xsputn, 3);
TEST_COMPARE_BLOB (shared->buffer, shared->buffer_length,
"CD", 2);
}
static void
with_compatibility_fputc (void *closure)
{
shared->return_value = '@';
TEST_COMPARE (fputc ('@', shared->fp), '@');
TEST_COMPARE (shared->calls, 1);
TEST_COMPARE (shared->calls_overflow, 1);
TEST_COMPARE (shared->value, '@');
}
static void
with_compatibility_fgetc (void *closure)
{
shared->return_value = 'X';
TEST_COMPARE (fgetc (shared->fp), 'X');
TEST_COMPARE (shared->calls, 1);
TEST_COMPARE (shared->calls_uflow, 1);
}
static void
with_compatibility_fflush (void *closure)
{
TEST_COMPARE (fflush (shared->fp), 0);
TEST_COMPARE (shared->calls, 1);
TEST_COMPARE (shared->calls_sync, 1);
}
/* Call CALLBACK in a subprocess, after setting up a custom file
object and updating shared->fp. */
static void
check_call (const char *name, void (*callback) (void *),
bool initially_disabled)
{
*shared = (struct shared)
{
.initially_disabled = initially_disabled,
};
/* Set up a custom file object. */
struct my_file file = my_file_create ();
shared->fp = &file.f;
if (shared->initially_disabled)
_IO_init (shared->fp, file.f._flags);
if (test_verbose > 0)
printf ("info: calling test %s\n", name);
support_isolate_in_subprocess (callback, NULL);
}
/* Run the tests. INITIALLY_DISABLED indicates whether custom vtables
are disabled when the test starts. */
static int
run_tests (bool initially_disabled)
{
/* The test relies on fatal error messages being printed to standard
error. */
setenv ("LIBC_FATAL_STDERR_", "1", 1);
shared = support_shared_allocate (sizeof (*shared));
shared->initially_disabled = initially_disabled;
init_termination_status ();
if (initially_disabled)
{
check_for_termination ("fprintf", without_compatibility_fprintf);
check_for_termination ("fputc", without_compatibility_fputc);
check_for_termination ("fgetc", without_compatibility_fgetc);
check_for_termination ("fflush", without_compatibility_fflush);
}
check_call ("fprintf", with_compatibility_fprintf, initially_disabled);
check_call ("fputc", with_compatibility_fputc, initially_disabled);
check_call ("fgetc", with_compatibility_fgetc, initially_disabled);
check_call ("fflush", with_compatibility_fflush, initially_disabled);
support_shared_free (shared);
shared = NULL;
return 0;
}
+37
View File
@@ -0,0 +1,37 @@
/* Test for libio vtables and their validation. Enabled through interposition.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Provide an interposed definition of the standard file handles with
our own vtable. stdout/stdin/stderr will not work as a result, but
a succesful test does not print anything, so this is fine. */
static const struct _IO_jump_t jumps;
#define _IO_file_jumps jumps
#include "stdfiles.c"
#include "tst-vtables-common.c"
static int
do_test (void)
{
return run_tests (false);
}
/* Calling setvbuf in the test driver is not supported with our
interposed file handles. */
#define TEST_NO_SETVBUF
#include <support/test-driver.c>
+29
View File
@@ -0,0 +1,29 @@
/* Test for libio vtables and their validation. Initially disabled case.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include "libioP.h"
#include "tst-vtables-common.c"
static int
do_test (void)
{
return run_tests (true);
}
#include <support/test-driver.c>
+39
View File
@@ -0,0 +1,39 @@
/* Test that _IO_wfile_sync does not crash (bug 20568).
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
#include <support/check.h>
#include <support/xunistd.h>
static int
do_test (void)
{
TEST_VERIFY_EXIT (setlocale (LC_ALL, "de_DE.UTF-8") != NULL);
/* Fill the stdio buffer and advance the read pointer. */
TEST_VERIFY_EXIT (fgetwc (stdin) != WEOF);
/* This calls _IO_wfile_sync, it should not crash. */
TEST_VERIFY_EXIT (setvbuf (stdin, NULL, _IONBF, 0) == 0);
/* Verify that the external file offset has been synchronized. */
TEST_COMPARE (xlseek (0, 0, SEEK_CUR), 1);
return 0;
}
#include <support/test-driver.c>
+1
View File
@@ -0,0 +1 @@
This is a test of _IO_wfile_sync.
+2 -2
View File
@@ -54,8 +54,8 @@ _IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args)
_IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
_IO_str_init_static_internal (&sf, string, init_string_size, string);
sf._sbf._f._flags &= ~_IO_USER_BUF;
sf._s._allocate_buffer = (_IO_alloc_type) malloc;
sf._s._free_buffer = (_IO_free_type) free;
sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
sf._s._free_buffer_unused = (_IO_free_type) free;
ret = _IO_vfprintf (&sf._sbf._f, format, args);
if (ret < 0)
{
+16
View File
@@ -70,3 +70,19 @@ _IO_vtable_check (void)
__libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n");
}
/* Some variants of libstdc++ interpose _IO_2_1_stdin_ etc. and
install their own vtables directly, without calling _IO_init or
other functions. Detect this by looking at the vtables values
during startup, and disable vtable validation in this case. */
#ifdef SHARED
__attribute__ ((constructor))
static void
check_stdfiles_vtables (void)
{
if (_IO_2_1_stdin_.vtable != &_IO_file_jumps
|| _IO_2_1_stdout_.vtable != &_IO_file_jumps
|| _IO_2_1_stderr_.vtable != &_IO_file_jumps)
IO_set_accept_foreign_vtables (&_IO_vtable_check);
}
#endif
+3 -2
View File
@@ -526,11 +526,12 @@ _IO_wfile_sync (_IO_FILE *fp)
generate the wide characters up to the current reading
position. */
int nread;
size_t wnread = (fp->_wide_data->_IO_read_ptr
- fp->_wide_data->_IO_read_base);
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
fp->_IO_read_base,
fp->_IO_read_end, delta);
fp->_IO_read_end, wnread);
fp->_IO_read_ptr = fp->_IO_read_base + nread;
delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
}
+2 -2
View File
@@ -92,8 +92,8 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc)
_IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
_IO_BUFSIZ / sizeof (wchar_t), buf);
new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF;
new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc;
new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free;
new_f->fp.bufloc = bufloc;
new_f->fp.sizeloc = sizeloc;
+6 -10
View File
@@ -63,7 +63,7 @@ _IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size,
fp->_wide_data->_IO_read_end = end;
}
/* A null _allocate_buffer function flags the strfile as being static. */
(((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
(((_IO_strfile *) fp)->_s._allocate_buffer_unused) = (_IO_alloc_type)0;
}
_IO_wint_t
@@ -95,9 +95,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
|| __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
return EOF;
new_buf
= (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
* sizeof (wchar_t));
new_buf = malloc (new_size * sizeof (wchar_t));
if (new_buf == NULL)
{
/* __ferror(fp) = 1; */
@@ -106,7 +104,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
if (old_buf)
{
__wmemcpy (new_buf, old_buf, old_wblen);
(*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
free (old_buf);
/* Make sure _IO_setb won't try to delete _IO_buf_base. */
fp->_wide_data->_IO_buf_base = NULL;
}
@@ -186,16 +184,14 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
return 1;
wchar_t *oldbuf = wd->_IO_buf_base;
wchar_t *newbuf
= (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
* sizeof (wchar_t));
wchar_t *newbuf = malloc (newsize * sizeof (wchar_t));
if (newbuf == NULL)
return 1;
if (oldbuf != NULL)
{
__wmemcpy (newbuf, oldbuf, _IO_wblen (fp));
(*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
free (oldbuf);
/* Make sure _IO_setb won't try to delete
_IO_buf_base. */
wd->_IO_buf_base = NULL;
@@ -357,7 +353,7 @@ void
_IO_wstr_finish (_IO_FILE *fp, int dummy)
{
if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
(((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base);
free (fp->_wide_data->_IO_buf_base);
fp->_wide_data->_IO_buf_base = NULL;
_IO_wdefault_finish (fp, 0);
+4
View File
@@ -34,6 +34,8 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-interpose-nothread \
tst-interpose-thread \
tst-alloc_buffer \
tst-malloc-tcache-leak \
tst-malloc-too-large \
tests-static := \
tst-interpose-static-nothread \
@@ -242,3 +244,5 @@ tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace
$(objpfx)tst-dynarray-fail-mem.out: $(objpfx)tst-dynarray-fail.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@; \
$(evaluate-test)
$(objpfx)tst-malloc-tcache-leak: $(shared-thread-library)
+5 -26
View File
@@ -116,7 +116,7 @@ int __malloc_initialized = -1;
} while (0)
#define arena_lock(ptr, size) do { \
if (ptr && !arena_is_corrupt (ptr)) \
if (ptr) \
__libc_lock_lock (ptr->mutex); \
else \
ptr = arena_get2 ((size), NULL); \
@@ -215,8 +215,7 @@ void
TUNABLE_CALLBACK (set_mallopt_check) (tunable_val_t *valp)
{
int32_t value = (int32_t) valp->numval;
do_set_mallopt_check (value);
if (check_action != 0)
if (value != 0)
__malloc_check_init ();
}
@@ -397,12 +396,8 @@ ptmalloc_init (void)
}
}
}
if (s && s[0])
{
__libc_mallopt (M_CHECK_ACTION, (int) (s[0] - '0'));
if (check_action != 0)
__malloc_check_init ();
}
if (s && s[0] != '\0' && s[0] != '0')
__malloc_check_init ();
#endif
#if HAVE_MALLOC_INIT_HOOK
@@ -837,7 +832,7 @@ reused_arena (mstate avoid_arena)
result = next_to_use;
do
{
if (!arena_is_corrupt (result) && !__libc_lock_trylock (result->mutex))
if (!__libc_lock_trylock (result->mutex))
goto out;
/* FIXME: This is a data race, see _int_new_arena. */
@@ -850,18 +845,6 @@ reused_arena (mstate avoid_arena)
if (result == avoid_arena)
result = result->next;
/* Make sure that the arena we get is not corrupted. */
mstate begin = result;
while (arena_is_corrupt (result) || result == avoid_arena)
{
result = result->next;
if (result == begin)
/* We looped around the arena list. We could not find any
arena that was either not corrupted or not the one we
wanted to avoid. */
return NULL;
}
/* No arena available without contention. Wait for the next in line. */
LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);
__libc_lock_lock (result->mutex);
@@ -958,10 +941,6 @@ arena_get_retry (mstate ar_ptr, size_t bytes)
if (ar_ptr != &main_arena)
{
__libc_lock_unlock (ar_ptr->mutex);
/* Don't touch the main arena if it is corrupt. */
if (arena_is_corrupt (&main_arena))
return NULL;
ar_ptr = &main_arena;
__libc_lock_lock (ar_ptr->mutex);
}
+7 -3
View File
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <dynarray.h>
#include <errno.h>
#include <malloc-internal.h>
#include <stdlib.h>
#include <string.h>
@@ -32,7 +33,7 @@ __libc_dynarray_emplace_enlarge (struct dynarray_header *list,
size. */
if (element_size < 4)
new_allocated = 16;
if (element_size < 8)
else if (element_size < 8)
new_allocated = 8;
else
new_allocated = 4;
@@ -43,8 +44,11 @@ __libc_dynarray_emplace_enlarge (struct dynarray_header *list,
{
new_allocated = list->allocated + list->allocated / 2 + 1;
if (new_allocated <= list->allocated)
/* Overflow. */
return false;
{
/* Overflow. */
__set_errno (ENOMEM);
return false;
}
}
size_t new_size;
+6 -1
View File
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <dynarray.h>
#include <errno.h>
#include <malloc-internal.h>
#include <stdlib.h>
#include <string.h>
@@ -38,7 +39,11 @@ __libc_dynarray_resize (struct dynarray_header *list, size_t size,
size_t new_size_bytes;
if (check_mul_overflow_size_t (size, element_size, &new_size_bytes))
return false;
{
/* Overflow. */
__set_errno (ENOMEM);
return false;
}
void *new_array;
if (list->array == scratch)
{
+24 -64
View File
@@ -121,12 +121,7 @@ malloc_check_get_size (mchunkptr p)
size -= c)
{
if (c <= 0 || size < (c + 2 * SIZE_SZ))
{
malloc_printerr (check_action, "malloc_check_get_size: memory corruption",
chunk2mem (p),
chunk_is_mmapped (p) ? NULL : arena_for_chunk (p));
return 0;
}
malloc_printerr ("malloc_check_get_size: memory corruption");
}
/* chunk2mem size. */
@@ -232,17 +227,11 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
return p;
}
/* Check for corruption of the top chunk, and try to recover if
necessary. */
static int
internal_function
/* Check for corruption of the top chunk. */
static void
top_check (void)
{
mchunkptr t = top (&main_arena);
char *brk, *new_brk;
INTERNAL_SIZE_T front_misalign, sbrk_size;
unsigned long pagesz = GLRO (dl_pagesize);
if (t == initial_top (&main_arena) ||
(!chunk_is_mmapped (t) &&
@@ -250,34 +239,9 @@ top_check (void)
prev_inuse (t) &&
(!contiguous (&main_arena) ||
(char *) t + chunksize (t) == mp_.sbrk_base + main_arena.system_mem)))
return 0;
return;
malloc_printerr (check_action, "malloc: top chunk is corrupt", t,
&main_arena);
/* Try to set up a new top chunk. */
brk = MORECORE (0);
front_misalign = (unsigned long) chunk2mem (brk) & MALLOC_ALIGN_MASK;
if (front_misalign > 0)
front_misalign = MALLOC_ALIGNMENT - front_misalign;
sbrk_size = front_misalign + mp_.top_pad + MINSIZE;
sbrk_size += pagesz - ((unsigned long) (brk + sbrk_size) & (pagesz - 1));
new_brk = (char *) (MORECORE (sbrk_size));
if (new_brk == (char *) (MORECORE_FAILURE))
{
__set_errno (ENOMEM);
return -1;
}
/* Call the `morecore' hook if necessary. */
void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
if (hook)
(*hook)();
main_arena.system_mem = (new_brk - mp_.sbrk_base) + sbrk_size;
top (&main_arena) = (mchunkptr) (brk + front_misalign);
set_head (top (&main_arena), (sbrk_size - front_misalign) | PREV_INUSE);
return 0;
malloc_printerr ("malloc: top chunk is corrupt");
}
static void *
@@ -292,7 +256,8 @@ malloc_check (size_t sz, const void *caller)
}
__libc_lock_lock (main_arena.mutex);
victim = (top_check () >= 0) ? _int_malloc (&main_arena, sz + 1) : NULL;
top_check ();
victim = _int_malloc (&main_arena, sz + 1);
__libc_lock_unlock (main_arena.mutex);
return mem2mem_check (victim, sz);
}
@@ -308,13 +273,7 @@ free_check (void *mem, const void *caller)
__libc_lock_lock (main_arena.mutex);
p = mem2chunk_check (mem, NULL);
if (!p)
{
__libc_lock_unlock (main_arena.mutex);
malloc_printerr (check_action, "free(): invalid pointer", mem,
&main_arena);
return;
}
malloc_printerr ("free(): invalid pointer");
if (chunk_is_mmapped (p))
{
__libc_lock_unlock (main_arena.mutex);
@@ -349,11 +308,7 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
const mchunkptr oldp = mem2chunk_check (oldmem, &magic_p);
__libc_lock_unlock (main_arena.mutex);
if (!oldp)
{
malloc_printerr (check_action, "realloc(): invalid pointer", oldmem,
&main_arena);
return malloc_check (bytes, NULL);
}
malloc_printerr ("realloc(): invalid pointer");
const INTERNAL_SIZE_T oldsize = chunksize (oldp);
checked_request2size (bytes + 1, nb);
@@ -374,8 +329,8 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
else
{
/* Must alloc, copy, free. */
if (top_check () >= 0)
newmem = _int_malloc (&main_arena, bytes + 1);
top_check ();
newmem = _int_malloc (&main_arena, bytes + 1);
if (newmem)
{
memcpy (newmem, oldmem, oldsize - 2 * SIZE_SZ);
@@ -386,19 +341,24 @@ realloc_check (void *oldmem, size_t bytes, const void *caller)
}
else
{
if (top_check () >= 0)
{
INTERNAL_SIZE_T nb;
checked_request2size (bytes + 1, nb);
newmem = _int_realloc (&main_arena, oldp, oldsize, nb);
}
top_check ();
INTERNAL_SIZE_T nb;
checked_request2size (bytes + 1, nb);
newmem = _int_realloc (&main_arena, oldp, oldsize, nb);
}
DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
/* GCC 7 warns about magic_p may be used uninitialized. But we never
reach here if magic_p is uninitialized. */
DIAG_IGNORE_NEEDS_COMMENT (7, "-Wmaybe-uninitialized");
#endif
/* mem2chunk_check changed the magic byte in the old chunk.
If newmem is NULL, then the old chunk will still be used though,
so we need to invert that change here. */
if (newmem == NULL)
*magic_p ^= 0xFF;
DIAG_POP_NEEDS_COMMENT;
__libc_lock_unlock (main_arena.mutex);
@@ -441,8 +401,8 @@ memalign_check (size_t alignment, size_t bytes, const void *caller)
}
__libc_lock_lock (main_arena.mutex);
mem = (top_check () >= 0) ? _int_memalign (&main_arena, alignment, bytes + 1) :
NULL;
top_check ();
mem = _int_memalign (&main_arena, alignment, bytes + 1);
__libc_lock_unlock (main_arena.mutex);
return mem2mem_check (mem, bytes);
}
+229 -312
View File
@@ -243,6 +243,9 @@
#include <malloc/malloc-internal.h>
/* For SINGLE_THREAD_P. */
#include <sysdep-cancel.h>
/*
Debugging:
@@ -1019,10 +1022,10 @@ static void* _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T,
static void* _int_memalign(mstate, size_t, size_t);
static void* _mid_memalign(size_t, size_t, void *);
static void malloc_printerr(int action, const char *str, void *ptr, mstate av);
static void malloc_printerr(const char *str) __attribute__ ((noreturn));
static void* internal_function mem2mem_check(void *p, size_t sz);
static int internal_function top_check(void);
static void top_check (void);
static void internal_function munmap_chunk(mchunkptr p);
#if HAVE_MREMAP
static mchunkptr internal_function mremap_chunk(mchunkptr p, size_t new_size);
@@ -1228,14 +1231,21 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
MINSIZE : \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
/* Same, except also perform argument check */
#define checked_request2size(req, sz) \
if (REQUEST_OUT_OF_RANGE (req)) { \
__set_errno (ENOMEM); \
return 0; \
} \
(sz) = request2size (req);
/* Same, except also perform an argument and result check. First, we check
that the padding done by request2size didn't result in an integer
overflow. Then we check (using REQUEST_OUT_OF_RANGE) that the resulting
size isn't so large that a later alignment would lead to another integer
overflow. */
#define checked_request2size(req, sz) \
({ \
(sz) = request2size (req); \
if (((sz) < (req)) \
|| REQUEST_OUT_OF_RANGE (sz)) \
{ \
__set_errno (ENOMEM); \
return 0; \
} \
})
/*
--------------- Physical chunk operations ---------------
@@ -1403,11 +1413,11 @@ typedef struct malloc_chunk *mbinptr;
/* Take a chunk off a bin list */
#define unlink(AV, P, BK, FD) { \
if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0)) \
malloc_printerr (check_action, "corrupted size vs. prev_size", P, AV); \
malloc_printerr ("corrupted size vs. prev_size"); \
FD = P->fd; \
BK = P->bk; \
if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \
malloc_printerr (check_action, "corrupted double-linked list", P, AV); \
malloc_printerr ("corrupted double-linked list"); \
else { \
FD->bk = BK; \
BK->fd = FD; \
@@ -1415,9 +1425,7 @@ typedef struct malloc_chunk *mbinptr;
&& __builtin_expect (P->fd_nextsize != NULL, 0)) { \
if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0) \
|| __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0)) \
malloc_printerr (check_action, \
"corrupted double-linked list (not small)", \
P, AV); \
malloc_printerr ("corrupted double-linked list (not small)"); \
if (FD->fd_nextsize == NULL) { \
if (P->fd_nextsize == P) \
FD->fd_nextsize = FD->bk_nextsize = FD; \
@@ -1612,27 +1620,6 @@ typedef struct malloc_chunk *mfastbinptr;
#define FASTBIN_CONSOLIDATION_THRESHOLD (65536UL)
/*
Since the lowest 2 bits in max_fast don't matter in size comparisons,
they are used as flags.
*/
/*
FASTCHUNKS_BIT held in max_fast indicates that there are probably
some fastbin chunks. It is set true on entering a chunk into any
fastbin, and cleared only in malloc_consolidate.
The truth value is inverted so that have_fastchunks will be true
upon startup (since statics are zero-filled), simplifying
initialization checks.
*/
#define FASTCHUNKS_BIT (1U)
#define have_fastchunks(M) (((M)->flags & FASTCHUNKS_BIT) == 0)
#define clear_fastchunks(M) catomic_or (&(M)->flags, FASTCHUNKS_BIT)
#define set_fastchunks(M) catomic_and (&(M)->flags, ~FASTCHUNKS_BIT)
/*
NONCONTIGUOUS_BIT indicates that MORECORE does not return contiguous
regions. Otherwise, contiguity is exploited in merging together,
@@ -1649,14 +1636,8 @@ typedef struct malloc_chunk *mfastbinptr;
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
/* ARENA_CORRUPTION_BIT is set if a memory corruption was detected on the
arena. Such an arena is no longer used to allocate chunks. Chunks
allocated in that arena before detecting corruption are not freed. */
#define ARENA_CORRUPTION_BIT (4U)
#define arena_is_corrupt(A) (((A)->flags & ARENA_CORRUPTION_BIT))
#define set_arena_corrupt(A) ((A)->flags |= ARENA_CORRUPTION_BIT)
/* Maximum size of memory handled in fastbins. */
static INTERNAL_SIZE_T global_max_fast;
/*
Set value of max_fast.
@@ -1668,13 +1649,36 @@ typedef struct malloc_chunk *mfastbinptr;
#define set_max_fast(s) \
global_max_fast = (((s) == 0) \
? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
#define get_max_fast() global_max_fast
static inline INTERNAL_SIZE_T
get_max_fast (void)
{
/* Tell the GCC optimizers that global_max_fast is never larger
than MAX_FAST_SIZE. This avoids out-of-bounds array accesses in
_int_malloc after constant propagation of the size parameter.
(The code never executes because malloc preserves the
global_max_fast invariant, but the optimizers may not recognize
this.) */
if (global_max_fast > MAX_FAST_SIZE)
__builtin_unreachable ();
return global_max_fast;
}
/*
----------- Internal state representation and initialization -----------
*/
/*
have_fastchunks indicates that there are probably some fastbin chunks.
It is set true on entering a chunk into any fastbin, and cleared early in
malloc_consolidate. The value is approximate since it may be set when there
are no fastbin chunks, or it may be clear even if there are fastbin chunks
available. Given it's sole purpose is to reduce number of redundant calls to
malloc_consolidate, it does not affect correctness. As a result we can safely
use relaxed atomic accesses.
*/
struct malloc_state
{
/* Serialize access. */
@@ -1683,6 +1687,10 @@ struct malloc_state
/* Flags (formerly in max_fast). */
int flags;
/* Set if the fastbin chunks contain recently inserted free blocks. */
/* Note this is a bool but not all targets support atomics on booleans. */
int have_fastchunks;
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
@@ -1797,9 +1805,6 @@ static struct malloc_par mp_ =
#endif
};
/* Maximum size of memory handled in fastbins. */
static INTERNAL_SIZE_T global_max_fast;
/*
Initialize a malloc_state struct.
@@ -1829,7 +1834,7 @@ malloc_init_state (mstate av)
set_noncontiguous (av);
if (av == &main_arena)
set_max_fast (DEFAULT_MXFAST);
av->flags |= FASTCHUNKS_BIT;
atomic_store_relaxed (&av->have_fastchunks, false);
av->top = initial_top (av);
}
@@ -1880,15 +1885,6 @@ void *weak_variable (*__memalign_hook)
void weak_variable (*__after_morecore_hook) (void) = NULL;
/* ---------------- Error behavior ------------------------------------ */
#ifndef DEFAULT_CHECK_ACTION
# define DEFAULT_CHECK_ACTION 3
#endif
static int check_action = DEFAULT_CHECK_ACTION;
/* ------------------ Testing support ----------------------------------*/
static int perturb_byte;
@@ -2194,11 +2190,6 @@ do_check_malloc_state (mstate av)
}
}
if (total != 0)
assert (have_fastchunks (av));
else if (!have_fastchunks (av))
assert (total == 0);
/* check normal bins */
for (i = 1; i < NBINS; ++i)
{
@@ -2566,11 +2557,8 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
set_head (old_top, (size + old_size) | PREV_INUSE);
else if (contiguous (av) && old_size && brk < old_end)
{
/* Oops! Someone else killed our space.. Can't touch anything. */
malloc_printerr (3, "break adjusted to free malloc space", brk,
av);
}
/* Oops! Someone else killed our space.. Can't touch anything. */
malloc_printerr ("break adjusted to free malloc space");
/*
Otherwise, make adjustments:
@@ -2861,11 +2849,7 @@ munmap_chunk (mchunkptr p)
(in the moment at least) so we combine the two values into one before
the bit test. */
if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0))
{
malloc_printerr (check_action, "munmap_chunk(): invalid pointer",
chunk2mem (p), NULL);
return;
}
malloc_printerr ("munmap_chunk(): invalid pointer");
atomic_decrement (&mp_.n_mmaps);
atomic_add (&mp_.mmapped_mem, -total_size);
@@ -2940,12 +2924,14 @@ typedef struct tcache_perthread_struct
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
static __thread char tcache_shutting_down = 0;
#define MAX_TCACHE_COUNT 127 /* Maximum value of counts[] entries. */
static __thread bool tcache_shutting_down = false;
static __thread tcache_perthread_struct *tcache = NULL;
/* Caller must ensure that we know tc_idx is valid and there's room
for more chunks. */
static void
static __always_inline void
tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
@@ -2957,7 +2943,7 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
/* Caller must ensure that we know tc_idx is valid and there's
available chunks to remove. */
static void *
static __always_inline void *
tcache_get (size_t tc_idx)
{
tcache_entry *e = tcache->entries[tc_idx];
@@ -2977,8 +2963,12 @@ tcache_thread_freeres (void)
if (!tcache)
return;
/* Disable the tcache and prevent it from being reinitialized. */
tcache = NULL;
tcache_shutting_down = true;
/* Free all of the entries and the tcache itself back to the arena
heap for coalescing. */
for (i = 0; i < TCACHE_MAX_BINS; ++i)
{
while (tcache_tmp->entries[i])
@@ -2990,8 +2980,6 @@ tcache_thread_freeres (void)
}
__libc_free (tcache_tmp);
tcache_shutting_down = 1;
}
text_set_element (__libc_thread_subfreeres, tcache_thread_freeres);
@@ -3050,7 +3038,8 @@ __libc_malloc (size_t bytes)
return (*hook)(bytes, RETURN_ADDRESS (0));
#if USE_TCACHE
/* int_free also calls request2size, be careful to not pad twice. */
size_t tbytes = request2size (bytes);
size_t tbytes;
checked_request2size (bytes, tbytes);
size_t tc_idx = csize2tidx (tbytes);
MAYBE_INIT_TCACHE ();
@@ -3066,6 +3055,14 @@ __libc_malloc (size_t bytes)
DIAG_POP_NEEDS_COMMENT;
#endif
if (SINGLE_THREAD_P)
{
victim = _int_malloc (&main_arena, bytes);
assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
&main_arena == arena_for_chunk (mem2chunk (victim)));
return victim;
}
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
@@ -3177,11 +3174,7 @@ __libc_realloc (void *oldmem, size_t bytes)
if ((__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0)
|| __builtin_expect (misaligned_chunk (oldp), 0))
&& !DUMPED_MAIN_ARENA_CHUNK (oldp))
{
malloc_printerr (check_action, "realloc(): invalid pointer", oldmem,
ar_ptr);
return NULL;
}
malloc_printerr ("realloc(): invalid pointer");
checked_request2size (bytes, nb);
@@ -3226,6 +3219,15 @@ __libc_realloc (void *oldmem, size_t bytes)
return newmem;
}
if (SINGLE_THREAD_P)
{
newp = _int_realloc (ar_ptr, oldp, oldsize, nb);
assert (!newp || chunk_is_mmapped (mem2chunk (newp)) ||
ar_ptr == arena_for_chunk (mem2chunk (newp)));
return newp;
}
__libc_lock_lock (ar_ptr->mutex);
newp = _int_realloc (ar_ptr, oldp, oldsize, nb);
@@ -3301,6 +3303,15 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
alignment = a;
}
if (SINGLE_THREAD_P)
{
p = _int_memalign (&main_arena, alignment, bytes);
assert (!p || chunk_is_mmapped (mem2chunk (p)) ||
&main_arena == arena_for_chunk (mem2chunk (p)));
return p;
}
arena_get (ar_ptr, bytes + alignment + MINSIZE);
p = _int_memalign (ar_ptr, alignment, bytes);
@@ -3393,7 +3404,11 @@ __libc_calloc (size_t n, size_t elem_size)
MAYBE_INIT_TCACHE ();
arena_get (av, sz);
if (SINGLE_THREAD_P)
av = &main_arena;
else
arena_get (av, sz);
if (av)
{
/* Check if we hand out the top chunk, in which case there may be no
@@ -3423,19 +3438,21 @@ __libc_calloc (size_t n, size_t elem_size)
}
mem = _int_malloc (av, sz);
assert (!mem || chunk_is_mmapped (mem2chunk (mem)) ||
av == arena_for_chunk (mem2chunk (mem)));
if (mem == 0 && av != NULL)
if (!SINGLE_THREAD_P)
{
LIBC_PROBE (memory_calloc_retry, 1, sz);
av = arena_get_retry (av, sz);
mem = _int_malloc (av, sz);
}
if (mem == 0 && av != NULL)
{
LIBC_PROBE (memory_calloc_retry, 1, sz);
av = arena_get_retry (av, sz);
mem = _int_malloc (av, sz);
}
if (av != NULL)
__libc_lock_unlock (av->mutex);
if (av != NULL)
__libc_lock_unlock (av->mutex);
}
/* Allocation failed even after a retry. */
if (mem == 0)
@@ -3527,8 +3544,6 @@ _int_malloc (mstate av, size_t bytes)
size_t tcache_unsorted_count; /* count of unsorted chunks processed */
#endif
const char *errstr = NULL;
/*
Convert request size to internal form by adding SIZE_SZ bytes
overhead plus possibly more to obtain necessary alignment and/or
@@ -3570,42 +3585,50 @@ _int_malloc (mstate av, size_t bytes)
{
idx = fastbin_index (nb);
mfastbinptr *fb = &fastbin (av, idx);
mchunkptr pp = *fb;
REMOVE_FB (fb, victim, pp);
if (victim != 0)
{
if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
{
errstr = "malloc(): memory corruption (fast)";
errout:
malloc_printerr (check_action, errstr, chunk2mem (victim), av);
return NULL;
}
check_remalloced_chunk (av, victim, nb);
#if USE_TCACHE
/* While we're here, if we see other chunks of the same size,
stash them in the tcache. */
size_t tc_idx = csize2tidx (nb);
if (tcache && tc_idx < mp_.tcache_bins)
{
mchunkptr tc_victim;
mchunkptr pp;
victim = *fb;
/* While bin not empty and tcache not full, copy chunks over. */
while (tcache->counts[tc_idx] < mp_.tcache_count
&& (pp = *fb) != NULL)
if (victim != NULL)
{
if (SINGLE_THREAD_P)
*fb = victim->fd;
else
REMOVE_FB (fb, pp, victim);
if (__glibc_likely (victim != NULL))
{
size_t victim_idx = fastbin_index (chunksize (victim));
if (__builtin_expect (victim_idx != idx, 0))
malloc_printerr ("malloc(): memory corruption (fast)");
check_remalloced_chunk (av, victim, nb);
#if USE_TCACHE
/* While we're here, if we see other chunks of the same size,
stash them in the tcache. */
size_t tc_idx = csize2tidx (nb);
if (tcache && tc_idx < mp_.tcache_bins)
{
REMOVE_FB (fb, tc_victim, pp);
if (tc_victim != 0)
mchunkptr tc_victim;
/* While bin not empty and tcache not full, copy chunks. */
while (tcache->counts[tc_idx] < mp_.tcache_count
&& (tc_victim = *fb) != NULL)
{
if (SINGLE_THREAD_P)
*fb = tc_victim->fd;
else
{
REMOVE_FB (fb, pp, tc_victim);
if (__glibc_unlikely (tc_victim == NULL))
break;
}
tcache_put (tc_victim, tc_idx);
}
}
}
}
#endif
void *p = chunk2mem (victim);
alloc_perturb (p, bytes);
return p;
}
void *p = chunk2mem (victim);
alloc_perturb (p, bytes);
return p;
}
}
}
/*
@@ -3628,11 +3651,9 @@ _int_malloc (mstate av, size_t bytes)
else
{
bck = victim->bk;
if (__glibc_unlikely (bck->fd != victim))
{
errstr = "malloc(): smallbin double linked list corrupted";
goto errout;
}
if (__glibc_unlikely (bck->fd != victim))
malloc_printerr
("malloc(): smallbin double linked list corrupted");
set_inuse_bit_at_offset (victim, nb);
bin->bk = bck;
bck->fd = bin;
@@ -3687,7 +3708,7 @@ _int_malloc (mstate av, size_t bytes)
else
{
idx = largebin_index (nb);
if (have_fastchunks (av))
if (atomic_load_relaxed (&av->have_fastchunks))
malloc_consolidate (av);
}
@@ -3723,8 +3744,7 @@ _int_malloc (mstate av, size_t bytes)
if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (chunksize_nomask (victim)
> av->system_mem, 0))
malloc_printerr (check_action, "malloc(): memory corruption",
chunk2mem (victim), av);
malloc_printerr ("malloc(): memory corruption");
size = chunksize (victim);
/*
@@ -3929,11 +3949,8 @@ _int_malloc (mstate av, size_t bytes)
have to perform a complete insert here. */
bck = unsorted_chunks (av);
fwd = bck->fd;
if (__glibc_unlikely (fwd->bk != bck))
{
errstr = "malloc(): corrupted unsorted chunks";
goto errout;
}
if (__glibc_unlikely (fwd->bk != bck))
malloc_printerr ("malloc(): corrupted unsorted chunks");
remainder->bk = bck;
remainder->fd = fwd;
bck->fd = remainder;
@@ -4036,11 +4053,8 @@ _int_malloc (mstate av, size_t bytes)
have to perform a complete insert here. */
bck = unsorted_chunks (av);
fwd = bck->fd;
if (__glibc_unlikely (fwd->bk != bck))
{
errstr = "malloc(): corrupted unsorted chunks 2";
goto errout;
}
if (__glibc_unlikely (fwd->bk != bck))
malloc_printerr ("malloc(): corrupted unsorted chunks 2");
remainder->bk = bck;
remainder->fd = fwd;
bck->fd = remainder;
@@ -4102,7 +4116,7 @@ _int_malloc (mstate av, size_t bytes)
/* When we are using atomic ops to free fast chunks we can get
here for all block sizes. */
else if (have_fastchunks (av))
else if (atomic_load_relaxed (&av->have_fastchunks))
{
malloc_consolidate (av);
/* restore original bin index */
@@ -4141,9 +4155,6 @@ _int_free (mstate av, mchunkptr p, int have_lock)
mchunkptr bck; /* misc temp for linking */
mchunkptr fwd; /* misc temp for linking */
const char *errstr = NULL;
int locked = 0;
size = chunksize (p);
/* Little security check which won't hurt performance: the
@@ -4152,21 +4163,11 @@ _int_free (mstate av, mchunkptr p, int have_lock)
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)
|| __builtin_expect (misaligned_chunk (p), 0))
{
errstr = "free(): invalid pointer";
errout:
if (!have_lock && locked)
__libc_lock_unlock (av->mutex);
malloc_printerr (check_action, errstr, chunk2mem (p), av);
return;
}
malloc_printerr ("free(): invalid pointer");
/* We know that each chunk is at least MINSIZE bytes in size or a
multiple of MALLOC_ALIGNMENT. */
if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size)))
{
errstr = "free(): invalid size";
goto errout;
}
malloc_printerr ("free(): invalid size");
check_inuse_chunk(av, p);
@@ -4205,60 +4206,59 @@ _int_free (mstate av, mchunkptr p, int have_lock)
|| __builtin_expect (chunksize (chunk_at_offset (p, size))
>= av->system_mem, 0))
{
bool fail = true;
/* We might not have a lock at this point and concurrent modifications
of system_mem might have let to a false positive. Redo the test
after getting the lock. */
if (have_lock
|| ({ assert (locked == 0);
__libc_lock_lock (av->mutex);
locked = 1;
chunksize_nomask (chunk_at_offset (p, size)) <= 2 * SIZE_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem;
}))
{
errstr = "free(): invalid next size (fast)";
goto errout;
}
if (! have_lock)
of system_mem might result in a false positive. Redo the test after
getting the lock. */
if (!have_lock)
{
__libc_lock_lock (av->mutex);
fail = (chunksize_nomask (chunk_at_offset (p, size)) <= 2 * SIZE_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem);
__libc_lock_unlock (av->mutex);
locked = 0;
}
if (fail)
malloc_printerr ("free(): invalid next size (fast)");
}
free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
set_fastchunks(av);
atomic_store_relaxed (&av->have_fastchunks, true);
unsigned int idx = fastbin_index(size);
fb = &fastbin (av, idx);
/* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */
mchunkptr old = *fb, old2;
unsigned int old_idx = ~0u;
do
{
/* Check that the top of the bin is not the record we are going to add
(i.e., double free). */
if (__builtin_expect (old == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}
/* Check that size of fastbin chunk at the top is the same as
size of the chunk that we are adding. We can dereference OLD
only if we have the lock, otherwise it might have already been
deallocated. See use of OLD_IDX below for the actual check. */
if (have_lock && old != NULL)
old_idx = fastbin_index(chunksize(old));
p->fd = old2 = old;
}
while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2);
if (have_lock && old != NULL && __builtin_expect (old_idx != idx, 0))
if (SINGLE_THREAD_P)
{
errstr = "invalid fastbin entry (free)";
goto errout;
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
p->fd = old;
*fb = p;
}
else
do
{
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
p->fd = old2 = old;
}
while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2))
!= old2);
/* Check that size of fastbin chunk at the top is the same as
size of the chunk that we are adding. We can dereference OLD
only if we have the lock, otherwise it might have already been
allocated again. */
if (have_lock && old != NULL
&& __builtin_expect (fastbin_index (chunksize (old)) != idx, 0))
malloc_printerr ("invalid fastbin entry (free)");
}
/*
@@ -4266,42 +4266,33 @@ _int_free (mstate av, mchunkptr p, int have_lock)
*/
else if (!chunk_is_mmapped(p)) {
if (! have_lock) {
/* If we're single-threaded, don't lock the arena. */
if (SINGLE_THREAD_P)
have_lock = true;
if (!have_lock)
__libc_lock_lock (av->mutex);
locked = 1;
}
nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the
top block. */
if (__glibc_unlikely (p == av->top))
{
errstr = "double free or corruption (top)";
goto errout;
}
malloc_printerr ("double free or corruption (top)");
/* Or whether the next chunk is beyond the boundaries of the arena. */
if (__builtin_expect (contiguous (av)
&& (char *) nextchunk
>= ((char *) av->top + chunksize(av->top)), 0))
{
errstr = "double free or corruption (out)";
goto errout;
}
malloc_printerr ("double free or corruption (out)");
/* Or whether the block is actually not marked used. */
if (__glibc_unlikely (!prev_inuse(nextchunk)))
{
errstr = "double free or corruption (!prev)";
goto errout;
}
malloc_printerr ("double free or corruption (!prev)");
nextsize = chunksize(nextchunk);
if (__builtin_expect (chunksize_nomask (nextchunk) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (nextsize >= av->system_mem, 0))
{
errstr = "free(): invalid next size (normal)";
goto errout;
}
malloc_printerr ("free(): invalid next size (normal)");
free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
@@ -4333,10 +4324,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
bck = unsorted_chunks(av);
fwd = bck->fd;
if (__glibc_unlikely (fwd->bk != bck))
{
errstr = "free(): corrupted unsorted chunks";
goto errout;
}
malloc_printerr ("free(): corrupted unsorted chunks");
p->fd = fwd;
p->bk = bck;
if (!in_smallbin_range(size))
@@ -4379,7 +4367,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
*/
if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
if (have_fastchunks(av))
if (atomic_load_relaxed (&av->have_fastchunks))
malloc_consolidate(av);
if (av == &main_arena) {
@@ -4398,10 +4386,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
}
}
if (! have_lock) {
assert (locked);
if (!have_lock)
__libc_lock_unlock (av->mutex);
}
}
/*
If the chunk was allocated via mmap, release via munmap().
@@ -4450,7 +4436,7 @@ static void malloc_consolidate(mstate av)
*/
if (get_max_fast () != 0) {
clear_fastchunks(av);
atomic_store_relaxed (&av->have_fastchunks, false);
unsorted_bin = unsorted_chunks(av);
@@ -4544,22 +4530,10 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
mchunkptr bck; /* misc temp for linking */
mchunkptr fwd; /* misc temp for linking */
unsigned long copysize; /* bytes to copy */
unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */
INTERNAL_SIZE_T* s; /* copy source */
INTERNAL_SIZE_T* d; /* copy destination */
const char *errstr = NULL;
/* oldmem size */
if (__builtin_expect (chunksize_nomask (oldp) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (oldsize >= av->system_mem, 0))
{
errstr = "realloc(): invalid old size";
errout:
malloc_printerr (check_action, errstr, chunk2mem (oldp), av);
return NULL;
}
malloc_printerr ("realloc(): invalid old size");
check_inuse_chunk (av, oldp);
@@ -4570,10 +4544,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
INTERNAL_SIZE_T nextsize = chunksize (next);
if (__builtin_expect (chunksize_nomask (next) <= 2 * SIZE_SZ, 0)
|| __builtin_expect (nextsize >= av->system_mem, 0))
{
errstr = "realloc(): invalid next size";
goto errout;
}
malloc_printerr ("realloc(): invalid next size");
if ((unsigned long) (oldsize) >= (unsigned long) (nb))
{
@@ -4626,43 +4597,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
}
else
{
/*
Unroll copy of <= 36 bytes (72 if 8byte sizes)
We know that contents have an odd number of
INTERNAL_SIZE_T-sized words; minimally 3.
*/
copysize = oldsize - SIZE_SZ;
s = (INTERNAL_SIZE_T *) (chunk2mem (oldp));
d = (INTERNAL_SIZE_T *) (newmem);
ncopies = copysize / sizeof (INTERNAL_SIZE_T);
assert (ncopies >= 3);
if (ncopies > 9)
memcpy (d, s, copysize);
else
{
*(d + 0) = *(s + 0);
*(d + 1) = *(s + 1);
*(d + 2) = *(s + 2);
if (ncopies > 4)
{
*(d + 3) = *(s + 3);
*(d + 4) = *(s + 4);
if (ncopies > 6)
{
*(d + 5) = *(s + 5);
*(d + 6) = *(s + 6);
if (ncopies > 8)
{
*(d + 7) = *(s + 7);
*(d + 8) = *(s + 8);
}
}
}
}
memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ);
_int_free (av, oldp, 1);
check_inuse_chunk (av, newp);
return chunk2mem (newp);
@@ -4724,6 +4659,13 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
*/
/* Check for overflow. */
if (nb > SIZE_MAX - alignment - MINSIZE)
{
__set_errno (ENOMEM);
return 0;
}
/* Call malloc with worst case padding to hit alignment. */
m = (char *) (_int_malloc (av, nb + alignment + MINSIZE));
@@ -4798,10 +4740,6 @@ _int_memalign (mstate av, size_t alignment, size_t bytes)
static int
mtrim (mstate av, size_t pad)
{
/* Don't touch corrupt arenas. */
if (arena_is_corrupt (av))
return 0;
/* Ensure initialization/consolidation */
malloc_consolidate (av);
@@ -5113,8 +5051,6 @@ static inline int
__always_inline
do_set_mallopt_check (int32_t value)
{
LIBC_PROBE (memory_mallopt_check_action, 2, value, check_action);
check_action = value;
return 1;
}
@@ -5163,8 +5099,11 @@ static inline int
__always_inline
do_set_tcache_count (size_t value)
{
LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count);
mp_.tcache_count = value;
if (value <= MAX_TCACHE_COUNT)
{
LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count);
mp_.tcache_count = value;
}
return 1;
}
@@ -5388,32 +5327,10 @@ libc_hidden_def (__libc_mallopt)
extern char **__libc_argv attribute_hidden;
static void
malloc_printerr (int action, const char *str, void *ptr, mstate ar_ptr)
malloc_printerr (const char *str)
{
/* Avoid using this arena in future. We do not attempt to synchronize this
with anything else because we minimally want to ensure that __libc_message
gets its resources safely without stumbling on the current corruption. */
if (ar_ptr)
set_arena_corrupt (ar_ptr);
if ((action & 5) == 5)
__libc_message ((action & 2) ? (do_abort | do_backtrace) : do_message,
"%s\n", str);
else if (action & 1)
{
char buf[2 * sizeof (uintptr_t) + 1];
buf[sizeof (buf) - 1] = '\0';
char *cp = _itoa_word ((uintptr_t) ptr, &buf[sizeof (buf) - 1], 16, 0);
while (cp > buf)
*--cp = '0';
__libc_message ((action & 2) ? (do_abort | do_backtrace) : do_message,
"*** Error in `%s': %s: 0x%s ***\n",
__libc_argv[0] ? : "<unknown>", str, cp);
}
else if (action & 2)
abort ();
__libc_message (do_abort, "%s\n", str);
__builtin_unreachable ();
}
/* We need a wrapper function for one of the additions of POSIX. */
+29
View File
@@ -18,6 +18,9 @@
#include "tst-dynarray-shared.h"
#include <errno.h>
#include <stdint.h>
#define DYNARRAY_STRUCT dynarray_long
#define DYNARRAY_ELEMENT long
#define DYNARRAY_PREFIX dynarray_long_
@@ -463,6 +466,31 @@ test_long_init (void)
}
}
/* Test overflow in resize. */
static void
test_long_overflow (void)
{
{
struct dynarray_long dyn;
dynarray_long_init (&dyn);
errno = EINVAL;
TEST_VERIFY (!dynarray_long_resize
(&dyn, (SIZE_MAX / sizeof (long)) + 1));
TEST_VERIFY (errno == ENOMEM);
TEST_VERIFY (dynarray_long_has_failed (&dyn));
}
{
struct dynarray_long_noscratch dyn;
dynarray_long_noscratch_init (&dyn);
errno = EINVAL;
TEST_VERIFY (!dynarray_long_noscratch_resize
(&dyn, (SIZE_MAX / sizeof (long)) + 1));
TEST_VERIFY (errno == ENOMEM);
TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn));
}
}
/* Test NUL-terminated string construction with the add function and
the simple finalize function. */
static void
@@ -538,6 +566,7 @@ do_test (void)
test_int ();
test_str ();
test_long_init ();
test_long_overflow ();
test_zstr ();
return 0;
}
+112
View File
@@ -0,0 +1,112 @@
/* Bug 22111: Test that threads do not leak their per thread cache.
Copyright (C) 2015-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/>. */
/* The point of this test is to start and exit a large number of
threads, while at the same time looking to see if the used
memory grows with each round of threads run. If the memory
grows above some linear bound we declare the test failed and
that the malloc implementation is leaking memory with each
thread. This is a good indicator that the thread local cache
is leaking chunks. */
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <pthread.h>
#include <assert.h>
#include <support/check.h>
#include <support/support.h>
#include <support/xthread.h>
void *
worker (void *data)
{
void *ret;
/* Allocate an arbitrary amount of memory that is known to fit into
the thread local cache (tcache). If we have at least 64 bins
(default e.g. TCACHE_MAX_BINS) we should be able to allocate 32
bytes and force malloc to fill the tcache. We are assuming tcahce
init happens at the first small alloc, but it might in the future
be deferred to some other point. Therefore to future proof this
test we include a full alloc/free/alloc cycle for the thread. We
need a compiler barrier to avoid the removal of the useless
alloc/free. We send some memory back to main to have the memory
freed after the thread dies, as just another check that the chunks
that were previously in the tcache are still OK to free after
thread death. */
ret = xmalloc (32);
__asm__ volatile ("" ::: "memory");
free (ret);
return (void *) xmalloc (32);
}
static int
do_test (void)
{
pthread_t *thread;
struct mallinfo info_before, info_after;
void *retval;
/* This is an arbitrary choice. We choose a total of THREADS
threads created and joined. This gives us enough iterations to
show a leak. */
int threads = 100000;
/* Avoid there being 0 malloc'd data at this point by allocating the
pthread_t required to run the test. */
thread = (pthread_t *) xcalloc (1, sizeof (pthread_t));
info_before = mallinfo ();
assert (info_before.uordblks != 0);
printf ("INFO: %d (bytes) are in use before starting threads.\n",
info_before.uordblks);
for (int loop = 0; loop < threads; loop++)
{
*thread = xpthread_create (NULL, worker, NULL);
retval = xpthread_join (*thread);
free (retval);
}
info_after = mallinfo ();
printf ("INFO: %d (bytes) are in use after all threads joined.\n",
info_after.uordblks);
/* We need to compare the memory in use before and the memory in use
after starting and joining THREADS threads. We almost always grow
memory slightly, but not much. Consider that if even 1-byte leaked
per thread we'd have THREADS bytes of additional memory, and in
general the in-use at the start of main is quite low. We will
always leak a full malloc chunk, and never just 1-byte, therefore
anything above "+ threads" from the start (constant offset) is a
leak. Obviously this assumes no thread-related malloc'd internal
libc data structures persist beyond the thread death, and any that
did would limit the number of times you could call pthread_create,
which is a QoI we'd want to detect and fix. */
if (info_after.uordblks > (info_before.uordblks + threads))
FAIL_EXIT1 ("Memory usage after threads is too high.\n");
/* Did not detect excessive memory usage. */
free (thread);
exit (0);
}
#include <support/test-driver.c>
+253
View File
@@ -0,0 +1,253 @@
/* Test and verify that too-large memory allocations fail with ENOMEM.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Bug 22375 reported a regression in malloc where if after malloc'ing then
free'ing a small block of memory, malloc is then called with a really
large size argument (close to SIZE_MAX): instead of returning NULL and
setting errno to ENOMEM, malloc incorrectly returns the previously
allocated block instead. Bug 22343 reported a similar case where
posix_memalign incorrectly returns successfully when called with an with
a really large size argument.
Both of these were caused by integer overflows in the allocator when it
was trying to pad the requested size to allow for book-keeping or
alignment. This test guards against such bugs by repeatedly allocating
and freeing small blocks of memory then trying to allocate various block
sizes larger than the memory bus width of 64-bit targets, or almost
as large as SIZE_MAX on 32-bit targets supported by glibc. In each case,
it verifies that such impossibly large allocations correctly fail. */
#include <stdlib.h>
#include <malloc.h>
#include <errno.h>
#include <stdint.h>
#include <sys/resource.h>
#include <libc-diag.h>
#include <support/check.h>
#include <unistd.h>
#include <sys/param.h>
/* This function prepares for each 'too-large memory allocation' test by
performing a small successful malloc/free and resetting errno prior to
the actual test. */
static void
test_setup (void)
{
void *volatile ptr = malloc (16);
TEST_VERIFY_EXIT (ptr != NULL);
free (ptr);
errno = 0;
}
/* This function tests each of:
- malloc (SIZE)
- realloc (PTR_FOR_REALLOC, SIZE)
- for various values of NMEMB:
- calloc (NMEMB, SIZE/NMEMB)
- calloc (SIZE/NMEMB, NMEMB)
- reallocarray (PTR_FOR_REALLOC, NMEMB, SIZE/NMEMB)
- reallocarray (PTR_FOR_REALLOC, SIZE/NMEMB, NMEMB)
and precedes each of these tests with a small malloc/free before it. */
static void
test_large_allocations (size_t size)
{
void * ptr_to_realloc;
test_setup ();
TEST_VERIFY (malloc (size) == NULL);
TEST_VERIFY (errno == ENOMEM);
ptr_to_realloc = malloc (16);
TEST_VERIFY_EXIT (ptr_to_realloc != NULL);
test_setup ();
TEST_VERIFY (realloc (ptr_to_realloc, size) == NULL);
TEST_VERIFY (errno == ENOMEM);
free (ptr_to_realloc);
for (size_t nmemb = 1; nmemb <= 8; nmemb *= 2)
if ((size % nmemb) == 0)
{
test_setup ();
TEST_VERIFY (calloc (nmemb, size / nmemb) == NULL);
TEST_VERIFY (errno == ENOMEM);
test_setup ();
TEST_VERIFY (calloc (size / nmemb, nmemb) == NULL);
TEST_VERIFY (errno == ENOMEM);
ptr_to_realloc = malloc (16);
TEST_VERIFY_EXIT (ptr_to_realloc != NULL);
test_setup ();
TEST_VERIFY (reallocarray (ptr_to_realloc, nmemb, size / nmemb) == NULL);
TEST_VERIFY (errno == ENOMEM);
free (ptr_to_realloc);
ptr_to_realloc = malloc (16);
TEST_VERIFY_EXIT (ptr_to_realloc != NULL);
test_setup ();
TEST_VERIFY (reallocarray (ptr_to_realloc, size / nmemb, nmemb) == NULL);
TEST_VERIFY (errno == ENOMEM);
free (ptr_to_realloc);
}
else
break;
}
static long pagesize;
/* This function tests the following aligned memory allocation functions
using several valid alignments and precedes each allocation test with a
small malloc/free before it:
memalign, posix_memalign, aligned_alloc, valloc, pvalloc. */
static void
test_large_aligned_allocations (size_t size)
{
/* ptr stores the result of posix_memalign but since all those calls
should fail, posix_memalign should never change ptr. We set it to
NULL here and later on we check that it remains NULL after each
posix_memalign call. */
void * ptr = NULL;
size_t align;
/* All aligned memory allocation functions expect an alignment that is a
power of 2. Given this, we test each of them with every valid
alignment from 1 thru PAGESIZE. */
for (align = 1; align <= pagesize; align *= 2)
{
test_setup ();
TEST_VERIFY (memalign (align, size) == NULL);
TEST_VERIFY (errno == ENOMEM);
/* posix_memalign expects an alignment that is a power of 2 *and* a
multiple of sizeof (void *). */
if ((align % sizeof (void *)) == 0)
{
test_setup ();
TEST_VERIFY (posix_memalign (&ptr, align, size) == ENOMEM);
TEST_VERIFY (ptr == NULL);
}
/* aligned_alloc expects a size that is a multiple of alignment. */
if ((size % align) == 0)
{
test_setup ();
TEST_VERIFY (aligned_alloc (align, size) == NULL);
TEST_VERIFY (errno == ENOMEM);
}
}
/* Both valloc and pvalloc return page-aligned memory. */
test_setup ();
TEST_VERIFY (valloc (size) == NULL);
TEST_VERIFY (errno == ENOMEM);
test_setup ();
TEST_VERIFY (pvalloc (size) == NULL);
TEST_VERIFY (errno == ENOMEM);
}
#define FOURTEEN_ON_BITS ((1UL << 14) - 1)
#define FIFTY_ON_BITS ((1UL << 50) - 1)
static int
do_test (void)
{
#if __WORDSIZE >= 64
/* This test assumes that none of the supported targets have an address
bus wider than 50 bits, and that therefore allocations for sizes wider
than 50 bits will fail. Here, we ensure that the assumption continues
to be true in the future when we might have address buses wider than 50
bits. */
struct rlimit alloc_size_limit
= {
.rlim_cur = FIFTY_ON_BITS,
.rlim_max = FIFTY_ON_BITS
};
setrlimit (RLIMIT_AS, &alloc_size_limit);
#endif /* __WORDSIZE >= 64 */
DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
/* GCC 7 warns about too-large allocations; here we want to test
that they fail. */
DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
#endif
/* Aligned memory allocation functions need to be tested up to alignment
size equivalent to page size, which should be a power of 2. */
pagesize = sysconf (_SC_PAGESIZE);
TEST_VERIFY_EXIT (powerof2 (pagesize));
/* Loop 1: Ensure that all allocations with SIZE close to SIZE_MAX, i.e.
in the range (SIZE_MAX - 2^14, SIZE_MAX], fail.
We can expect that this range of allocation sizes will always lead to
an allocation failure on both 64 and 32 bit targets, because:
1. no currently supported 64-bit target has an address bus wider than
50 bits -- and (2^64 - 2^14) is much wider than that;
2. on 32-bit targets, even though 2^32 is only 4 GB and potentially
addressable, glibc itself is more than 2^14 bytes in size, and
therefore once glibc is loaded, less than (2^32 - 2^14) bytes remain
available. */
for (size_t i = 0; i <= FOURTEEN_ON_BITS; i++)
{
test_large_allocations (SIZE_MAX - i);
test_large_aligned_allocations (SIZE_MAX - i);
}
#if __WORDSIZE >= 64
/* On 64-bit targets, we need to test a much wider range of too-large
sizes, so we test at intervals of (1 << 50) that allocation sizes
ranging from SIZE_MAX down to (1 << 50) fail:
The 14 MSBs are decremented starting from "all ON" going down to 1,
the 50 LSBs are "all ON" and then "all OFF" during every iteration. */
for (size_t msbs = FOURTEEN_ON_BITS; msbs >= 1; msbs--)
{
size_t size = (msbs << 50) | FIFTY_ON_BITS;
test_large_allocations (size);
test_large_aligned_allocations (size);
size = msbs << 50;
test_large_allocations (size);
test_large_aligned_allocations (size);
}
#endif /* __WORDSIZE >= 64 */
DIAG_POP_NEEDS_COMMENT;
return 0;
}
#include <support/test-driver.c>
-4
View File
@@ -66,10 +66,6 @@ do_test (void)
if (p == NULL)
merror ("realloc (NULL, 10) failed.");
/* errno should be clear on success (POSIX). */
if (p != NULL && save != 0)
merror ("errno is set but should not be");
free (p);
p = calloc (20, 1);
+14 -7
View File
@@ -754,9 +754,13 @@ When the source file is compiled using @code{_FILE_OFFSET_BITS == 64} on a
@c This is a syscall for Linux v4.6. The sysdeps/posix fallback emulation
@c is also MT-Safe since it calls preadv.
This function is similar to the @code{preadv} function, with the difference
it adds an extra @var{flags} parameter of type @code{int}. The supported
@var{flags} are dependent of the underlying system. For Linux it supports:
This function is similar to the @code{preadv} function, with the
difference it adds an extra @var{flags} parameter of type @code{int}.
Additionally, if @var{offset} is @math{-1}, the current file position
is used and updated (like the @code{readv} function).
The supported @var{flags} are dependent of the underlying system. For
Linux it supports:
@vtable @code
@item RWF_HIPRI
@@ -823,10 +827,13 @@ When the source file is compiled using @code{_FILE_OFFSET_BITS == 64} on a
@c This is a syscall for Linux v4.6. The sysdeps/posix fallback emulation
@c is also MT-Safe since it calls pwritev.
This function is similar to the @code{pwritev} function, with the difference
it adds an extra @var{flags} parameter of type @code{int}. The supported
@var{flags} are dependent of the underlying system and for Linux it supports
the same ones as for @code{preadv2}.
This function is similar to the @code{pwritev} function, with the
difference it adds an extra @var{flags} parameter of type @code{int}.
Additionally, if @var{offset} is @math{-1}, the current file position
should is used and updated (like the @code{writev} function).
The supported @var{flags} are dependent of the underlying system. For
Linux, the supported flags are the same as those for @code{preadv2}.
When the source file is compiled with @code{_FILE_OFFSET_BITS == 64} the
@code{pwritev2} function is in fact @code{pwritev64v2} and the type
+9 -12
View File
@@ -1104,7 +1104,6 @@ When calling @code{mallopt}, the @var{param} argument specifies the
parameter to be set, and @var{value} the new value to be set. Possible
choices for @var{param}, as defined in @file{malloc.h}, are:
@comment TODO: @item M_CHECK_ACTION
@vtable @code
@item M_MMAP_MAX
The maximum number of chunks to allocate with @code{mmap}. Setting this
@@ -1309,17 +1308,15 @@ The block was already freed.
Another possibility to check for and guard against bugs in the use of
@code{malloc}, @code{realloc} and @code{free} is to set the environment
variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set, a
special (less efficient) implementation is used which is designed to be
tolerant against simple errors, such as double calls of @code{free} with
the same argument, or overruns of a single byte (off-by-one bugs). Not
all such errors can be protected against, however, and memory leaks can
result. If @code{MALLOC_CHECK_} is set to @code{0}, any detected heap
corruption is silently ignored; if set to @code{1}, a diagnostic is
printed on @code{stderr}; if set to @code{2}, @code{abort} is called
immediately. This can be useful because otherwise a crash may happen
much later, and the true cause for the problem is then very hard to
track down.
variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set to a
non-zero value, a special (less efficient) implementation is used which
is designed to be tolerant against simple errors, such as double calls
of @code{free} with the same argument, or overruns of a single byte
(off-by-one bugs). Not all such errors can be protected against,
however, and memory leaks can result.
Any detected heap corruption results in immediate termination of the
process.
There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries
it could possibly be exploited since diverging from the normal programs
-7
View File
@@ -195,13 +195,6 @@ this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic
threshold adjustment was already disabled.
@end deftp
@deftp Probe memory_mallopt_check_action (int @var{$arg1}, int @var{$arg2})
This probe is triggered shortly after the @code{memory_mallopt} probe,
when the parameter to be changed is @code{M_CHECK_ACTION}. Argument
@var{$arg1} is the requested value, and @var{$arg2} is the previous
value of this @code{malloc} parameter.
@end deftp
@deftp Probe memory_mallopt_perturb (int @var{$arg1}, int @var{$arg2})
This probe is triggered shortly after the @code{memory_mallopt} probe,
when the parameter to be changed is @code{M_PERTURB}. Argument
+5
View File
@@ -109,6 +109,11 @@ The @var{filedes} is not associated with a terminal.
@item ERANGE
The buffer length @var{len} is too small to store the string to be
returned.
@item ENODEV
The @var{filedes} is associated with a terminal device that is a slave
pseudo-terminal, but the file name associated with that device could
not be determined. This is a GNU extension.
@end table
@end deftypefun
+10 -24
View File
@@ -71,27 +71,13 @@ following tunables in the @code{malloc} namespace:
This tunable supersedes the @env{MALLOC_CHECK_} environment variable and is
identical in features.
Setting this tunable enables a special (less efficient) memory allocator for
the malloc family of functions that is designed to be tolerant against simple
errors such as double calls of free with the same argument, or overruns of a
single byte (off-by-one bugs). Not all such errors can be protected against,
however, and memory leaks can result. The following list describes the values
that this tunable can take and the effect they have on malloc functionality:
@itemize @bullet
@item @code{0} Ignore all errors. The default allocator continues to be in
use, but all errors are silently ignored.
@item @code{1} Report errors. The alternate allocator is selected and heap
corruption, if detected, is reported as diagnostic messages to @code{stderr}
and the program continues execution.
@item @code{2} Abort on errors. The alternate allocator is selected and if
heap corruption is detected, the program is ended immediately by calling
@code{abort}.
@item @code{3} Fully enabled. The alternate allocator is selected and is fully
functional. That is, if heap corruption is detected, a verbose diagnostic
message is printed to @code{stderr} and the program is ended by calling
@code{abort}.
@end itemize
Setting this tunable to a non-zero value enables a special (less
efficient) memory allocator for the malloc family of functions that is
designed to be tolerant against simple errors such as double calls of
free with the same argument, or overruns of a single byte (off-by-one
bugs). Not all such errors can be protected against, however, and memory
leaks can result. Any detected heap corruption results in immediate
termination of the process.
Like @env{MALLOC_CHECK_}, @code{glibc.malloc.check} has a problem in that it
diverges from normal program behavior by writing to @code{stderr}, which could
@@ -201,8 +187,8 @@ per-thread cache. The default (and maximum) value is 1032 bytes on
@deftp Tunable glibc.malloc.tcache_count
The maximum number of chunks of each size to cache. The default is 7.
There is no upper limit, other than available system memory. If set
to zero, the per-thread cache is effectively disabled.
The upper limit is 127. If set to zero, the per-thread cache is effectively
disabled.
The approximate maximum overhead of the per-thread cache is thus equal
to the number of bins times the chunk count in each bin times the size
@@ -267,7 +253,7 @@ This tunable is specific to i386 and x86-64.
@deftp Tunable glibc.tune.cpu
The @code{glibc.tune.cpu=xxx} tunable allows the user to tell @theglibc{} to
assume that the CPU is @code{xxx} where xxx may have one of these values:
@code{generic}, @code{thunderxt88}.
@code{generic}, @code{falkor}, @code{thunderxt88}, @code{ares}.
This tunable is specific to aarch64.
@end deftp
+4 -1
View File
@@ -203,7 +203,8 @@ tests-static = test-fpucw-static test-fpucw-ieee-static \
test-signgam-ullong-static test-signgam-ullong-init-static
ifneq (,$(CXX))
tests += test-math-isinff test-math-iszero
tests += test-math-isinff test-math-iszero test-math-issignaling \
test-math-iscanonical test-math-iseqsig
endif
ifneq (no,$(PERL))
@@ -350,6 +351,8 @@ CFLAGS-test-signgam-ullong-init-static.c = -std=c99
CFLAGS-test-math-isinff.cc = -std=gnu++11
CFLAGS-test-math-iszero.cc = -std=gnu++11
CFLAGS-test-math-issignaling.cc = -std=gnu++11
CFLAGS-test-math-iscanonical.cc = -std=gnu++11
CFLAGS-test-iszero-excess-precision.c = -fexcess-precision=standard
CFLAGS-test-iseqsig-excess-precision.c = -fexcess-precision=standard
+147 -10
View File
@@ -402,7 +402,13 @@ enum
/* Return number of classification appropriate for X. */
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \
&& !defined __OPTIMIZE_SIZE__
&& (!defined __OPTIMIZE_SIZE__ || defined __cplusplus)
/* The check for __cplusplus allows the use of the builtin, even
when optimization for size is on. This is provided for
libstdc++, only to let its configure test work when it is built
with -Os. No further use of this definition of fpclassify is
expected in C++ mode, since libstdc++ provides its own version
of fpclassify in cmath (which undefines fpclassify). */
# define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \
FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
# else
@@ -412,6 +418,15 @@ enum
/* Return nonzero value if sign of X is negative. */
# if __GNUC_PREREQ (6,0)
# define signbit(x) __builtin_signbit (x)
# elif defined __cplusplus
/* In C++ mode, __MATH_TG cannot be used, because it relies on
__builtin_types_compatible_p, which is a C-only builtin.
The check for __cplusplus allows the use of the builtin instead of
__MATH_TG. This is provided for libstdc++, only to let its configure
test work. No further use of this definition of signbit is expected
in C++ mode, since libstdc++ provides its own version of signbit
in cmath (which undefines signbit). */
# define signbit(x) __builtin_signbitl (x)
# elif __GNUC_PREREQ (4,0)
# define signbit(x) __MATH_TG ((x), __builtin_signbit, (x))
# else
@@ -442,8 +457,12 @@ enum
/* Return nonzero value if X is positive or negative infinity. */
# if __HAVE_DISTINCT_FLOAT128 && !__GNUC_PREREQ (7,0) \
&& !defined __SUPPORT_SNAN__
/* __builtin_isinf_sign is broken for float128 only before GCC 7.0. */
&& !defined __SUPPORT_SNAN__ && !defined __cplusplus
/* Since __builtin_isinf_sign is broken for float128 before GCC 7.0,
use the helper function, __isinff128, with older compilers. This is
only provided for C mode, because in C++ mode, GCC has no support
for __builtin_types_compatible_p (and when in C++ mode, this macro is
not used anyway, because libstdc++ headers undefine it). */
# define isinf(x) \
(__builtin_types_compatible_p (__typeof (x), _Float128) \
? __isinff128 (x) : __builtin_isinf_sign (x))
@@ -470,7 +489,32 @@ enum
# include <bits/iscanonical.h>
/* Return nonzero value if X is a signaling NaN. */
# define issignaling(x) __MATH_TG ((x), __issignaling, (x))
# ifndef __cplusplus
# define issignaling(x) __MATH_TG ((x), __issignaling, (x))
# else
/* In C++ mode, __MATH_TG cannot be used, because it relies on
__builtin_types_compatible_p, which is a C-only builtin. On the
other hand, overloading provides the means to distinguish between
the floating-point types. The overloading resolution will match
the correct parameter (regardless of type qualifiers (i.e.: const
and volatile)). */
extern "C++" {
inline int issignaling (float __val) { return __issignalingf (__val); }
inline int issignaling (double __val) { return __issignaling (__val); }
inline int
issignaling (long double __val)
{
# ifdef __NO_LONG_DOUBLE_MATH
return __issignaling (__val);
# else
return __issignalingl (__val);
# endif
}
# if __HAVE_DISTINCT_FLOAT128
inline int issignaling (_Float128 __val) { return __issignalingf128 (__val); }
# endif
} /* extern C++ */
# endif
/* Return nonzero value if X is subnormal. */
# define issubnormal(x) (fpclassify (x) == FP_SUBNORMAL)
@@ -484,15 +528,40 @@ enum
# endif
# else /* __cplusplus */
extern "C++" {
# ifdef __SUPPORT_SNAN__
inline int
iszero (float __val)
{
return __fpclassifyf (__val) == FP_ZERO;
}
inline int
iszero (double __val)
{
return __fpclassify (__val) == FP_ZERO;
}
inline int
iszero (long double __val)
{
# ifdef __NO_LONG_DOUBLE_MATH
return __fpclassify (__val) == FP_ZERO;
# else
return __fpclassifyl (__val) == FP_ZERO;
# endif
}
# if __HAVE_DISTINCT_FLOAT128
inline int
iszero (_Float128 __val)
{
return __fpclassifyf128 (__val) == FP_ZERO;
}
# endif
# else
template <class __T> inline bool
iszero (__T __val)
{
# ifdef __SUPPORT_SNAN__
return fpclassify (__val) == FP_ZERO;
# else
return __val == 0;
# endif
}
# endif
} /* extern C++ */
# endif /* __cplusplus */
#endif /* Use IEC_60559_BFP_EXT. */
@@ -776,8 +845,76 @@ extern int matherr (struct exception *__exc);
/* Return X == Y but raising "invalid" and setting errno if X or Y is
a NaN. */
# define iseqsig(x, y) \
__MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
# if !defined __cplusplus || (__cplusplus < 201103L && !defined __GNUC__)
# define iseqsig(x, y) \
__MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
# else
/* In C++ mode, __MATH_TG cannot be used, because it relies on
__builtin_types_compatible_p, which is a C-only builtin. Moreover,
the comparison macros from ISO C take two floating-point arguments,
which need not have the same type. Choosing what underlying function
to call requires evaluating the formats of the arguments, then
selecting which is wider. The macro __MATH_EVAL_FMT2 provides this
information, however, only the type of the macro expansion is
relevant (actually evaluating the expression would be incorrect).
Thus, the type is used as a template parameter for __iseqsig_type,
which calls the appropriate underlying function. */
extern "C++" {
template<typename> struct __iseqsig_type;
template<> struct __iseqsig_type<float>
{
static int __call (float __x, float __y) throw ()
{
return __iseqsigf (__x, __y);
}
};
template<> struct __iseqsig_type<double>
{
static int __call (double __x, double __y) throw ()
{
return __iseqsig (__x, __y);
}
};
template<> struct __iseqsig_type<long double>
{
static int __call (long double __x, long double __y) throw ()
{
# ifndef __NO_LONG_DOUBLE_MATH
return __iseqsigl (__x, __y);
# else
return __iseqsig (__x, __y);
# endif
}
};
# if __HAVE_DISTINCT_FLOAT128
template<> struct __iseqsig_type<_Float128>
{
static int __call (_Float128 __x, _Float128 __y) throw ()
{
return __iseqsigf128 (__x, __y);
}
};
# endif
template<typename _T1, typename _T2>
inline int
iseqsig (_T1 __x, _T2 __y) throw ()
{
# if __cplusplus >= 201103L
typedef decltype (__MATH_EVAL_FMT2 (__x, __y)) _T3;
# else
typedef __typeof (__MATH_EVAL_FMT2 (__x, __y)) _T3;
# endif
return __iseqsig_type<_T3>::__call (__x, __y);
}
} /* extern "C++" */
# endif /* __cplusplus */
#endif
__END_DECLS
+48
View File
@@ -0,0 +1,48 @@
/* Test for the C++ implementation of iscanonical.
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 _GNU_SOURCE 1
#include <math.h>
#include <stdio.h>
static int errors;
template <class T>
static void
check_type ()
{
T val = 0;
/* Check if iscanonical is available in C++ mode (bug 22235). */
if (iscanonical (val) == 0)
errors++;
}
static int
do_test (void)
{
check_type<float> ();
check_type<double> ();
check_type<long double> ();
#if __HAVE_DISTINCT_FLOAT128
check_type<_Float128> ();
#endif
return errors != 0;
}
#include <support/test-driver.c>
+111
View File
@@ -0,0 +1,111 @@
/* Test for the C++ implementation of iseqsig.
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 _GNU_SOURCE 1
#include <math.h>
#include <stdio.h>
#include <limits>
/* There is no NaN for _Float128 in std::numeric_limits.
Include ieee754_float128.h and use the bitfields in the union
ieee854_float128.ieee_nan to build a NaN. */
#if __HAVE_DISTINCT_FLOAT128
# include <ieee754_float128.h>
#endif
#include <support/check.h>
static void
check (int actual, int expected, const char *actual_expr, int line)
{
if (actual != expected)
{
support_record_failure ();
printf ("%s:%d: error: %s\n", __FILE__, line, actual_expr);
printf ("%s:%d: expected: %d\n", __FILE__, line, expected);
printf ("%s:%d: actual: %d\n", __FILE__, line, actual);
}
}
#define CHECK(actual, expected) \
check ((actual), (expected), #actual, __LINE__)
template <class T1, class T2>
static void
check_type ()
{
T1 t1 = 0;
T2 t2 = 0;
CHECK (iseqsig (t1, t2), 1);
t2 = 1;
CHECK (iseqsig (t1, t2), 0);
if (std::numeric_limits<T1>::has_quiet_NaN
&& std::numeric_limits<T2>::has_quiet_NaN)
{
CHECK (iseqsig (std::numeric_limits<T1>::quiet_NaN (), t2), 0);
CHECK (iseqsig (t1, std::numeric_limits<T2>::quiet_NaN ()), 0);
CHECK (iseqsig (std::numeric_limits<T1>::quiet_NaN (),
std::numeric_limits<T2>::quiet_NaN ()), 0);
}
}
#if __HAVE_DISTINCT_FLOAT128
static void
check_float128 ()
{
ieee854_float128 q1, q2, q3_nan;
q1.d = 0;
q2.d = 1;
q3_nan.ieee_nan.negative = 0;
q3_nan.ieee_nan.exponent = 0x7FFF;
q3_nan.ieee_nan.quiet_nan = 1;
q3_nan.ieee_nan.mantissa0 = 0x0000;
q3_nan.ieee_nan.mantissa1 = 0x00000000;
q3_nan.ieee_nan.mantissa2 = 0x00000000;
q3_nan.ieee_nan.mantissa3 = 0x00000000;
CHECK (iseqsig (q1.d, q1.d), 1);
CHECK (iseqsig (q1.d, q2.d), 0);
CHECK (iseqsig (q1.d, q3_nan.d), 0);
CHECK (iseqsig (q3_nan.d, q3_nan.d), 0);
}
#endif
static int
do_test (void)
{
check_type<float, float> ();
check_type<float, double> ();
check_type<float, long double> ();
check_type<double, float> ();
check_type<double, double> ();
check_type<double, long double> ();
check_type<long double, float> ();
check_type<long double, double> ();
check_type<long double, long double> ();
#if __HAVE_DISTINCT_FLOAT128
check_float128 ();
#endif
return 0;
}
#include <support/test-driver.c>
+113
View File
@@ -0,0 +1,113 @@
/* Test for the C++ implementation of issignaling.
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 _GNU_SOURCE 1
#include <math.h>
#include <stdio.h>
#include <limits>
/* There is no signaling_NaN for _Float128 in std::numeric_limits.
Include ieee754_float128.h and use the bitfields in the union
ieee854_float128.ieee_nan to build a signaling NaN. */
#if __HAVE_DISTINCT_FLOAT128
# include <ieee754_float128.h>
#endif
static bool errors;
static void
check (int actual, int expected, const char *actual_expr, int line)
{
if (actual != expected)
{
errors = true;
printf ("%s:%d: error: %s\n", __FILE__, line, actual_expr);
printf ("%s:%d: expected: %d\n", __FILE__, line, expected);
printf ("%s:%d: actual: %d\n", __FILE__, line, actual);
}
}
#define CHECK(actual, expected) \
check ((actual), (expected), #actual, __LINE__)
template <class T>
static void
check_type ()
{
typedef std::numeric_limits<T> limits;
CHECK (issignaling (T{0}), 0);
if (limits::has_infinity)
{
CHECK (issignaling (limits::infinity ()), 0);
CHECK (issignaling (-limits::infinity ()), 0);
}
if (limits::has_quiet_NaN)
CHECK (issignaling (limits::quiet_NaN ()), 0);
if (limits::has_signaling_NaN)
CHECK (issignaling (limits::signaling_NaN ()), 1);
}
#if __HAVE_DISTINCT_FLOAT128
static void
check_float128 ()
{
ieee854_float128 q;
q.d = 0;
CHECK (issignaling (q.d), 0);
/* Infinity. */
q.ieee.negative = 0;
q.ieee.exponent = 0x7FFF;
q.ieee.mantissa0 = 0x0000;
q.ieee.mantissa1 = 0x00000000;
q.ieee.mantissa2 = 0x00000000;
q.ieee.mantissa3 = 0x00000000;
CHECK (issignaling (q.d), 0);
/* Quiet NaN. */
q.ieee_nan.quiet_nan = 1;
q.ieee_nan.mantissa0 = 0x0000;
CHECK (issignaling (q.d), 0);
/* Still a quiet NaN. */
q.ieee_nan.quiet_nan = 1;
q.ieee_nan.mantissa0 = 0x4000;
CHECK (issignaling (q.d), 0);
/* Signaling NaN. */
q.ieee_nan.quiet_nan = 0;
q.ieee_nan.mantissa0 = 0x4000;
CHECK (issignaling (q.d), 1);
}
#endif
static int
do_test (void)
{
check_type<float> ();
check_type<double> ();
check_type<long double> ();
#if __HAVE_DISTINCT_FLOAT128
check_float128 ();
#endif
return errors;
}
#include <support/test-driver.c>
+79
View File
@@ -22,6 +22,13 @@
#include <limits>
/* Support for _Float128 in std::numeric_limits is limited.
Include ieee754_float128.h and use the bitfields in the union
ieee854_float128.ieee_nan to build corner-case inputs. */
#if __HAVE_DISTINCT_FLOAT128
# include <ieee754_float128.h>
#endif
static bool errors;
static void
@@ -72,12 +79,84 @@ check_type ()
std::numeric_limits<T>::has_denorm == std::denorm_absent);
}
#if __HAVE_DISTINCT_FLOAT128
static void
check_float128 ()
{
ieee854_float128 q;
q.d = 0.0Q;
CHECK (iszero (q.d), 1);
q.d = -0.0Q;
CHECK (iszero (q.d), 1);
q.d = 1.0Q;
CHECK (iszero (q.d), 0);
q.d = -1.0Q;
CHECK (iszero (q.d), 0);
/* Normal min. */
q.ieee.negative = 0;
q.ieee.exponent = 0x0001;
q.ieee.mantissa0 = 0x0000;
q.ieee.mantissa1 = 0x00000000;
q.ieee.mantissa2 = 0x00000000;
q.ieee.mantissa3 = 0x00000000;
CHECK (iszero (q.d), 0);
q.ieee.negative = 1;
CHECK (iszero (q.d), 0);
/* Normal max. */
q.ieee.negative = 0;
q.ieee.exponent = 0x7FFE;
q.ieee.mantissa0 = 0xFFFF;
q.ieee.mantissa1 = 0xFFFFFFFF;
q.ieee.mantissa2 = 0xFFFFFFFF;
q.ieee.mantissa3 = 0xFFFFFFFF;
CHECK (iszero (q.d), 0);
q.ieee.negative = 1;
CHECK (iszero (q.d), 0);
/* Infinity. */
q.ieee.negative = 0;
q.ieee.exponent = 0x7FFF;
q.ieee.mantissa0 = 0x0000;
q.ieee.mantissa1 = 0x00000000;
q.ieee.mantissa2 = 0x00000000;
q.ieee.mantissa3 = 0x00000000;
CHECK (iszero (q.d), 0);
/* Quiet NaN. */
q.ieee_nan.quiet_nan = 1;
q.ieee_nan.mantissa0 = 0x0000;
CHECK (iszero (q.d), 0);
/* Signaling NaN. */
q.ieee_nan.quiet_nan = 0;
q.ieee_nan.mantissa0 = 0x4000;
CHECK (iszero (q.d), 0);
/* Denormal min. */
q.ieee.negative = 0;
q.ieee.exponent = 0x0000;
q.ieee.mantissa0 = 0x0000;
q.ieee.mantissa1 = 0x00000000;
q.ieee.mantissa2 = 0x00000000;
q.ieee.mantissa3 = 0x00000001;
CHECK (iszero (q.d), 0);
q.ieee.negative = 1;
CHECK (iszero (q.d), 0);
}
#endif
static int
do_test (void)
{
check_type<float> ();
check_type<double> ();
check_type<long double> ();
#if __HAVE_DISTINCT_FLOAT128
check_float128 ();
#endif
return errors;
}
+19 -9
View File
@@ -408,6 +408,15 @@
# endif
#endif
#if __GNUC_PREREQ (8, 0)
/* Describes a char array whose address can safely be passed as the first
argument to strncpy and strncat, as the char array is not necessarily
a NUL-terminated string. */
# define __attribute_nonstring__ __attribute__ ((__nonstring__))
#else
# define __attribute_nonstring__
#endif
#if (!defined _Static_assert && !defined __cplusplus \
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
&& (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
@@ -464,17 +473,18 @@
# define __glibc_macro_warning(msg)
#endif
/* Support for generic selection (ISO C11) is available in GCC since
version 4.9. Previous versions do not provide generic selection,
even though they might set __STDC_VERSION__ to 201112L, when in
-std=c11 mode. Thus, we must check for !defined __GNUC__ when
testing __STDC_VERSION__ for generic selection support.
/* Generic selection (ISO C11) is a C-only feature, available in GCC
since version 4.9. Previous versions do not provide generic
selection, even though they might set __STDC_VERSION__ to 201112L,
when in -std=c11 mode. Thus, we must check for !defined __GNUC__
when testing __STDC_VERSION__ for generic selection support.
On the other hand, Clang also defines __GNUC__, so a clang-specific
check is required to enable the use of generic selection. */
#if __GNUC_PREREQ (4, 9) \
|| __glibc_clang_has_extension (c_generic_selections) \
|| (!defined __GNUC__ && defined __STDC_VERSION__ \
&& __STDC_VERSION__ >= 201112L)
#if !defined __cplusplus \
&& (__GNUC_PREREQ (4, 9) \
|| __glibc_clang_has_extension (c_generic_selections) \
|| (!defined __GNUC__ && defined __STDC_VERSION__ \
&& __STDC_VERSION__ >= 201112L))
# define __HAVE_GENERIC_SELECTION 1
#else
# define __HAVE_GENERIC_SELECTION 0
+38
View File
@@ -16,6 +16,7 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <array_length.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
@@ -25,6 +26,7 @@
#include <support/check.h>
#include <support/temp_file.h>
#include <support/xunistd.h>
static char *temp_filename;
static int temp_fd;
@@ -50,6 +52,42 @@ do_prepare (int argc, char **argv)
pwritev (__fd, __iov, __iovcnt, __offset)
#endif
static __attribute__ ((unused)) void
do_test_without_offset (void)
{
xftruncate (temp_fd, 0);
xwrite (temp_fd, "123", 3);
xlseek (temp_fd, 2, SEEK_SET);
{
struct iovec iov[] =
{
{ (void *) "abc", 3 },
{ (void *) "xyzt", 4 },
};
TEST_COMPARE (PWRITEV (temp_fd, iov, array_length (iov), -1), 7);
}
TEST_COMPARE (xlseek (temp_fd, 0, SEEK_CUR), 9);
xlseek (temp_fd, 1, SEEK_SET);
char buf1[3];
char buf2[2];
{
struct iovec iov[] =
{
{ buf1, sizeof (buf1) },
{ buf2, sizeof (buf2) },
};
TEST_COMPARE (PREADV (temp_fd, iov, array_length (iov), -1),
sizeof (buf1) + sizeof (buf2));
TEST_COMPARE (memcmp ("2ab", buf1, sizeof (buf1)), 0);
TEST_COMPARE (memcmp ("cx", buf2, sizeof (buf2)), 0);
TEST_COMPARE (xlseek (temp_fd, 0, SEEK_CUR), 6);
}
xftruncate (temp_fd, 0);
}
static int
do_test_with_offset (off_t offset)
{
+76 -1
View File
@@ -19,10 +19,85 @@
#include <limits.h>
#include <support/check.h>
#ifndef RWF_HIPRI
# define RWF_HIPRI 0
#endif
#ifndef RWF_DSYNC
# define RWF_DSYNC 0
#endif
#ifndef RWF_SYNC
# define RWF_SYNC 0
#endif
#ifndef RWF_NOWAIT
# define RWF_NOWAIT 0
#endif
#ifndef RWF_APPEND
# define RWF_APPEND 0
#endif
#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \
| RWF_APPEND)
static void
do_test_with_invalid_fd (void)
{
char buf[256];
struct iovec iov = { buf, sizeof buf };
/* Check with flag being 0 to use the fallback code which calls pwritev
or writev. */
TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1);
TEST_COMPARE (errno, EBADF);
TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1);
TEST_COMPARE (errno, EBADF);
/* Same tests as before but with flags being different than 0. Since
there is no emulation for any flag value, fallback code returns
ENOTSUP. This is different running on a kernel with preadv2/pwritev2
support, where EBADF is returned). */
TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
}
static void
do_test_with_invalid_iov (void)
{
{
char buf[256];
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = (size_t)SSIZE_MAX + 1;
TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1);
TEST_COMPARE (errno, EINVAL);
TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1);
TEST_COMPARE (errno, EINVAL);
/* Same as for invalid file descriptor tests, emulation fallback
first checks for flag value and return ENOTSUP. */
TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
}
{
/* An invalid iovec buffer should trigger an invalid memory access
or an error (Linux for instance returns EFAULT). */
struct iovec iov[IOV_MAX+1] = { 0 };
TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
}
}
static void
do_test_with_invalid_flags (void)
{
#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT)
/* Set the next bit from the mask of all supported flags. */
int invalid_flag = __builtin_clz (RWF_SUPPORTED);
invalid_flag = 0x1 << ((sizeof (int) * CHAR_BIT) - invalid_flag);
+3
View File
@@ -29,6 +29,9 @@ static int
do_test (void)
{
do_test_with_invalid_flags ();
do_test_without_offset ();
do_test_with_invalid_fd ();
do_test_with_invalid_iov ();
return do_test_with_offset (0);
}
+3
View File
@@ -31,6 +31,9 @@ static int
do_test (void)
{
do_test_with_invalid_flags ();
do_test_without_offset ();
do_test_with_invalid_fd ();
do_test_with_invalid_iov ();
return do_test_with_offset (0);
}
+13 -4
View File
@@ -227,6 +227,10 @@ CFLAGS-pt-system.c = -fexceptions
LDLIBS-tst-once5 = -lstdc++
CFLAGS-tst-thread_local1.o = -std=gnu++11
LDLIBS-tst-thread_local1 = -lstdc++
CFLAGS-tst-thread-exit-clobber.o = -std=gnu++11
LDLIBS-tst-thread-exit-clobber = -lstdc++
CFLAGS-tst-minstack-throw.o = -std=gnu++11
LDLIBS-tst-minstack-throw = -lstdc++
tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
@@ -302,7 +306,9 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
c89 gnu89 c99 gnu99 c11 gnu11) \
tst-bad-schedattr \
tst-thread_local1 tst-mutex-errorcheck tst-robust10 \
tst-robust-fork tst-create-detached tst-memstream
tst-robust-fork tst-create-detached tst-memstream \
tst-thread-exit-clobber tst-minstack-cancel tst-minstack-exit \
tst-minstack-throw
tests-internal := tst-typesizes \
tst-rwlock19 tst-rwlock20 \
@@ -367,7 +373,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \
tst-oncex3 tst-oncex4
ifeq ($(build-shared),yes)
tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1
tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder
tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1
tests-nolibpthread += tst-fini1
ifeq ($(have-z-execstack),yes)
@@ -379,7 +385,7 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
tst-join7mod
tst-join7mod tst-compat-forwarder-mod
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \
tst-cleanup4aux.o tst-cleanupx4aux.o
test-extras += tst-cleanup4aux tst-cleanupx4aux
@@ -453,7 +459,8 @@ endif
ifeq (,$(CXX))
# These tests require a C++ compiler and runtime.
tests-unsupported += tst-cancel24 tst-cancel24-static tst-once5
tests-unsupported += tst-cancel24 tst-cancel24-static tst-once5 \
tst-thread-exit-clobber tst-minstack-throw
endif
# These tests require a C++ compiler and runtime with thread_local support.
ifneq ($(have-cxx-thread_local),yes)
@@ -718,6 +725,8 @@ $(objpfx)tst-oddstacklimit.out: $(objpfx)tst-oddstacklimit $(objpfx)tst-basic1
$(evaluate-test)
endif
$(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
# The tests here better do not run in parallel
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
.NOTPARALLEL:
+33 -2
View File
@@ -356,7 +356,7 @@ setup_stack_prot (char *mem, size_t size, char *guard, size_t guardsize,
const int prot)
{
char *guardend = guard + guardsize;
#if _STACK_GROWS_DOWN
#if _STACK_GROWS_DOWN && !defined(NEED_SEPARATE_REGISTER_STACK)
/* As defined at guard_position, for architectures with downward stack
the guard page is always at start of the allocated area. */
if (__mprotect (guardend, size - guardsize, prot) != 0)
@@ -372,6 +372,33 @@ setup_stack_prot (char *mem, size_t size, char *guard, size_t guardsize,
return 0;
}
/* Mark the memory of the stack as usable to the kernel. It frees everything
except for the space used for the TCB itself. */
static inline void
__always_inline
advise_stack_range (void *mem, size_t size, uintptr_t pd, size_t guardsize)
{
uintptr_t sp = (uintptr_t) CURRENT_STACK_FRAME;
size_t pagesize_m1 = __getpagesize () - 1;
#if _STACK_GROWS_DOWN && !defined(NEED_SEPARATE_REGISTER_STACK)
size_t freesize = (sp - (uintptr_t) mem) & ~pagesize_m1;
assert (freesize < size);
if (freesize > PTHREAD_STACK_MIN)
__madvise (mem, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
#else
/* Page aligned start of memory to free (higher than or equal
to current sp plus the minimum stack size). */
uintptr_t freeblock = (sp + PTHREAD_STACK_MIN + pagesize_m1) & ~pagesize_m1;
uintptr_t free_end = (pd - guardsize) & ~pagesize_m1;
if (free_end > freeblock)
{
size_t freesize = free_end - freeblock;
assert (freesize < size);
__madvise ((void*) freeblock, freesize, MADV_DONTNEED);
}
#endif
}
/* Returns a usable stack for a new thread either by allocating a
new stack or reusing a cached stack of sufficient size.
ATTR must be non-NULL and point to a valid pthread_attr.
@@ -506,6 +533,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* Make sure the size of the stack is enough for the guard and
eventually the thread descriptor. */
guardsize = (attr->guardsize + pagesize_m1) & ~pagesize_m1;
if (guardsize < attr->guardsize || size + guardsize < guardsize)
/* Arithmetic overflow. */
return EINVAL;
size += guardsize;
if (__builtin_expect (size < ((guardsize + __static_tls_size
+ MINIMAL_REST_STACK + pagesize_m1)
& ~pagesize_m1),
@@ -727,7 +758,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
- offsetof (pthread_mutex_t,
__data.__list.__next));
pd->robust_head.list_op_pending = NULL;
#ifdef __PTHREAD_MUTEX_HAVE_PREV
#if __PTHREAD_MUTEX_HAVE_PREV
pd->robust_prev = &pd->robust_head;
#endif
pd->robust_head.list = &pd->robust_head;
+3 -3
View File
@@ -169,7 +169,7 @@ struct pthread
pid_t pid_ununsed;
/* List of robust mutexes the thread is holding. */
#ifdef __PTHREAD_MUTEX_HAVE_PREV
#if __PTHREAD_MUTEX_HAVE_PREV
void *robust_prev;
struct robust_list_head robust_head;
@@ -380,9 +380,9 @@ struct pthread
/* Machine-specific unwind info. */
struct _Unwind_Exception exc;
/* If nonzero pointer to area allocated for the stack and its
size. */
/* If nonzero, pointer to the area allocated for the stack and guard. */
void *stackblock;
/* Size of the stackblock area including the guard. */
size_t stackblock_size;
/* Size of the included guard area. */
size_t guardsize;
+2 -5
View File
@@ -297,7 +297,7 @@ __pthread_initialize_minimal_internal (void)
/* Initialize the robust mutex data. */
{
#ifdef __PTHREAD_MUTEX_HAVE_PREV
#if __PTHREAD_MUTEX_HAVE_PREV
pd->robust_prev = &pd->robust_head;
#endif
pd->robust_head.list = &pd->robust_head;
@@ -473,8 +473,5 @@ strong_alias (__pthread_initialize_minimal_internal,
size_t
__pthread_get_minstack (const pthread_attr_t *attr)
{
struct pthread_attr *iattr = (struct pthread_attr *) attr;
return (GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN
+ iattr->guardsize);
return GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN;
}
+10 -21
View File
@@ -25,36 +25,25 @@
symbol in libpthread, but the historical ABI requires it. For static
linking, there is no need to provide anything here--the libc version
will be linked in. For shared library ABI compatibility, there must be
longjmp and siglongjmp symbols in libpthread.so; so we define them using
IFUNC to redirect to the libc function. */
longjmp and siglongjmp symbols in libpthread.so.
With an IFUNC resolver, it would be possible to avoid the indirection,
but the IFUNC resolver might run before the __libc_longjmp symbol has
been relocated, in which case the IFUNC resolver would not be able to
provide the correct address. */
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
# if HAVE_IFUNC
# undef INIT_ARCH
# define INIT_ARCH()
# define DEFINE_LONGJMP(name) libc_ifunc (name, &__libc_longjmp)
extern __typeof(longjmp) longjmp_ifunc;
extern __typeof(siglongjmp) siglongjmp_ifunc;
# else /* !HAVE_IFUNC */
static void __attribute__ ((noreturn, used))
longjmp_compat (jmp_buf env, int val)
{
__libc_longjmp (env, val);
}
# define DEFINE_LONGJMP(name) strong_alias (longjmp_compat, name)
strong_alias (longjmp_compat, longjmp_alias)
compat_symbol (libpthread, longjmp_alias, longjmp, GLIBC_2_0);
# endif /* HAVE_IFUNC */
DEFINE_LONGJMP (longjmp_ifunc)
compat_symbol (libpthread, longjmp_ifunc, longjmp, GLIBC_2_0);
strong_alias (longjmp_ifunc, siglongjmp_ifunc)
compat_symbol (libpthread, siglongjmp_ifunc, siglongjmp, GLIBC_2_0);
strong_alias (longjmp_alias, siglongjmp_alias)
compat_symbol (libpthread, siglongjmp_alias, siglongjmp, GLIBC_2_0);
#endif
+8 -16
View File
@@ -25,29 +25,21 @@
libpthread, but the historical ABI requires it. For static linking,
there is no need to provide anything here--the libc version will be
linked in. For shared library ABI compatibility, there must be a
'system' symbol in libpthread.so; so we define it using IFUNC to
redirect to the libc function. */
'system' symbol in libpthread.so.
With an IFUNC resolver, it would be possible to avoid the indirection,
but the IFUNC resolver might run before the __libc_system symbol has
been relocated, in which case the IFUNC resolver would not be able to
provide the correct address. */
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
# if HAVE_IFUNC
extern __typeof(system) system_ifunc;
# undef INIT_ARCH
# define INIT_ARCH()
libc_ifunc (system_ifunc, &__libc_system)
# else /* !HAVE_IFUNC */
static int __attribute__ ((used))
system_compat (const char *line)
{
return __libc_system (line);
}
strong_alias (system_compat, system_ifunc)
# endif /* HAVE_IFUNC */
compat_symbol (libpthread, system_ifunc, system, GLIBC_2_0);
strong_alias (system_compat, system_alias)
compat_symbol (libpthread, system_alias, system, GLIBC_2_0);
#endif
+6
View File
@@ -647,4 +647,10 @@ check_stacksize_attr (size_t st)
return EINVAL;
}
#define ASSERT_PTHREAD_STRING(x) __STRING (x)
#define ASSERT_PTHREAD_INTERNAL_OFFSET(type, member, offset) \
_Static_assert (offsetof (type, member) == offset, \
"offset of " #member " field of " #type " != " \
ASSERT_PTHREAD_STRING (offset))
#endif /* pthreadP.h */
+6 -2
View File
@@ -405,8 +405,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
{
/* There is still a waiter after spinning. Set the wake-request
flag and block. Relaxed MO is fine because this is just about
this futex word. */
r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1);
this futex word.
Update r to include the set wake-request flag so that the upcoming
futex_wait only blocks if the flag is still set (otherwise, we'd
violate the basic client-side futex protocol). */
r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1;
if ((r >> 1) > 0)
futex_wait_simple (cond->__data.__g_refs + g1, r, private);
+4 -27
View File
@@ -520,7 +520,7 @@ START_THREAD_DEFN
#ifndef __ASSUME_SET_ROBUST_LIST
/* If this thread has any robust mutexes locked, handle them now. */
# ifdef __PTHREAD_MUTEX_HAVE_PREV
# if __PTHREAD_MUTEX_HAVE_PREV
void *robust = pd->robust_head.list;
# else
__pthread_slist_t *robust = pd->robust_list.__next;
@@ -538,7 +538,7 @@ START_THREAD_DEFN
__list.__next));
robust = *((void **) robust);
# ifdef __PTHREAD_MUTEX_HAVE_PREV
# if __PTHREAD_MUTEX_HAVE_PREV
this->__list.__prev = NULL;
# endif
this->__list.__next = NULL;
@@ -551,31 +551,8 @@ START_THREAD_DEFN
}
#endif
/* Mark the memory of the stack as usable to the kernel. We free
everything except for the space used for the TCB itself. */
size_t pagesize_m1 = __getpagesize () - 1;
#ifdef _STACK_GROWS_DOWN
char *sp = CURRENT_STACK_FRAME;
size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1;
assert (freesize < pd->stackblock_size);
if (freesize > PTHREAD_STACK_MIN)
__madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
#else
/* Page aligned start of memory to free (higher than or equal
to current sp plus the minimum stack size). */
void *freeblock = (void*)((size_t)(CURRENT_STACK_FRAME
+ PTHREAD_STACK_MIN
+ pagesize_m1)
& ~pagesize_m1);
char *free_end = (char *) (((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
/* Is there any space to free? */
if (free_end > (char *)freeblock)
{
size_t freesize = (size_t)(free_end - (char *)freeblock);
assert (freesize < pd->stackblock_size);
__madvise (freeblock, freesize, MADV_DONTNEED);
}
#endif
advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd,
pd->guardsize);
/* If the thread is detached free the TCB. */
if (IS_DETACHED (pd))
+5 -2
View File
@@ -57,9 +57,12 @@ pthread_getattr_np (pthread_t thread_id, pthread_attr_t *attr)
/* The sizes are subject to alignment. */
if (__glibc_likely (thread->stackblock != NULL))
{
iattr->stacksize = thread->stackblock_size;
/* The stack size reported to the user should not include the
guard size. */
iattr->stacksize = thread->stackblock_size - thread->guardsize;
#if _STACK_GROWS_DOWN
iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
iattr->stackaddr = (char *) thread->stackblock
+ thread->stackblock_size;
#else
iattr->stackaddr = (char *) thread->stackblock;
#endif
+13
View File
@@ -23,6 +23,7 @@
#include <kernel-features.h>
#include "pthreadP.h"
#include <atomic.h>
#include <pthread-offsets.h>
#include <stap-probe.h>
@@ -58,6 +59,18 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
const struct pthread_mutexattr *imutexattr;
assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T);
ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__nusers,
__PTHREAD_MUTEX_NUSERS_OFFSET);
ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__kind,
__PTHREAD_MUTEX_KIND_OFFSET);
ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__spins,
__PTHREAD_MUTEX_SPINS_OFFSET);
#if __PTHREAD_MUTEX_LOCK_ELISION
ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__elision,
__PTHREAD_MUTEX_ELISION_OFFSET);
#endif
ASSERT_PTHREAD_INTERNAL_OFFSET (pthread_mutex_t, __data.__list,
__PTHREAD_MUTEX_LIST_OFFSET);
imutexattr = ((const struct pthread_mutexattr *) mutexattr
?: &default_mutexattr);
+53 -4
View File
@@ -92,6 +92,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
&mutex->__data.__list.__next);
/* We need to set op_pending before starting the operation. Also
see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
oldval = mutex->__data.__lock;
do
@@ -117,7 +120,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
/* But it is inconsistent unless marked otherwise. */
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exist here. If we fall
@@ -133,6 +141,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
int kind = PTHREAD_MUTEX_TYPE (mutex);
if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
{
/* We do not need to ensure ordering wrt another memory
access. Also see comments at ENQUEUE_MUTEX. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
return EDEADLK;
@@ -140,6 +150,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
/* We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
@@ -158,6 +170,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
id, 0);
if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
{
/* We haven't acquired the lock as it is already acquired by
another owner. We do not need to ensure ordering wrt another
memory access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -171,13 +186,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
if (oldval == id)
lll_unlock (mutex->__data.__lock,
PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
/* FIXME This violates the mutex destruction requirements. See
__pthread_mutex_unlock_full. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
}
while ((oldval & FUTEX_OWNER_DIED) != 0);
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
mutex->__data.__owner = id;
@@ -203,10 +225,15 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
if (robust)
/* Note: robust PI futexes are signaled by setting bit 0. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
(void *) (((uintptr_t) &mutex->__data.__list.__next)
| 1));
{
/* Note: robust PI futexes are signaled by setting bit 0. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
(void *) (((uintptr_t) &mutex->__data.__list.__next)
| 1));
/* We need to set op_pending before starting the operation. Also
see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
}
oldval = mutex->__data.__lock;
@@ -215,12 +242,16 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
{
if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
{
/* We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EDEADLK;
}
if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
{
/* We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Just bump the counter. */
@@ -242,6 +273,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
{
if ((oldval & FUTEX_OWNER_DIED) == 0)
{
/* We haven't acquired the lock as it is already acquired by
another owner. We do not need to ensure ordering wrt another
memory access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -262,6 +296,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
{
/* The kernel has not yet finished the mutex owner death.
We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -279,7 +316,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
/* But it is inconsistent unless marked otherwise. */
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exit here. If we fall
@@ -302,13 +344,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
0, 0);
/* To the kernel, this will be visible after the kernel has
acquired the mutex in the syscall. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
if (robust)
{
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX_PI (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
}
+19
View File
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <stackinfo.h>
#include <libc-diag.h>
static void *
tf (void *arg)
@@ -362,7 +363,16 @@ do_test (void)
result = 1;
}
DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
/* GCC 8 warns about aliasing of the restrict-qualified arguments
passed &a. Since pthread_create does not dereference its fourth
argument, this aliasing, which is deliberate in this test, cannot
in fact cause problems. */
DIAG_IGNORE_NEEDS_COMMENT (8, "-Wrestrict");
#endif
err = pthread_create (&th, &a, tf, &a);
DIAG_POP_NEEDS_COMMENT;
if (err)
{
error (0, err, "pthread_create #2 failed");
@@ -388,7 +398,16 @@ do_test (void)
result = 1;
}
DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
/* GCC 8 warns about aliasing of the restrict-qualified arguments
passed &a. Since pthread_create does not dereference its fourth
argument, this aliasing, which is deliberate in this test, cannot
in fact cause problems. */
DIAG_IGNORE_NEEDS_COMMENT (8, "-Wrestrict");
#endif
err = pthread_create (&th, &a, tf, &a);
DIAG_POP_NEEDS_COMMENT;
if (err)
{
error (0, err, "pthread_create #3 failed");
+28
View File
@@ -0,0 +1,28 @@
/* 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/>. */
/* Call the function system through a statically initialized pointer. */
#include <stdlib.h>
int (*system_function) (const char *) = system;
void
call_system (void)
{
system_function (NULL);
}
+35
View File
@@ -0,0 +1,35 @@
/* 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/>. */
/* Test that the compat forwaders in libpthread work correctly. */
#include <support/test-driver.h>
extern void call_system (void);
int
do_test (void)
{
/* Calling the system function from a shared library that is not linked
against libpthread, when the main program is linked against
libpthread, should not crash. */
call_system ();
return 0;
}
#include <support/test-driver.c>
+48
View File
@@ -0,0 +1,48 @@
/* Test cancellation with a minimal stack size.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Note: This test is similar to tst-minstack-exit, but is separate to
avoid spurious test passes due to warm-up effects. */
#include <limits.h>
#include <unistd.h>
#include <support/check.h>
#include <support/xthread.h>
static void *
threadfunc (void *closure)
{
while (1)
pause ();
return NULL;
}
static int
do_test (void)
{
pthread_attr_t attr;
xpthread_attr_init (&attr);
xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
pthread_t thr = xpthread_create (&attr, threadfunc, NULL);
xpthread_cancel (thr);
TEST_VERIFY (xpthread_join (thr) == PTHREAD_CANCELED);
xpthread_attr_destroy (&attr);
return 0;
}
#include <support/test-driver.c>
+46
View File
@@ -0,0 +1,46 @@
/* Test that pthread_exit works with the minimum stack size.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Note: This test is similar to tst-minstack-cancel, but is separate
to avoid spurious test passes due to warm-up effects. */
#include <limits.h>
#include <unistd.h>
#include <support/check.h>
#include <support/xthread.h>
static void *
threadfunc (void *closure)
{
pthread_exit (threadfunc);
return NULL;
}
static int
do_test (void)
{
pthread_attr_t attr;
xpthread_attr_init (&attr);
xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
pthread_t thr = xpthread_create (&attr, threadfunc, NULL);
TEST_VERIFY (xpthread_join (thr) == threadfunc);
xpthread_attr_destroy (&attr);
return 0;
}
#include <support/test-driver.c>
+87
View File
@@ -0,0 +1,87 @@
/* Test that throwing C++ exceptions works with the minimum stack size.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <stdexcept>
#include <limits.h>
#include <string.h>
#include <support/check.h>
#include <support/xthread.h>
/* Throw a std::runtime_exception. */
__attribute__ ((noinline, noclone, weak))
void
do_throw_exception ()
{
throw std::runtime_error ("test exception");
}
/* Class with a destructor, to trigger unwind handling. */
struct class_with_destructor
{
class_with_destructor ();
~class_with_destructor ();
};
__attribute__ ((noinline, noclone, weak))
class_with_destructor::class_with_destructor ()
{
}
__attribute__ ((noinline, noclone, weak))
class_with_destructor::~class_with_destructor ()
{
}
__attribute__ ((noinline, noclone, weak))
void
function_with_destructed_object ()
{
class_with_destructor obj;
do_throw_exception ();
}
static void *
threadfunc (void *closure)
{
try
{
function_with_destructed_object ();
FAIL_EXIT1 ("no exception thrown");
}
catch (std::exception &e)
{
TEST_COMPARE (strcmp (e.what (), "test exception"), 0);
return reinterpret_cast<void *> (threadfunc);
}
FAIL_EXIT1 ("no exception caught");
}
static int
do_test (void)
{
pthread_attr_t attr;
xpthread_attr_init (&attr);
xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
pthread_t thr = xpthread_create (&attr, threadfunc, NULL);
TEST_VERIFY (xpthread_join (thr) == threadfunc);
xpthread_attr_destroy (&attr);
return 0;
}
#include <support/test-driver.c>
+243
View File
@@ -0,0 +1,243 @@
/* Test that pthread_exit does not clobber callee-saved registers.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include <support/check.h>
#include <support/xthread.h>
/* This test attempts to check that callee-saved registers are
restored to their original values when destructors are run after
pthread_exit is called. GCC PR 83641 causes this test to fail.
The constants have been chosen randomly and are magic values which
are used to detect whether registers have been clobbered. The idea
is that these values are hidden behind a compiler barrier and only
present in .rodata initially, so that it is less likely that they
are in a register by accident.
The checker class can be stored in registers, and the magic values
are directly loaded into these registers. The checker destructor
is eventually invoked by pthread_exit and calls one of the
check_magic functions to verify that the class contents (that is,
register value) is correct.
These tests are performed both for unsigned int and double values,
to cover different calling conventions. */
template <class T>
struct values
{
T v0;
T v1;
T v2;
T v3;
T v4;
};
static const values<unsigned int> magic_values =
{
0x57f7fc72,
0xe582daba,
0x5f6ac994,
0x35efddb7,
0x1fbf5a74,
};
static const values<double> magic_values_double =
{
0.6764041905675465,
0.9533336788140494,
0.6091161359041452,
0.7668653957125336,
0.010374520235509666,
};
/* Special index value which tells check_magic that no check should be
performed. */
enum { no_check = -1 };
/* Check that VALUE is the magic value for INDEX, behind a compiler
barrier. */
__attribute__ ((noinline, noclone, weak))
void
check_magic (int index, unsigned int value)
{
switch (index)
{
case 0:
TEST_COMPARE (value, magic_values.v0);
break;
case 1:
TEST_COMPARE (value, magic_values.v1);
break;
case 2:
TEST_COMPARE (value, magic_values.v2);
break;
case 3:
TEST_COMPARE (value, magic_values.v3);
break;
case 4:
TEST_COMPARE (value, magic_values.v4);
break;
case no_check:
break;
default:
FAIL_EXIT1 ("invalid magic value index %d", index);
}
}
/* Check that VALUE is the magic value for INDEX, behind a compiler
barrier. Double variant. */
__attribute__ ((noinline, noclone, weak))
void
check_magic (int index, double value)
{
switch (index)
{
case 0:
TEST_VERIFY (value == magic_values_double.v0);
break;
case 1:
TEST_VERIFY (value == magic_values_double.v1);
break;
case 2:
TEST_VERIFY (value == magic_values_double.v2);
break;
case 3:
TEST_VERIFY (value == magic_values_double.v3);
break;
case 4:
TEST_VERIFY (value == magic_values_double.v4);
break;
case no_check:
break;
default:
FAIL_EXIT1 ("invalid magic value index %d", index);
}
}
/* Store a magic value and check, via the destructor, that it has the
expected value. */
template <class T, int I>
struct checker
{
T value;
checker (T v)
: value (v)
{
}
~checker ()
{
check_magic (I, value);
}
};
/* The functions call_pthread_exit_0, call_pthread_exit_1,
call_pthread_exit are used to call pthread_exit indirectly, with
the intent of clobbering the register values. */
__attribute__ ((noinline, noclone, weak))
void
call_pthread_exit_0 (const values<unsigned int> *pvalues)
{
checker<unsigned int, no_check> c0 (pvalues->v0);
checker<unsigned int, no_check> c1 (pvalues->v1);
checker<unsigned int, no_check> c2 (pvalues->v2);
checker<unsigned int, no_check> c3 (pvalues->v3);
checker<unsigned int, no_check> c4 (pvalues->v4);
pthread_exit (NULL);
}
__attribute__ ((noinline, noclone, weak))
void
call_pthread_exit_1 (const values<double> *pvalues)
{
checker<double, no_check> c0 (pvalues->v0);
checker<double, no_check> c1 (pvalues->v1);
checker<double, no_check> c2 (pvalues->v2);
checker<double, no_check> c3 (pvalues->v3);
checker<double, no_check> c4 (pvalues->v4);
values<unsigned int> other_values = { 0, };
call_pthread_exit_0 (&other_values);
}
__attribute__ ((noinline, noclone, weak))
void
call_pthread_exit ()
{
values<double> other_values = { 0, };
call_pthread_exit_1 (&other_values);
}
/* Create on-stack objects and check that their values are restored by
pthread_exit. If Nested is true, call pthread_exit indirectly via
call_pthread_exit. */
template <class T, bool Nested>
__attribute__ ((noinline, noclone, weak))
void *
threadfunc (void *closure)
{
const values<T> *pvalues = static_cast<const values<T> *> (closure);
checker<T, 0> c0 (pvalues->v0);
checker<T, 1> c1 (pvalues->v1);
checker<T, 2> c2 (pvalues->v2);
checker<T, 3> c3 (pvalues->v3);
checker<T, 4> c4 (pvalues->v4);
if (Nested)
call_pthread_exit ();
else
pthread_exit (NULL);
/* This should not be reached. */
return const_cast<char *> ("");
}
static int
do_test ()
{
puts ("info: unsigned int, direct pthread_exit call");
pthread_t thr
= xpthread_create (NULL, &threadfunc<unsigned int, false>,
const_cast<values<unsigned int> *> (&magic_values));
TEST_VERIFY (xpthread_join (thr) == NULL);
puts ("info: double, direct pthread_exit call");
thr = xpthread_create (NULL, &threadfunc<double, false>,
const_cast<values<double> *> (&magic_values_double));
TEST_VERIFY (xpthread_join (thr) == NULL);
puts ("info: unsigned int, indirect pthread_exit call");
thr = xpthread_create (NULL, &threadfunc<unsigned int, true>,
const_cast<values<unsigned int> *> (&magic_values));
TEST_VERIFY (xpthread_join (thr) == NULL);
puts ("info: double, indirect pthread_exit call");
thr = xpthread_create (NULL, &threadfunc<double, true>,
const_cast<values<double> *> (&magic_values_double));
TEST_VERIFY (xpthread_join (thr) == NULL);
return 0;
}
#include <support/test-driver.c>
+3 -2
View File
@@ -1077,14 +1077,15 @@ cannot handle old request version %d; current version is %d"),
if (debug_level > 0)
{
#ifdef SO_PEERCRED
char pbuf[sizeof ("/proc//exe") + 3 * sizeof (long int)];
# ifdef PATH_MAX
char buf[PATH_MAX];
# else
char buf[4096];
# endif
snprintf (buf, sizeof (buf), "/proc/%ld/exe", (long int) pid);
ssize_t n = readlink (buf, buf, sizeof (buf) - 1);
snprintf (pbuf, sizeof (pbuf), "/proc/%ld/exe", (long int) pid);
ssize_t n = readlink (pbuf, buf, sizeof (buf) - 1);
if (n <= 0)
dbg_log (_("\
+1 -1
View File
@@ -67,7 +67,7 @@ dbg_log (const char *fmt,...)
char buf[256];
strftime (buf, sizeof (buf), "%c", &now);
char msg[512];
char msg[1024];
snprintf (msg, sizeof (msg), "%s - %d: %s%s", buf, getpid (), msg2,
msg2[strlen (msg2) - 1] == '\n' ? "" : "\n");
if (dbgout)
+1 -1
View File
@@ -480,7 +480,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
{
const char *group = key;
key = (char *) rawmemchr (key, '\0') + 1;
size_t group_len = key - group - 1;
size_t group_len = key - group;
const char *host = *key++ ? key : NULL;
if (host != NULL)
key = (char *) rawmemchr (key, '\0') + 1;
+9
View File
@@ -58,6 +58,12 @@ tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \
tst-nss-test5
xtests = bug-erange
# Tests which need libdl
ifeq (yes,$(build-shared))
tests += tst-nss-files-hosts-erange
tests += tst-nss-files-hosts-multi
endif
# If we have a thread library then we can test cancellation against
# some routines like getpwuid_r.
ifeq (yes,$(have-thread-library))
@@ -154,3 +160,6 @@ $(patsubst %,$(objpfx)%.out,$(tests)) : \
ifeq (yes,$(have-thread-library))
$(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library)
endif
$(objpfx)tst-nss-files-hosts-erange: $(libdl)
$(objpfx)tst-nss-files-hosts-multi: $(libdl)
+9 -1
View File
@@ -234,6 +234,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
H_ERRNO_VAR_P))
{
case -1:
# ifdef NEED__RES
__resolv_context_put (res_ctx);
# endif
return errno;
case 1:
#ifdef NEED_H_ERRNO
@@ -253,7 +256,12 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result
H_ERRNO_VAR);
if (nscd_status >= 0)
return nscd_status;
{
# ifdef NEED__RES
__resolv_context_put (res_ctx);
# endif
return nscd_status;
}
}
#endif
+217 -193
View File
@@ -22,6 +22,8 @@
#include <arpa/nameser.h>
#include <netdb.h>
#include <resolv/resolv-internal.h>
#include <scratch_buffer.h>
#include <alloc_buffer.h>
/* Get implementation for some internal functions. */
@@ -115,6 +117,219 @@ DB_LOOKUP (hostbyaddr, ,,,
}, const void *addr, socklen_t len, int af)
#undef EXTRA_ARGS_VALUE
/* Type of the address and alias arrays. */
#define DYNARRAY_STRUCT array
#define DYNARRAY_ELEMENT char *
#define DYNARRAY_PREFIX array_
#include <malloc/dynarray-skeleton.c>
static enum nss_status
gethostbyname3_multi (FILE * stream, const char *name, int af,
struct hostent *result, char *buffer, size_t buflen,
int *errnop, int *herrnop, int flags)
{
assert (af == AF_INET || af == AF_INET6);
/* We have to get all host entries from the file. */
struct scratch_buffer tmp_buffer;
scratch_buffer_init (&tmp_buffer);
struct hostent tmp_result_buf;
struct array addresses;
array_init (&addresses);
struct array aliases;
array_init (&aliases);
enum nss_status status;
/* Preserve the addresses and aliases encountered so far. */
for (size_t i = 0; result->h_addr_list[i] != NULL; ++i)
array_add (&addresses, result->h_addr_list[i]);
for (size_t i = 0; result->h_aliases[i] != NULL; ++i)
array_add (&aliases, result->h_aliases[i]);
/* The output buffer re-uses now-unused space at the end of the
buffer, starting with the aliases array. It comes last in the
data produced by internal_getent. (The alias names themselves
are still located in the line read in internal_getent, which is
stored at the beginning of the buffer.) */
struct alloc_buffer outbuf;
{
char *bufferend = (char *) result->h_aliases;
outbuf = alloc_buffer_create (bufferend, buffer + buflen - bufferend);
}
while (true)
{
status = internal_getent (stream, &tmp_result_buf, tmp_buffer.data,
tmp_buffer.length, errnop, herrnop, af,
flags);
/* Enlarge the buffer if necessary. */
if (status == NSS_STATUS_TRYAGAIN && *herrnop == NETDB_INTERNAL
&& *errnop == ERANGE)
{
if (!scratch_buffer_grow (&tmp_buffer))
{
*errnop = ENOMEM;
/* *herrnop and status already have the right value. */
break;
}
/* Loop around and retry with a larger buffer. */
}
else if (status == NSS_STATUS_SUCCESS)
{
/* A line was read. Check that it matches the search
criteria. */
int matches = 1;
struct hostent *old_result = result;
result = &tmp_result_buf;
/* The following piece is a bit clumsy but we want to use
the `LOOKUP_NAME_CASE' value. The optimizer should do
its job. */
do
{
LOOKUP_NAME_CASE (h_name, h_aliases)
result = old_result;
}
while ((matches = 0));
/* If the line matches, we need to copy the addresses and
aliases, so that we can reuse tmp_buffer for the next
line. */
if (matches)
{
/* Record the addresses. */
for (size_t i = 0; tmp_result_buf.h_addr_list[i] != NULL; ++i)
{
/* Allocate the target space in the output buffer,
depending on the address family. */
void *target;
if (af == AF_INET)
{
assert (tmp_result_buf.h_length == 4);
target = alloc_buffer_alloc (&outbuf, struct in_addr);
}
else if (af == AF_INET6)
{
assert (tmp_result_buf.h_length == 16);
target = alloc_buffer_alloc (&outbuf, struct in6_addr);
}
else
__builtin_unreachable ();
if (target == NULL)
{
/* Request a larger output buffer. */
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
status = NSS_STATUS_TRYAGAIN;
break;
}
memcpy (target, tmp_result_buf.h_addr_list[i],
tmp_result_buf.h_length);
array_add (&addresses, target);
}
/* Record the aliases. */
for (size_t i = 0; tmp_result_buf.h_aliases[i] != NULL; ++i)
{
char *alias = tmp_result_buf.h_aliases[i];
array_add (&aliases,
alloc_buffer_copy_string (&outbuf, alias));
}
/* If the real name is different add, it also to the
aliases. This means that there is a duplication in
the alias list but this is really the user's
problem. */
{
char *new_name = tmp_result_buf.h_name;
if (strcmp (old_result->h_name, new_name) != 0)
array_add (&aliases,
alloc_buffer_copy_string (&outbuf, new_name));
}
/* Report memory allocation failures during the
expansion of the temporary arrays. */
if (array_has_failed (&addresses) || array_has_failed (&aliases))
{
*errnop = ENOMEM;
*herrnop = NETDB_INTERNAL;
status = NSS_STATUS_UNAVAIL;
break;
}
/* Request a larger output buffer if we ran out of room. */
if (alloc_buffer_has_failed (&outbuf))
{
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
status = NSS_STATUS_TRYAGAIN;
break;
}
result = old_result;
} /* If match was found. */
/* If no match is found, loop around and fetch another
line. */
} /* status == NSS_STATUS_SUCCESS. */
else
/* internal_getent returned an error. */
break;
} /* while (true) */
/* Propagate the NSS_STATUS_TRYAGAIN error to the caller. It means
that we may not have loaded the complete result.
NSS_STATUS_NOTFOUND, however, means that we reached the end of
the file successfully. */
if (status != NSS_STATUS_TRYAGAIN)
status = NSS_STATUS_SUCCESS;
if (status == NSS_STATUS_SUCCESS)
{
/* Copy the address and alias arrays into the output buffer and
add NULL terminators. The pointed-to elements were directly
written into the output buffer above and do not need to be
copied again. */
size_t addresses_count = array_size (&addresses);
size_t aliases_count = array_size (&aliases);
char **out_addresses = alloc_buffer_alloc_array
(&outbuf, char *, addresses_count + 1);
char **out_aliases = alloc_buffer_alloc_array
(&outbuf, char *, aliases_count + 1);
if (out_addresses == NULL || out_aliases == NULL)
{
/* The output buffer is not large enough. */
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
status = NSS_STATUS_TRYAGAIN;
/* Fall through to function exit. */
}
else
{
/* Everything is allocated in place. Make the copies and
adjust the array pointers. */
memcpy (out_addresses, array_begin (&addresses),
addresses_count * sizeof (char *));
out_addresses[addresses_count] = NULL;
memcpy (out_aliases, array_begin (&aliases),
aliases_count * sizeof (char *));
out_aliases[aliases_count] = NULL;
result->h_addr_list = out_addresses;
result->h_aliases = out_aliases;
status = NSS_STATUS_SUCCESS;
}
}
scratch_buffer_free (&tmp_buffer);
array_free (&addresses);
array_free (&aliases);
return status;
}
enum nss_status
_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
char *buffer, size_t buflen, int *errnop,
@@ -143,199 +358,8 @@ _nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
if (status == NSS_STATUS_SUCCESS
&& _res_hconf.flags & HCONF_FLAG_MULTI)
{
/* We have to get all host entries from the file. */
size_t tmp_buflen = MIN (buflen, 4096);
char tmp_buffer_stack[tmp_buflen]
__attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));
char *tmp_buffer = tmp_buffer_stack;
struct hostent tmp_result_buf;
int naddrs = 1;
int naliases = 0;
char *bufferend;
bool tmp_buffer_malloced = false;
while (result->h_aliases[naliases] != NULL)
++naliases;
bufferend = (char *) &result->h_aliases[naliases + 1];
again:
while ((status = internal_getent (stream, &tmp_result_buf, tmp_buffer,
tmp_buflen, errnop, herrnop, af,
flags))
== NSS_STATUS_SUCCESS)
{
int matches = 1;
struct hostent *old_result = result;
result = &tmp_result_buf;
/* The following piece is a bit clumsy but we want to use the
`LOOKUP_NAME_CASE' value. The optimizer should do its
job. */
do
{
LOOKUP_NAME_CASE (h_name, h_aliases)
result = old_result;
}
while ((matches = 0));
if (matches)
{
/* We could be very clever and try to recycle a few bytes
in the buffer instead of generating new arrays. But
we are not doing this here since it's more work than
it's worth. Simply let the user provide a bit bigger
buffer. */
char **new_h_addr_list;
char **new_h_aliases;
int newaliases = 0;
size_t newstrlen = 0;
int cnt;
/* Count the new aliases and the length of the strings. */
while (tmp_result_buf.h_aliases[newaliases] != NULL)
{
char *cp = tmp_result_buf.h_aliases[newaliases];
++newaliases;
newstrlen += strlen (cp) + 1;
}
/* If the real name is different add it also to the
aliases. This means that there is a duplication
in the alias list but this is really the user's
problem. */
if (strcmp (old_result->h_name,
tmp_result_buf.h_name) != 0)
{
++newaliases;
newstrlen += strlen (tmp_result_buf.h_name) + 1;
}
/* Make sure bufferend is aligned. */
assert ((bufferend - (char *) 0) % sizeof (char *) == 0);
/* Now we can check whether the buffer is large enough.
16 is the maximal size of the IP address. */
if (bufferend + 16 + (naddrs + 2) * sizeof (char *)
+ roundup (newstrlen, sizeof (char *))
+ (naliases + newaliases + 1) * sizeof (char *)
>= buffer + buflen)
{
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
status = NSS_STATUS_TRYAGAIN;
goto out;
}
new_h_addr_list =
(char **) (bufferend
+ roundup (newstrlen, sizeof (char *))
+ 16);
new_h_aliases =
(char **) ((char *) new_h_addr_list
+ (naddrs + 2) * sizeof (char *));
/* Copy the old data in the new arrays. */
for (cnt = 0; cnt < naddrs; ++cnt)
new_h_addr_list[cnt] = old_result->h_addr_list[cnt];
for (cnt = 0; cnt < naliases; ++cnt)
new_h_aliases[cnt] = old_result->h_aliases[cnt];
/* Store the new strings. */
cnt = 0;
while (tmp_result_buf.h_aliases[cnt] != NULL)
{
new_h_aliases[naliases++] = bufferend;
bufferend = (__stpcpy (bufferend,
tmp_result_buf.h_aliases[cnt])
+ 1);
++cnt;
}
if (cnt < newaliases)
{
new_h_aliases[naliases++] = bufferend;
bufferend = __stpcpy (bufferend,
tmp_result_buf.h_name) + 1;
}
/* Final NULL pointer. */
new_h_aliases[naliases] = NULL;
/* Round up the buffer end address. */
bufferend += (sizeof (char *)
- ((bufferend - (char *) 0)
% sizeof (char *))) % sizeof (char *);
/* Now the new address. */
new_h_addr_list[naddrs++] =
memcpy (bufferend, tmp_result_buf.h_addr,
tmp_result_buf.h_length);
/* Also here a final NULL pointer. */
new_h_addr_list[naddrs] = NULL;
/* Store the new array pointers. */
old_result->h_aliases = new_h_aliases;
old_result->h_addr_list = new_h_addr_list;
/* Compute the new buffer end. */
bufferend = (char *) &new_h_aliases[naliases + 1];
assert (bufferend <= buffer + buflen);
result = old_result;
}
}
if (status == NSS_STATUS_TRYAGAIN)
{
size_t newsize = 2 * tmp_buflen;
if (tmp_buffer_malloced)
{
char *newp = realloc (tmp_buffer, newsize);
if (newp != NULL)
{
assert ((((uintptr_t) newp)
& (__alignof__ (struct hostent_data) - 1))
== 0);
tmp_buffer = newp;
tmp_buflen = newsize;
goto again;
}
}
else if (!__libc_use_alloca (buflen + newsize))
{
tmp_buffer = malloc (newsize);
if (tmp_buffer != NULL)
{
assert ((((uintptr_t) tmp_buffer)
& (__alignof__ (struct hostent_data) - 1))
== 0);
tmp_buffer_malloced = true;
tmp_buflen = newsize;
goto again;
}
}
else
{
tmp_buffer
= extend_alloca (tmp_buffer, tmp_buflen,
newsize
+ __alignof__ (struct hostent_data));
tmp_buffer = (char *) (((uintptr_t) tmp_buffer
+ __alignof__ (struct hostent_data)
- 1)
& ~(__alignof__ (struct hostent_data)
- 1));
goto again;
}
}
else
status = NSS_STATUS_SUCCESS;
out:
if (tmp_buffer_malloced)
free (tmp_buffer);
}
status = gethostbyname3_multi
(stream, name, af, result, buffer, buflen, errnop, herrnop, flags);
internal_endent (&stream);
}
+109
View File
@@ -0,0 +1,109 @@
/* Parse /etc/hosts in multi mode with a trailing long line (bug 21915).
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 <dlfcn.h>
#include <errno.h>
#include <gnu/lib-names.h>
#include <netdb.h>
#include <nss.h>
#include <support/check.h>
#include <support/check_nss.h>
#include <support/namespace.h>
#include <support/test-driver.h>
#include <support/xunistd.h>
struct support_chroot *chroot_env;
#define X10 "XXXXXXXXXX"
#define X100 X10 X10 X10 X10 X10 X10 X10 X10 X10 X10
#define X1000 X100 X100 X100 X100 X100 X100 X100 X100 X100 X100
static void
prepare (int argc, char **argv)
{
chroot_env = support_chroot_create
((struct support_chroot_configuration)
{
.resolv_conf = "",
.hosts =
"127.0.0.1 localhost localhost.localdomain\n"
"::1 localhost localhost.localdomain\n"
"192.0.2.1 example.com\n"
"#" X1000 X100 "\n",
.host_conf = "multi on\n",
});
}
static int
do_test (void)
{
support_become_root ();
if (!support_can_chroot ())
return EXIT_UNSUPPORTED;
__nss_configure_lookup ("hosts", "files");
if (dlopen (LIBNSS_FILES_SO, RTLD_LAZY) == NULL)
FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
xchroot (chroot_env->path_chroot);
errno = ERANGE;
h_errno = NETDB_INTERNAL;
check_hostent ("gethostbyname example.com",
gethostbyname ("example.com"),
"name: example.com\n"
"address: 192.0.2.1\n");
errno = ERANGE;
h_errno = NETDB_INTERNAL;
check_hostent ("gethostbyname2 AF_INET example.com",
gethostbyname2 ("example.com", AF_INET),
"name: example.com\n"
"address: 192.0.2.1\n");
{
struct addrinfo hints =
{
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
};
errno = ERANGE;
h_errno = NETDB_INTERNAL;
struct addrinfo *ai;
int ret = getaddrinfo ("example.com", "80", &hints, &ai);
check_addrinfo ("example.com AF_UNSPEC", ai, ret,
"address: STREAM/TCP 192.0.2.1 80\n");
if (ret == 0)
freeaddrinfo (ai);
hints.ai_family = AF_INET;
errno = ERANGE;
h_errno = NETDB_INTERNAL;
ret = getaddrinfo ("example.com", "80", &hints, &ai);
check_addrinfo ("example.com AF_INET", ai, ret,
"address: STREAM/TCP 192.0.2.1 80\n");
if (ret == 0)
freeaddrinfo (ai);
}
support_chroot_free (chroot_env);
return 0;
}
#define PREPARE prepare
#include <support/test-driver.c>
+331
View File
@@ -0,0 +1,331 @@
/* Parse /etc/hosts in multi mode with many addresses/aliases.
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 <dlfcn.h>
#include <errno.h>
#include <gnu/lib-names.h>
#include <netdb.h>
#include <nss.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/check_nss.h>
#include <support/namespace.h>
#include <support/support.h>
#include <support/test-driver.h>
#include <support/test-driver.h>
#include <support/xmemstream.h>
#include <support/xstdio.h>
#include <support/xunistd.h>
#include <sys/resource.h>
struct support_chroot *chroot_env;
static void
prepare (int argc, char **argv)
{
chroot_env = support_chroot_create
((struct support_chroot_configuration)
{
.resolv_conf = "",
.hosts = "", /* See write_hosts below. */
.host_conf = "multi on\n",
});
}
/* Create the /etc/hosts file from outside the chroot. */
static void
write_hosts (int count)
{
TEST_VERIFY (count > 0 && count <= 65535);
FILE *fp = xfopen (chroot_env->path_hosts, "w");
fputs ("127.0.0.1 localhost localhost.localdomain\n"
"::1 localhost localhost.localdomain\n",
fp);
for (int i = 0; i < count; ++i)
{
fprintf (fp, "10.4.%d.%d www4.example.com\n",
(i / 256) & 0xff, i & 0xff);
fprintf (fp, "10.46.%d.%d www.example.com\n",
(i / 256) & 0xff, i & 0xff);
fprintf (fp, "192.0.2.1 alias.example.com v4-%d.example.com\n", i);
fprintf (fp, "2001:db8::6:%x www6.example.com\n", i);
fprintf (fp, "2001:db8::46:%x www.example.com\n", i);
fprintf (fp, "2001:db8::1 alias.example.com v6-%d.example.com\n", i);
}
xfclose (fp);
}
/* Parameters of a single test. */
struct test_params
{
const char *name; /* Name to query. */
const char *marker; /* Address marker for the name. */
int count; /* Number of addresses/aliases. */
int family; /* AF_INET, AF_INET_6 or AF_UNSPEC. */
bool canonname; /* True if AI_CANONNAME should be enabled. */
};
/* Expected result of gethostbyname/gethostbyname2. */
static char *
expected_ghbn (const struct test_params *params)
{
TEST_VERIFY (params->family == AF_INET || params->family == AF_INET6);
struct xmemstream expected;
xopen_memstream (&expected);
if (strcmp (params->name, "alias.example.com") == 0)
{
fprintf (expected.out, "name: %s\n", params->name);
char af;
if (params->family == AF_INET)
af = '4';
else
af = '6';
for (int i = 0; i < params->count; ++i)
fprintf (expected.out, "alias: v%c-%d.example.com\n", af, i);
for (int i = 0; i < params->count; ++i)
if (params->family == AF_INET)
fputs ("address: 192.0.2.1\n", expected.out);
else
fputs ("address: 2001:db8::1\n", expected.out);
}
else /* www/www4/www6 name. */
{
bool do_ipv4 = params->family == AF_INET
&& strncmp (params->name, "www6", 4) != 0;
bool do_ipv6 = params->family == AF_INET6
&& strncmp (params->name, "www4", 4) != 0;
if (do_ipv4 || do_ipv6)
{
fprintf (expected.out, "name: %s\n", params->name);
if (do_ipv4)
for (int i = 0; i < params->count; ++i)
fprintf (expected.out, "address: 10.%s.%d.%d\n",
params->marker, i / 256, i % 256);
if (do_ipv6)
for (int i = 0; i < params->count; ++i)
fprintf (expected.out, "address: 2001:db8::%s:%x\n",
params->marker, i);
}
else
fputs ("error: HOST_NOT_FOUND\n", expected.out);
}
xfclose_memstream (&expected);
return expected.buffer;
}
/* Expected result of getaddrinfo. */
static char *
expected_gai (const struct test_params *params)
{
bool do_ipv4 = false;
bool do_ipv6 = false;
if (params->family == AF_UNSPEC)
do_ipv4 = do_ipv6 = true;
else if (params->family == AF_INET)
do_ipv4 = true;
else if (params->family == AF_INET6)
do_ipv6 = true;
struct xmemstream expected;
xopen_memstream (&expected);
if (strcmp (params->name, "alias.example.com") == 0)
{
if (params->canonname)
fprintf (expected.out,
"flags: AI_CANONNAME\n"
"canonname: %s\n",
params->name);
if (do_ipv4)
for (int i = 0; i < params->count; ++i)
fputs ("address: STREAM/TCP 192.0.2.1 80\n", expected.out);
if (do_ipv6)
for (int i = 0; i < params->count; ++i)
fputs ("address: STREAM/TCP 2001:db8::1 80\n", expected.out);
}
else /* www/www4/www6 name. */
{
if (strncmp (params->name, "www4", 4) == 0)
do_ipv6 = false;
else if (strncmp (params->name, "www6", 4) == 0)
do_ipv4 = false;
/* Otherwise, we have www as the name, so we do both. */
if (do_ipv4 || do_ipv6)
{
if (params->canonname)
fprintf (expected.out,
"flags: AI_CANONNAME\n"
"canonname: %s\n",
params->name);
if (do_ipv4)
for (int i = 0; i < params->count; ++i)
fprintf (expected.out, "address: STREAM/TCP 10.%s.%d.%d 80\n",
params->marker, i / 256, i % 256);
if (do_ipv6)
for (int i = 0; i < params->count; ++i)
fprintf (expected.out,
"address: STREAM/TCP 2001:db8::%s:%x 80\n",
params->marker, i);
}
else
fputs ("error: Name or service not known\n", expected.out);
}
xfclose_memstream (&expected);
return expected.buffer;
}
static void
run_gbhn_gai (struct test_params *params)
{
char *ctx = xasprintf ("name=%s marker=%s count=%d family=%d",
params->name, params->marker, params->count,
params->family);
if (test_verbose > 0)
printf ("info: %s\n", ctx);
/* Check gethostbyname, gethostbyname2. */
if (params->family == AF_INET)
{
char *expected = expected_ghbn (params);
check_hostent (ctx, gethostbyname (params->name), expected);
free (expected);
}
if (params->family != AF_UNSPEC)
{
char *expected = expected_ghbn (params);
check_hostent (ctx, gethostbyname2 (params->name, params->family),
expected);
free (expected);
}
/* Check getaddrinfo. */
for (int do_canonical = 0; do_canonical < 2; ++do_canonical)
{
params->canonname = do_canonical;
char *expected = expected_gai (params);
struct addrinfo hints =
{
.ai_family = params->family,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
};
if (do_canonical)
hints.ai_flags |= AI_CANONNAME;
struct addrinfo *ai;
int ret = getaddrinfo (params->name, "80", &hints, &ai);
check_addrinfo (ctx, ai, ret, expected);
if (ret == 0)
freeaddrinfo (ai);
free (expected);
}
free (ctx);
}
/* Callback for the subprocess which runs the test in a chroot. */
static void
subprocess (void *closure)
{
struct test_params *params = closure;
xchroot (chroot_env->path_chroot);
static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC, -1 };
static const char *const names[] =
{
"www.example.com", "www4.example.com", "www6.example.com",
"alias.example.com",
NULL
};
static const char *const names_marker[] = { "46", "4", "6", "" };
for (int family_idx = 0; families[family_idx] >= 0; ++family_idx)
{
params->family = families[family_idx];
for (int names_idx = 0; names[names_idx] != NULL; ++names_idx)
{
params->name = names[names_idx];
params->marker = names_marker[names_idx];
run_gbhn_gai (params);
}
}
}
/* Run the test for a specific number of addresses/aliases. */
static void
run_test (int count)
{
write_hosts (count);
struct test_params params =
{
.count = count,
};
support_isolate_in_subprocess (subprocess, &params);
}
static int
do_test (void)
{
support_become_root ();
if (!support_can_chroot ())
return EXIT_UNSUPPORTED;
/* This test should not use gigabytes of memory. */
{
struct rlimit limit;
if (getrlimit (RLIMIT_AS, &limit) != 0)
{
printf ("getrlimit (RLIMIT_AS) failed: %m\n");
return 1;
}
long target = 200 * 1024 * 1024;
if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target)
{
limit.rlim_cur = target;
if (setrlimit (RLIMIT_AS, &limit) != 0)
{
printf ("setrlimit (RLIMIT_AS) failed: %m\n");
return 1;
}
}
}
__nss_configure_lookup ("hosts", "files");
if (dlopen (LIBNSS_FILES_SO, RTLD_LAZY) == NULL)
FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
/* Run the tests with a few different address/alias counts. */
for (int count = 1; count <= 111; ++count)
run_test (count);
run_test (1111);
run_test (22222);
support_chroot_free (chroot_env);
return 0;
}
#define PREPARE prepare
#include <support/test-driver.c>
+1 -1
View File
@@ -5920,7 +5920,7 @@ msgstr "Le fichier existe"
#. TRANS also when you rename a file with @code{rename} (@pxref{Renaming Files}).
#: sysdeps/gnu/errlist.c:211
msgid "Invalid cross-device link"
msgstr "Lien croisé de périphéque invalide"
msgstr "Lien physique inter-périphérique invalide"
#. TRANS The wrong type of device was given to a function that expects a
#. TRANS particular sort of device.

Some files were not shown because too many files have changed in this diff Show More