From patchwork Wed Aug 12 20:42:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: DJ Delorie X-Patchwork-Id: 141269 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 D72464BB3B80 for ; Wed, 12 Aug 2026 20:50:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D72464BB3B80 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Mn1dDk+l X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 872264BA23E4 for ; Wed, 12 Aug 2026 20:49:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 872264BA23E4 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 872264BA23E4 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1786567761; cv=none; b=ecIn36mpbEHz5NX9/8Kslzo/ijhdbHWhWKHUJunAIwoZDBGppKM1WNDfYvJn3UMUqViRq5d7PEF3d/BPT4u959DOy3HvEtVPFnScOqirz1IMT+fzAwQEeZnRmwdEI4sUqo4wU4b0N6LV/AX5wTR1wKk1WxAJU3mG89Ga5L8n3IE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1786567761; c=relaxed/simple; bh=zXjuJnkqcgafPeFMddJGlSWMAnrc2eq8ifQOo669FMA=; h=DKIM-Signature:Message-ID:From:Date:Subject:To; b=Ecpf4cENWrUkJQAJ0TKi/duC7lcXCXBqlEpGpnu52PBz6aS8pdGeu1i19daP8IBqfaYHepRM6Qn5Y3b6nR6zMH3glcOAuv8EsGoVLxoGy8HI1u7UxnD+QvwwZnM3sAWDWZI4QOpoMqKaiQqiaHZHc9XuA48w3TITcxEqyL67sck= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Mn1dDk+l DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 872264BA23E4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1786567761; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:content-type:content-type; bh=H1c8OIHFeudQdhgjCRTMLeNXYsmTgEZlfU8lvguD1p4=; b=Mn1dDk+lR5yGgAePZEMcXWSKyXBCff+AtT+8Z2QNIEPCmTd4SyYG5DxKWZz/67aiAVdLTr xQC5t3wBlqZBOcBmCes2DJQbJnAj5UJ0wnT2TRC0JeEVHoaWw2HkfXdKDJUjQBZfKoYOTK js75GGdlJwpL/IcpiJTYRjI+YY6xUzM= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-314-9QZa9GiLP-KxofWfE6DO2Q-1; Wed, 12 Aug 2026 16:49:14 -0400 X-MC-Unique: 9QZa9GiLP-KxofWfE6DO2Q-1 X-Mimecast-MFC-AGG-ID: 9QZa9GiLP-KxofWfE6DO2Q_1786567753 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B64CD1800646 for ; Wed, 12 Aug 2026 20:49:13 +0000 (UTC) Received: from greed.delorie.com (unknown [10.22.88.50]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6E50318005BB for ; Wed, 12 Aug 2026 20:49:12 +0000 (UTC) Received: from greed.delorie.com (localhost [127.0.0.1]) by greed.delorie.com (8.16.1/8.16.1) with ESMTPS id 67CKnB2H3709306 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT) for ; Wed, 12 Aug 2026 16:49:11 -0400 Received: (from dj@localhost) by greed.delorie.com (8.16.1/8.16.1/Submit) id 67CKnBIl3709305; Wed, 12 Aug 2026 16:49:11 -0400 Message-ID: <587b3a82d77ed767a78068dd67ab529e2a9e1499.1786567326.git.dj@redhat.com> From: DJ Delorie Date: Wed, 12 Aug 2026 16:42:06 -0400 Subject: [PATCH v2 1/1] rtld: add glibc.rtld.optional_static_tls_alignment To: libc-alpha@sourceware.org X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 2 X-Mimecast-MFC-PROC-ID: 9xwzEn-quOvc0U6WcavbLeknNk050DkizR0dm6K-mpM_1786567753 X-Mimecast-Originator: redhat.com Content-type: text/plain; charset=UTF-8 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_NONE, TXREP 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 Add an alignment tunable to go along with glibc.rtld.optional_static_tls to optimize loading audit modules with higher-than-default alignment requirements. Unlike the extra size, this is only used when creating the TLS area so need not be stored in GLRO(). --- changes in v2: - add the other tls case type for adding extra alignment elf/Makefile | 8 ++++++++ elf/dl-tls.c | 9 +++++++++ elf/dl-tunables.list | 5 +++++ elf/tst-tlsalign-tunable-a.c | 32 +++++++++++++++++++++++++++++ elf/tst-tlsalign-tunable.c | 39 ++++++++++++++++++++++++++++++++++++ manual/tunables.texi | 8 ++++++++ 6 files changed, 101 insertions(+) create mode 100644 elf/tst-tlsalign-tunable-a.c create mode 100644 elf/tst-tlsalign-tunable.c diff --git a/elf/Makefile b/elf/Makefile index dbc6cfec7f..bb916d51f6 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -308,6 +308,7 @@ tests-container := \ tst-dl-cache-long-path \ tst-ldconfig-bad-aux-cache \ tst-ldconfig-ld_so_conf-update \ + tst-tlsalign-tunable \ # tests-container ifeq (no,$(build-hardcoded-path-in-tests)) @@ -1084,6 +1085,7 @@ modules-names += \ tst-tls22-mod2-gnu2 \ tst-tls23-mod \ tst-tlsalign-lib \ + tst-tlsalign-tunable-a \ tst-tlsgap-mod0 \ tst-tlsgap-mod1 \ tst-tlsgap-mod2 \ @@ -1824,6 +1826,12 @@ $(objpfx)tst-nodelete-opened.out: $(objpfx)tst-nodelete-opened-lib.so $(objpfx)tst-tlsalign-extern: $(objpfx)tst-tlsalign-vars.o $(objpfx)tst-tlsalign-extern-static: $(objpfx)tst-tlsalign-vars.o +tst-tlsalign-tunable-TUNABLES = glibc.rtld.optional_static_tls_alignment=0x1000 +tst-tlsalign-tunable-TUNABLES += glibc.rtld.optional_static_tls=0x3000 +tst-tlsalign-tunable-ENV = LD_AUDIT=$(objpfx)tst-tlsalign-tunable-a.so +#tst-tlsalign-tunable-ENV = LD_DEBUG=all +$(objpfx)tst-tlsalign-tunable.out: $(objpfx)tst-tlsalign-tunable-a.so + # The resolver translation unit must always be compiled with # -fstack-protector-all so the canary code is emitted regardless of the # default. diff --git a/elf/dl-tls.c b/elf/dl-tls.c index 1380bd7083..e4c93bace0 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -126,6 +126,8 @@ tls_static_surplus (int nns, int opt_tls) backwards compatibility. */ #define LEGACY_TLS (1664 - tls_static_surplus (DEFAULT_NNS, OPTIONAL_TLS)) +static size_t optional_static_tls_alignment = 0; + /* Calculate the size of the static TLS surplus, when the given number of audit modules are loaded. Must be called after the number of audit modules is known and before static TLS allocation. */ @@ -136,6 +138,7 @@ _dl_tls_static_surplus_init (size_t naudit) nns = TUNABLE_GET (nns, size_t, NULL); opt_tls = TUNABLE_GET (optional_static_tls, size_t, NULL); + optional_static_tls_alignment = TUNABLE_GET (optional_static_tls_alignment, size_t, NULL); if (nns > DL_NNS) nns = DL_NNS; if (DL_NNS - nns < naudit) @@ -346,6 +349,9 @@ _dl_determine_tlsoffset (void) size_t extra_tls_size = _dl_extra_tls_get_size (); size_t extra_tls_align = _dl_extra_tls_get_align (); + /* Apply any user-specified alignment, if larger. */ + extra_tls_align = MAX (extra_tls_align, optional_static_tls_alignment); + /* Increase the maximum alignment with the extra TLS alignment requirements if necessary. */ max_align = MAX (max_align, extra_tls_align); @@ -426,6 +432,9 @@ _dl_determine_tlsoffset (void) size_t extra_tls_size = _dl_extra_tls_get_size (); size_t extra_tls_align = _dl_extra_tls_get_align (); + /* Apply any user-specified alignment, if larger. */ + extra_tls_align = MAX (extra_tls_align, optional_static_tls_alignment); + /* Increase the maximum alignment with the extra TLS alignment requirements if necessary. */ max_align = MAX (max_align, extra_tls_align); diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 111649f145..4c78444542 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -101,6 +101,11 @@ glibc { minval: 0 default: 512 } + optional_static_tls_alignment { + type: SIZE_T + minval: 0 + default: 0 + } enable_secure { type: INT_32 minval: 0 diff --git a/elf/tst-tlsalign-tunable-a.c b/elf/tst-tlsalign-tunable-a.c new file mode 100644 index 0000000000..d1a2063e39 --- /dev/null +++ b/elf/tst-tlsalign-tunable-a.c @@ -0,0 +1,32 @@ +#include + +__thread int x; +__thread int b[4] __attribute__((tls_model("initial-exec"))) __attribute__((aligned(0x1000))); + +/* These exist just to make the above variables "used". */ +int * +func_x(void) +{ + return &x; +} + +int * +func_b(void) +{ + return b; +} + +void __attribute__((constructor)) +la_ctor(void) +{ + write(1, "AUDITctor\n", 10); + /* We only care if the auditor got loaded. It doesn't need to + run. */ + _exit(0); +} + +unsigned int +la_version( unsigned int version ) +{ + return version; +} diff --git a/elf/tst-tlsalign-tunable.c b/elf/tst-tlsalign-tunable.c new file mode 100644 index 0000000000..3ef2ae2e14 --- /dev/null +++ b/elf/tst-tlsalign-tunable.c @@ -0,0 +1,39 @@ +/* Test for large alignment in TLS blocks, BZ#18383. + Copyright (C) 2015-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 specifically tests that the + glibc.rtld.optional_static_tls_alignment tunable works, by loading + an audit module that can't load without alignment help. */ + +#include +#include +#include + +static __thread int tdata1 = 1; + +static int +do_test (void) +{ + printf("tst-tlsalign-tunable!\n"); + /* If the test passes, the auditor itself will call exit with a + value of 0. If we get here, we've failed. "Use" tdata1 here + too. */ + return tdata1 ? EXIT_FAILURE : 43; +} + +#include diff --git a/manual/tunables.texi b/manual/tunables.texi index 713f669c4c..772e55167a 100644 --- a/manual/tunables.texi +++ b/manual/tunables.texi @@ -422,6 +422,14 @@ changed once allocated at process startup. The default allocation of optional static TLS is 512 bytes and is allocated in every thread. @end deftp +@deftp Tunable glibc.rtld.optional_static_tls_alignment +Sets a minimum alignment for the static TLS. The loader normally uses +the alignment requirements of shared objects, but this might be needed +for audit modules that have a higher-than-default alignment +requirement, as an alternative to requesting excessive +optional_static_tls (above). +@end deftp + @deftp Tunable glibc.rtld.dynamic_sort Sets the algorithm to use for DSO sorting, valid values are @samp{1} and @samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is