Building with ubsan, the test triggers:
UBSAN: Undefined behaviour in programs/locfile.c:598:3 null pointer passed as argument 2, nonnull attribute declared at unknown:0:0
The obstack_grow is only define for size > 0.
It removes the wrapper by moving the error/EDOM handling to an
out-of-line implementation (__math_invalidf_i/__math_invalidf_li).
Also, __glibc_unlikely is used on errors case since it helps
code generation on recent gcc.
The code now builds to with gcc-14 on aarch64:
0000000000000000 <__ilogbf>:
0: 1e260000 fmov w0, s0
4: d3577801 ubfx x1, x0, #23, #8
8: 340000e1 cbz w1, 24 <__ilogbf+0x24>
c: 5101fc20 sub w0, w1, #0x7f
10: 7103fc3f cmp w1, #0xff
14: 54000040 b.eq 1c <__ilogbf+0x1c> // b.none
18: d65f03c0 ret
1c: 12b00000 mov w0, #0x7fffffff // #2147483647
20: 14000000 b 0 <__math_invalidf_i>
24: 53175800 lsl w0, w0, #9
28: 340000a0 cbz w0, 3c <__ilogbf+0x3c>
2c: 5ac01000 clz w0, w0
30: 12800fc1 mov w1, #0xffffff81 // #-127
34: 4b000020 sub w0, w1, w0
38: d65f03c0 ret
3c: 320107e0 mov w0, #0x80000001 // #-2147483647
40: 14000000 b 0 <__math_invalidf_i>
Some ABI requires additional adjustments:
* i386 and m68k requires to use the template version, since
both provide __ieee754_ilogb implementatations.
* loongarch uses a custom implementation as well.
* powerpc64le also has a custom implementation for POWER9, which
is also used for float and float128 version. The generic
e_ilogb.c implementation is moved on powerpc to keep the
current code as-is.
Checked on aarch64-linux-gnu and x86_64-linux-gnu.
It removes the wrapper by moving the error/EDOM handling to an
out-of-line implementation (__math_invalid_i/__math_invalid_li).
Also, __glibc_unlikely is used on errors case since it helps
code generation on recent gcc.
The code now builds to with gcc-14 on aarch64:
0000000000000000 <__ilogb>:
0: 9e660000 fmov x0, d0
4: d374f801 ubfx x1, x0, #52, #11
8: 340000e1 cbz w1, 24 <__ilogb+0x24>
c: 510ffc20 sub w0, w1, #0x3ff
10: 711ffc3f cmp w1, #0x7ff
14: 54000040 b.eq 1c <__ilogb+0x1c> // b.none
18: d65f03c0 ret
1c: 12b00000 mov w0, #0x7fffffff // #2147483647
20: 14000000 b 0 <__math_invalid_i>
24: d374cc00 lsl x0, x0, #12
28: b40000a0 cbz x0, 3c <__ilogb+0x3c>
2c: dac01000 clz x0, x0
30: 12807fc1 mov w1, #0xfffffc01 // #-1023
34: 4b000020 sub w0, w1, w0
38: d65f03c0 ret
3c: 320107e0 mov w0, #0x80000001 // #-2147483647
40: 14000000 b 0 <__math_invalid_i>
Some ABI requires additional adjustments:
* i386 and m68k requires to use the template version, since
both provide __ieee754_ilogb implementatations.
* loongarch uses a custom implementation as well.
* powerpc64le also has a custom implementation for POWER9, which
is also used for float and float128 version. The generic
e_ilogb.c implementation is moved on powerpc to keep the
current code as-is.
Checked on aarch64-linux-gnu and x86_64-linux-gnu.
Building with ubsan triggers:
UBSAN: Undefined behaviour in ../sysdeps/ieee754/dbl-64/s_expm1.c:242:4 left shift of 4294967271 by 20 cannot be represented in type 'int'
Since at the time k is always positive, just cast to uint32_t.
When building with ubsan the ifunc resolvers triggers:
UBSAN: Undefined behaviour in ../sysdeps/aarch64/multiarch/memchr.c:34:1 left shift of 255 by 24 cannot be represented in type 'int'
The midr is defined as uint64_t, so use UINT64_C to define the masks
as well.
Multiple tests fail when malloc-debug is built with ubsan:
UBSAN: Undefined behaviour in malloc-debug.c:231:24 applying non-zero offset to a NULL pointer
The main issue is it tries to apply DUMPED_MAIN_ARENA_CHUNK or
for mem2chunk for NULL pointers.
The elf/tst-dl-printf-static test when built with ubsan triggers:
UBSAN: Undefined behaviour in vfprintf-process-arg.c:58:36 negation of 9223372036854775808 cannot be represented in type 'long int'
The elf/tst-cpu-features-supports (and other tests that check for
CPU features) triggers the following issue with ubsan:
UBSAN: Undefined behaviour in ../sysdeps/x86/sys/platform/x86.h:59:42 left shift of 1 by 31 cannot be represented in type 'int'
The active_array is unsigned, so use an unsigned constant as well.
The elf/tst-plt-rewrite2 and elf/tst-plt-rewrite2 triggers the
failures with ubsan:
UBSAN: Undefined behaviour in ../sysdeps/x86_64/dl-machine.h:637:39 store to misaligned address 0x00007adb50230021 for type 'uint32_t'
The ubsan triggers on elf/tst-tls-allocation-failure-static-patched:
UBSAN: Undefined behaviour in ../sysdeps/unix/sysv/linux/dl-early_allocate.c:58:16 pointer index expression with base 0x0000555578792000 overflowed to 0x8000555578792cc0
The function is called with a size larger than PTRDIFF_MAX, and
the addition than overflow. Fix it by limiting the size up to
PTRDIFF_MAX, like all other malloc functions.
On 32-bit architecture ubsan triggers:
UBSAN: Undefined behaviour in dl-load.c:1345:54 pointer index expression with base 0x00612508 overflowed to 0xf7c3a508
Use explicit uintptr_t operation instead.
The ubsan triggers:
UBSAN: Undefined behaviour in programs/locfile.c:644:3 null pointer passed as argument 2, nonnull attribute declared at unknown:0:0
The obstack_grow is only required if there is extra elements to be
inserted (n_elems > 0).
The ubsan triggers:
UBSAN: Undefined behaviour in ./elem-hash.h:27:14 left shift of 360447856 by 3 cannot be represented in type 'int'
Using unsigned shift here zero fill like signed.
The ubsan triggers:
UBSAN: Undefined behaviour in programs/ld-collate.c:1557:7 variable length array bound evaluates to non-positive value 0
nrules is guaranteed to be at most sizeof (((struct element_t *)
0)->used_in_level) * 8, so use it instead.
The ubsan triggers:
UBSAN: Undefined behaviour in programs/ld-collate.c:862:5 null pointer passed as argument 2, nonnull attribute declared at unknown:0:0,
The memcpy is only requires if current 'weights' is nonnull, so
check it before calling it.
The ubsan triggers:
UBSAN: Undefined behaviour in programs/charmap.c:908:2 null pointer passed as argument 2, nonnull attribute declared at unknown:0:0
This is not an isseu since size is always '0' in this case.
When building with --enable-ubsan, the relocation code triggers:
UBSAN: Undefined behaviour in get-dynamic-info.h:56:30 left shift of 1879047925 by 1 cannot be represented in type 'int'
Originally from
https://sourceware.org/pipermail/libc-alpha/2015-August/063015.html.
On mips, arc, powerpc, and s390 gcc 14 triggers the warning
In function ‘charmap_new_char’,
inlined from ‘parse_charmap.isra’ at ../locale/programs/charmap.c:570:6:
../locale/programs/charmap.c:1017:32: error: ‘strncmp’ specified bound [2147483649, 4294967295] exceeds maximum object size 2147483647 [-Werror=stringop-overread]
1017 | if (cp == &from[len1 - 1] || strncmp (from, to, prefix_len) != 0)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../locale/programs/charmap.c:1017:32: error: ‘strncmp’ specified bound [2147483649, 4294967295] exceeds maximum object size 2147483647 [-Werror=stringop-overread]
cc1: all warnings being treated as errors
So move the case to an special function and disable the sanitizer.
With ubsan enable, libc.so fails to build with:
[...]linkobj/libc_pic.a(setcontext.os): in function `__start_context':
[...]sysdeps/unix/sysv/linux/riscv/setcontext.S:111:(.text+0xc0): relocation
truncated to fit: R_RISCV_JAL against symbol `__GI_exit' defined in .text section
in [...]/linkobj/libc_pic.a(exit.os)
Using 'call' instead of 'j' works regardless whether UBSAN.
It is enabled through a new configure flag, --enable-ubsan, and
should be used for debugging and/or testing. Not all ubsan handlers
are implemented, only those generated/required by glibc libraries,
programs, and tests. Some extra handlers might be needed in future
C++ tests, and __ubsan_handle_dynamic_type_cache_miss also needs a
proper implementation.
The ubsan handlers are exported from ld.so since they are used on
all libraries and tests. This might interfere with ubsan from
compiler runtime (when programs are built with libubsan in shared
mode), and this is completely untested and/or not supported at the
moment.
There is no support for the UBSAN_OPTIONS environment variable,
although some options are supported through glibc.ubsan tunables.
Currently, glibc.ubsan.halt_on_errors can be used to avoid
the process halt when any UB handler is issued.
Using -fsanitize=undefined enables some extra compiler checks that
are not easily enabled through the libc-diag.h macro. For instance
on iconv/iconvconfig.c, gcc 14.2.1 shows:
In file included from ../include/bits/string_fortified.h:1,
from ../string/string.h:548,
from ../include/string.h:60,
from iconvconfig.c:32:
In function ‘strcpy’,
inlined from ‘write_output’ at iconvconfig.c:1033:7,
inlined from ‘main’ at iconvconfig.c:340:14:
../string/bits/string_fortified.h:81:10: error: ‘__builtin_memcpy’ offset [0, 7] is out of the bounds [0, 0] [-Werror=array-bounds=]
81 | return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../string/bits/string_fortified.h:81:10: error: ‘__builtin_memcpy’ offset [0, 7] is out of the bounds [0, 0] [-Werror=array-bounds=]
cc1: all warnings being treated as errors
Some extra code adjustments are required to fix such cases.
This preliminary support is still incomplete:
* Not all targets are supported, nor have I checked the test suitei
on all successful targets. Also, I only checked with limited gcc
versions (only gcc 14.2.1 and for some targets 15.0.0).
Currently --enable-ubsan builds on Linux for aarch64, arm, hppa,
i686, powerpc64, microblaze, mips64, loongarch64, sparc, s390x, and
x86_64.
* The instrumentation is disabled on rltd.c, although it is enabled
on other loaders functions.
* A lot of test cases show failures due to UB.
Also, gcc-14 triggers an ICE building math routines. gcc-15
works correctly.
On x86-64 and compiling with -O2 using stdc_leading_zeros compiles to
the bsr instruction. The fls function removed by this patch is inlined
but still loops while checking each bit individually.
* nss/getaddrinfo.c: Include <stdbit.h>.
(fls): Remove function. This function contains a left shift of 31 on an
'int' which is undefined.
(rfc3484_sort): Use stdc_leading_zeros instead of fls.
Signed-off-by: Collin Funk <collin.funk1@gmail.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
These routines are not extensively used (gnulib documentation even
recommend use a replacement [1]), and there is already a POWER8
version that uses proper vectorized instructions.
[1] https://www.gnu.org/software/gnulib/manual/gnulib.html#C-strings
Checked with a build for some powerpc variations.
Reviewed-by: Peter Bergner <bergner@linux.ibm.com>
Add stubs and partial docs for many undocumented pthreads functions.
While neither exhaustive nor complete, gives minimal usage docs
for many functions and expands the pthreads chapters, making it
easier to continue improving this section in the future.
Reviewed-by: Collin Funk <collin.funk1@gmail.com>
The glibc-hwcaps subdirectories are extended by "z17". Libraries are loaded if
the z17 facility bits are active:
- Miscellaneous-instruction-extensions facility 4
- Vector-enhancements-facility 3
- Vector-Packed-Decimal-Enhancement Facility 3
- CPU: Concurrent-Functions Facility
tst-glibc-hwcaps.c is extended in order to test z17 via new marker6.
In case of running on a z17 with a kernel not recognizing z17 yet,
AT_PLATFORM will be z900 but vector-bit in AT_HWCAP is set. This situation
is now recognized and this testcase does not fail.
A fatal glibc error is dumped if glibc was build with architecture
level set for z17, but run on an older machine (See dl-hwcap-check.h).
Note, you might get an SIGILL before this check if you don't use:
configure --with-rtld-early-cflags=-march=<older-machine>
ld.so --list-diagnostics now also dumps information about s390.cpu_features.
Independent from z17, the s390x kernel won't introduce new HWCAP-Bits if there
is no special handling needed in kernel itself. For z17, we don't have new
HWCAP flags, but have to check the facility bits retrieved by
stfle-instruction.
Instead of storing all the stfle-bits (currently four 64bit values) in the
cpu_features struct, we now only store those bits, which are needed within
glibc itself. Note that we have this list twice, one with original values and
the other one which can be filtered with GLIBC_TUNABLES=glibc.cpu.hwcaps.
Those new fields are stored in so far reserved space in cpu_features struct.
Thus processes started in between the update of glibc package and we e.g. have
a new ld.so and an old libc.so, won't crash. The glibc internal ifunc-resolvers
would not select the best optimized variant.
The users of stfle-bits are also updated:
- parsing of GLIBC_TUNABLES=glibc.cpu.hwcaps
- glibc internal ifunc-resolvers
- __libc_ifunc_impl_list
- sysconf
While working on implementing compoundn, I noticed that
libm-test-pown.inc was wrongly using TEST_ff_f and AUTO_TESTS_ff_f
when the actual types involved meant fL_f should be used instead of
ff_f; fix to use the correct descriptor strings for pown. (These
strings affect how gen-libm-test.py generates a C file in some cases.
The structure type test_fL_f_data for expected results and the use of
RUN_TEST_LOOP_fL_f in the ALL_RM_TEST call were already correct.)
Tested for x86_64. The generated libm-test-pown.c was actually
unchanged, but the old descriptor strings were still logically
incorrect.
Inline tcache_try_malloc into calloc since it is the only caller. Also fix
usize2tidx and use it in __libc_malloc, __libc_calloc and _mid_memalign.
The result is simpler, cleaner code.
Reviewed-by: DJ Delorie <dj@redhat.com>
The left shift overflows for 'int', use uint32_t instead. It syncs
with CORE-MATH commit bbfabd99.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The left shift overflows for 'int', use uint64_t instead. It syncs
with CORE-MATH commit d0a2be200cbc1344d800d9ef0ebee9ad67dd3ad8.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The left shift overflows for 'int', use uint32_t instead. It syncs
with CORE-MATH commit bbfabd993a71b049c210b0febfd06d18369fadc1.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The left shift overflows for 'int64_t', use unsigned instead. It syncs
with CORE-MATH commit f7c7408d1749ec2859ea249495af699359ae559b.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The left shift overflows for 'int', use uint64_t instead. It syncs
with CORE-MATH commit bbfabd99.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The left shift overflows for 'int', use a literal instead. It syncs
with OPTIMIZED-ROUTINES commit 0f87f607b976820ef41fe64d004fe67dc7af8236.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The left shift overflows for 'int', use uint64_t instead. It syncs
with CORE-MATH commit 4d6192d2.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The left shift overflows for 'int', use unsigned instead. It syncs
with CORE-MATH commit 4d6192d2.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
The BZ 32653 fix (12a497c716) kept the
stack pointer zeroing from make_main_stack_executable on
_dl_make_stack_executable. However, previously the 'stack_endp'
pointed to temporary variable created before the call of
_dl_map_object_from_fd; while now we use the __libc_stack_end
directly.
Since pthread_getattr_np relies on correct __libc_stack_end, if
_dl_make_stack_executable is called (for instance, when
glibc.rtld.execstack=2 is set) __libc_stack_end will be set to zero,
and the call will always fail.
The __libc_stack_end zero was used a mitigation hardening, but since
52a01100ad it is used solely on
pthread_getattr_np code. So there is no point in zeroing anymore.
Checked on x86_64-linux-gnu and i686-linux-gnu.
Reviewed-by: Sam James <sam@gentoo.org>
Hardware ctz instructions are available in the RISC-V Zbb and XTheadBb extension. With special `-march` flags defined, we can generate more simplified code compared to the generic implementation of `ffs`/`ffsll`.
Signed-off-by: Julian Zhu <julian.oerv@isrc.iscas.ac.cn>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
The __printf_fp_buffer_1 issues count_leading_zeros with 0 argument,
which might leads to call __builtin_ctz depending of the ABI.
Replace with stdbit.h function instead.
Checked on x86_64-linux-gnu and i686-linux-gnu.
Reviewed-by: Paul Eggert <eggert@cs.ucla.edu>
This patch changes the shell script that selects which arguments are used
for the execution of bench-malloc-thread.
The problem seems to have been introduced in commit:
commit 2d6427a63c
Author: Wangyang Guo <wangyang.guo@intel.com>
Date: Fri Nov 29 16:05:35 2024 +0800
benchtests: Add calloc test
With current condition, the following error "/bin/sh: 3: [[: not found"
occurs when executing `make bench BENCHSET="malloc-thread"` and the else
path is taken, using incorrect arguments for bench test execution.
Error is reproducible in Debian based distros.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
The <termio.h> interface is absolutely ancient: it was obsoleted by
<termios.h> already in the first version of POSIX (1988) and thus
predates the very first version of Linux. Unfortunately, some constant
macros are used both by <termio.h> and <termios.h>; particularly
problematic is the baud rate constants since the termio interface
*requires* that the baud rate is set via an enumeration as part of
c_cflag.
In preparation of revamping the termios interface to support the
arbitrary baud rate capability that the Linux kernel has supported
since 2008, remove <termio.h> in the hope that no one still uses this
archaic interface.
Note that there is no actual code in glibc to support termio: it is
purely an unabstracted ioctl() interface.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
"Recent" GCC versions (since commit fc62716fe8d1, backported to stable
branches) emit a vzeroupper instruction at the end of functions
containing AVX instructions. This causes the tst-audit10 test to fail
on CPUs lacking AVX instructions, despite the AVX512F check. The crash
occurs in the pltenter function of tst-auditmod10b.c.
Fix that by moving the code guarded by the check_avx512 function into
specific functions using the target ("avx512f") attribute. Note that
since commit 5359c3bc91 ("x86-64: Remove compiler -mavx512f check") it
is safe to assume that the compiler has AVX512F support, thus the
__AVX512F__ checks can be dropped.
Tested on non-AVX, AVX2 and AVX512F machines.
Reviewed-by: Florian Weimer <fweimer@redhat.com>