From patchwork Wed Mar 18 19:34:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 131921 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 740A04BB3BAD for ; Wed, 18 Mar 2026 19:36:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 740A04BB3BAD Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=BLWckpnl X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-dl1-x1229.google.com (mail-dl1-x1229.google.com [IPv6:2607:f8b0:4864:20::1229]) by sourceware.org (Postfix) with ESMTPS id E14CD4C3183B for ; Wed, 18 Mar 2026 19:35:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E14CD4C3183B 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 E14CD4C3183B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1229 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773862510; cv=none; b=a+y5HL9Sk4LXdrI1I5SEwxxnFrzeXhptdeZ4CbhgKyKdcZqwLjV4uxtbZVKG3ks828Cla5gvizDf032pfm17jQqsfviOXPMz+U3VERzH+3QcLqmD3hbGJ3fjQeRItpUu9F0CrcPk/jQqQCEj7O6Oyl9ItxRPplk/MNaAGDdDA00= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773862510; c=relaxed/simple; bh=WwoMWUQT49YF+ZAPSEB1m7mBkJV26OasmSW5eYcZEmc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Ff3b+d0je1Xl7HIgJXhROmVmzCqBvie1DSSJWbko/qZxDXu6hL/gkzj7E5WTp/JuE4EkBh+GbXiG5gtrC+nP1FNzNEqTVyEVOAIYTpwHAMkgozC4O/lJEbSfOSMH93KYsMpQZM4rXSdzp9oK/48D5RgmSVbQcD2HCFu5p5IhVmc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E14CD4C3183B Received: by mail-dl1-x1229.google.com with SMTP id a92af1059eb24-12776bebe9fso497482c88.1 for ; Wed, 18 Mar 2026 12:35:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1773862508; x=1774467308; 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=77zVOOXse/n2wNWc0w2UdYEzCsqPiFzlIkaSY69n+7Y=; b=BLWckpnlocMMAwBReepAjVFzZQgwM8QY9cU/KTwC3wPSR1+OPt2CAuvAO5Si1hlAQl yUpBNZg+N1SIjoqr1FJrhQOOVSng1mx17+SO0eHn1Z+4vMAiQA5FuYZVWswriUcISJ5n w6O1AX9M5eUoos7nfFjDhWfsZ22W3Ye0kAaqugsTRoY1QB1E+DuxkRxGiShppS+ywQEa Jt5zvMNT+Py4muBOoKu4IqB3mC247hVArnRe2nDMRok5ICXbC138qPxh6AorUL1tkwxB zGZA6HXuUjr04RVBe6SWXlx+jwwdhzgeyIQbNuH9hSVDG/P2rnYnVZa90uqUgj9WH/uL 0faQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773862508; x=1774467308; 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=77zVOOXse/n2wNWc0w2UdYEzCsqPiFzlIkaSY69n+7Y=; b=RCwZB4QPMnGH7WrUMfZ0+3y4qzHz1HJofBfUYM2P8oFBGMtOUoDvyuRiDiMZth50sa m1VgAHxK05ZHqmSq+e6gafIr6mFGPg5kzK/T7ORrR0D9QuxXPHYmaOdqCzj8RfpxpGW4 crzDWs80rdsOs6cQfMD4IhzvgpRaQC+nNWbZiV4mAaamnSarM0EpUBvPnkPDg93RhzPc aO36qssVZBsEesE44kLAF0+R9C+rJF7NiOHW5D0Sk9rbpqghGwmZ7xuD6I8zHkofp4hG 795bbhFNFCvibSUa5dDeTmnFSHWm3n+Zby0hCclMUTJrrS6fIrWROTja3+YlesRZE7JC Hqkw== X-Gm-Message-State: AOJu0YyGYOMecfQl1/3xTVqlnUH1OzpqkHlLHc8fWzUbleaIY0yFlbRU sYnW8K9vrle2wNp/AnTIc0E5iTajJghYCFjoj4ScOkLSVvdgVyK37okqzdNAz7J1edPI2nBbCnS TPHtS X-Gm-Gg: ATEYQzwtDqIaAf+OHbe2byt1chbzSP7PhAnlSA2cCgg8TslgENyPkQJaAfV+xZ9ej90 wtJvqevtuSB7H7F7Tm6ikd17OO5EBhwolDSEunXi/ATBtkEmn1Tucak7Sd3Vo6bKE0u9U1QbE7H 8mQnk1OQqr8k4wFknGWxE+2IOaHRoLnhy8kpcltWkNYPpUYn7ShQQyNOOAfU9hmOlUWpGIzE3iT p1vDYky7w2xRJx+jE7RkHaclV2udxiGKEZQ0ugr2sNF0+XtPMJVThy4uyQRAKNGw6NpURs7JKdl gjHO1c+iBjM2hvm1iUT5eGK/72GoxIGiPxHCRYWhrqREPqSwi1LuN53+hCO/YvvU4gYflgL7Btd RdSdbtWbzETa2rvQ+CZ6WxuYSrHVe5cLZRbxCxEWSzDAFaBfDFlByEpCB2LtTTlshQnMCSWwdSN zBNcpFwuY2yy+vYQUvgOd70fXzU0y4nw26TE4= X-Received: by 2002:a05:7022:423:b0:11e:161:c008 with SMTP id a92af1059eb24-129a716192bmr2455557c88.26.1773862507955; Wed, 18 Mar 2026 12:35:07 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:f5a4:2159:38c8:c951:d029]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-129b4147522sm4238937c88.15.2026.03.18.12.35.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Mar 2026 12:35:07 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Florian Weimer , Samuel Thibault Subject: [PATCH v8 3/6] Fix assert during static startup (BZ 33326) Date: Wed, 18 Mar 2026 16:34:14 -0300 Message-ID: <20260318193454.2466865-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260318193454.2466865-1-adhemerval.zanella@linaro.org> References: <20260318193454.2466865-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_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED 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 statuup 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 | 17 +++++++- 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 + .../riscv/multiarch/dl-symbol-redir-ifunc.h | 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 | 7 ++++ .../x86_64/multiarch/dl-symbol-redir-ifunc.h | 32 +++++++++++++++ 31 files changed, 422 insertions(+), 9 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 4c253a344a..541929c3b6 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 7f039b5563..29d771ef7a 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -277,6 +277,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 \ @@ -288,6 +289,10 @@ tests-static-internal := \ tst-tunables-enable_secure \ # tests-static-internal +tests-special += \ + $(objpfx)tst-assert-startup-static.out \ + # tests-special + CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o tst-tls1-static-non-pie-no-pie = yes @@ -3532,7 +3537,6 @@ $(objpfx)tst-origin.out: tst-origin.sh $(objpfx)tst-origin $(objpfx)tst-dlopen-sgid.out: $(objpfx)tst-dlopen-sgid-mod.so - ifeq ($(run-built-tests),yes) $(objpfx)tst-tls-debug-recursive.out: tst-tls-debug-recursive.sh \ $(objpfx)tst-recursive-tls \ @@ -3554,3 +3558,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 0000000000..a3312cd9e5 --- /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 __libc_assert, and __libc_assert_fail does issues the translation + routines (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 08e1e0ec25..ec6b78c495 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -185,6 +185,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 04596b53b1..8a39121777 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -528,6 +528,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 aa0b0c2f57..969726cccb 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 9f772614bf..a686fd1f92 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"); diff --git a/sysdeps/aarch64/multiarch/memcpy_generic.S b/sysdeps/aarch64/multiarch/memcpy_generic.S index c6d09081f4..d622268305 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 0000000000..4a6c81aa8d --- /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 0000000000..f786be0930 --- /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 8af00d2846..43f50f8bcc 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"); #endif diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c index 3f0e302b5e..1ff20d4feb 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 3a49b855ca..60ba2e50d2 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 0000000000..560f57366b --- /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 4680092cd8..03f6f12032 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 c9178223a8..0437a05a89 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/riscv/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/riscv/multiarch/dl-symbol-redir-ifunc.h index 24b78711e3..69a0790838 100644 --- a/sysdeps/riscv/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/riscv/multiarch/dl-symbol-redir-ifunc.h @@ -21,6 +21,7 @@ #ifndef SHARED asm ("memset = __memset_generic"); +asm ("memcpy = __memcpy_generic"); #endif #endif diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile index 985b4f25ee..078c0d165d 100644 --- a/sysdeps/s390/Makefile +++ b/sysdeps/s390/Makefile @@ -104,6 +104,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 += wcslen wcslen-vx wcslen-c \ wcsnlen wcsnlen-vx wcsnlen-c \ diff --git a/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/s390/multiarch/dl-symbol-redir-ifunc.h index a128cd05bd..3721f3d95b 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 0000000000..f660d019c7 --- /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 ffe1eee87d..1a76efd542 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 ffe1eee87d..1a76efd542 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 8797c5c9b3..18727605ce 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 f1f8c3f44c..9a70905df8 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 0000000000..ab6f96300f --- /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 0000000000..291f92ee14 --- /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 0000000000..ef6a6a20b8 --- /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 8327d32374..d92c74d712 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 0000000000..b23b8e5386 --- /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 a865090a53..484ff77f7d 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile @@ -8,6 +8,13 @@ sysdep_routines += \ memset-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-memset-generic.c += $(no-stack-protector) diff --git a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h index b607e525f2..15968896c0 100644 --- a/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h +++ b/sysdeps/x86_64/multiarch/dl-symbol-redir-ifunc.h @@ -54,6 +54,38 @@ asm ("memcmp = " HAVE_MEMCMP_IFUNC_GENERIC); asm ("strlen = " HAVE_STRCMP_IFUNC_GENERIC); +#if MINIMUM_X86_ISA_LEVEL >= 4 +# define HAVE_MEMPCPY_IFUNC_GENERIC "__mempcpy_evex_unaligned" +#elif MINIMUM_X86_ISA_LEVEL == 3 +# define HAVE_MEMPCPY_IFUNC_GENERIC "__mempcpy_avx_unaligned" +#else +# define HAVE_MEMPCPY_IFUNC_GENERIC "__mempcpy_sse2_unaligned" +#endif + +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