From patchwork Fri May 29 16:26:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 136096 X-Patchwork-Delegate: fweimer@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8C3484BA7998 for ; Fri, 29 May 2026 16:30:17 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by sourceware.org (Postfix) with ESMTPS id 5B32B4BA23E9 for ; Fri, 29 May 2026 16:28:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5B32B4BA23E9 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5B32B4BA23E9 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::72a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780072112; cv=none; b=ZKAKK0KcUyIJRC/5+T7lNa5HcNRfy7SKAM0ruuKX4z9EDaxZ8e74ViR6Jy5+b67ScCU8nSkuN2D9k49AzHjQpQ7ysfa1PFH6INGvilgRerUnMd9FGekpm4zkKs3cOvZ7Th+VAmJz9zjBqFBHDYTfBOr4oBte2V6Lij+VHWP4Q20= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1780072112; c=relaxed/simple; bh=aAEtRUUP1+lK84J/pwPIRPhkR6b1qlCu/kLKJ5B+6Vw=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Jugt2oavHxNO2Mu2C/cRrOEz5qvGPYkjmr4pqywvdYGrtAwBW/CozSSx7ZwPMGPjQFIRC6jAY5Ifef9KqANioXe8eDlioraVp1ueloJz48aO3FG9fixnEeJ7yOk7r49ARLq706p7DudPASjjeOFA6CrpnaMQTcw8iWDioKcjpFc= ARC-Authentication-Results: i=1; sourceware.org Received: by mail-qk1-x72a.google.com with SMTP id af79cd13be357-914bf8abeaeso619155985a.0 for ; Fri, 29 May 2026 09:28:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1780072112; x=1780676912; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GUKkcIXopM+Kv/6v4WAoRSs4kQjDLGiAxO8cNWxBwp4=; b=Wv6SnkMPK55ASw1CRMnH2oq8mI1FROhZApOW2xU6SrmqVLtI4JyITn6ZGZcaJR0LUx ArOT5NbVaI1aMQf94vTIdlNQMIR76IiRozPVwlSOvTkglGASIIYPUmxTumUWsy5knpRr rE2mvQ+A+fmUV+LD9NLyR8EEQ/fCH58FgDiwEf+AkrMveZwQ/3pf5/h2+KuJ+zGG/vkR gWhSW8oh3ZoC3j/f2R1VTk765v5ytXPC0JT4p+gF1Xgfh4UTATKud9WltCEzCKx3rC+R qmArhzlph+zNKfEqsyLh2vj+gFDda5n/QfH36Ds1e+636c7LuOk1xZxa1ffoLeMC6zRA DPGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780072112; x=1780676912; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=GUKkcIXopM+Kv/6v4WAoRSs4kQjDLGiAxO8cNWxBwp4=; b=M78qfH5KOjUSXndYejueEvMDmdeP3+5muUmd8lBkbHv3OflDDoxHTJnYq2D8gARzMP 5TLD7/h8tOBSb/q8tKMFrSrriaiIcsMk+suo1VbTIdCSLTyuTzYJ/VhtwxuhvqpvGpL3 kfHWHRz6yA3a17ejK/5oP56ArIdrswxegD6FYcGTVvW7M8ojQDeMGHCMFAVCaypa9Hd9 28gaw6mDAr6XO2g1P97OLwQ3Pu8EROTYNomzM68y6hpZlJy6VF9UvnUyGAzErCjZLQ+b dWPADTAQ++5uT538dYAwzR65d1MMsqA7CkGZhibLXDxEgudHyaBsaFGLNHEf3KUFZu8m QUDA== X-Gm-Message-State: AOJu0Yysdu67uI7fJe8pSKvpj79CJIWFJmJI/KkdkBwU/b4SKidhLktx JRaFLGyF+Z5k0L2BGpUrkvQBwH1h2h4I8xCbvL2YPYNilXuFRai5rta29F1rM76mZoEqWYfMHjh bqtO/ X-Gm-Gg: Acq92OGo6li7tMn/CI1k4Y64hpn41wxOww4NGYEitvAYQ+vi7HfeAVroZefI+zHbbke 0aGy26WOLS6vvyeRVXiBaxjyPvBya+6ZzVHW1yRWD/MviyHTk+hbcMwKmfn/Ve8HH6GRUEx/87m TNqC9VPbhiE464kDzzvWte+EZRjcymkInsbOdoClF4p/S5CMr36ZLOiNPKofiSt2KzC1+L57vX8 u6q9ZpnNCjNNBspM0VX1GlFaGetYDBP4Ak3fkqYL+ZTGwao5K8dgwNu1IXeFs606eV2wlM2py7p AzMf3FbrVYy+MANTEAL315leHJG4cba3tJQMDToznefKBMDBJ3cLRgZbRqNWIg4WVeoGEAkq4mY xlqm7M4cKE8g/3P0Sb8YK1M3pW8VXtCufGLCatytNH3xk4CxbirzITzvgAeeN4mkRv7946ADRpE t4cyxM7x9wnqediuzwV0f70kFJj4xUHCnaS68+Ij0IAITNWw== X-Received: by 2002:a05:620a:371b:b0:915:3d27:a816 with SMTP id af79cd13be357-9153da3ce1fmr59953785a.49.1780072111255; Fri, 29 May 2026 09:28:31 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:efc6:96e6:e80e:65cc:b3cd]) by smtp.gmail.com with ESMTPSA id af79cd13be357-9153244c085sm234346985a.6.2026.05.29.09.28.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 09:28:30 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Florian Weimer Subject: [PATCH v9 3/5] Fix assert during static startup (BZ 33326) Date: Fri, 29 May 2026 13:26:42 -0300 Message-ID: <20260529162818.3749464-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260529162818.3749464-1-adhemerval.zanella@linaro.org> References: <20260529162818.3749464-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The BZ#33326 testcase triggers an assertion during process startup, which results in a segmentation fault instead of an error message and process termination with a SIGABRT. The assert issues __libc_message_impl, which in turn might call string functions depending on the ABI (strchrnul, strlen, memcpy/mempcpy), system calls (writev and mmap), and finally the abort call. Since each function may be called during process startup, before self-relocation and/or the thread pointer being set up, the functions should be built without stack protection. The dl-symbol-redir-ifunc.h is also expanded to cover strlen/memcpy/mempcpy/strchrnul on multiple architectures that implement ifunc. On i386, syscalls should not use the vDSO ("call *%gs:SYSINFO_OFFSET") during program startup because thread pointer is not yet initialized. This requires __raise_direct, _dl_writev, and _dl_mmap to use I386_USE_SYSENTER. To avoid possible sysdep.h I386_USE_SYSENTER redefinition, all implementations are done on their own translation unit. The s390x requires not calling libgcc for the generic strchrnul-c (via ctz/clz macros) due to a libgcc issue: the __clzdi2 builtin is not built against a hidden reference to __clz_tab, which creates a GOT reference for static-pie (and it cannot be called before self-relocation). Creating a test case is challenging. For static-pie, the assert is only called for ill-formed ELF files on elf_get_dynamic_info and by some targets on ELF_DYNAMIC_RELOCATE (although not all targets use assert in their dl-machine.h). Some targets also issue __libc_fatal on ARCH_SETUP_IREL, but also only for ill-formatted ELF files. The test employs a different strategy and overrides the __tunables_init symbol, which is invoked immediately before self-relocation and TLS setup. The test is built with -Wl,-z,muldefs to avoid linker issues. I checked on aarch64, x86_64, i686, s390x (qemu), sparc (qemu), mips64el (qemu), armhf, riscv, and powerpc. --- assert/Makefile | 5 +++ elf/Makefile | 18 +++++++++ elf/tst-assert-startup-static.c | 40 +++++++++++++++++++ libio/Makefile | 5 +++ stdlib/Makefile | 5 +++ string/Makefile | 1 + .../aarch64/multiarch/dl-symbol-redir-ifunc.h | 1 + sysdeps/aarch64/multiarch/memcpy_generic.S | 4 ++ .../armv7/multiarch/dl-symbol-redir-ifunc.h | 27 +++++++++++++ sysdeps/generic/dl-mmap.h | 34 ++++++++++++++++ .../lp64/multiarch/dl-symbol-redir-ifunc.h | 2 + sysdeps/posix/libc_fatal.c | 12 ++++-- .../powerpc32/power4/multiarch/Makefile | 5 +++ .../be/multiarch/dl-symbol-redir-ifunc.h | 27 +++++++++++++ .../le/multiarch/dl-symbol-redir-ifunc.h | 1 + sysdeps/powerpc/powerpc64/multiarch/Makefile | 1 + sysdeps/s390/Makefile | 5 +++ .../s390/multiarch/dl-symbol-redir-ifunc.h | 4 ++ sysdeps/s390/string-bitops.h | 27 +++++++++++++ .../sparcv9/multiarch/dl-symbol-redir-ifunc.h | 3 ++ .../sparc64/multiarch/dl-symbol-redir-ifunc.h | 3 ++ sysdeps/unix/sysv/linux/Makefile | 12 ++++++ sysdeps/unix/sysv/linux/i386/Makefile | 14 +++++++ sysdeps/unix/sysv/linux/i386/dl-mmap.c | 36 +++++++++++++++++ sysdeps/unix/sysv/linux/i386/dl-mmap.h | 27 +++++++++++++ sysdeps/unix/sysv/linux/i386/dl-writev.c | 32 +++++++++++++++ sysdeps/unix/sysv/linux/i386/dl-writev.h | 15 ++++--- sysdeps/unix/sysv/linux/i386/raise_direct.c | 26 ++++++++++++ .../unix/sysv/linux/riscv/multiarch/Makefile | 8 ++++ .../x86_64/multiarch/dl-symbol-redir-ifunc.h | 22 ++++++++++ 30 files changed, 414 insertions(+), 8 deletions(-) create mode 100644 elf/tst-assert-startup-static.c create mode 100644 sysdeps/arm/armv7/multiarch/dl-symbol-redir-ifunc.h create mode 100644 sysdeps/generic/dl-mmap.h create mode 100644 sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h create mode 100644 sysdeps/s390/string-bitops.h create mode 100644 sysdeps/unix/sysv/linux/i386/dl-mmap.c create mode 100644 sysdeps/unix/sysv/linux/i386/dl-mmap.h create mode 100644 sysdeps/unix/sysv/linux/i386/dl-writev.c create mode 100644 sysdeps/unix/sysv/linux/i386/raise_direct.c diff --git a/assert/Makefile b/assert/Makefile index 4c253a344ae..541929c3b67 100644 --- a/assert/Makefile +++ b/assert/Makefile @@ -33,6 +33,11 @@ routines := \ assert-perr \ # routines +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-__libc_assert_fail.o = $(no-stack-protector) +CFLAGS-__libc_assert_fail.op = $(no-stack-protector) + tests := \ test-assert \ test-assert-2 \ diff --git a/elf/Makefile b/elf/Makefile index a58a902451c..0fed0f270fc 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -278,6 +278,7 @@ tests-static-normal := \ # tests-static-normal tests-static-internal := \ + tst-assert-startup-static \ tst-dl-printf-static \ tst-dl_find_object-static \ tst-env-setuid-tunables \ @@ -296,6 +297,12 @@ tests-static-internal += \ # tests-static-internal endif +ifeq (yes,$(run-built-tests)) +tests-special += \ + $(objpfx)tst-assert-startup-static.out \ + # tests-special +endif + CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o tst-tls1-static-non-pie-no-pie = yes CRT-tst-ifunc-resolver-protector-static-non-pie := $(csu-objpfx)crt1.o @@ -3670,3 +3677,14 @@ $(objpfx)tst-dl-debug-exclude.out: tst-dl-debug-exclude.sh \ $(objpfx)tst-recursive-tls > $@; \ $(evaluate-test) endif + +CFLAGS-tst-assert-startup-static.c += $(no-stack-protector) +LDFLAGS-tst-assert-startup-static = -Wl,-z,muldefs + +$(objpfx)tst-assert-startup-static.out: $(objpfx)tst-assert-startup-static + $(test-program-cmd-before-env) \ + $(run-program-env) \ + $< > $@ 2>&1; echo "status: $$?" >> $@; \ + grep -q 'Fatal glibc error: tst-assert-startup-static' $@ \ + && grep -q '^status: 134$$' $@; \ + $(evaluate-test) diff --git a/elf/tst-assert-startup-static.c b/elf/tst-assert-startup-static.c new file mode 100644 index 00000000000..9fd79a0e243 --- /dev/null +++ b/elf/tst-assert-startup-static.c @@ -0,0 +1,40 @@ +/* Check if assert work during program startup. + Copyright (C) 2026 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 + . */ + +#include +#include + +/* The __tunables_init is called just before self-relocation and TLS setup, + and the __libc_assert_fail is used internally for assert() calls. */ +extern _Noreturn __typeof (__assert_fail) __libc_assert_fail; + +void __tunables_init (char **env) +{ +/* The assert called by the loader/startup issues __libc_assert_fail instead + of __[]assert[_fail], and __libc_assert_fail does not perform the + translation (which would require additional handling to be called at this + point, like disable stack protection). So issue the internal routine + directly, instead of using assert here. */ + __libc_assert_fail ("error", __FILE__, __LINE__, __func__); +} + +int main (int argc, char *argv[]) +{ + /* Fail with a different error code than abort. */ + exit (EXIT_FAILURE); +} diff --git a/libio/Makefile b/libio/Makefile index 616107ee105..09b1b907dc2 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -195,6 +195,11 @@ endif CPPFLAGS += $(libio-mtsafe) +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-libc_fatal.o = $(no-stack-protector) +CFLAGS-libc_fatal.op = $(no-stack-protector) + # Support for exception handling. CFLAGS-fileops.c += -fexceptions CFLAGS-fputc.c += -fexceptions diff --git a/stdlib/Makefile b/stdlib/Makefile index addf7dc99ff..18c8b21910d 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -530,6 +530,11 @@ generated += \ tst-putenvmod.so \ # generated +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-abort.o = $(no-stack-protector) +CFLAGS-abort.op = $(no-stack-protector) + CFLAGS-bsearch.c += $(uses-callbacks) CFLAGS-qsort.c += $(uses-callbacks) CFLAGS-system.c += -fexceptions diff --git a/string/Makefile b/string/Makefile index aa0b0c2f57a..969726cccb0 100644 --- a/string/Makefile +++ b/string/Makefile @@ -287,6 +287,7 @@ CFLAGS-wordcopy.c += $(no-stack-protector) CFLAGS-strncmp.c += $(no-stack-protector) CFLAGS-memset.c += $(no-stack-protector) CFLAGS-strlen.c += $(no-stack-protector) +CFLAGS-strchrnul.c += $(no-stack-protector) ifeq ($(run-built-tests),yes) $(objpfx)tst-svc-cmp.out: tst-svc.expect $(objpfx)tst-svc.out diff --git a/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h index 26fcd1977ea..ddfd6bd45d8 100644 --- a/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/aarch64/multiarch/dl-symbol-redir-ifunc.h @@ -19,6 +19,7 @@ #ifndef _DL_IFUNC_GENERIC_H #define _DL_IFUNC_GENERIC_H +asm ("memcpy = __memcpy_generic"); asm ("memset = __memset_generic"); asm ("strlen = __strlen_generic"); #ifndef SHARED diff --git a/sysdeps/aarch64/multiarch/memcpy_generic.S b/sysdeps/aarch64/multiarch/memcpy_generic.S index c6d09081f47..d6222683056 100644 --- a/sysdeps/aarch64/multiarch/memcpy_generic.S +++ b/sysdeps/aarch64/multiarch/memcpy_generic.S @@ -42,3 +42,7 @@ #endif #include "../memcpy.S" + +#if IS_IN (rtld) +strong_alias (memcpy, __memcpy_generic) +#endif diff --git a/sysdeps/arm/armv7/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/arm/armv7/multiarch/dl-symbol-redir-ifunc.h new file mode 100644 index 00000000000..4a6c81aa8dc --- /dev/null +++ b/sysdeps/arm/armv7/multiarch/dl-symbol-redir-ifunc.h @@ -0,0 +1,27 @@ +/* Symbol redirection for loader/static initialization code. Linux/ARM + version. + Copyright (C) 2026 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 + . */ + +#ifndef _DL_IFUNC_GENERIC_H +#define _DL_IFUNC_GENERIC_H + +#ifndef __ARM_NEON__ +asm ("memcpy = __memcpy_vfp"); +#endif + +#endif diff --git a/sysdeps/generic/dl-mmap.h b/sysdeps/generic/dl-mmap.h new file mode 100644 index 00000000000..f786be0930c --- /dev/null +++ b/sysdeps/generic/dl-mmap.h @@ -0,0 +1,34 @@ +/* mmap wrapper for dynamic loader. + Copyright (C) 2026 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 + . */ + +#ifndef _DL_MMAP_H +#define _DL_MMAP_H + +#include + +/* This mmap call is used to allocate some memory to backup assert() messages + before TLS setup is done (which setup the thread pointer used by some ABIs + to issues syscalls). */ + +static inline void * +_dl_mmap (void *addr, size_t len, int prot, int flags) +{ + return __mmap (addr, len, prot, flags, -1, 0); +} + +#endif diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h index 1cd204c2f69..4379770c314 100644 --- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h @@ -20,8 +20,10 @@ #define _DL_IFUNC_GENERIC_H #ifndef SHARED +asm ("memcpy = __memcpy_aligned"); asm ("memset = __memset_aligned"); asm ("memcmp = __memcmp_aligned"); +asm ("__strchrnul = __strchrnul_aligned"); asm ("strlen = __strlen_aligned"); asm ("memcpy = __memcpy_unaligned"); asm ("memmove = __memmove_unaligned"); diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c index 3f0e302b5ea..1ff20d4feb7 100644 --- a/sysdeps/posix/libc_fatal.c +++ b/sysdeps/posix/libc_fatal.c @@ -16,7 +16,12 @@ License along with the GNU C Library; if not, see . */ +/* Mark symbols hidden in static PIE for early self relocation to work. */ +#if BUILD_PIE_DEFAULT +# pragma GCC visibility push(hidden) +#endif #include +#include #include #include #include @@ -24,6 +29,7 @@ #include #include #include +#include #ifdef FATAL_PREPARE_INCLUDE #include FATAL_PREPARE_INCLUDE @@ -113,9 +119,9 @@ __libc_message_impl (const char *vma_name, const char *fmt, ...) total = ALIGN_UP (total + sizeof (struct abort_msg_s) + 1, GLRO(dl_pagesize)); - struct abort_msg_s *buf = __mmap (NULL, total, - PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); + struct abort_msg_s *buf = _dl_mmap (NULL, total, + PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE); if (__glibc_likely (buf != MAP_FAILED)) { buf->size = total; diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile b/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile index 3a49b855ca5..60ba2e50d28 100644 --- a/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile @@ -11,4 +11,9 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ strchr-power7 strchr-ppc32 \ wordcopy-power7 wordcopy-ppc32 \ memmove-power7 memmove-ppc + +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-strchrnul-ppc32.o = $(no-stack-protector) +CFLAGS-strchrnul-ppc32.op = $(no-stack-protector) endif diff --git a/sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h new file mode 100644 index 00000000000..560f57366b2 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/be/multiarch/dl-symbol-redir-ifunc.h @@ -0,0 +1,27 @@ +/* Symbol rediretion for loader/static initialization code. + Copyright (C) 2026 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 + . */ + +#ifndef _DL_IFUNC_GENERIC_H +#define _DL_IFUNC_GENERIC_H + +#ifndef SHARED +asm ("__mempcpy = __mempcpy_ppc"); +asm ("__strchrnul = __strchrnul_ppc"); +#endif + +#endif diff --git a/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h index 4680092cd8e..03f6f12032a 100644 --- a/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/powerpc/powerpc64/le/multiarch/dl-symbol-redir-ifunc.h @@ -21,5 +21,6 @@ asm ("memset = __memset_power8"); asm ("__mempcpy = __mempcpy_power7"); +asm ("__strchrnul = __strchrnul_power8"); #endif diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile index c9178223a87..0437a05a895 100644 --- a/sysdeps/powerpc/powerpc64/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile @@ -40,3 +40,4 @@ endif # Called during static initialization CFLAGS-strncmp-ppc64.c += $(no-stack-protector) +CFLAGS-strchrnul-ppc64.c += $(no-stack-protector) diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile index 481e8347925..01e4a4344fd 100644 --- a/sysdeps/s390/Makefile +++ b/sysdeps/s390/Makefile @@ -258,6 +258,11 @@ routines_no_fortify += \ # routines_no_fortify endif +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-strchrnul-c.o = $(no-stack-protector) +CFLAGS-strchrnul-c.op = $(no-stack-protector) + ifeq ($(subdir),wcsmbs) sysdep_routines += \ wcpcpy \ diff --git a/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h index a128cd05bd2..3721f3d95bb 100644 --- a/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h @@ -21,11 +21,15 @@ #include #include +#include #define IFUNC_SYMBOL_STR1(s) #s #define IFUNC_SYMBOL_STR(s) IFUNC_SYMBOL_STR1(s) +#ifndef SHARED asm ("memset = " IFUNC_SYMBOL_STR(MEMSET_DEFAULT)); asm ("memcmp = " IFUNC_SYMBOL_STR(MEMCMP_DEFAULT)); +asm ("__strchrnul = " IFUNC_SYMBOL_STR(STRCHRNUL_DEFAULT)); +#endif #endif diff --git a/sysdeps/s390/string-bitops.h b/sysdeps/s390/string-bitops.h new file mode 100644 index 00000000000..f660d019c77 --- /dev/null +++ b/sysdeps/s390/string-bitops.h @@ -0,0 +1,27 @@ +/* Zero byte detection, define whether to use stdbit.h + Copyright (C) 2026 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 + . */ + +/* s390x support static-pie and the libgcc implementation for + __builtin_clzl/__builtin_ctzl might access extern data that is not marked + as hidden, which creates additiona GOT access that is used before + self-relocation. */ +#if __ARCH__ > 6 +# define HAVE_BITOPTS_WORKING 1 +#else +# define HAVE_BITOPTS_WORKING 0 +#endif diff --git a/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h index ffe1eee87d5..1a76efd5425 100644 --- a/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/sparc/sparc32/sparcv9/multiarch/dl-symbol-redir-ifunc.h @@ -19,6 +19,9 @@ #ifndef _DL_IFUNC_GENERIC_H #define _DL_IFUNC_GENERIC_H +#ifndef SHARED asm ("memset = __memset_ultra1"); +asm ("memcpy = __memcpy_ultra1"); +#endif #endif diff --git a/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h index ffe1eee87d5..1a76efd5425 100644 --- a/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/sparc/sparc64/multiarch/dl-symbol-redir-ifunc.h @@ -19,6 +19,9 @@ #ifndef _DL_IFUNC_GENERIC_H #define _DL_IFUNC_GENERIC_H +#ifndef SHARED asm ("memset = __memset_ultra1"); +asm ("memcpy = __memcpy_ultra1"); +#endif #endif diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 17f0c309a62..abf0972dfb2 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -114,6 +114,11 @@ sysdep_routines += \ xstat \ xstat64 \ # sysdep_routines +# +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-setvmaname.o = $(no-stack-protector) +CFLAGS-setvmaname.op = $(no-stack-protector) CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables @@ -459,6 +464,13 @@ sysdep_routines += \ raise_direct \ # sysdep_routines +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-raise.o = $(no-stack-protector) +CFLAGS-raise.op = $(no-stack-protector) +CFLAGS-raise_direct.o = $(no-stack-protector) +CFLAGS-raise_direct.op = $(no-stack-protector) + tests-special += \ $(objpfx)tst-signal-numbers.out \ # tests-special diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index f1f8c3f44cf..9a70905df84 100644 --- a/sysdeps/unix/sysv/linux/i386/Makefile +++ b/sysdeps/unix/sysv/linux/i386/Makefile @@ -28,3 +28,17 @@ ifeq ($(subdir),rt) librt-routines += sysdep librt-shared-only-routines += sysdep endif + +ifeq ($(subdir),elf) +sysdep_routines += \ + dl-mmap \ + dl-writev \ + # sysdep-routines + +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-dl-mmap.o = $(no-stack-protector) +CFLAGS-dl-mmap.op = $(no-stack-protector) +CFLAGS-dl-writev.o = $(no-stack-protector) +CFLAGS-dl-writev.op = $(no-stack-protector) +endif diff --git a/sysdeps/unix/sysv/linux/i386/dl-mmap.c b/sysdeps/unix/sysv/linux/i386/dl-mmap.c new file mode 100644 index 00000000000..ab6f96300fb --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/dl-mmap.c @@ -0,0 +1,36 @@ +/* mmap wrapper for dynamic loader. Linux/i386 version. + Copyright (C) 2026 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 + . */ + +/* This mmap call is used to allocate some memory to backup assert() messages + before TLS setup is done, so it can not use "call *%gs:SYSINFO_OFFSET" + during startup in static PIE. */ +#if BUILD_PIE_DEFAULT +# define I386_USE_SYSENTER 0 +#endif + +#include +#include +#include +#include + +void * +_dl_mmap (void *addr, size_t len, int prot, int flags) +{ + return (void *) MMAP_CALL (mmap2, addr, len, prot, flags, -1, 0); +} + diff --git a/sysdeps/unix/sysv/linux/i386/dl-mmap.h b/sysdeps/unix/sysv/linux/i386/dl-mmap.h new file mode 100644 index 00000000000..291f92ee14f --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/dl-mmap.h @@ -0,0 +1,27 @@ +/* mmap wrapper for dynamic loader. + Copyright (C) 2026 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 + . */ + +#ifndef _DL_MMAP_H +#define _DL_MMAP_H + +/* i386 requires out-of-line implementation because it sets + I386_USE_SYSENTER to 0 to avoid use the vDSO. */ +void * _dl_mmap (void *addr, size_t len, int prot, int flags) + attribute_hidden; + +#endif diff --git a/sysdeps/unix/sysv/linux/i386/dl-writev.c b/sysdeps/unix/sysv/linux/i386/dl-writev.c new file mode 100644 index 00000000000..ef6a6a20b82 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/dl-writev.c @@ -0,0 +1,32 @@ +/* writev wrapper for the dynamic linker. Linux/i386 version. + Copyright (C) 2013-2026 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 + . */ + +/* This writev call is used to assert() before TLS setup is done, so it can + not use "call *%gs:SYSINFO_OFFSET" during startup in static PIE. */ +#if BUILD_PIE_DEFAULT +# define I386_USE_SYSENTER 0 +#endif + +#include +#include + +ssize_t +_dl_writev (int fd, const struct iovec *iov, size_t niov) +{ + return INTERNAL_SYSCALL_CALL (writev, fd, iov, niov); +} diff --git a/sysdeps/unix/sysv/linux/i386/dl-writev.h b/sysdeps/unix/sysv/linux/i386/dl-writev.h index 8327d32374e..d92c74d7126 100644 --- a/sysdeps/unix/sysv/linux/i386/dl-writev.h +++ b/sysdeps/unix/sysv/linux/i386/dl-writev.h @@ -16,9 +16,14 @@ License along with the GNU C Library; if not, see . */ -#if BUILD_PIE_DEFAULT -/* Can't use "call *%gs:SYSINFO_OFFSET" during startup in static PIE. */ -# define I386_USE_SYSENTER 0 -#endif +#ifndef _DL_WRITEV_H +#define _DL_WRITEV_H -#include +#include + +/* i386 requires out-of-line implementation because it sets + I386_USE_SYSENTER to 0 to avoid use the vDSO. */ +ssize_t _dl_writev (int fd, const struct iovec *iov, size_t niov) + attribute_hidden; + +#endif diff --git a/sysdeps/unix/sysv/linux/i386/raise_direct.c b/sysdeps/unix/sysv/linux/i386/raise_direct.c new file mode 100644 index 00000000000..b23b8e5386f --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/raise_direct.c @@ -0,0 +1,26 @@ +/* Internal function to send a signal to itself. Linux/i386 version. + Copyright (C) 2026 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 + . */ + +/* This is called from abort() (issued by assert()) before TLS setup is done, + so it can not use "call *%gs:SYSINFO_OFFSET" during startup in static + PIE. */ +#if BUILD_PIE_DEFAULT +# define I386_USE_SYSENTER 0 +#endif + +#include diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile index 2fdd4af3eb7..a10dd30d12b 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile @@ -24,8 +24,16 @@ sysdep_routines += \ strncmp-vector \ # sysdep_routines +# Called during static library initialization, so turn stack-protection +# off for non-shared builds. +CFLAGS-memset-generic.o = $(no-stack-protector) +CFLAGS-memset-generic.op = $(no-stack-protector) +CFLAGS-memcpy-generic.o = $(no-stack-protector) +CFLAGS-memcpy-generic.op = $(no-stack-protector) + CFLAGS-memcpy_noalignment.c += -mno-strict-align # Called during static initialization +CFLAGS-strlen-generic.c += $(no-stack-protector) CFLAGS-memset-generic.c += $(no-stack-protector) CFLAGS-memcpy-generic.c += $(no-stack-protector) endif diff --git a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h index 1f3ca20307c..4d9cc5dd914 100644 --- a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h @@ -73,6 +73,28 @@ asm ("memmove = " HAVE_MEMMOVE_IFUNC_GENERIC); asm ("mempcpy = " HAVE_MEMPCPY_IFUNC_GENERIC); asm ("__mempcpy = " HAVE_MEMPCPY_IFUNC_GENERIC); + +#if MINIMUM_X86_ISA_LEVEL >= 4 +# define HAVE_STRCHRNUL_IFUNC_GENERIC "__strchrnul_evex" +#elif MINIMUM_X86_ISA_LEVEL == 3 +# define HAVE_STRCHRNUL_IFUNC_GENERIC "__strchrnul_avx2" +#else +# define HAVE_STRCHRNUL_IFUNC_GENERIC "__strchrnul_sse2" +#endif + +asm ("__strchrnul = " HAVE_STRCHRNUL_IFUNC_GENERIC); + + +#if MINIMUM_X86_ISA_LEVEL >= 4 +# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_evex" +#elif MINIMUM_X86_ISA_LEVEL == 3 +# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_avx2" +#else +# define HAVE_STRLEN_IFUNC_GENERIC "__strlen_sse2" +#endif + +asm ("strlen = " HAVE_STRLEN_IFUNC_GENERIC); + #endif /* SHARED */ #endif