From patchwork Tue Mar 11 17:09:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872464 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1595576wri; Tue, 11 Mar 2025 10:17:35 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUEMzVpX4/ovPgVrypxzM9GwnBaxQ2byEYYrWvXj6mQZ2+v4FEux4YnPbw2EgcmvD/G2lh+gQ==@linaro.org X-Google-Smtp-Source: AGHT+IHdsyWamU6yrLjtwEI6ZR+V7FHBPsPHaC6BWA6UMJ7hPhjE/z3My31vvwwkT5X2g/vPRTNB X-Received: by 2002:a05:622a:41ca:b0:476:67d8:930e with SMTP id d75a77b69052e-47667d89941mr150802331cf.34.1741713454906; Tue, 11 Mar 2025 10:17:34 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713454; cv=pass; d=google.com; s=arc-20240605; b=ByXS/+0sJ1iXy3R4lnIjsfrpbcRJb4qKiln27cSwMu8qQJ38smmNAIjRTjqzHQcW/G rzpb2ROHgkhWVJ3DKLksb5Z+2e5mRn19GU2zsbMqajrGorOV8DYkQd4VGG21b4HVm5x8 iXSzFVDy4sxo70wm4Kf/P0sqw8FoqiSDePVMG09LYmb7RtgxQNWNymsDdQAZEyGT9z5w bI5wr0F5D819+Walbm+KLZT/rexlydsQ76T7hlmH3CKDS6BaZYEBopJ8ONOjzeBp1bq/ GZGqCp6SP9HsAlLMQmqkj/OyVYdD1tQeu74u6D5JDrJM3TDyJ9AOzMDDBtLqIyhlT/rC U+KA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=wjocoMMmVQ/8mAVoB7HFOKEgc8zq8saKqEsRGWHedKc=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=gORk9nn1705Gq4MHHdYrm63elqQW0lWziSG/Dr5H26AdEHSlht9s1rX5lIk2+GkkPv pIq15yegNyyc4qLjkwI8NbOFQ/fwMpxGqXP8n7KYCTFdvkpIDksxJQSbmteWVuUDtj+X 1E+/l3t09q/4HjBfA9XyFa/0D5n3jYqk2N/w3ro28/5v3GmOf+mfzXZ3AeF3Ho0IKGUj Uk+EjMLID8eRxvcN+Sc7DHaYavn6CeYoGVho1jkloWZKq4X5c+v0makbj/cpQ3l8ONBg x/ZyFov5JEsK/16ijAozdjkk8rMIEIoTMlioVr9j1wYN1GiCKL+V3tlA3ECxUdyDcbio 7KSQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VzwgaUAB; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id d75a77b69052e-47688166e6bsi46948341cf.140.2025.03.11.10.17.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:17:34 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VzwgaUAB; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6748A385771D for ; Tue, 11 Mar 2025 17:17:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6748A385771D 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=VzwgaUAB X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by sourceware.org (Postfix) with ESMTPS id CC90D3857C78 for ; Tue, 11 Mar 2025 17:13:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CC90D3857C78 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 CC90D3857C78 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1034 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713195; cv=none; b=MpY+HSOgGvXyE3t8/Sdc7KcNcnC/yeYbUqpSO7u4VY9z97EPgGLC585zkOSfa3RSHJ4zUNtOWMqcczBHDzo1AqJxl+pIRTWMRjLgu0/eoEAkT9FbwMWzPFPh3MF6EhTer3DDN0WCBZ5S+sTSEJMgx1AiTt21RD+g3zuvtUsbf7U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713195; c=relaxed/simple; bh=uH7CSWFXywnUjek1JNtkvXvszoE+IGG35Jlv5CsvIDo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=NMEeq1D3btUGrtzIRQAszMLWzCZmNen4Pl2YlX1ZwYNSF0tjlm2EYKGdNaQZv6uVuLxve/mCmJh6yqKRMzIwZ9HsfikVDilag7pPdhPVh8RdTllVg7Dt5Kx8ei65S9J2q20ROfIl2tEVg9ERRF5kAsPRDp7Uu4Ps53WwS47jJ/M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC90D3857C78 Received: by mail-pj1-x1034.google.com with SMTP id 98e67ed59e1d1-2fec3176ef3so8548862a91.1 for ; Tue, 11 Mar 2025 10:13:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713193; x=1742317993; 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=wjocoMMmVQ/8mAVoB7HFOKEgc8zq8saKqEsRGWHedKc=; b=VzwgaUABevcyU3oWni+/wlQq1yIgjdslgGbuzC3sAFBpS16n2EBmcBFEWXTAeRPhy5 7IPRZ5DJ6UlvkpnqGTFG1PclwYFxmM1hemGs+G8Qft7w3c/skss9u8G/n3dTdPeEasPp vWy+dQfmeKPVmsO2SUbmneb4Yquis0ISoeqxFPj7sPEa7nMV2hdLSMg/tBP/++R3npIH DrYDJOyug+QYbY8oaRXlyY47NaKQhLS/0D0KnqTFDVlHMNTBNEtjlS9DCPcPJ4g5z8ci dgvZHxYnwS9urJ7XDpD+NaYM6mbqytn7zzoAPBD9DVY2Ll9Y6lkJ9kctm0t0cWD6YqbC 8tZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713193; x=1742317993; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wjocoMMmVQ/8mAVoB7HFOKEgc8zq8saKqEsRGWHedKc=; b=VSewVH5hGeIm3dHqOT2Aw3Cyr9mqi9R4ldTCICSfcskgPOwwAGX62NKB5X7fXG2vN2 5C0U1BMr7OvIuhyvx1PocbYkA1zifR5D7JyShRpLFPKfew4dyO0JTDTDTwIRWiagbkwS r7qY/VSVJXtzTwBBB6oPpIbf2rdCCKRYnKDHtVnCMLSysHV4Z5wToJNvp3scwRFnHYy5 AgZHMaaXmUnXbGpEEkDCXH+poRCMQR1ir5H1B1NRHufYN/sxtqVHiOfC/T848tLDoW69 xHfUMxDbmLYtxzf100a+R85lq31h2LFSpAcRoI03/Nlii+UTtq0Fai8J3VwAwzOmaZF0 WEZQ== X-Gm-Message-State: AOJu0Yxohd4fonjI5/qEx41oNt1zYrU3/7fLL7JO/MhrKqQZx8LxhCtA Q3u5JzDZN/8Q2lwWjB9tF+M0OMYJynH+vfmP4hoo7+m5llW1TXhevu4cTVqdJRF9XaeXnqbfICd g X-Gm-Gg: ASbGncsZXi4cGdHn1VwmieLR4tZbg+FUJnct9NWL9kIpxICVA1rG7erZduHxIigt8yg 11xC5fndTrddpPlkWRaLDwFGLWmo5fx9vBMS1QxVMDuDptcl8HnRsMWK8Sqc+sQPp248SW0iEmG jgwNAfIe8l9oxxi0uOwCjMk8ri95f8LnAdCcp/MqkyDUpkaClOR7+GTG/q5GUEoYn/bY9oEANGu S13BwAAsnqEpqsS9f64sQwQ6B124pMD5gnYIaY9AxXHhN1Pe7cEgmn9MDDZzC5j0vb7DsTNn1FV zIYulLas4Mb2I2O4mVEIz0/B86HWfMQ2Uva/zfrW3TDFRZM1TFlI6R4= X-Received: by 2002:a17:90a:d605:b0:2ee:db8a:2a01 with SMTP id 98e67ed59e1d1-2ff7cf128cdmr25706503a91.30.1741713193176; Tue, 11 Mar 2025 10:13:13 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:12 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 1/9] linux: Add mseal syscall support Date: Tue, 11 Mar 2025 14:09:48 -0300 Message-ID: <20250311171305.89091-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org It has been added on Linux 6.10 (8be7258aad44b5e25977a98db136f677fa6f4370) as a way to block operations such as mapping, moving to another location, shrinking the size, expanding the size, or modifying it to a pre-existent memory mapping. Although the system only works on 64-bit CPU, the entrypoint was added for all ABIs (since kernel might eventually implement it to additional ones and/or the abi can execute on a 64-bit kernel). Checked on x86_64-linux-gnu. --- NEWS | 4 +- manual/memory.texi | 69 +++++++++++++++ sysdeps/unix/sysv/linux/Makefile | 2 + sysdeps/unix/sysv/linux/Versions | 3 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/bits/mman-shared.h | 8 ++ sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/kernel-features.h | 8 ++ .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/syscalls.list | 1 + sysdeps/unix/sysv/linux/tst-mseal-pkey.c | 84 +++++++++++++++++++ sysdeps/unix/sysv/linux/tst-mseal.c | 67 +++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 40 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/tst-mseal-pkey.c create mode 100644 sysdeps/unix/sysv/linux/tst-mseal.c diff --git a/NEWS b/NEWS index e2e40e141c..4732ec2522 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,9 @@ Version 2.42 Major new features: - [Add new features here] +* On Linux, the mseal function has been added. It allows to seal memory + mappings to avoid further change during process execution such as protection + permissions, unmapping, moving to another location, or shrinking the size. Deprecated and removed features, and other changes affecting compatibility: diff --git a/manual/memory.texi b/manual/memory.texi index dc4621e2c5..f092ee4ce6 100644 --- a/manual/memory.texi +++ b/manual/memory.texi @@ -3072,6 +3072,75 @@ process memory, no matter how it was allocated. However, portable use of the function requires that it is only used with memory regions returned by @code{mmap} or @code{mmap64}. +@deftypefun int mseal (void *@var{address}, size_t @var{length}, unsigned long @var{flags}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + +A successful call to the @code {mseal} function protects the memory +range @var{address} of @var{length} bytes, previous allocated with +@code{mmap} or @code{mremap}, against further metadata changes such +as: + +@itemize @bullet +@item +Unmapping, moving to another location, extending or shrinking the size, +via @code{munmap} and @code{mremap}. + +@item +Moving or expanding a different VMA into the current location, via +@code{mremap}. + +@item +Modifying the memory range with @code{mmap} along with flag @code{MAP_FIXED}. + +@item +Change the protection flags with @code{mprotect} or @code{pkey_mprotect}. Also +for certain destructive @code{madvise} behaviours (@code{MADV_DONTNEED}, +@code{MADV_FREE}, @code{MADV_DONTNEED_LOCKED}, and @code{MADV_WIPEONFORK}), +@code{mseal} only blocks the operation if the protection key associate with +the memory denies write. + +@item +Destructive behaviors on anonymous memory, such as @code{madvice} with +@code{MADV_DONTNEED}. +@end itemize + +The @var{address} must be an allocated virtual memory done by @code{mmap} +or @code{mremap}, and it must be page aligned. The end address (@var{address} +plus @var{length}) must be within an allocated virtual memory range. There +should be no unallocated memory between the start and end of address range. + +The @var{flags} is currently ununsed. + +The @code{mseal} function returns @math{0} on sucess and @math{-1} on +failure. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EPERM +The system blocked the operation, and the given address range is unmodified +without a partial update. This error is also returned when @code{mseal} +is issued on a 32 bit CPUs (the sealing is currently supported only on +64-bit CPUs, although 32 bit binaries running on 64 bit kernel is +supported). + +@item ENOMEM +Either the @var{address} is not allocated, or the end address is not within the +allocation, or there is an unallocated memory between start and end address. + +@item ENOSYS +The kernel does not support the @code{mseal} syscall. + +@strong{NB:} The memory sealing changes the lifetime of a mapping, where the +sealing memory could not be unmapped until the process terminates or replaces +the process image through @code{execve} function. The sealed mappings are +inherited through @code{fork}. + +@end table +@end deftypefun + @subsection Memory Protection Keys @cindex memory protection key diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 395d2d6593..ae46e0726d 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -213,6 +213,8 @@ tests += \ tst-misalign-clone \ tst-mlock2 \ tst-mount \ + tst-mseal \ + tst-mseal-pkey \ tst-ntp_adjtime \ tst-ntp_gettime \ tst-ntp_gettimex \ diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 55d565545a..e5d226165e 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -332,6 +332,9 @@ libc { sched_getattr; sched_setattr; } + GLIBC_2.42 { + mseal; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 38db77e4f7..eab487fc76 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2750,3 +2750,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 637bfce9fb..d6d3464c46 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -3097,6 +3097,7 @@ GLIBC_2.4 wprintf F GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 4a305cf730..2c7aa2c939 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2511,3 +2511,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 1d54f71b14..54fd3d3a83 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -2803,6 +2803,7 @@ GLIBC_2.4 xprt_register F GLIBC_2.4 xprt_unregister F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index ff7e8bc40b..4231ef1ffd 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -2800,6 +2800,7 @@ GLIBC_2.4 xprt_register F GLIBC_2.4 xprt_unregister F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/bits/mman-shared.h b/sysdeps/unix/sysv/linux/bits/mman-shared.h index 31590979b9..b9892f62c2 100644 --- a/sysdeps/unix/sysv/linux/bits/mman-shared.h +++ b/sysdeps/unix/sysv/linux/bits/mman-shared.h @@ -81,6 +81,14 @@ int pkey_free (int __key) __THROW; range. */ int pkey_mprotect (void *__addr, size_t __len, int __prot, int __pkey) __THROW; +/* Seal the address range to avoid further modifications, such as remmap to + shrink or expand the VMA, change protection permission with mprotect, + unmap with munmap, destructive semantic such madvise with MADV_DONTNEED. + The address range must be valid VMA, withouth any gap (unallocated memory) + between start and end, and ADDR much be page aligned (LEN will be page + aligned implicitly). */ +int mseal (void *__addr, size_t __len, unsigned long flags) __THROW; + __END_DECLS #endif /* __USE_GNU */ diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index c3ed65467d..53265587ca 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2787,3 +2787,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 991475380c..2ad9eb1286 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2824,6 +2824,7 @@ GLIBC_2.4 unshare F GLIBC_2.41 cacheflush F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 4fedf775d4..f808d3f110 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -3007,6 +3007,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 86b2d3ce51..a44824991f 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -257,4 +257,12 @@ # define __ASSUME_FCHMODAT2 0 #endif +/* The mseal system call was introduced across all architectures in Linux 6.10 + (although only supported on 64-bit CPUs). */ +#if __LINUX_KERNEL_VERSION >= 0x060A00 +# define __ASSUME_MSEAL 1 +#else +# define __ASSUME_MSEAL 0 +#endif + #endif /* kernel-features.h */ diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 0024282289..db7a5896ff 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2271,3 +2271,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 142595eb3e..91250faca5 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -2783,6 +2783,7 @@ GLIBC_2.4 xprt_register F GLIBC_2.4 xprt_unregister F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 85e7746c10..f5f8c2d613 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2950,6 +2950,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 91dc1b8378..e505d338f4 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2836,3 +2836,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 3440e90f6f..c360b28fd1 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2833,3 +2833,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 5ee7b8c52f..fa09f9d9c9 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2911,6 +2911,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index ae7474c0f0..1db4a115c8 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2917,6 +2917,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index cdf040dec2..770fa9b042 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2819,6 +2819,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index c356a11b1c..c41f91db28 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2261,3 +2261,4 @@ GLIBC_2.40 setcontext F GLIBC_2.40 swapcontext F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 7937f94cf0..8eccaa5c92 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -3140,6 +3140,7 @@ GLIBC_2.4 wprintf F GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index d6e35f31d2..f827f65615 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -3185,6 +3185,7 @@ GLIBC_2.4 wprintf F GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 2268d6890d..141186553d 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2894,6 +2894,7 @@ GLIBC_2.4 wprintf F GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 7f61b14bc8..7786c97072 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2970,3 +2970,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 4187241f50..090a8a3cc3 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2514,3 +2514,4 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.40 __riscv_hwprobe F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 8935beccac..8f8daa10b2 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2714,3 +2714,4 @@ GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.40 __riscv_hwprobe F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index e69dc7ccf6..68ad13d4d1 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -3138,6 +3138,7 @@ GLIBC_2.4 wprintf F GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 7d860001d8..b07e767d44 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2931,6 +2931,7 @@ GLIBC_2.4 wprintf F GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index fcb8161841..841da24118 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2830,6 +2830,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 3fd078d125..2a8cba719e 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2827,6 +2827,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 1ce1fe9da7..8f9031f344 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -3159,6 +3159,7 @@ GLIBC_2.4 wprintf F GLIBC_2.4 wscanf F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 07507b86f6..e5abc49fce 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2795,6 +2795,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index f1cfe8dc13..424bf43868 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -39,6 +39,7 @@ mlockall - mlockall i:i mlockall mount EXTRA mount i:sssUp __mount mount mount_setattr EXTRA mount_setattr i:isUpU mount_setattr move_mount EXTRA move_mount i:isisU move_mount +mseal EXTRA mseal i:bUU __mseal mseal munlock - munlock i:aU munlock munlockall - munlockall i: munlockall nfsservctl EXTRA nfsservctl i:ipp __compat_nfsservctl nfsservctl@GLIBC_2.0:GLIBC_2.28 diff --git a/sysdeps/unix/sysv/linux/tst-mseal-pkey.c b/sysdeps/unix/sysv/linux/tst-mseal-pkey.c new file mode 100644 index 0000000000..d194fbaaaf --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-mseal-pkey.c @@ -0,0 +1,84 @@ +/* Basic tests for mseal and pkey. + Copyright (C) 2025 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 +#include +#include + +static int +do_test (void) +{ + TEST_VERIFY_EXIT (mseal (MAP_FAILED, 0, 0) == -1); + if (errno == ENOSYS || errno == EPERM) + FAIL_UNSUPPORTED ("kernel does not support mseal"); + TEST_COMPARE (errno, EINVAL); + + int key = pkey_alloc (0, 0); + if (key < 0) + { + if (errno == ENOSYS) + FAIL_UNSUPPORTED + ("kernel does not support memory protection keys"); + if (errno == EINVAL) + FAIL_UNSUPPORTED + ("CPU does not support memory protection keys: %m"); + if (errno == ENOSPC) + FAIL_UNSUPPORTED + ("no keys available or kernel does not support memory" + " protection keys"); + FAIL_EXIT1 ("pkey_alloc: %m"); + } + + long pagesize = xsysconf (_SC_PAGESIZE); + + void *page = xmmap (NULL, pagesize, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1); + + TEST_COMPARE (pkey_mprotect (page, pagesize, PROT_READ | PROT_WRITE, + key), 0); + + TEST_VERIFY_EXIT (mseal (page, pagesize, 0) == 0); + + /* For certain destructive madvise behaviours (MADV_DONTNEED, + MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK), mseal + only blocks the operation if the PKRU denies write. */ + TEST_VERIFY_EXIT (pkey_set (key, 0) == 0); + TEST_COMPARE (madvise (page, pagesize, MADV_DONTNEED), 0); + + /* The other mapping operation change are always blocked, + regardless of PKRU state. */ + TEST_COMPARE (pkey_mprotect (page, pagesize, PROT_READ, key), -1); + TEST_COMPARE (errno, EPERM); + + TEST_COMPARE (mprotect (page, pagesize, PROT_READ), -1); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (pkey_set (key, PKEY_DISABLE_WRITE) == 0); + TEST_COMPARE (madvise (page, pagesize, MADV_DONTNEED), -1); + TEST_COMPARE (errno, EPERM); + + TEST_COMPARE (mprotect (page, pagesize, PROT_READ), -1); + TEST_COMPARE (errno, EPERM); + TEST_COMPARE (munmap (page, pagesize),-1); + TEST_COMPARE (errno, EPERM); + + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/tst-mseal.c b/sysdeps/unix/sysv/linux/tst-mseal.c new file mode 100644 index 0000000000..0aff1e9e4c --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-mseal.c @@ -0,0 +1,67 @@ +/* Basic tests for mseal. + Copyright (C) 2025 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 +#include +#include + +static int +do_test (void) +{ + TEST_VERIFY_EXIT (mseal (MAP_FAILED, 0, 0) == -1); + if (errno == ENOSYS || errno == EPERM) + FAIL_UNSUPPORTED ("kernel does not support mseal"); + TEST_COMPARE (errno, EINVAL); + + size_t pagesize = getpagesize (); + void *p = xmmap (NULL, 4 * pagesize, PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1); + xmunmap (p + 2 * pagesize, pagesize); + + /* Unaligned address. */ + TEST_VERIFY_EXIT (mseal (p + 1, pagesize, 0) == -1); + TEST_COMPARE (errno, EINVAL); + + /* Length too big. */ + TEST_VERIFY_EXIT (mseal (p, 3 * pagesize, 0) == -1); + TEST_COMPARE (errno, ENOMEM); + + TEST_VERIFY_EXIT (mseal (p, pagesize, 0) == 0); + /* Apply the same seal should be idempotent. */ + TEST_VERIFY_EXIT (mseal (p, pagesize, 0) == 0); + + TEST_VERIFY_EXIT (mprotect (p, pagesize, PROT_WRITE) == -1); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (munmap (p, pagesize) == -1); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (mremap (p, pagesize, 2 * pagesize, 0) == MAP_FAILED); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (madvise (p, pagesize, MADV_DONTNEED) == -1); + TEST_COMPARE (errno, EPERM); + + xmunmap (p + pagesize, pagesize); + xmunmap (p + 3 * pagesize, pagesize); + + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 5acf49dbe8..5a22654095 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2746,6 +2746,7 @@ GLIBC_2.4 unlinkat F GLIBC_2.4 unshare F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 02d1bb97dc..d627f4fcce 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2765,3 +2765,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F GLIBC_2.39 stdc_trailing_zeros_us F GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F +GLIBC_2.42 mseal F From patchwork Tue Mar 11 17:09:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872462 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1594052wri; Tue, 11 Mar 2025 10:14:13 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXL00H+MEoyzVTHAwgNNEb2/YWBdV1r4plmPAhDGX0P2MCdantYfR30FY1K6kj0bJzLy91MUQ==@linaro.org X-Google-Smtp-Source: AGHT+IEQrlgQMcBTGfyW+xWEoY5TvnUKiCya+WNj9YSyOHSSR3qtWxVUbildRGbeXzYkO5wZl7SE X-Received: by 2002:a05:6102:cd3:b0:4bb:eb4a:f9f0 with SMTP id ada2fe7eead31-4c30a76a09dmr12092696137.24.1741713252934; Tue, 11 Mar 2025 10:14:12 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713252; cv=pass; d=google.com; s=arc-20240605; b=YmtBrrm2zBcpoH8plIefXt1dC6b040tNJeCbvL7i8jUpamDXr8QDN9ilmvomaMAD9p 5UwgTlkzGUPice+0qdXEUVHBMaNd+Q7HuEz1y8EtQizrID9iYCkte0riNvHNNVUpbNOn Kw8BACXRfDZgFnbtWTQddSl4BSxkP9qYK1T3p0sGwJoNtuTlPBm2LzVhmgaEG/XbSWPI O3f5ozd+Qtw7FGFmh1ZP9BY7Zks7wV5blggUFHs/xH3X8VmDfGAA9IAwF+9z5xIfncX8 NC4wSqmzkrc4Deq7TVAgMDIii9oNoNwa9SuCp/t3FNDnbABv0zPeGVfALPOHBbUY95MW SA/A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=rfPK/162DYzl2VVkadfbNZehzDek7E/3GL4/JyDErMU=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=Kw0758cr/SnrNtJL63pe2NO65GwrQzDt+HGleatgh1deFtYIyFJ4VQpLA0abYkJPPS fxWUCitgfCrzB94qEszq43Fr9QO0swFgkDUFGnNvWT0ULhvbzossbNAVAlU3VxHXqaLd qAPYA/esugc+ObBRkla4EZryeVEV5KKAhPfOoL7qykUOPJdFsgvl9oVBAF4jSBopNHxk 0J5YQLBpdVYBAWbaBgy1073bawa5MlyFxyRT1VTDG+NRMkSJyDYiTKvOzlzCF0uUFde0 lZZbbkBHygUtAWJ/J9Wev1hnUjgnz+zhcNFmRdu6FaOvwri8Z6RzwbMzRS0v62EdajmX 0hMg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=X7bkBVFf; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id ada2fe7eead31-4c31833deffsi2204996137.277.2025.03.11.10.14.12 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:14:12 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=X7bkBVFf; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6B76C3857BA7 for ; Tue, 11 Mar 2025 17:14:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6B76C3857BA7 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=X7bkBVFf X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by sourceware.org (Postfix) with ESMTPS id 091473857B98 for ; Tue, 11 Mar 2025 17:13:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 091473857B98 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 091473857B98 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::102d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713197; cv=none; b=r7eERlkRyaZr9zk0hmb1WH9mdt/0j0y4RatOp2hW0eUsQf7EkMr9uGJidEP/4hl5lJgWZ+hirNkuBfM1ghCWRt/Gt0/9NEAfngdLvJfpHkrzwbOiPAOLmu608qQGaWQOyLfhh+kvwl/5UVHfqyCW6PjfpPWhIUmVFRAK45NWx7o= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713197; c=relaxed/simple; bh=SwX2QvuGK7skVWBNWlkjLMl1ikEU1WbfLdpGJEnA0h0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=iF3A/exv9NPlEUioyt9b7aEQeqHLO9rnumidDnQO/Cy4Dpx0MSdeiXiLidj0sNOI15WgL2BbAUvdxqEOkwe3Mw6fOkjntJMd6diPPfk/xmWKmDyRsWn99VLG/OwvyOYcIQMv6CtIPpkh5jCatAxU0tqvQPXETlSfkdu0bjvMG1M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 091473857B98 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2ff64550991so8882117a91.0 for ; Tue, 11 Mar 2025 10:13:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713196; x=1742317996; 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=rfPK/162DYzl2VVkadfbNZehzDek7E/3GL4/JyDErMU=; b=X7bkBVFfx2UYHC62l6Yf2mmiGNS3qeVUtD/ldlimarSPgyD3EXNwba+44Wxa1Jwsba 7kIugR3uXgGaqxi4hskjl2laYhoxOgORTBtlP7anyQyMEzeZ2i4EiSaKgVLw62ukDDi+ J/X+ebRQ6gUnLjqGcbOcZ4kgQTLysvsjcwlrDbOXr3FTJzvl3UBDHidaD7b1ifyaKP0E UdaRzavNsn2egwsOrvJXaeiwYBkeGROG4yPiAgcWBWzVY6YVyIyZ62QIaTLaJ19ITMdb m7wURqGkbZk6+htBHzAtgPFzaMqpgClRK01UYHtzn2UPqebQAGVbdSLzP4GyvDuPIecj bISg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713196; x=1742317996; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rfPK/162DYzl2VVkadfbNZehzDek7E/3GL4/JyDErMU=; b=t+1e0c1zmAB/shEY1ZB9aB9gUE7GCpjG5LTnsUk+OV+saCWbHG9fb0InbaG2HaRNk2 +4ctF4D5XKCh6aJqTT3AFKJBCwnfjjvkiL/VCrvramZuJMphc/yQbo5LCAvwXA5x6BkJ Fs+qjm2FUHMrWIROoDhHFfCYe/XRj9exFdpizszJ0pxJloHGXD0QLjfk3Tu5JL5JxPMA 6lpd0YX4Puh1XwXKdK/0TTmatUVAKlslrMRXC48gMFjKKq2mVQs0q3VJMglj+yJAmno3 LBO50+2pFgDXW6YQKhTf+xXrtOOoKVUns6XAimR0dtaZ22wFYwC7G37sfM9yLW4s98PD LTEQ== X-Gm-Message-State: AOJu0YyG7k6ZWyLvHeVr6NmwmhAFyCvnNNWYZsqwjEiOLvsht/vYQnqh XAeSTvEKe1ctrLrrn/eiHLQupLIC7w+VGMr+E4hdGjlWY9atRc/qv+Oj3qThaAZTYI8WcRKy5UT w X-Gm-Gg: ASbGncvKhZyuMUFrZ912ptCVyRcAAQDf4E8rwoGn6uU99jkyAsXRv806L92PxpIY2li 5Lklf1Y9E8nRZsnKxcHkF308IMct7r7Zv3iGAdQkDumlWM44VNk0VI9dMLYMM6ErY7PInUxl0B3 bEmmnlcaoaJTIm//ry9VLWe99pGIm4REalxZgxtIP6Uz+dxjmmCqNvay0wbCaCEsDZkt7m1u51t Yvfq81ucDChGkyqZgiKVXsy51WrZ/F7MNqluO4laDm/olNJsXFXqoo9yB8d/S/2b+Hqg9HRlK+G v2zyN+hnXoY3jUC/sU1HclKnEH7xM6QCjP7ZKtN426Y3lHpi1AO+zGBWKFavIL/Bew== X-Received: by 2002:a17:90b:384a:b0:2ff:5ec1:6c6a with SMTP id 98e67ed59e1d1-2ff7cea69acmr31135370a91.18.1741713195631; Tue, 11 Mar 2025 10:13:15 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:15 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 2/9] elf: Parse gnu properties for statically linked binaries Date: Tue, 11 Mar 2025 14:09:49 -0300 Message-ID: <20250311171305.89091-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org It allows static binary to opt-in of memory sealing. The aarch64 already does it for GCS, so refactor it to use __libc_process_gnu_attributes instead. Checked on x86_64-linux-gnu. --- csu/libc-start.c | 4 ++ elf/dl-support.c | 13 ++++++ sysdeps/generic/libc-prop.h | 44 ++++++++++++++++++++ sysdeps/unix/sysv/linux/aarch64/libc-start.h | 11 ----- sysdeps/x86/dl-prop.h | 4 +- 5 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 sysdeps/generic/libc-prop.h diff --git a/csu/libc-start.c b/csu/libc-start.c index 6f3d52e223..44fe5d5738 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -276,6 +277,9 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), /* Perform IREL{,A} relocations. */ ARCH_SETUP_IREL (); + /* Process notes: PT_NOTE / PT_GNU_PROPERTY. */ + __libc_process_gnu_attributes (); + /* The stack guard goes into the TCB, so initialize it early. */ ARCH_SETUP_TLS (); diff --git a/elf/dl-support.c b/elf/dl-support.c index c7860f327a..d8f1dd8ee9 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -45,6 +45,7 @@ #include #include #include +#include extern char *__progname; char **_dl_argv = &__progname; /* This is checked for some error messages. */ @@ -330,6 +331,18 @@ _dl_non_dynamic_init (void) _dl_main_map.l_relro_size = ph->p_memsz; break; } + /* Process program headers again, but scan them backwards so + that PT_NOTE can be skipped if PT_GNU_PROPERTY exits. */ + for (const ElfW(Phdr) *ph = &_dl_phdr[_dl_phnum]; ph != _dl_phdr; --ph) + switch (ph[-1].p_type) + { + case PT_NOTE: + _dl_process_pt_note (&_dl_main_map, -1, &ph[-1]); + break; + case PT_GNU_PROPERTY: + _dl_process_pt_gnu_property (&_dl_main_map, -1, &ph[-1]); + break; + } if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X) && TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL) == 0) diff --git a/sysdeps/generic/libc-prop.h b/sysdeps/generic/libc-prop.h new file mode 100644 index 0000000000..723575d29b --- /dev/null +++ b/sysdeps/generic/libc-prop.h @@ -0,0 +1,44 @@ +/* Support for GNU properties for static builds. Generic version. + Copyright (C) 2025 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 _LIBC_PROP_H +#define _LIBC_PROP_H + +#include + +/* Called at the start of program execution to handle GNU attribute from + PT_NOTE / PT_GNU_PROPERTY. Must be on a top-level stack frame that does + not return. */ +static __always_inline void +__libc_process_gnu_attributes (void) +{ +# ifndef SHARED + struct link_map *main_map = _dl_get_dl_main_map (); + const ElfW(Phdr) *phdr = GL(dl_phdr); + const ElfW(Phdr) *ph; + for (ph = phdr; ph < phdr + GL(dl_phnum); ph++) + if (ph->p_type == PT_GNU_PROPERTY) + { + _dl_process_pt_gnu_property (main_map, -1, ph); + _rtld_main_check (main_map, _dl_argv[0]); + break; + } +# endif +} + +#endif diff --git a/sysdeps/unix/sysv/linux/aarch64/libc-start.h b/sysdeps/unix/sysv/linux/aarch64/libc-start.h index 75ae0a884a..64acbdb533 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc-start.h +++ b/sysdeps/unix/sysv/linux/aarch64/libc-start.h @@ -34,17 +34,6 @@ aarch64_libc_setup_tls (void) { __libc_setup_tls (); - struct link_map *main_map = _dl_get_dl_main_map (); - const ElfW(Phdr) *phdr = GL(dl_phdr); - const ElfW(Phdr) *ph; - for (ph = phdr; ph < phdr + GL(dl_phnum); ph++) - if (ph->p_type == PT_GNU_PROPERTY) - { - _dl_process_pt_gnu_property (main_map, -1, ph); - _rtld_main_check (main_map, _dl_argv[0]); - break; - } - if (GL(dl_aarch64_gcs) != 0) { int ret = INLINE_SYSCALL_CALL (prctl, PR_SET_SHADOW_STACK_STATUS, diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h index 8625751427..9a5e10821c 100644 --- a/sysdeps/x86/dl-prop.h +++ b/sysdeps/x86/dl-prop.h @@ -66,9 +66,11 @@ dl_isa_level_check (struct link_map *m, const char *program) static inline void __attribute__ ((always_inline)) _rtld_main_check (struct link_map *m, const char *program) { +#ifdef SAHRED dl_isa_level_check (m, program); -#if CET_ENABLED +# if CET_ENABLED _dl_cet_check (m, program); +# endif #endif } From patchwork Tue Mar 11 17:09:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872463 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1594270wri; Tue, 11 Mar 2025 10:14:38 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUpLyh1sqd+MWqcm8CCCI8JpVW6TimowY68kA0a+kdhSmHiywSsa8ecgOaRp9R7w60hdcRuAw==@linaro.org X-Google-Smtp-Source: AGHT+IFj57/1KuDZHTuUSTTkCS4NSSwFqkNbrReryg+66W+01SXhBjDaimSBd9ZiXbbrvByoW/UJ X-Received: by 2002:ad4:5aac:0:b0:6d8:80e8:d567 with SMTP id 6a1803df08f44-6e9005f732emr289317076d6.18.1741713278500; Tue, 11 Mar 2025 10:14:38 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713278; cv=pass; d=google.com; s=arc-20240605; b=FQAB32kaOJJdSGuqtYp+MpwVRqWLoCph6kpP+WetHKh16uTCeIuoCCec37BlUWcydU uIUwtAZuQHXSFXsG+61C19WofFaaorcriFipmCz/6sLtYmKisZOP9FBZa6rLEaw/NgIe nYPc21Eae3/b3Ymkk/s2sPbBWlI/INlrDm5I4K6GZ3LSk74UJMPS5s5lDKRSAFLM6zq4 HoArbDXqiiycPMZiPQfn8oAg99VzE/+6BGhJQCyrfDQZtpXh8qVZ3erY8MjTCHa3OYhM KzLG/vKzUdvfL2HNAajflF8NR7Finn8CO1I++Do4gAtHckb/ifZzr2uOlKiq+Tg7wToA KMxg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=ybyPxwCuz5krpqkgUSdkTFiLFdsZ91hk+hsk1bkBMJM=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=JCVjHqD/40ilw9uBpqiL0FEVOHAC0pknNWAFRdGnmrHpiJWIrc9MREggdcnEBSEp0f lSkWH50a2N6CzXGzGHa5JPiF+VKzAGxLEn0Sv1BBGkqIWa8HuJ+9AxdLzX7r893oRgQN TbBmcUvf/4MQt6b7iMNxaRQTG2Dr1/X/ny6QCbeqsNHH0iUGZ6vvPswRQzAnS/WLn9T3 q62cjKU62zXqJZtfaLKSoxDWBNpKCE31C2nJQeb7VY0HozTgI56QdLDiBOqtzg2rP9kR 9E5ASijWnZmCSKJ7jvrriEVWShZlCZBoOl4TWR0SNDWpDSB9vVgAppyVvTkPgwuXGhTb j4Ug==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TYKTUVIN; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id 6a1803df08f44-6e90dc4f5a4si68573996d6.48.2025.03.11.10.14.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:14:38 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TYKTUVIN; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 102F73857C78 for ; Tue, 11 Mar 2025 17:14:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 102F73857C78 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=TYKTUVIN X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by sourceware.org (Postfix) with ESMTPS id 61C4F3857836 for ; Tue, 11 Mar 2025 17:13:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 61C4F3857836 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 61C4F3857836 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1030 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713199; cv=none; b=jHMmhjzrI0Lb2PC6xquUFDyZ+DB/XBg1YZpo8rAZwhmGymws1TsKm6/FMiO+cH870iEdtyXIijgUauvE74X5K94NInU8pg+WF+rZ9YR4y6/3IAbKlytypWj1QOncVmnqKuklQ7WL/p48oX0R99buAsUmZ5c+NoRwJB8D6iS+cpw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713199; c=relaxed/simple; bh=f/sItMdvG1ZTZQ+4mASeHkHlibVui1E0+RK9MXmp0Og=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=YoYbMNSOTDlIhWKLD9WgZZ0HYQJjEJVgKg0X5tI3fGSOXDRUBQPNoFv1qryrZ3LqdmZB4dkItXKlOwJin0Mp1iylI9pWTwutbEQvgYk+a1Iq5BAvh/q6Wr9hNQHa7GmBQ7gbN/twhl4907vTTMrV2kewelcVCzJ/9YH3NEckaLU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 61C4F3857836 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2ff80290e44so9491724a91.0 for ; Tue, 11 Mar 2025 10:13:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713198; x=1742317998; 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=ybyPxwCuz5krpqkgUSdkTFiLFdsZ91hk+hsk1bkBMJM=; b=TYKTUVING+lK8onNfEN8Aws3CQP/p9lyPQmlyHNBR6yMJybOWR/XOPNwryWCR8gbYc bFF+OOT3AdXB2vyLCD427xh0fN0pbF0sSCWZe3axHprMH6gKK94R9cy+pa9Oh74LkFuQ j7usnn06k0+voUGyFPtTA7ImQH+owKYqxErcwsolDTRCC1Jxhs7IebsfNIsqWflXqfOP /VQuJzH49/xnViK+wOGyDgDmxBjPGuzXpC61tZsB7RVOb8v5/bfqe0mgf9IY+aG1Baxk /B6HnL1OT9uyp258t62+j0gU119u98y+KfIZo9dTzfzuu9wIeD+zKcOxi6+jz3ow3Dkf SeNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713198; x=1742317998; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ybyPxwCuz5krpqkgUSdkTFiLFdsZ91hk+hsk1bkBMJM=; b=oXF42bGjYGMHiHX8v50J9UUWvOy3COGvAqQ+SWEll5vpS+rn4T9xRqzzvBTXBc+45z GtwoOaT2+l8psbM6M0juURA+6w8uTpNm3O760rsCBlwlMWoykTF+XaoKAxLJWMvGyZct VQZvDPr3YZjvglm+hF9YP1hNF8Ro8BMzlj5X8gZe6vq0Utv3JOW59rjNyXsY2rTMiCq4 jj/mKUOOvoUhU+drGZ8iS1GT4KaYslCTx63RsnpX26ZYQj/E4tNC7eDYHCHUEZt1pC+H 4/3cup67viD5HpAtSfIaOb4JUXICTaBiSN/yRwOx5J4Opwo3IYOWGiYN1URKYfMABhQP PxWw== X-Gm-Message-State: AOJu0YxoyKZJb+RtD5Jzq0xPD8dYbPw00ir40++iIOSgIT17zHnlafzs 5pObBxftmd3HMBhd6IWMNYieGHUA2BdpXh22GFwItVfpX1tMygdEWTmpYs2MIf51v4I3gPP4wG3 K X-Gm-Gg: ASbGncuPzsnpneZelyr109Ca02aJXR1vFeYWHoV0kBLl16pDMsMBeMPuxTw+FnhLrPU yHxsfHVC+EICybZ2w1QFML3A1bGopK4sux3eaI5Jt4lxAOCVRC3yiq4xRhMWvify8ns29BfeCfr Q0aJPLZCJAKqG5peNeUDMkm+E/UwH7Fe3ied7GUhdIC1WU98ujZDo1bE/ONOO9OveuqyAtgGfQL OuCG/XJwubByAmg3XC7lGtkYJO1A6XDB0ss1FMQVJzMq3cMdZr7CDB0Zh68SrpW37ctpitXiu5J SwtdOKAiZDNmicRYHU55YCD2BkO7fHQr/lrngqXkZGB6XBxdQdb0sj4= X-Received: by 2002:a17:90b:5110:b0:2ee:5bc9:75c3 with SMTP id 98e67ed59e1d1-2ff7ce7b375mr26059972a91.5.1741713198176; Tue, 11 Mar 2025 10:13:18 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:17 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 3/9] elf: Parse gnu properties for the loader Date: Tue, 11 Mar 2025 14:09:50 -0300 Message-ID: <20250311171305.89091-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org So it can opt-in for memory sealing. Checked on x86_64-linux-gnu. --- elf/rtld.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/elf/rtld.c b/elf/rtld.c index 00b25c1a73..727e16f233 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1724,11 +1724,15 @@ dl_main (const ElfW(Phdr) *phdr, /* PT_GNU_RELRO is usually the last phdr. */ size_t cnt = rtld_ehdr->e_phnum; while (cnt-- > 0) - if (rtld_phdr[cnt].p_type == PT_GNU_RELRO) + switch (rtld_phdr[cnt].p_type) { + case PT_GNU_RELRO: _dl_rtld_map.l_relro_addr = rtld_phdr[cnt].p_vaddr; _dl_rtld_map.l_relro_size = rtld_phdr[cnt].p_memsz; break; + case PT_GNU_PROPERTY: + _dl_process_pt_gnu_property (&_dl_rtld_map, -1, &rtld_phdr[cnt]); + break; } /* Add the dynamic linker to the TLS list if it also uses TLS. */ From patchwork Tue Mar 11 17:09:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872467 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1597543wri; Tue, 11 Mar 2025 10:22:07 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVZdnLI3J9nxmUAOEQEsH70w96mTBP27pYv/cnK+c9f7F0M1/WGyRGTttf4XdNW7gsntsP4ew==@linaro.org X-Google-Smtp-Source: AGHT+IE9jbWt6HT+OKYnolHgxbGEGC8YswKUB2m20ibyD+8IuGdAuqifllntg8xMLv2dubq6rRtj X-Received: by 2002:a05:622a:1b8e:b0:467:5da6:8096 with SMTP id d75a77b69052e-476996491b6mr65844311cf.44.1741713727090; Tue, 11 Mar 2025 10:22:07 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713727; cv=pass; d=google.com; s=arc-20240605; b=A2i965cgP7wXLGbhNAlBxSDCzmhUytaF95x0iBNx6Du9rfS9rA3RaooaUiaOxdq+E7 dkbPudQ6Z2JncLK9MKb4Dyy28dVCCNPC0TXraBhNLuZgtdcwrqcN34CcQjbNADAd3zML 1lMTrKXZopAyXtKYS+4MyO/luYwCB/7ZXSFUE+HSPVa9vtrtPIqp4LPOcn3QMPInwqBz HrgUT+wYareSBw0r6vSRjegKzIIZ9XgIykt87qaQeFhGdjFB+zunw+7+E8i1JjCCStXE 5qXkTHCw+juNTULVqdKNtNb/d/4s8aXSM0XKibVaF4vr7UqqNGBfIDWofMe4XCXtc6VJ ROpg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=at4hYQy73R2Y2hnRsyfBEa3QMs8p2LC02dy7pKV/IAg=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=evRxHvNpwCy4qYITPXcJgj28H6i6ku7LJBYH2nBnlaCg0GDBAjYPvoAsth4UGMwuwW Jmz+x8OmXUw98mJ+TPBOwH/e0nqTmXhKdNrSmviPapO0jBJTanCjaUWvS2TThKOc34Up VP3FXF5Oy0Cds3lYb55GgjsuqihSxE0hp3D54E2BJrOepACI8U5ERIZp+amA1Sb6wTep d80J4PqMrFBaNqhGLrom43ogxQLrmM3GsE2Xt6SMm+EgZCC/GVeEgoGDqpVsAUnHO+ws W86ICtB94LFkoPtArJ9SXGxDvh7OXI9E6F8ePhZ+77AUbhJ0w6uYINHBeOnT0MURTOOm exIA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JTATFhSL; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id d75a77b69052e-4769802bb34si26669541cf.81.2025.03.11.10.22.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:22:07 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JTATFhSL; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A67873858435 for ; Tue, 11 Mar 2025 17:22:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A67873858435 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=JTATFhSL X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by sourceware.org (Postfix) with ESMTPS id 89A7C3857709 for ; Tue, 11 Mar 2025 17:13:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 89A7C3857709 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 89A7C3857709 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1034 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713201; cv=none; b=nEkS4j3npPNr8Y6OVvV7xAeAWdPT1OiZLfUTIZQeQ/DfwnkcWeBSe3P8Hijurdr4R0ljkVdR2DNsEtjgX4WuGTX7XtTfK+gpMlABHRUfHVCQF7CdCPrKimZBHnj3CRn9XJVh7y6p2/z6hmGElhAThlSt9LriRYQjgQT0m4pVDhY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713201; c=relaxed/simple; bh=Bv/4jiyOZD/W1VDRIGxafP+IgckmjmGnp4CqTOf7N/A=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Wr7YVix+3biXf9Jyc/t8AdHeeBVR+8jGk5qHHxx8Amhgd54T03AuEpNoAr2+PAgXwvvdimiOCO1CaMy534YgjWG30UNEZQ6qM3kvgk7xumzwVfS1bubXSifb3C7MC7xLbKYLV+PquoDOu8e58F6wChH5UobhfotzncvY+zlrF1Y= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 89A7C3857709 Received: by mail-pj1-x1034.google.com with SMTP id 98e67ed59e1d1-2fec13a4067so8980647a91.2 for ; Tue, 11 Mar 2025 10:13:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713200; x=1742318000; 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=at4hYQy73R2Y2hnRsyfBEa3QMs8p2LC02dy7pKV/IAg=; b=JTATFhSL/sx/BWYsJiPxN27EBGLqb8GnNAoUGZZ2G6rb9Dp8kHiXKowIY60L6nQ3Aj QpAb/fuULEuyMUPeD0/eHv9eSRuMI7aEegqOY6E20iSvUojTLV7vxsLO10LosvV351aA KFxAvxTD5G7x11pXETh8I9ebxdGIGXNjr4BzAyimOxNp/3ajxX59vQtR1SKH3RdScrOF gTOGxtc+rM5Kn1nnIpCTawe3PXuBmqJxZM/NmLYFA9wlX50QdNRG9KiRrTdjGKgEnTEd KRNwvkw5RWzh62eEDmDN0n0H/qRBTfyCvQXY1djuiVCG7ZUT/uhW2MGq5+w03DTswlkK TVxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713200; x=1742318000; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=at4hYQy73R2Y2hnRsyfBEa3QMs8p2LC02dy7pKV/IAg=; b=TN5vFBmafc304DBUhzHHmxCor1ufjJ/nNocKsgTEpGC416VRhUsSysATWse011JJSQ ZbOZF9JpI42MsBfpR7R7hWR5s3o3siGdEGAss3NTg4/KSZAEp3X089f8myFj6G++yFNf hKrbTwRDuy5UG431OOmtxMughozYPTavJtOpCr5RUOcdIL/FtdwSSmjZ3cQHNVFxZxi2 zEydwNIBdn18EwcAQB0tUD+okYlhXyY0JLvtq3xIXz0UfTYOQocfAY926e1FYj7k8yUc gzfSMV1Jn3xMmu+EDk33+aOdz9pnL6/SqHMftl9+3OFqIW7bfI1kDdy5atFDc4yIwyCl uC4A== X-Gm-Message-State: AOJu0YwAxW0WIUXnoTDb+6RjgPyikdYKz2NK1J5SebWPokHbeQ+leYRZ gM7G+8Y0uAHItpyykX9CoyV7StwOUyg0qgFVvjNoQ7PlDBqadOTPvooPAy24eA8I/Kzrey/4iJD a X-Gm-Gg: ASbGncvDoJUci9Abejc+BVoADxP901zxDPpitVHqEPWfBYbkLrd3bqjzEo3AuEthgri yB+oiOa52CdIhXZL+9z7qLLtvrvHHMFNIjrrNbji8/HJeHmAVGYnOnjOeIPSW1X6ZpWVbnTH0x5 JvCVv8OZwls0F5oPwJ+mtSCBG9P7jarvk2cu6y0aDfVFP1jUJbfG0L1NQZ9sIdX1Gbjv9IifxAe Y+3I4NTU618ovlrLn2x7MujhuXCkk5+/ojcRNdWOiIpotv/GOvg3QLbIsEYYQJGEm+nW8batqhu gqIrAkFDcJ8SG/PxwULswUkBueFKAFbk2ZC4AsYlN3fgVR15Suyd0ZE= X-Received: by 2002:a17:90b:17d1:b0:2fe:d766:ad95 with SMTP id 98e67ed59e1d1-300ff0c9c49mr6345335a91.9.1741713200355; Tue, 11 Mar 2025 10:13:20 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:19 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 4/9] elf: Use RTLD_NODELETE for dependencies Date: Tue, 11 Mar 2025 14:09:51 -0300 Message-ID: <20250311171305.89091-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org So dlopen dependencies for objects opened with RTLD_NODELETE are also marked with RTLD_NODELETE. Checked on x86_64-linux-gnu. --- elf/dl-open.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elf/dl-open.c b/elf/dl-open.c index 60a1dce9de..c770cbc7da 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -597,7 +597,8 @@ dl_open_worker_begin (void *a) /* Load that object's dependencies. */ _dl_map_object_deps (new, NULL, 0, 0, - mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT)); + mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT + | RTLD_NODELETE)); /* So far, so good. Now check the versions. */ for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i) From patchwork Tue Mar 11 17:09:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872465 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1595914wri; Tue, 11 Mar 2025 10:18:20 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUxepLyVsMpLayuXxJ6DBzENUkvDHEOS2MqxzcTvIcZ4f4yXl+HwYiohu9C4H5dkpcb0y8gzw==@linaro.org X-Google-Smtp-Source: AGHT+IGIrd6961LJTksd+yVggqRp2QC/j8+3pxFiJRTbdmOjOWhVFHZpU58pwjTYxsaLmNnsp96C X-Received: by 2002:a05:6102:3752:b0:4c1:9288:906c with SMTP id ada2fe7eead31-4c30a5e8ce8mr11265827137.9.1741713500684; Tue, 11 Mar 2025 10:18:20 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713500; cv=pass; d=google.com; s=arc-20240605; b=lY3wAgzoi7yrhQGQdkRlEr5w87VqA0N35wXRaAVVAOB5bwLiOyKb6yi0wWe1KBWbjZ Jl3AbXpZCkh9hcO5eMO1sacuAoKFEeT0bYEVy7erb9aA/6AMKfhBOpResJ3HOM20NZND 8tbztOBaDZFDEy37rk3yPMLLAbOCDr/2dmMx1aU1sO5ffEi1YC5JSOgZYo7XZphkVOAy mcyiTsTMtTKw41uaieJ5C/E6bDHnQrU8rOvuikLK7v1r0LtK3pT3RSZcUlB2Hza1hX2c ZKpGiFsqDRQHeW2C79juGP1SQ4NM3OG14MK+VRkYqOByo95ds5NCbEH8wFHWdt+bDkM6 V9/g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=wMGcSe5SZydZnvho56iyXDzmNMG4L/TGAYC53A5VlkU=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=innw32NeGw2PYcorczJslk1gidotTt6WEItJ79A7rE5n+MnHQcGbaf/6jpMHk4c4mv O1zySRAZfpJIKkrLB/y+kPhL++U0DKVV39II+orYOw+R+P/23HuQV3dld0IRlUit8eGM owDCvD0BV3cb84aLD7IR7YEUTGfApg4QE/MtNK+hHLBB1/NygeNjpKo5fWUjD5bns4yq G7i5b0XAa8Kn8PgnAQHuuBZnBrovv7mDS87MmMql4ujZBx73EW/cQyRvxMAdvF+PoVKa F1trY7dWOguX9MJhs0jS2Mseh8YiD1NPAAfJSliLJCrjG6CiF0g3lFZNXmV37S5+xolc 8fBg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iBpLcPPV; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id ada2fe7eead31-4c2fbd606casi2802711137.663.2025.03.11.10.18.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:18:20 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iBpLcPPV; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2BABA3857718 for ; Tue, 11 Mar 2025 17:18:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2BABA3857718 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=iBpLcPPV X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by sourceware.org (Postfix) with ESMTPS id 61727385770D for ; Tue, 11 Mar 2025 17:13:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 61727385770D 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 61727385770D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1031 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713206; cv=none; b=dXo0CPiQoP1mdbVMSm8akqHLqxaMe9yZRZpiL/mnm5VMZvGSqorgbDCay4VPiEKfjodtkkWsNO0pnNnDoDXOrP7BNaQkTPCSRcot1ei9Jb+mRCayGn0jWlMjkwlCCXDFMmxyvcrzyVhPYUtSmEyHsOXf/HimD4+JmnxgGC9I7Do= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713206; c=relaxed/simple; bh=z7quWWkQzN7gPgdYwied7VhUjb3IvrTzhRZ9bGSXoV0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=QIM72UL8BQfHxJYllygsZjocaP+PsnJ6wnyUqkUmKcC2wpu5z1ok4sZS4Tn+4xcGD1aD+nHuoPMI03EUdoHfzFSwZOZ2jS8YvpPnRAcQ9cNcnww5ZJRkeXU4kUnFM3GejPTpiLvoEfT+fbs7YBzr8DiiJN/y5R/Bt6lhnItM7sE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 61727385770D Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-2ff6e91cff5so8402135a91.2 for ; Tue, 11 Mar 2025 10:13:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713205; x=1742318005; 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=wMGcSe5SZydZnvho56iyXDzmNMG4L/TGAYC53A5VlkU=; b=iBpLcPPVr/mF3FZp2Na6C2L88/HnrtFdeUfZGu8Q0KjzsIFBJv/2XbvKKp+KSA6AvW c/PyUfZxTmRyVZ7YfrodIrinxIjuE7YwMny6S2dp73+Wc/Ogu8zLYSgyGSp6YZbhlimZ i1oM1n0PhEZq613zDd0tms60ZvptbvzlLtigkuFyALCkS4Y3RInBxISflIorzLvWWy+a Ty1ekUDhv7S1Jg//tSSdHnJGgkpPCGygdIkFXDnqXO/b8f6CWqlcm8dIIvL6HmptUPP3 sI4s6ANUZv3Pf7mPbjs0dQPDeTEDw5m5EMrQp76OwOuKuG+Po4AfVlpkGkUscFHrT0xn dWCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713205; x=1742318005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wMGcSe5SZydZnvho56iyXDzmNMG4L/TGAYC53A5VlkU=; b=P0/9c/brD+H0QaYdNxqjHPPC2bwns48Bwm8FKZLVGcw1jJIz+YzOYLNPHaybZ4+mdT YvilIcvkjmukVfwvvzdxQWy7ekDmY63gD0DMV1Oypyg7Gsfhq8qgHWZcVXYOOXLYRNfr KLViWjTkyd80QvSZFZCkaWO4j0ruo94dMeI+PwT3TWrqD6wlvvfgTySnsWcXU50+m2rF 5u9Ryt8woChEfBcf6rKgjGynfB/WV+EQEEuVLuVNxRSWIp/lZsa8VcSCiMHErCrBZ8Mu LrDRA8g4+KqXfAv9A5jSSEXSmzW5dk9m4gcealG4Ni3hf9cNmP114Ri5BqWOArM+FHyc YWjw== X-Gm-Message-State: AOJu0YxvML0mqlviM6cXVaLNva2wv3tuBOheu+WsolkB6Yw75F7Vc2TO Eh5D7ClyBm/EfGi9x0VT38vOTLSx+YFhMoI8B/NhGtK7H3T8oYnLoaz4yVdOwMSRWcYuQIQfaic / X-Gm-Gg: ASbGnctTFTuBKUPYEHSSeTwX1+YuEvufjB8P8V5At7FIK4DErYIFCMbL0bN9efxIAG1 mbBZlMJt9p0j6egSJ5iGYqNs7AibVL56XtXpCxCCJ0Iib+BozNgGq4gwnYgWAlGhYcJGzQjUn7f s9w1qrcG3T+prmiA9r1Osj0h+etkb26lbFgsX/kzqiFTTPCxJAWz61NMwMNSgwK45hgvBJ5s+Id VJtfUu4lwmilRBdRZKqaU01G2RzMeAIxFI5BJheTfNf6pRzPjVvx9MkVucn07jI/xuO3d3DBo9u pARI3VXgvLrtWb7lsfWBu4BMrEh6HAETF9ex9CaCnwxJt0h/CbV5OPHzkpbtAcm5hA== X-Received: by 2002:a17:90b:4b11:b0:2f1:2fa5:1924 with SMTP id 98e67ed59e1d1-2ff7cf0726cmr23147032a91.26.1741713202920; Tue, 11 Mar 2025 10:13:22 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:22 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 5/9] elf: Add support to memory sealing Date: Tue, 11 Mar 2025 14:09:52 -0300 Message-ID: <20250311171305.89091-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org The new Linux mseal syscall allows marking a memory mapping to avoidi further changes (such as changing the protection flags). The memory sealing is done in multiple places where the memory is supposed to be immutable during program execution: * All shared library dependencies from the binary, including the read-only segments after PT_GNU_RELRO setup. * The binary itself, including dynamic and static linked ones. In both cases, it is up either to binary or the loader to set up the sealing. * Any preload libraries, including dependencies. * Any library loaded with dlopen with RTLD_NODELETE flag. * Audit modules. The memory sealing is controlled by a new gnu attribute, GNU_PROPERTY_MEMORY_SEAL, added by the new static linker option '-z memory-seal'. It is set per binary, including statically linked and shared objects. The GNU_PROPERTY_MEMORY_SEAL enforcement depends on whether the kernel supports the mseal syscall and how glibc is configured. On the default configuration that aims to support older kernel releases, the memory sealing attribute is taken as a hint. If glibc is configured with a minimum kernel of 6.10, where mseal is implied to be supported, sealing is enforced. Checked on x86_64-linux-gnu and aarch64-linux-gnu. --- NEWS | 10 ++++++ elf/dl-load.c | 4 +++ elf/dl-map-segments.h | 17 ++++++++-- elf/dl-reloc.c | 54 ++++++++++++++++++++++++++++++ elf/dl-support.c | 7 ++++ elf/elf.h | 2 ++ elf/rtld.c | 13 ++++++- elf/setup-vdso.h | 2 ++ include/link.h | 8 +++++ sysdeps/aarch64/dl-prop.h | 5 +++ sysdeps/generic/dl-mseal.h | 22 ++++++++++++ sysdeps/generic/dl-prop-mseal.h | 34 +++++++++++++++++++ sysdeps/generic/dl-prop.h | 5 +++ sysdeps/generic/ldsodefs.h | 10 ++++++ sysdeps/unix/sysv/linux/Makefile | 4 +++ sysdeps/unix/sysv/linux/dl-mseal.c | 51 ++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/dl-mseal.h | 31 +++++++++++++++++ sysdeps/x86/dl-prop.h | 4 +++ 18 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 sysdeps/generic/dl-mseal.h create mode 100644 sysdeps/generic/dl-prop-mseal.h create mode 100644 sysdeps/unix/sysv/linux/dl-mseal.c create mode 100644 sysdeps/unix/sysv/linux/dl-mseal.h diff --git a/NEWS b/NEWS index 4732ec2522..fc460ede05 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,16 @@ Major new features: mappings to avoid further change during process execution such as protection permissions, unmapping, moving to another location, or shrinking the size. +* The loader will memory seal all libraries that contains the new gnu + attribute GNU_PROPERTY_MEMORY_SEAL. The memory sealing uses the new Linux + mseal syscall, and it will be applied to all shared libraries dependencies, + the binary, any preload and audit modules, and aby library loaded with + RTLD_NODELETE. + + If the GNU_PROPERTY_MEMORY_SEAL gnu attribute it not present on the binary, + memory sealing will not be applied for its dependencies (and even if the + objects has the memory sealing attribute). + Deprecated and removed features, and other changes affecting compatibility: [Add deprecations, removals and changes affecting compatibility here] diff --git a/elf/dl-load.c b/elf/dl-load.c index 4998652adf..f104cc7544 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1447,6 +1447,10 @@ cannot enable executable stack as shared object requires"); /* Assign the next available module ID. */ _dl_assign_tls_modid (l); + if (l->l_seal == lt_seal_toseal + && (mode & __RTLD_DLOPEN) && !(mode & RTLD_NODELETE)) + l->l_seal = lt_seal_dont_dlopen; + #ifdef DL_AFTER_LOAD DL_AFTER_LOAD (l); #endif diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index ee68dda550..b154b14836 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -19,6 +19,7 @@ #include #include +#include /* Map a segment and align it properly. */ @@ -116,11 +117,15 @@ _dl_map_segments (struct link_map *l, int fd, if (__glibc_unlikely (loadcmds[nloadcmds - 1].mapstart < c->mapend)) return N_("ELF load command address/offset not page-aligned"); + + caddr_t hole_start = (caddr_t) (l->l_addr + c->mapend); + size_t hole_size = loadcmds[nloadcmds - 1].mapstart - c->mapend; + if (__glibc_unlikely - (__mprotect ((caddr_t) (l->l_addr + c->mapend), - loadcmds[nloadcmds - 1].mapstart - c->mapend, - PROT_NONE) < 0)) + (__mprotect (hole_start, hole_size, PROT_NONE) < 0)) return DL_MAP_SEGMENTS_ERROR_MPROTECT; + if (GLRO(dl_enable_seal) && l->l_seal == lt_seal_toseal) + _dl_mseal (hole_start, hole_size, l->l_name); } l->l_contiguous = 1; @@ -218,6 +223,12 @@ _dl_map_segments (struct link_map *l, int fd, } __set_vma_name ((void*)zeropage, zeroend - zeropage, bssname); } + + /* We need to seal this here because it will not be part of + the PT_LOAD segments, nor it is taken in RELRO + calculation. */ + if (GLRO(dl_enable_seal) && l->l_seal == lt_seal_toseal) + _dl_mseal (mapat, zeroend - zeropage, l->l_name); } } diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 05bf54bebd..2b37676182 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -28,6 +28,7 @@ #include <_itoa.h> #include #include "dynamic-link.h" +#include /* Statistics function. */ #ifdef SHARED @@ -345,6 +346,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], return; _dl_relocate_object_no_relro (l, scope, reloc_mode, consider_profiling); _dl_protect_relro (l); + _dl_mseal_map (l, false); } void @@ -369,6 +371,58 @@ cannot apply additional memory protection after relocation"); } } +static void +_dl_mseal_map_1 (struct link_map *l, bool dep) +{ + if (!GLRO(dl_enable_seal)) + return; + + /* The DEP is used internaly to memory seal audit modules after they are + dynamic loaded, since they might be unloaded if some constraints are not + met (for instance, if la_version is not supported). + For dlopen without RTLD_NODELETE, do not apply memory sealing. */ + if (l->l_seal == lt_seal_dont + || (dep + ? l->l_seal != lt_seal_dont_dlopen + : l->l_seal == lt_seal_dont_dlopen)) + return; + + if (l->l_contiguous) + _dl_mseal ((void *) l->l_map_start, l->l_map_end - l->l_map_start, + l->l_name); + else + { + /* We can use the PT_LOAD segments because even if relro splits the + original RW VMA, mseal works with multiple VMAs with different + protection flags. */ + const ElfW(Phdr) *ph; + for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph) + switch (ph->p_type) + { + case PT_LOAD: + { + ElfW(Addr) mapstart = l->l_addr + + (ph->p_vaddr & ~(GLRO(dl_pagesize) - 1)); + ElfW(Addr) allocend = l->l_addr + ph->p_vaddr + ph->p_memsz; + _dl_mseal ((void *) mapstart, allocend - mapstart, l->l_name); + } + break; + } + } + + l->l_seal = lt_seal_sealed; +} + +void +_dl_mseal_map (struct link_map *l, bool dep) +{ + if (l->l_searchlist.r_list == NULL || !dep) + _dl_mseal_map_1 (l, dep); + else + for (unsigned int i = 0; i < l->l_searchlist.r_nlist; ++i) + _dl_mseal_map_1 (l->l_searchlist.r_list[i], dep); +} + void __attribute_noinline__ _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt) diff --git a/elf/dl-support.c b/elf/dl-support.c index d8f1dd8ee9..ab74f3b51c 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -46,6 +46,7 @@ #include #include #include +#include extern char *__progname; char **_dl_argv = &__progname; /* This is checked for some error messages. */ @@ -100,6 +101,7 @@ static struct link_map _dl_main_map = .l_used = 1, .l_tls_offset = NO_TLS_OFFSET, .l_serial = 1, + .l_seal = lt_seal_dont, }; /* Namespace information. */ @@ -164,6 +166,8 @@ uint64_t _dl_hwcap4; enum dso_sort_algorithm _dl_dso_sort_algo; +bool _dl_enable_seal; + /* The value of the FPU control word the kernel will preset in hardware. */ fpu_control_t _dl_fpu_control = _FPU_DEFAULT; @@ -344,6 +348,8 @@ _dl_non_dynamic_init (void) break; } + GLRO(dl_enable_seal) = _dl_main_map.l_seal == lt_seal_toseal; + if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X) && TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL) == 0) _dl_fatal_printf ("Fatal glibc error: executable stack is not allowed\n"); @@ -352,6 +358,7 @@ _dl_non_dynamic_init (void) /* Setup relro on the binary itself. */ _dl_protect_relro (&_dl_main_map); + _dl_mseal_map (&_dl_main_map, false); } #ifdef DL_SYSINFO_IMPLEMENTATION diff --git a/elf/elf.h b/elf/elf.h index c0f61489ec..f7d38eeffb 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -1359,6 +1359,8 @@ typedef struct #define GNU_PROPERTY_STACK_SIZE 1 /* No copy relocation on protected data symbol. */ #define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 +/* No memory sealing. */ +#define GNU_PROPERTY_MEMORY_SEAL 3 /* A 4-byte unsigned integer property: A bit is set if it is set in all relocatable inputs. */ diff --git a/elf/rtld.c b/elf/rtld.c index 727e16f233..25058cb242 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -478,6 +479,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) _dl_rtld_map.l_real = &_dl_rtld_map; _dl_rtld_map.l_map_start = (ElfW(Addr)) &__ehdr_start; _dl_rtld_map.l_map_end = (ElfW(Addr)) _end; + _dl_rtld_map.l_seal = lt_seal_dont; /* Copy the TLS related data if necessary. */ #ifndef DONT_USE_BOOTSTRAP_MAP # if NO_TLS_OFFSET != 0 @@ -1023,6 +1025,10 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d); /* Mark the DSO as being used for auditing. */ dlmargs.map->l_auditing = 1; + + /* Audit modules can not be loaded with RTLD_NODELETE, so apply the sealing + after after loading (including its dependencies) */ + _dl_mseal_map (dlmargs.map, true); } /* Load all audit modules. */ @@ -1101,6 +1107,7 @@ rtld_setup_main_map (struct link_map *main_map) /* And it was opened directly. */ ++main_map->l_direct_opencount; main_map->l_contiguous = 1; + main_map->l_seal = lt_seal_dont; /* A PT_LOAD segment at an unexpected address will clear the l_contiguous flag. The ELF specification says that PT_LOAD @@ -1216,6 +1223,8 @@ rtld_setup_main_map (struct link_map *main_map) break; } + GLRO(dl_enable_seal) = main_map->l_seal == lt_seal_toseal; + /* Adjust the address of the TLS initialization image in case the executable is actually an ET_DYN object. */ if (main_map->l_tls_initimage != NULL) @@ -2318,8 +2327,10 @@ dl_main (const ElfW(Phdr) *phdr, __rtld_malloc_init_real (main_map); } - /* All ld.so initialization is complete. Apply RELRO. */ + /* All ld.so initialization is complete. Apply RELRO and memory + sealing. */ _dl_protect_relro (&_dl_rtld_map); + _dl_mseal_map (&_dl_rtld_map, false); /* Relocation is complete. Perform early libc initialization. This is the initial libc, even if audit modules have been loaded with diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h index 935d9e3baf..5119fa1321 100644 --- a/elf/setup-vdso.h +++ b/elf/setup-vdso.h @@ -66,6 +66,8 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)), /* The vDSO is always used. */ l->l_used = 1; + /* The PT_LOAD may not cover all the vdso mapping. */ + l->l_seal = lt_seal_dont; /* Initialize l_local_scope to contain just this map. This allows the use of dl_lookup_symbol_x to resolve symbols within the vdso. diff --git a/include/link.h b/include/link.h index 518bfd1670..677d82b38b 100644 --- a/include/link.h +++ b/include/link.h @@ -214,6 +214,14 @@ struct link_map lt_library map. */ unsigned int l_tls_in_slotinfo:1; /* TLS slotinfo updated in dlopen. */ + enum /* Memory sealing status. */ + { + lt_seal_dont = 0, /* Do not seal the object. */ + lt_seal_dont_dlopen, /* Do not seal from a dlopen. */ + lt_seal_toseal, /* The library is marked to be sealed. */ + lt_seal_sealed /* The library is sealed. */ + } l_seal:2; + /* NODELETE status of the map. Only valid for maps of type lt_loaded. Lazy binding sets l_nodelete_active directly, potentially from signal handlers. Initial loading of an diff --git a/sysdeps/aarch64/dl-prop.h b/sysdeps/aarch64/dl-prop.h index abca2be7fa..888308eed0 100644 --- a/sysdeps/aarch64/dl-prop.h +++ b/sysdeps/aarch64/dl-prop.h @@ -19,6 +19,8 @@ #ifndef _DL_PROP_H #define _DL_PROP_H +#include + extern void _dl_bti_protect (struct link_map *, int) attribute_hidden; extern void _dl_bti_check (struct link_map *, const char *) @@ -50,6 +52,9 @@ static inline int _dl_process_gnu_property (struct link_map *l, int fd, uint32_t type, uint32_t datasz, void *data) { + if (_dl_process_gnu_property_seal (l, fd, type, datasz, data)) + return 1; + if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { /* Stop if the property note is ill-formed. */ diff --git a/sysdeps/generic/dl-mseal.h b/sysdeps/generic/dl-mseal.h new file mode 100644 index 0000000000..b100a7cb2c --- /dev/null +++ b/sysdeps/generic/dl-mseal.h @@ -0,0 +1,22 @@ +/* Memory sealing. Generic version. + Copyright (C) 2025 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 + . */ + +static inline void +_dl_mseal (void *addr, size_t len, const char *object) +{ +} diff --git a/sysdeps/generic/dl-prop-mseal.h b/sysdeps/generic/dl-prop-mseal.h new file mode 100644 index 0000000000..36a7e71e4b --- /dev/null +++ b/sysdeps/generic/dl-prop-mseal.h @@ -0,0 +1,34 @@ +/* Support for GNU properties. Generic version. + Copyright (C) 2025 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_PROP_MSEAL_H +#define _DL_PROP_MSEAL_H + +static __always_inline bool +_dl_process_gnu_property_seal (struct link_map *l, int fd, uint32_t type, + uint32_t datasz, void *data) +{ + if (type == GNU_PROPERTY_MEMORY_SEAL && datasz == 0) + { + l->l_seal = lt_seal_toseal; + return true; + } + return false; +} + +#endif diff --git a/sysdeps/generic/dl-prop.h b/sysdeps/generic/dl-prop.h index 6d4e62ea84..ac53061dea 100644 --- a/sysdeps/generic/dl-prop.h +++ b/sysdeps/generic/dl-prop.h @@ -19,6 +19,8 @@ #ifndef _DL_PROP_H #define _DL_PROP_H +#include + /* The following functions are used by the dynamic loader and the dlopen machinery to process PT_NOTE and PT_GNU_PROPERTY entries in the binary or shared object. The notes can be used to change the @@ -47,6 +49,9 @@ static inline int __attribute__ ((always_inline)) _dl_process_gnu_property (struct link_map *l, int fd, uint32_t type, uint32_t datasz, void *data) { + if (_dl_process_gnu_property_seal (l, fd, type, datasz, data)) + return 1; + /* Continue until GNU_PROPERTY_1_NEEDED is found. */ if (type == GNU_PROPERTY_1_NEEDED) { diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 8465cbaa9b..6c8d6fadba 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -642,6 +642,8 @@ struct rtld_global_ro EXTERN enum dso_sort_algorithm _dl_dso_sort_algo; + EXTERN bool _dl_enable_seal; + #ifdef SHARED /* We add a function table to _rtld_global which is then used to call the function instead of going through the PLT. The result @@ -1021,6 +1023,14 @@ void _dl_relocate_object_no_relro (struct link_map *map, /* Protect PT_GNU_RELRO area. */ extern void _dl_protect_relro (struct link_map *map) attribute_hidden; +/* Issue memory sealing for the link map MAP. If MAP is contiguous the + whole region is sealed, otherwise iterate over the program headerrs and + seal each PT_LOAD segment.i + The DEP specify whether to seal the dependencies as well, and it is + used for the case where sealing is done after loading (for instance + for audit modules). */ +extern void _dl_mseal_map (struct link_map *map, bool dep) attribute_hidden; + /* Call _dl_signal_error with a message about an unhandled reloc type. TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R__* value. PLT is nonzero if this was a PLT reloc; it just affects the message. */ diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index ae46e0726d..a72635e340 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -652,6 +652,10 @@ sysdep-rtld-routines += \ dl-sbrk \ # sysdep-rtld-routines +dl-routines += \ + dl-mseal \ + # dl-routines + others += \ pldd \ # others diff --git a/sysdeps/unix/sysv/linux/dl-mseal.c b/sysdeps/unix/sysv/linux/dl-mseal.c new file mode 100644 index 0000000000..74ab688ef3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/dl-mseal.c @@ -0,0 +1,51 @@ +/* Memory sealing. Linux version. + Copyright (C) 2025 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 +#include +#include +#include + +void +_dl_mseal (void *addr, size_t len, const char *object) +{ + int r = 0; + bool fail = false; +#if __ASSUME_MSEAL + r = INTERNAL_SYSCALL_CALL (mseal, addr, len, 0); + fail = r != 0; +#else + static int mseal_supported = true; + /* Avoid issuing mseal again if it is not supported by the kernel. */ + if (atomic_load_relaxed (&mseal_supported)) + { + int r = INTERNAL_SYSCALL_CALL (mseal, addr, len, 0); + if (r == -ENOSYS) + atomic_store_relaxed (&mseal_supported, false); + else + fail = r != 0; + } +#endif + if (fail) + { + static const char errstring[] = N_("\ +cannot apply memory sealing"); + _dl_signal_error (-r, DSO_FILENAME (object), NULL, errstring); + } +} diff --git a/sysdeps/unix/sysv/linux/dl-mseal.h b/sysdeps/unix/sysv/linux/dl-mseal.h new file mode 100644 index 0000000000..b0a9e9523d --- /dev/null +++ b/sysdeps/unix/sysv/linux/dl-mseal.h @@ -0,0 +1,31 @@ +/* Memory sealing. Linux version. + Copyright (C) 2025 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_MSEAL_H +#define _DL_MSEAL_H + +/* Seal the ADDR or size LEN to protect against fruthermodifications, such as + changes on the permission flags (through mprotect), remap (through + mmap and/or remap), shrink, destruction changes (madvise with + MADV_DONTNEED), or change its size. The input has the same constraints + as the mseal syscall. + + Any error than than unsupported by the kerneltriggers a _dl_signal_error. */ +void _dl_mseal (void *addr, size_t len, const char *object) attribute_hidden; + +#endif diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h index 9a5e10821c..e9e1940530 100644 --- a/sysdeps/x86/dl-prop.h +++ b/sysdeps/x86/dl-prop.h @@ -19,6 +19,7 @@ #ifndef _DL_PROP_H #define _DL_PROP_H +#include #include extern void _dl_cet_check (struct link_map *, const char *) @@ -243,6 +244,9 @@ _dl_process_gnu_property (struct link_map *l, int fd, uint32_t type, uint32_t datasz, void *data) { /* This is called on each GNU property. */ + if (_dl_process_gnu_property_seal (l, fd, type, datasz, data)) + return 1; + unsigned int needed_1 = 0; unsigned int feature_1_and = 0; unsigned int isa_1_needed = 0; From patchwork Tue Mar 11 17:09:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872466 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1596267wri; Tue, 11 Mar 2025 10:19:15 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWrU9MVfrkvWyblooAWaKkw2Kw2RxQ8nI/aWDj9igO6G+zxm8RPwnl4R79JJekKcBD+zQpDhQ==@linaro.org X-Google-Smtp-Source: AGHT+IFkiePgxvrVmPoGXzePuW9J1O5G1ELQ6jXWLbhTqkGBDdUbPxEF5MtDUfdr+AW3rhzL35+6 X-Received: by 2002:a05:6102:a54:b0:4c1:b3a5:9fa with SMTP id ada2fe7eead31-4c30a6d2076mr11903084137.16.1741713555458; Tue, 11 Mar 2025 10:19:15 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713555; cv=pass; d=google.com; s=arc-20240605; b=ClMX0BdXsVe0T5XC/OI3QSACgB7nYvsUX5PDp04dn4UVYXv3p/mjz4oPt/lKte+NcB 3ZCNPRLrZYT2/UCVt7FRH5Ya7rwwcBTHFXO2Hwfp55SlArr3V74Qjsa9tTeSHfcItcvh RHAEY0CjXYkAel0FXlDrsbDXdle+btWTT22OGPqfN8UFhTXA3hKJ+Ojd+mh2GZi9aOev EErI35Xr22xSKNW/Z3o5TZdFpZD4vl46v5PigeeEj2KuqKgCOAW4AZRox0tUOHN4hhIt Xs1dj7GzEF/aJbY9h+IoSantf51lbn41Xz+tWEhftufIqfA/zhAHWh+xALZpVZrxx7L6 x1Lw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=Ict4xh+DXxkVkPFu5vpkKgS/fbpOwvrAHBBj+H+Gsf4=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=J8kpM5lRbs7E30yVlhsSv+n4RxAYU/8d82BytFFXAduADQ8IPI+gYZCCkBi7LrnmKQ HJYeItuk/HLgoaxS8UAIMVVQVWjOhZc8KHcfJ0JSraE7fR/1yrw/4hzBORQZZfm0XcrG wcTJo74vynlY0kr0tsSr6n+RNsG0akkDr4kmJ+qJe9W9D3aj4oHU29edVoecxtDVSJsT 4uNloeGHZ7+WopTUXDwDgo2RQ4mz6G9svVTkByXqUroZdE6Tn2x/vbmQ3QQIiRl1SufB gfLBm2ySQ6dPolRD3mKSPUL0YDh+zRcX1NNo5sS6Gp5QvE0hQMJ3lzdOZeQOalnGy7FG kNYg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mfPcAgr9; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id ada2fe7eead31-4c30c1e6c5asi2271390137.419.2025.03.11.10.19.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:19:15 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mfPcAgr9; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 89EA03857BA7 for ; Tue, 11 Mar 2025 17:19:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 89EA03857BA7 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=mfPcAgr9 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by sourceware.org (Postfix) with ESMTPS id A0E223857838 for ; Tue, 11 Mar 2025 17:13:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A0E223857838 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 A0E223857838 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1033 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713206; cv=none; b=ifKOGNE1peM/PKzkDRkQtONH5LFvzoVnZcb7R5P9oEzDa5M/MZDCaburlm7EJhQ79F9bTGU2NUID6/CeHterTIyta01qCcTcRr6m4UCgPDG6yB3Jt5YRW9FOcD8J1G4dv00e2MGg/6m5dqx7fmviyVD+T4Sob+q/MLU5QR6w+k8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713206; c=relaxed/simple; bh=JAlp5064dOB12re6bGkvg6yaNYsReC2ChCXUibrMBhg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=VhxaJvfbdvxgyEiPcDgDBE1Zu0xaVgfCPORpeIPf6PYXTG+pA2VFwQUrYByA/nzhTvNdQp5WYA84iJgp1ig7nRQmfFzFEnWRiFyyRs316UOY48XafySOUdqfiMlA8mF8549FQEj8N9hP9godcJHoP5+ITB62ilNBZkcw4wVyEMA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A0E223857838 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-2ff6e91cff5so8402147a91.2 for ; Tue, 11 Mar 2025 10:13:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713205; x=1742318005; 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=Ict4xh+DXxkVkPFu5vpkKgS/fbpOwvrAHBBj+H+Gsf4=; b=mfPcAgr9ft0E571AJmsbhCnKAIbrOVWf/BbvaRWPrX14ywddb16uxPnTxLaJSAsi9Z nzZo4GMOOSjKqDIiYPEO3Vide/eEG7ydTSVH/G/G1j21T+c7tEmSTw+wmZMmAr67ErlY Ipu+hBgiQXmrBIzltAczCaNTr7lLWNjlHColdfp8GtUNEoXR2mNUnJZjCeIR0t5cbAFA moSiTb1ib7MYEoysJc3fcO01GbtjdnvnygfzAWeL/RBxnzSCAY83G+9/AbJ5ArlFIIzP 5nrXZ1sdcsKrxU5BOR8/nHAtitmzODmCLRVQ1kI4ZnMGqDq8MC7mLDbqWZChbKndSDdJ nrYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713205; x=1742318005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ict4xh+DXxkVkPFu5vpkKgS/fbpOwvrAHBBj+H+Gsf4=; b=ltrL/tsoxYllSQ6g66J/v3OHkAtwDcNjO49mGqvgDe4jHx0FkKAKSw3iVRwstZsSFk po3T0wZQ7l3/fo8qtkvKGKE6T40bHAf98R1cALMdyG1Rk7lr/kteEJFoDLKMIHIDrn8+ jHB9ThHm91yC5GD8y7FLhKdk+M6etxfMMmomEvtsDlYTnL35RJaVaGkrsmn9JowfRpnJ tqzoZzExMPtXjPkKEFRkO+gXLLc9ytUesIej0N7qfYprAfedpeRnElRfWfoXQDxj1KVA L+RY/LscGHchDPXeoNFUWYNBc2BiuSpjpR3hnSYQRdesXW+/NUeE4AD4HXUUxZJFJL0L 6BHw== X-Gm-Message-State: AOJu0Yye9XHWKjmpmwxaS/lxoe5uj+9gn914K6YuamEEkuLFLNSvOyTI pC0yA+YKZXL5EqIDbmKapoEAB9YsSJ8bd2FCBWv3OKYufE+oA6DCOpn72YpSSpB6lgUFcnlm8iV b X-Gm-Gg: ASbGncve7vWnAEI20wSDIIMPkx3A4tb1HZdx95UsiVMrPQ90PKNiR00s5FAim/W1f7c mVwOGT/AExRxy8kp1/XczSHHa5Fe0D2i0dDmdW6PoM87acj/zJ15ih1gmt0SIkbCxl9vaMmgEZg XkcgkRdAp+SsvQ+wA7IMWzIeSq8XRgdec9yfuwuo4iN0CDG5h2vigiAvKDhb+fykcVUgXRWXpcQ O1EOUexVUqIs+w7OFEMAkDqvMV1uNOup/eHAYc6xan+kebcltFW3LyN5zm/OOF0xkVvHaWk2+cc 1Ee71qxIMkvHhN2BOSaB+oHogFGVIIcwIApEW4USlCHESmbfUWYz1LE= X-Received: by 2002:a17:90b:38cd:b0:2ee:741c:e9f4 with SMTP id 98e67ed59e1d1-2ff7ce8e5dfmr27902066a91.11.1741713205168; Tue, 11 Mar 2025 10:13:25 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:24 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 6/9] Add --enable-memory-sealing configure option Date: Tue, 11 Mar 2025 14:09:53 -0300 Message-ID: <20250311171305.89091-7-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org It allows all libraries, programs, and the testsuite in glibc to be built with memory sealing if the toochain supports it. The default is disabled. Checked on aarch64-linux-gnu and x86_64-linux-gnu. --- INSTALL | 6 +++++ Makeconfig | 19 ++++++++++++++- Makerules | 2 ++ NEWS | 3 +++ configure | 57 ++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 19 +++++++++++++++ elf/Makefile | 19 +++++++++++---- manual/install.texi | 5 ++++ 8 files changed, 124 insertions(+), 6 deletions(-) diff --git a/INSTALL b/INSTALL index a56179a9c9..0c8e20f605 100644 --- a/INSTALL +++ b/INSTALL @@ -251,6 +251,12 @@ passed to 'configure'. For example: Disable using 'scv' instruction for syscalls. All syscalls will use 'sc' instead, even if the kernel supports 'scv'. PowerPC only. +'--enable-memory-sealing' + Build glibc libraries, programs, and the testsuite with memory + sealing support (GNU_PROPERTY_MEMORY_SEAL). It does not disable + support for memory sealing, which will still be applied if the + program has the attribute. + '--build=BUILD-SYSTEM' '--host=HOST-SYSTEM' These options are for cross-compiling. If you specify both options diff --git a/Makeconfig b/Makeconfig index aa547a443f..1b0a9d95f1 100644 --- a/Makeconfig +++ b/Makeconfig @@ -389,6 +389,21 @@ dt-relr-ldflag = no-dt-relr-ldflag = endif +# Linker options to enable and disable memory sealing (GNU_PROPERTY_MEMORY_SEAL), +# if --enable--memory-sealing is used explicit enable memory sealing for the case +# the linker defaults to it. +ifeq ($(have-z-memory-seal),yes) +no-memory-seal-ldflag = -Wl,-z,nomemory-seal +ifeq ($(enable-memory-seal),yes) +memory-seal-ldflag = -Wl,-z,memory-seal +else +memory-seal-ldflag = $(no-memory-seal-ldflag) +endif +else +memory-seal-ldflag = +no-memory-seal-ldflag = +endif + ifeq (no,$(build-pie-default)) pie-default = $(no-pie-ccflag) else # build-pie-default @@ -433,6 +448,7 @@ link-extra-libs-tests = $(libsupport) ifndef +link-pie +link-pie-before-inputs = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(dt-relr-ldflag)) \ + $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \ -Wl,-O1 -nostdlib -nostartfiles \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ @@ -466,6 +482,7 @@ ifndef +link-static +link-static-before-inputs = -nostdlib -nostartfiles -static \ $(if $($(@F)-no-pie),$(no-pie-ldflag),$(static-pie-ldflag)) \ $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(static-pie-dt-relr-ldflag)) \ + $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \ $(+preinit) $(+prectorT) @@ -542,7 +559,7 @@ endif # +link # Command for linking test programs with crt1.o from glibc 2.0. +link-2.0-before-inputs = -nostdlib -nostartfiles $(no-pie-ldflag) \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ - $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ + $(relro-LDFLAGS) $(memory-seal-ldflag) $(hashstyle-LDFLAGS) \ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-name-2.0)) \ $(+preinit) $(+prector) +link-2.0-before-libc = -o $@ $(+link-2.0-before-inputs) \ diff --git a/Makerules b/Makerules index ada616891e..02ce3949cf 100644 --- a/Makerules +++ b/Makerules @@ -544,6 +544,7 @@ define build-shlib-helper $(LINK.o) -shared -static-libgcc -Wl,-O1 $(sysdep-LDFLAGS) \ $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) $(rtld-LDFLAGS) \ $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(dt-relr-ldflag)) \ + $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \ $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \ $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \ -Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \ @@ -560,6 +561,7 @@ define build-module-helper $(LINK.o) -shared -static-libgcc $(sysdep-LDFLAGS) $(rtld-LDFLAGS) \ $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) \ $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(dt-relr-ldflag)) \ + $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \ -B$(csu-objpfx) $(load-map-file) \ $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \ $(link-test-modules-rpath-link) \ diff --git a/NEWS b/NEWS index fc460ede05..ff241b2863 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ Major new features: memory sealing will not be applied for its dependencies (and even if the objects has the memory sealing attribute). +* A new configure option, "--enable-memory-sealing", can be used to build + the GNU C Library libraries and programs with memory sealing. + Deprecated and removed features, and other changes affecting compatibility: [Add deprecations, removals and changes affecting compatibility here] diff --git a/configure b/configure index 80b4a63f1b..dda60ed91d 100755 --- a/configure +++ b/configure @@ -820,6 +820,7 @@ enable_mathvec enable_cet enable_scv enable_fortify_source +enable_memory_sealing with_cpu ' ac_precious_vars='build_alias @@ -1505,6 +1506,8 @@ Optional Features: Use -D_FORTIFY_SOURCE=[1|2|3] to control code hardening, defaults to highest possible value supported by the build compiler. + --enable-memory-sealing Build glibc libraries, programs, and the testsuite + with memory sealing [default=no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -4883,6 +4886,16 @@ case "$enable_fortify_source" in *) as_fn_error $? "Not a valid argument for --enable-fortify-source: \"$enable_fortify_source\"" "$LINENO" 5;; esac +# Check whether --enable-memory-sealing was given. +if test ${enable_memory_sealing+y} +then : + enableval=$enable_memory_sealing; enable_memory_sealing=$enableval +else case e in #( + e) enable_memory_sealing=no ;; +esac +fi + + # We keep the original values in `$config_*' and never modify them, so we # can write them unchanged into config.make. Everything else uses # $machine, $vendor, and $os, and changes them whenever convenient. @@ -7410,6 +7423,49 @@ printf "%s\n" "$libc_cv_fpie" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z memory-seal" >&5 +printf %s "checking for linker that supports -z memory-seal... " >&6; } +libc_linker_feature=no +cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then + if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,memory-seal -nostdlib \ + -nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \ + | grep "warning: -z memory-seal ignored" > /dev/null 2>&1; then + true + else + libc_linker_feature=yes + fi +fi +rm -f conftest* +if test $libc_linker_feature = yes; then + libc_cv_z_memory_seal=yes +else + libc_cv_z_memory_seal=no +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5 +printf "%s\n" "$libc_linker_feature" >&6; } +# Enable memory-sealing iff it is available and glibc is not configured +# with --disable-defautl-memory-sealing +if test "$libc_cv_z_memory_seal" = no; then + default_memory_sealing=no +fi +config_vars="$config_vars +have-z-memory-seal = $libc_cv_z_memory_seal" +config_vars="$config_vars +enable-memory-seal = $enable_memory_sealing" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5 printf %s "checking for GLOB_DAT reloc... " >&6; } if test ${libc_cv_has_glob_dat+y} @@ -8945,7 +9001,6 @@ load-address-ldflag = $libc_cv_load_address_ldflag" # Check if compilers support GCS in branch protection: - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports -mbranch-protection=gcs" >&5 printf %s "checking if compiler supports -mbranch-protection=gcs... " >&6; } if test ${libc_cv_cc_gcs+y} diff --git a/configure.ac b/configure.ac index 7d04b54c98..d514179e1b 100644 --- a/configure.ac +++ b/configure.ac @@ -440,6 +440,12 @@ case "$enable_fortify_source" in *) AC_MSG_ERROR([Not a valid argument for --enable-fortify-source: "$enable_fortify_source"]);; esac +AC_ARG_ENABLE([memory-sealing], + AS_HELP_STRING([--enable-memory-sealing], + [Build glibc libraries, programs, and the testsuite with memory sealing @<:@default=no@:>@]), + [enable_memory_sealing=$enableval], + [enable_memory_sealing=no]) + # We keep the original values in `$config_*' and never modify them, so we # can write them unchanged into config.make. Everything else uses # $machine, $vendor, and $os, and changes them whenever convenient. @@ -1360,6 +1366,19 @@ LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no]) AC_SUBST(libc_cv_fpie) +LIBC_LINKER_FEATURE([-z memory-seal], + [-Wl,-z,memory-seal], + [libc_cv_z_memory_seal=yes], + [libc_cv_z_memory_seal=no]) +# Enable memory-sealing iff it is available and glibc is not configured +# with --disable-defautl-memory-sealing +if test "$libc_cv_z_memory_seal" = no; then + default_memory_sealing=no +fi +LIBC_CONFIG_VAR([have-z-memory-seal], [$libc_cv_z_memory_seal]) +LIBC_CONFIG_VAR([enable-memory-seal], [$enable_memory_sealing]) + + AC_CACHE_CHECK(for GLOB_DAT reloc, libc_cv_has_glob_dat, [dnl cat > conftest.c < $@ 2>&1; $(evaluate-test) diff --git a/manual/install.texi b/manual/install.texi index d001e8220b..7056768885 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -280,6 +280,11 @@ C++ libraries. Disable using @code{scv} instruction for syscalls. All syscalls will use @code{sc} instead, even if the kernel supports @code{scv}. PowerPC only. +@item --disable-default-memory-seal +Don't build glibc libraries, programs, and the testsuite with +memory sealing support (@code{GNU_PROPERTY_MEMORY_SEAL}). By default, +memory sealing is enabled if toolchain suports the linker option. + @item --build=@var{build-system} @itemx --host=@var{host-system} These options are for cross-compiling. If you specify both options and From patchwork Tue Mar 11 17:09:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872469 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1597814wri; Tue, 11 Mar 2025 10:22:49 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVIAKy4Vd3JI5YG26COKwpLgx8qrlH9nUhqnVY1GG6ACcRwP9+Aop3LjKgGYVwLHyQxpxJ9TQ==@linaro.org X-Google-Smtp-Source: AGHT+IGbpKlCoDwQubvsz425TpHhMLejdb/GX4KRbC3VBORELZFo+8YvUnN48zk515+r1wZxZeY3 X-Received: by 2002:a05:6214:20cf:b0:6e4:4484:f357 with SMTP id 6a1803df08f44-6e9006adc5amr195827776d6.30.1741713769452; Tue, 11 Mar 2025 10:22:49 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713769; cv=pass; d=google.com; s=arc-20240605; b=ShtLTRCR1PJ4rYPWKJiVJoKlV+eGsxKbKxkcjJAz3GtGuFkoKDts1a9xArvi8KIQtG Ir7ogGsW2xA3qXKmOAV++bRjHnELx7TEgtGSBorrDUpT8xMNzdToR3oAH/UzYb/rFg0a Hbzt1wGTl5hPOuHiJUE9ka+4ISmC2d8YFDHkN/tOvWPC+Nz9dG1gZ6cFlvVUmwz526cx CAt3h5cuVcA+qUyXpNDcYZOOkKtpjLfPiRWP3G9KEp88xaz3t/iW9H7mOV2/vkVTH9uq C9L7nMIpc2RB/qmMe7F5wxmi+vmn2gQITVZ4yrOrwfsWyxuY/N9HJyXWa7NHFalpqHkV gYcA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=oNaGxGf3NFXAIz8+wRf6wbrE20ueQGVRP1/m51Cb5x0=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=Gvn28JZHfRukRrL45JIoSu7rcUiBen4HRFRHolcpNTN7NS7eHo+LORp1zSagEOqEsS AnduZzsbBoF3fpXdZECH6sbfV/DI0KvA6qqpHd7UjSPEvUUePx9ncTaoQSZC18ViQGLQ 117ysX/IhQeCLg+3n4MyjJ7ONjzNG5Qw91nQOBSHo+5q+wuEy9AiZso+QE1asI/jatk0 QbQgkXDcfngxHH1VCuxe/dgyjZbPlS7Nhdb/94ZTj8J91ax9o5X6hLU0lppJ6Rv6ECA1 rXYtzYS/oQ3rC6BP18eCQ7zwulItwsIZfpEdSNNTwpzX9Xeg3qGBzvXniBxTrfATyAif KOQw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=nu6d5lpl; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id 6a1803df08f44-6e908cd45d7si77827816d6.101.2025.03.11.10.22.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:22:49 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=nu6d5lpl; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 006A63857711 for ; Tue, 11 Mar 2025 17:22:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 006A63857711 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=nu6d5lpl X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by sourceware.org (Postfix) with ESMTPS id B58153857719 for ; Tue, 11 Mar 2025 17:13:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B58153857719 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 B58153857719 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::102e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713210; cv=none; b=T5xps0VquT3YQJOk04U2EhA0Pdr+MfyanwUaBdyo0Zpql/PakAuP1RiM5+9z7zowqmyFGD6T2Hkkd8jOkMNfS8uHr7xviIfCIV15Sh6Jvba+DKxcovUivPchnFQaZbZKay/SGmMbCjSO05WtseixSXYZoX42FV3aUmgoi22Z9iw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713210; c=relaxed/simple; bh=mh2TjsIQxUMQfz12OPkykzq2w/RztTiPSOy86WP+gEE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=G+o278EmHQEOdrDM0XskXU68FDQ9KcSbDzN29GB5PKMAa0DUUn4pX9lnu0kIMCXksyZJh+WsQz9OfrmNCyBqcpuIJEPmKOzSzIBNKSel1llhpTdrJ+OanF5cVtbO4yv79rdWcHqn6fIDjYF9gMk82tlyUJ8VL1FrtUv4K8yCb0g= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B58153857719 Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-2fa8ac56891so8675947a91.2 for ; Tue, 11 Mar 2025 10:13:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713208; x=1742318008; 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=oNaGxGf3NFXAIz8+wRf6wbrE20ueQGVRP1/m51Cb5x0=; b=nu6d5lpldbyz1ahCbF8sVWbVN6J6d0DRaGzb+/TdsYUsgi7dIGjUhT8nkC5CCYS5qw 1GSZGOBPcnwzIniPUshXHEzY6jjQ4x1wcu7MhflXpqEZzTBawD7nSPT7aAmjyMQcEnCd N/gXL8AfFwTw6ws7PDxRFx5AexDqTDqjHP1I6yQSFK6nNkpoPuKW0RhJBg92XERNF3HJ E8H187e/NwAbwTL+4wwISyI/UmU7KhxtNyLov/5YDRR/RxftlvyQjvTfC4/XodJHXX8P vbWb+3S7VJctvw/8K/DNvsQOOGlERoj4H4pjNTTLiFQPEfRQMLvDhSphmNs+xVj6ZKmL MEOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713208; x=1742318008; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oNaGxGf3NFXAIz8+wRf6wbrE20ueQGVRP1/m51Cb5x0=; b=ZkzyvchLIzP1Ehbq6s4wUhsCSX0xwcP8N7Yfj8R4G6cQ+M1KApwyrP4uCjMDdjlomr ImSMswE3OZ5STzgppr64PL+Q62yTME8ZuLAEKMfpfMMS4bohAyFZMkr+fvbjWFZnJkDL BVQ6+G26o8VG8fLsq+izkvbDKwe6GKuX317nSMnfL9JFIkwrveSBcymjutH9EoiUrtE8 dvkh4EckR+34pQNB1X8nNTIFdseg08R7rp1HyivFOUQxstILCMUc7iS0mCjtHcG1Gf6p 9m7qkxLPJO2EAeVQkmNyeeVr4tL+Gi4RbYbdysT+UZE7K4JJPTh/4Yeg1+izWOxG/m5V x7jg== X-Gm-Message-State: AOJu0Yw9v21jrJqQRNZe1PZM+ksptxZYY7T6Qtv5ESH0thorDxUhYS63 sn8Ot2FNZtPzdpv9k98K3NdyBhETRjIRY72AgEYY7+d0tvDb3oyOSEMN+WR7K3+Z52+PI0dnnPE v X-Gm-Gg: ASbGncsm7EkAQpdze4kMl1hjwN88NMrV9sEA3nAmltH2eJVAy4EY8346k22WysYu7K7 3Jq5d3P1H60FEukg9VbKYNa86plnrNciU6/enmsZQ9VRJLelFy8d/JAmkJ1Hu9ZZeVXBb4qe3rZ leTOkPKNlf/o/1m4RLCAHiWV3uAmGkEn48srew2YAw+D2bcry1GMv9DGt35LsA8d5Iyw5CJoZJy PgYsgHCGaA3Fx0JW+44WWfKNhxVQ1r8/JEQBFXElkACORlPPkZa9kI3QovF3a2roH0d7J20HohA miYJBGH+TaW2qgntgazpMkx41oNtN21/8Qtv4bh29X7Aq9jXkVQHwzD8PKPdgzjBmQ== X-Received: by 2002:a17:90a:e7ce:b0:2ff:58a4:9db3 with SMTP id 98e67ed59e1d1-2ff7cf25652mr27497107a91.35.1741713207710; Tue, 11 Mar 2025 10:13:27 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:27 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 7/9] linux: Add memory sealing tests Date: Tue, 11 Mar 2025 14:09:54 -0300 Message-ID: <20250311171305.89091-8-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org The new tests added are: 1. tst-dl_mseal: check memory sealing is applied for statically linked binaries. 2. tst-dl_mseal-static: memory sealing is not applied if there is no gnu attribute for statically linked binaries. 3. tst-dl-mseal: check memory sealing works as expected on multiples places: - On the binary itself. - On a LD_PRELOAD library. - On a depedency modules (tst-dl_mseal-mod-{1,2}.so). - On a audit modules (tst-dl_mseal-auditmod.so). - On a dlopen dependency opened with RTLD_NODELETE). - On the libgcc_s Aopened by thread unwind. 4. tst-dl-mseal-noseal: check if mixing object with and without memory sealing works as expected. Checked on x86_64-linux-gnu and aarch64-linux-gnu. --- sysdeps/unix/sysv/linux/Makefile | 78 ++++++ .../unix/sysv/linux/tst-dl_mseal-auditmod.c | 23 ++ sysdeps/unix/sysv/linux/tst-dl_mseal-common.h | 29 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-1.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-2.c | 19 ++ sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c | 19 ++ sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c | 19 ++ sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c | 90 ++++++ .../unix/sysv/linux/tst-dl_mseal-preload.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-skeleton.c | 263 ++++++++++++++++++ .../sysv/linux/tst-dl_mseal-static-noseal.c | 59 ++++ sysdeps/unix/sysv/linux/tst-dl_mseal-static.c | 56 ++++ sysdeps/unix/sysv/linux/tst-dl_mseal.c | 92 ++++++ 15 files changed, 823 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-common.h create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-static.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal.c diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index a72635e340..8fe74be95f 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -687,6 +687,84 @@ tests-special += \ $(objpfx)tst-nolink-libc-2.out \ # tests-special endif + +ifeq ($(have-z-memory-seal),yes) +tests-static += \ + tst-dl_mseal-static \ + tst-dl_mseal-static-noseal \ + # tests-static + +tests += \ + $(tests-static) \ + tst-dl_mseal \ + tst-dl_mseal-noseal \ + # tests + +modules-names += \ + tst-dl_mseal-auditmod \ + tst-dl_mseal-dlopen-1 \ + tst-dl_mseal-dlopen-1-1 \ + tst-dl_mseal-dlopen-2 \ + tst-dl_mseal-dlopen-2-1 \ + tst-dl_mseal-mod-1 \ + tst-dl_mseal-mod-2 \ + tst-dl_mseal-preload \ + # modules-names + +$(objpfx)tst-dl_mseal.out: \ + $(objpfx)tst-dl_mseal-auditmod.so \ + $(objpfx)tst-dl_mseal-preload.so \ + $(objpfx)tst-dl_mseal-mod-1.so \ + $(objpfx)tst-dl_mseal-mod-2.so \ + $(objpfx)tst-dl_mseal-dlopen-1.so \ + $(objpfx)tst-dl_mseal-dlopen-1-1.so \ + $(objpfx)tst-dl_mseal-dlopen-2.so \ + $(objpfx)tst-dl_mseal-dlopen-2-1.so + +$(objpfx)tst-dl_mseal-noseal.out: \ + $(objpfx)tst-dl_mseal-auditmod.so \ + $(objpfx)tst-dl_mseal-preload.so \ + $(objpfx)tst-dl_mseal-mod-1.so \ + $(objpfx)tst-dl_mseal-mod-2.so \ + $(objpfx)tst-dl_mseal-dlopen-1.so \ + $(objpfx)tst-dl_mseal-dlopen-1-1.so \ + $(objpfx)tst-dl_mseal-dlopen-2.so \ + $(objpfx)tst-dl_mseal-dlopen-2-1.so + +ifeq ($(enable-memory-seal),yes) +CFLAGS-tst-dl_mseal.c += -DDEFAULT_MEMORY_SEAL +CFLAGS-tst-dl_mseal-noseal.c += -DDEFAULT_MEMORY_SEAL +endif + +LDFLAGS-tst-dl_mseal = -Wl,--no-as-needed -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-static = -Wl,--no-as-needed -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-mod-1.so = -Wl,--no-as-needed -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-mod-2.so = -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-dlopen-1.so = -Wl,--no-as-needed +LDFLAGS-tst-dl_mseal-dlopen-2.so = -Wl,--no-as-needed -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-preload.so = -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-auditmod.so = -Wl,-z,memory-seal + +tst-dl_mseal-noseal-no-memory-seal = yes +tst-dl_mseal-dlopen-1-1.so-no-memory-seal = yes +tst-dl_mseal-dlopen-2-1.so-no-memory-seal = yes + +$(objpfx)tst-dl_mseal: $(objpfx)tst-dl_mseal-mod-1.so +$(objpfx)tst-dl_mseal-noseal: $(objpfx)tst-dl_mseal-mod-1.so +$(objpfx)tst-dl_mseal-mod-1.so: $(objpfx)tst-dl_mseal-mod-2.so +$(objpfx)tst-dl_mseal-dlopen-1.so: $(objpfx)tst-dl_mseal-dlopen-1-1.so +$(objpfx)tst-dl_mseal-dlopen-2.so: $(objpfx)tst-dl_mseal-dlopen-2-1.so + +LDFLAGS-tst-dl_mseal-noseal = -Wl,--no-as-needed + +tst-dl_mseal-static-noseal-no-memory-seal = yes + +tst-dl_mseal-ARGS = -- $(host-test-program-cmd) +tst-dl_mseal-static-ARGS = -- $(host-test-program-cmd) +tst-dl_mseal-noseal-ARGS = -- $(host-test-program-cmd) +tst-dl_mseal-static-noseal-ARGS = -- $(host-test-program-cmd) +endif + endif # $(subdir) == elf ifeq ($(subdir),rt) diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c new file mode 100644 index 0000000000..7767620456 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c @@ -0,0 +1,23 @@ +/* Audit module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +unsigned int +la_version (unsigned int v) +{ + return v; +} diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-common.h b/sysdeps/unix/sysv/linux/tst-dl_mseal-common.h new file mode 100644 index 0000000000..4e2461b889 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-common.h @@ -0,0 +1,29 @@ +/* Basic tests for sealing. + Copyright (C) 2025 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 + . */ + +#define LIB_PRELOAD "tst-dl_mseal-preload.so" + +#define LIB_AUDIT "tst-dl_mseal-auditmod.so" + +#define LIB_MODULE1 "tst-dl_mseal-mod-1.so" +#define LIB_MODULE1_DEP "tst-dl_mseal-mod-2.so" + +#define LIB_DLOPEN_DEFAULT "tst-dl_mseal-dlopen-1.so" +#define LIB_DLOPEN_DEFAULT_DEP "tst-dl_mseal-dlopen-1-1.so" +#define LIB_DLOPEN_NODELETE "tst-dl_mseal-dlopen-2.so" +#define LIB_DLOPEN_NODELETE_DEP "tst-dl_mseal-dlopen-2-1.so" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c new file mode 100644 index 0000000000..fd116536ee --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c @@ -0,0 +1,19 @@ +/* Additional module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +int foo2_1 (void) { return 42; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c new file mode 100644 index 0000000000..aa7a18390e --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c @@ -0,0 +1,19 @@ +/* Additional module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +int foo2 (void) { return 42; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c new file mode 100644 index 0000000000..dc3d832343 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c @@ -0,0 +1,19 @@ +/* Additional module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +int bar2_1 (void) { return 42; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c new file mode 100644 index 0000000000..6be7ce4d3d --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c @@ -0,0 +1,19 @@ +/* Additional module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +int bar2 (void) { return 42; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c new file mode 100644 index 0000000000..e8e42de5bf --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c @@ -0,0 +1,19 @@ +/* Additional module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +int foo1 (void) { return 42; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c new file mode 100644 index 0000000000..05226a443d --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c @@ -0,0 +1,19 @@ +/* Additional module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +int bar1 (void) { return 42; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c new file mode 100644 index 0000000000..686347c86e --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c @@ -0,0 +1,90 @@ +/* Basic tests for sealing. + Copyright (C) 2025 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 +#include + +/* Check if memory sealing is not applied if program does not have the + GNU_PROPERTY_MEMORY_SEAL attribute. It included: + - On the binary itself. + - On a LD_PRELOAD library. + - On a dependency modules (tst-dl_mseal-mod-{1,2}.so). + - On a audit modules (tst-dl_mseal-auditmod.so). + - On a dlopen dependency opened with RTLD_NODELETE + (tst-dl_mseal-dlopen-{2,2-1}.so). + - On the libgcc_s opened by thread unwind. */ + +#include "tst-dl_mseal-common.h" + +/* Expected libraries that loader will seal. */ +static const char *expected_sealed_vmas[] = +{ + "", +}; + +/* Expected non sealed libraries. */ +static const char *expected_non_sealed_vmas[] = +{ + "libc.so", + "ld.so", + "tst-dl_mseal-noseal", + LIB_PRELOAD, + LIB_AUDIT, + LIB_MODULE1, + LIB_MODULE1_DEP, + LIB_DLOPEN_NODELETE, + LIB_DLOPEN_NODELETE_DEP, + LIB_DLOPEN_DEFAULT, + LIB_DLOPEN_DEFAULT_DEP, + /* Auxiliary pages mapped by the kernel. */ + "[vdso]", + "[sigpage]", +}; + +/* Special pages, either Auxiliary kernel pages where permission can not be + changed or auxiliary libs that we can know prior hand that sealing is + enabled. */ +static const char *expected_non_sealed_special[] = +{ + LIBGCC_S_SO, + "[vectors]", +}; + +static void * +tf (void *closure) +{ + pthread_exit (NULL); + return NULL; +} + +static void +run_extra_steps (void) +{ + /* dlopen should work even if the modules contains the sealing attribute. */ + xdlopen (LIB_DLOPEN_NODELETE, RTLD_NOW | RTLD_NODELETE); + xdlopen (LIB_DLOPEN_DEFAULT, RTLD_NOW); + + /* pthread_exit will load LIBGCC_S_SO. */ + xpthread_join (xpthread_create (NULL, tf, NULL)); +} + +#define LD_PRELOAD LIB_PRELOAD +#define LD_AUDIT LIB_AUDIT + +#include "tst-dl_mseal-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c new file mode 100644 index 0000000000..414c8c7295 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c @@ -0,0 +1,19 @@ +/* Additional module for tst-dl_mseal test. + Copyright (C) 2025 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 + . */ + +int foo (void) { return 42; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c new file mode 100644 index 0000000000..570a0a867d --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c @@ -0,0 +1,263 @@ +/* Basic tests for memory sealing. + Copyright (C) 2025 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if UINTPTR_MAX == UINT64_MAX +# define PTR_FMT "#018" PRIxPTR +#else +# define PTR_FMT "#010" PRIxPTR +#endif + +static int +new_flags (const char flags[4]) +{ + bool read_flag = flags[0] == 'r'; + bool write_flag = flags[1] == 'w'; + bool exec_flag = flags[2] == 'x'; + + write_flag = !write_flag; + + return (read_flag ? PROT_READ : 0) + | (write_flag ? PROT_WRITE : 0) + | (exec_flag ? PROT_EXEC : 0); +} + +/* Libraries/VMA that could not be sealed, and that checking for sealing + does not work (kernel does not allow changing protection). */ +static const char *non_sealed_vmas[] = +{ + ".", /* basename value for empty string anonymous + mappings. */ + "[heap]", + "[vsyscall]", + "[vvar]", + "[stack]", + "[vvar_vclock]", + "zero", /* /dev/zero */ +}; + +static int +is_in_string_list (const char *s, const char *const list[], size_t len) +{ + for (size_t i = 0; i != len; i++) + if (strcmp (s, list[i]) == 0) + return i; + return -1; +} +#define IS_IN_STRING_LIST(__s, __list) \ + is_in_string_list (__s, __list, array_length (__list)) + +static int +handle_restart (void) +{ + run_extra_steps (); + + FILE *fp = xfopen ("/proc/self/maps", "r"); + char *line = NULL; + size_t linesiz = 0; + + unsigned long pagesize = getpagesize (); + + bool found_expected[array_length(expected_sealed_vmas)] = { false }; + while (xgetline (&line, &linesiz, fp) > 0) + { + uintptr_t start; + uintptr_t end; + char flags[5] = { 0 }; + char name[256] = { 0 }; + int idx; + + /* The line is in the form: + start-end flags offset dev inode pathname */ + int r = sscanf (line, + "%" SCNxPTR "-%" SCNxPTR " %4s %*s %*s %*s %256s", + &start, + &end, + flags, + name); + TEST_VERIFY_EXIT (r == 3 || r == 4); + + int found = false; + + const char *libname = basename (name); + if ((idx = IS_IN_STRING_LIST (libname, expected_sealed_vmas)) + != -1) + { + /* Check if we can change the protection flags of the segment. */ + int new_prot = new_flags (flags); + TEST_VERIFY_EXIT (mprotect ((void *) start, end - start, + new_prot) == -1); + TEST_VERIFY_EXIT (errno == EPERM); + + /* Also checks trying to map over the sealed libraries. */ + { + char *p = mmap ((void *) start, pagesize, new_prot, + MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + TEST_VERIFY_EXIT (p == MAP_FAILED); + TEST_VERIFY_EXIT (errno == EPERM); + } + + /* And if remap is also blocked. */ + { + char *p = mremap ((void *) start, end - start, end - start, 0); + TEST_VERIFY_EXIT (p == MAP_FAILED); + TEST_VERIFY_EXIT (errno == EPERM); + } + + printf ("sealed: vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n", + start, + end, + flags, + name); + + found_expected[idx] = true; + found = true; + } + else if ((idx = IS_IN_STRING_LIST (libname, expected_non_sealed_vmas)) + != -1) + { + /* Check if expected non-sealed segments protection can indeed be + changed. The idea is to use something that would not break + process execution, so just try to mprotect with all protection + bits. */ + int new_prot = PROT_READ | PROT_WRITE | PROT_EXEC; + TEST_VERIFY_EXIT (mprotect ((void *) start, end - start, new_prot) + == 0); + + printf ("not-sealed: vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n", + start, + end, + flags, + name); + + found = true; + } + else if (IS_IN_STRING_LIST (libname, expected_non_sealed_special) != -1) + { + /* These pages protection can no be changed. */ + found = true; + } + + if (!found) + { + if (IS_IN_STRING_LIST (libname, non_sealed_vmas) != -1) + printf ("not-sealed: vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n", + start, + end, + flags, + name); + else + FAIL_EXIT1 ("unexpected vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n", + start, + end, + flags, + name); + } + } + xfclose (fp); + + printf ("\n"); + + /* Also check if all the expected sealed maps were found. */ + for (int i = 0; i < array_length (expected_sealed_vmas); i++) + if (expected_sealed_vmas[i][0] && !found_expected[i]) + FAIL_EXIT1 ("expected VMA %s not sealed\n", expected_sealed_vmas[i]); + + return 0; +} + +static int restart; +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +static int +do_test (int argc, char *argv[]) +{ + /* We must have either: + - One or four parameters left if called initially: + + path to ld.so optional + + "--library-path" optional + + the library path optional + + the application name */ + if (restart) + return handle_restart (); + + /* Check the test requirements. */ + { + int r = mseal (NULL, 0, 0); + if (r == -1 && (errno == ENOSYS || errno == EPERM)) + FAIL_UNSUPPORTED ("mseal is not supported by the kernel"); + else + TEST_VERIFY_EXIT (r == 0); + } + support_need_proc ("Reads /proc/self/maps to get stack names."); + + char *spargv[9]; + int i = 0; + for (; i < argc - 1; i++) + spargv[i] = argv[i + 1]; + spargv[i++] = (char *) "--direct"; + spargv[i++] = (char *) "--restart"; + spargv[i] = NULL; + + char *envvarss[] = { +#ifdef LD_PRELOAD + (char *) "LD_PRELOAD=" LD_PRELOAD, +#endif +#ifdef LD_AUDIT + (char *) "LD_AUDIT=" LD_AUDIT, +#endif + NULL + }; + + struct support_capture_subprocess result = + support_capture_subprogram (spargv[0], spargv, envvarss); + support_capture_subprocess_check (&result, "tst-dl_mseal", 0, + sc_allow_stdout); + + { + FILE *out = fmemopen (result.out.buffer, result.out.length, "r"); + TEST_VERIFY (out != NULL); + char *line = NULL; + size_t linesz = 0; + while (xgetline (&line, &linesz, out)) + printf ("%s", line); + fclose (out); + } + + support_capture_subprocess_free (&result); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c new file mode 100644 index 0000000000..dcaea0c7cf --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c @@ -0,0 +1,59 @@ +/* Basic tests for sealing. Static version. + Copyright (C) 2025 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 + +/* This test checks the GNU_PROPERTY_MEMORY_SEAL handling on a statically + built binary. In this case only the vDSO (if existent) will be sealed. */ + +#define TEST_STATIC 1 + +/* Expected libraries that loader will seal. */ +static const char *expected_sealed_vmas[] = +{ + "", +}; + +/* Expected non sealed libraries. */ +static const char *expected_non_sealed_vmas[] = +{ + "tst-dl_mseal-static-noseal", + /* Auxiary pages mapped by the kernel. */ + "[vdso]", + "[sigpage]", +}; + +/* Auxiliary kernel pages where permission can not be changed. */ +static const char *expected_non_sealed_special[] = +{ + "[vectors]", +}; + +static void * +tf (void *closure) +{ + return NULL; +} + +static void +run_extra_steps (void) +{ + xpthread_join (xpthread_create (NULL, tf, NULL)); +} + +#include "tst-dl_mseal-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-static.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-static.c new file mode 100644 index 0000000000..bca9e0d813 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-static.c @@ -0,0 +1,56 @@ +/* Basic tests for sealing. Static version. + Copyright (C) 2025 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 + +/* This test checks the memory sealing work on a statically built binary. */ + +#define TEST_STATIC 1 + +/* Expected libraries that loader will seal. */ +static const char *expected_sealed_vmas[] = +{ + "tst-dl_mseal-static", +}; + +/* Auxiliary pages mapped by the kernel. */ +static const char *expected_non_sealed_vmas[] = +{ + "[vdso]", + "[sigpage]", +}; + +/* Auxiliary kernel pages where permission can not be changed. */ +static const char *expected_non_sealed_special[] = +{ + "[vectors]", +}; + +static void * +tf (void *closure) +{ + return NULL; +} + +static void +run_extra_steps (void) +{ + xpthread_join (xpthread_create (NULL, tf, NULL)); +} + +#include "tst-dl_mseal-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal.c new file mode 100644 index 0000000000..1a45f2aa84 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal.c @@ -0,0 +1,92 @@ +/* Basic tests for sealing. + Copyright (C) 2025 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 +#include +#include "tst-dl_mseal-common.h" + +/* Check if memory sealing works as expected on multiples places: + - On the binary itself. + - On a LD_PRELOAD library. + - On a dependency modules (tst-dl_mseal-mod-{1,2}.so). + - On a audit modules (tst-dl_mseal-auditmod.so). + - On a dlopen dependency opened with RTLD_NODELETE + (tst-dl_mseal-dlopen-{2,2-1}.so). + - On the libgcc_s opened by thread unwind. */ + +/* Expected libraries that loader will seal. */ +static const char *expected_sealed_vmas[] = +{ +#ifdef DEFAULT_MEMORY_SEAL + "libc.so", + "ld.so", +#endif + "tst-dl_mseal", + LIB_MODULE1, + LIB_MODULE1_DEP, + LIB_PRELOAD, + LIB_AUDIT, + LIB_DLOPEN_NODELETE, +}; + +/* Expected non sealed libraries. */ +static const char *expected_non_sealed_vmas[] = +{ +#ifndef DEFAULT_MEMORY_SEAL + "libc.so", + "ld.so", +#endif + LIB_DLOPEN_DEFAULT, + LIB_DLOPEN_DEFAULT_DEP, + LIB_DLOPEN_NODELETE_DEP, + /* Auxiliary pages mapped by the kernel. */ + "[vdso]", + "[sigpage]", +}; + +/* Special pages, either Auxiliary kernel pages where permission can not be + changed or auxiliary libs that we can know prior hand that sealing is + enabled. */ +static const char *expected_non_sealed_special[] = +{ + LIBGCC_S_SO, + "[vectors]", +}; + +static void * +tf (void *closure) +{ + pthread_exit (NULL); + return NULL; +} + +static void +run_extra_steps (void) +{ + xdlopen (LIB_DLOPEN_NODELETE, RTLD_NOW | RTLD_NODELETE); + xdlopen (LIB_DLOPEN_DEFAULT, RTLD_NOW); + + /* pthread_exit will load LIBGCC_S_SO. */ + xpthread_join (xpthread_create (NULL, tf, NULL)); +} + +#define LD_PRELOAD LIB_PRELOAD +#define LD_AUDIT LIB_AUDIT + +#include "tst-dl_mseal-skeleton.c" From patchwork Tue Mar 11 17:09:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872470 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1598994wri; Tue, 11 Mar 2025 10:25:35 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXw+BBgzTnjsZdGgPzooz5HJrDrbZV+KSDEnwb0jOEcpRaDbRkwzu74LXiyDlLdzgm8q7Sx3g==@linaro.org X-Google-Smtp-Source: AGHT+IE7L7HjRs/vK24WlNHfV/GNd8jNpbVerm9cB+O2G31TMSzijWRV+nUgoTPuxIlJyfQg/KSF X-Received: by 2002:ac8:5844:0:b0:476:8612:f029 with SMTP id d75a77b69052e-4768612f242mr117775891cf.48.1741713935646; Tue, 11 Mar 2025 10:25:35 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713935; cv=pass; d=google.com; s=arc-20240605; b=Omvmy3lR+/i9wmNv0u6ZWDmgKGH8qYvV6t8d+JB0QDUYh1ar5zAYtgWv8VAcLRYgHJ Xh/bLbPM/nRPJS5xjC6H4z+jnhZIiOFlCKCdVduHHRdgXRuRa6sIyV+/LIEgOzWEly0Q XT0IRYX9viwmaOTYBTWvhhkFN3bU8UGaM2GwW8mFENTpGE701DaFR3fzuttbIS9pev/L 6T2ZIgmy75hB7fawwKiGTE3/gFzvt2nTg84wdUFTh0w8qWG2p3x+N6x9SeqwjLZOe6/g kRNwRat+eI+bXpOiLrYR6kxNaktVRVnzc9nE97KFGQatiTbeYmBIMc1y8VBXwmd8kR1D 7Mxg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=oVp7RRm19QIFZVtmKrgo8+0Hn6WP4QAZT+lg6tXT1tk=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=DeqSkBH94H34yTTXAbdjUnDtOIx+i2MUS098FVolM9bzxCS+AsFFfVRaxya7OlX9HE bBQx1BAeu5OYsjdXaBY7RK/+GckpHBi3mYfuCn+RaRitq5yrAdYGJ34LcWPuQMSiawOG euK613/im2DW2CJU+Ik1sf9wGNzdVo6cex/mdNZZ+p0fpbdBeZCxSlfjFrTI837phS6x vPoIN6BOOGftS9P3PI03umNA8icRyHBvi7k4dfXpz8TfTAlimzwuOEnDGrFoIExTteue KSEkMrkIGxiEBBKlAjD9aNoh7YTRzo9H3Mh328KUgCZK9K7P45d/ld2pomJk6UuPrhRI IB8g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=zB0TYWOv; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id d75a77b69052e-476731ab509si67090191cf.470.2025.03.11.10.25.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:25:35 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=zB0TYWOv; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 24CE63857737 for ; Tue, 11 Mar 2025 17:25:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 24CE63857737 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=zB0TYWOv X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by sourceware.org (Postfix) with ESMTPS id 975953857C78 for ; Tue, 11 Mar 2025 17:13:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 975953857C78 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 975953857C78 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1033 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713211; cv=none; b=XJdPZ3Z76V3RFwiGsoQcvxBp79hhgvDapOF1kKyy7RQdcmW9JtEKEGJWUuTvRVxuAHWO56GLc9B+x7cDqy8gBpsdRzTZpMCRl0mIM6rq/2aw3UdFc+Zc6mG5eyXFiySb9Odz1n0ichtKVXDnck3WvS7gG/46qkbPHk/DtAGVIkI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713211; c=relaxed/simple; bh=VWhdE4tHlSAlHamy2w+K4imthWEy6k56IhF0dF+tbFA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=iDVUBgt/gYZVBXTMXimNApBIn0/Uln9Kx08WCHXH0AawAVwbnmZY2/FoaIvQ6lcw6wNLZLQWSbu6l4kkaDg7xO+VUbKq3Iz4bc6yQGzdbXO0LBhODX+hSzkZLrSp29p5Mwy63aekCMVZoen7pqG/9//mS9+FKL2D+SbXaNBFSv0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 975953857C78 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-2ff04f36fd2so9709321a91.1 for ; Tue, 11 Mar 2025 10:13:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713210; x=1742318010; 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=oVp7RRm19QIFZVtmKrgo8+0Hn6WP4QAZT+lg6tXT1tk=; b=zB0TYWOviSVv7npGX5qkttpEyKMTD+9FdL4jwOitAOZTG144vUtaGuMUDBqqqrBhN0 LvUptWk1c4rbgdAdRJkzVllRiw45R5H1Yq4ty2QdwyqHPcTUtwHVeUIEq/xQtTkufV7W vo986tOh45AkAK6Weroi8jl6Dc645QvXj1NxnrmRu/iQUbOzNXek34RyUEighwfwgyw4 ksEM1Q4L0BZT4b2ReTkTnDvEjH+e7E1XaN0EBHLdVJ+/xp8I6N7JzLjdpMjKd6jOq514 P2m8EM0KjhLy/CYFQ3K6Ggf4TWwfb9O0KfRhGxJHyz69dlwisIFn/xxwkQHA+AXuRoUM 6oeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713210; x=1742318010; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oVp7RRm19QIFZVtmKrgo8+0Hn6WP4QAZT+lg6tXT1tk=; b=MRJwYeNWA9cDmix4WLb6tUfmlJCrGQOLSQ56oIukZU0d65kHjPh4CWUoEzsFc9/+md 3LNCyHQu02KQnJVBDexVY6Juwt5XVaiRzCjFbQ3ebwvzgT0I/k0giTq5MNH/PlYUn/7G 5ihqyUD35DM15ZvZwd1chrwdTPNjU+qYF6CYniH8JeP3pm8WHJJ4FbrJbOjyBNvxqeM4 1OD2/IRdK5Ufab6PmIcq+KlUOqPAC0P/cXp2FPdadWWxNu2xWm6tVKrjudMmW61pAstb hjcqgcDnlJzoWsPKQjpVklF7jgFuonN4M9JvEDRuL2cr6imU4k1kO/+YIYM2+/0BlegB BlMg== X-Gm-Message-State: AOJu0Yx95blctKnBLUogPFCBiubxD2J+9yaUtwIZO6IHzjSE3bOFtLkL VkGqciMeKhHqJ3x12WkVoZSEydsR+QW0GdJlSm7D752qvVvVi0bg5wim+ED8EjZxbJWqxs6zos8 x X-Gm-Gg: ASbGncvi9f8hKclv1txRjHyjXgzU5HmkcsIuVl+augd8pw7t59l9KbZwj2koq6SPyzL QYsyMlwzqHNEZ6ejuEX1j1tQBnO/uXSW1dsh+TYCDlLIG1/T3TZMwVZfWGjxkc8MnwLXbC6Aj5D TFX5Fa9GBqLTEeG0sPO6ikLqqR6K1rm2ZKH8TFRDqX4IJO6dY0RhJELBPkAx4WIeUHeH672II4V kaaBR820oFLunI/A/40M5HSsXGuCAOKQPAhwIyT2fE+TQrnhTUA96kpoYPEx2V+x+52bTdC7ve0 cnsiQMDqpZs8nrVt64tXjrYJi7BXsHZ6hPYnNOugQ6vidKz9vtKM3pw= X-Received: by 2002:a17:90b:384a:b0:2fe:ba7f:8032 with SMTP id 98e67ed59e1d1-2ff7ce6ec12mr29711271a91.9.1741713210192; Tue, 11 Mar 2025 10:13:30 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:29 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 8/9] linux: Add support for PT_GNU_MUTABLE Date: Tue, 11 Mar 2025 14:09:55 -0300 Message-ID: <20250311171305.89091-9-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org Since memory sealing is applied for all the PT_LOAD segments, a new program header is also supported so users can define a region where sealing should not be applied (so users can later initialize and change memory protection). The special section, PT_GNU_MUTABLE (reference implemented at [1]), marks a memory region that should not be sealed if the GNU_PROPERTY_MEMORY_SEAL attribute is present. The section name starts with ".gnu.mutable" and has an alignment and size of the defined maximum page size (-z max-page-size linker option). For instance the code: #define GNU_MUTABLE_SECTION_NAME ".gnu.mutable" unsigned char mutable_array1[64] __attribute__ ((section (GNU_MUTABLE_SECTION_NAME))) = { 0 }; unsigned char mutable_array2[32] __attribute__ ((section (GNU_MUTABLE_SECTION_NAME))) = { 0 }; places both 'mutable_array1' and 'mutable_array2' on a page aligned memory region with the size of a page. The linker sets the alignment and size to simplify support for ABIs with multiple page sizes, otherwise user would need to know the maximum page size to correctly define the alignment and size of the variable. Checked on aarch64-linux-gnu and x86_64-linux-gnu. [1] https://sourceware.org/git/?p=binutils-gdb.git;a=shortlog;h=refs/heads/azanella/pt_gnu_mutable --- configure | 33 +++ configure.ac | 19 ++ elf/dl-load.c | 5 + elf/dl-reloc.c | 29 ++- elf/dl-support.c | 5 + elf/elf.h | 2 + elf/rtld.c | 5 + include/link.h | 4 + sysdeps/unix/sysv/linux/Makefile | 23 ++ .../sysv/linux/tst-dl_mseal-mutable-dlopen.c | 1 + .../sysv/linux/tst-dl_mseal-mutable-mod.c | 47 ++++ .../sysv/linux/tst-dl_mseal-mutable-mod.h | 33 +++ .../sysv/linux/tst-dl_mseal-mutable-static.c | 2 + .../unix/sysv/linux/tst-dl_mseal-mutable.c | 242 ++++++++++++++++++ 14 files changed, 446 insertions(+), 4 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-dlopen.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.h create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-static.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mutable.c diff --git a/configure b/configure index dda60ed91d..83c79147dd 100755 --- a/configure +++ b/configure @@ -7465,6 +7465,39 @@ have-z-memory-seal = $libc_cv_z_memory_seal" config_vars="$config_vars enable-memory-seal = $enable_memory_sealing" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PT_GNU_MUTABLE support" >&5 +printf %s "checking PT_GNU_MUTABLE support... " >&6; } +if test ${libc_cv_gnu_mutable+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then + if $READELF -lW conftest | grep 'GNU_MUTABLE' > /dev/null; then + libc_cv_gnu_mutable=yes + fi +fi +rm -r conftest* ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gnu_mutable" >&5 +printf "%s\n" "$libc_cv_gnu_mutable" >&6; } +config_vars="$config_vars +have-pt-gnu-mutable = $libc_cv_gnu_mutable" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GLOB_DAT reloc" >&5 printf %s "checking for GLOB_DAT reloc... " >&6; } diff --git a/configure.ac b/configure.ac index d514179e1b..f62ccd4545 100644 --- a/configure.ac +++ b/configure.ac @@ -1378,6 +1378,25 @@ fi LIBC_CONFIG_VAR([have-z-memory-seal], [$libc_cv_z_memory_seal]) LIBC_CONFIG_VAR([enable-memory-seal], [$enable_memory_sealing]) +AC_CACHE_CHECK([PT_GNU_MUTABLE support], + libc_cv_gnu_mutable, [dnl +cat > conftest.c <&AS_MESSAGE_LOG_FD]) +then + if $READELF -lW conftest | grep 'GNU_MUTABLE' > /dev/null; then + libc_cv_gnu_mutable=yes + fi +fi +rm -r conftest*]) +LIBC_CONFIG_VAR([have-pt-gnu-mutable], [$libc_cv_gnu_mutable]) + AC_CACHE_CHECK(for GLOB_DAT reloc, libc_cv_has_glob_dat, [dnl diff --git a/elf/dl-load.c b/elf/dl-load.c index f104cc7544..a0d7d30e58 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1220,6 +1220,11 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, l->l_relro_addr = ph->p_vaddr; l->l_relro_size = ph->p_memsz; break; + + case PT_GNU_MUTABLE: + l->l_mutable_addr = ph->p_vaddr; + l->l_mutable_size = ph->p_memsz; + break; } if (__glibc_unlikely (nloadcmds == 0)) diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 2b37676182..d706a57101 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -37,7 +37,6 @@ # define bump_num_cache_relocations() ((void) 0) #endif - /* We are trying to perform a static TLS relocation in MAP, but it was dynamically loaded. This can only work if there is enough surplus in the static TLS area already allocated for each running thread. If this @@ -371,6 +370,29 @@ cannot apply additional memory protection after relocation"); } } +static void +_dl_mseal_map_2 (const struct link_map *l, ElfW(Addr) map_start, + ElfW(Addr) map_end) +{ + ElfW(Addr) mutable_start = 0, mutable_end = 0; + if (l->l_mutable_size != 0) + { + mutable_start = l->l_addr + l->l_mutable_addr; + mutable_end = mutable_start + l->l_mutable_size; + } + + if (mutable_start >= map_start && mutable_end < map_end) + { + size_t seg1_size = mutable_start - map_start; + size_t seg2_size = map_end - mutable_end; + _dl_mseal ((void *) map_start, seg1_size, l->l_name); + if (seg2_size != 0) + _dl_mseal ((void *) mutable_end, seg2_size, l->l_name); + } + else + _dl_mseal ((void *) map_start, map_end - map_start, l->l_name); +} + static void _dl_mseal_map_1 (struct link_map *l, bool dep) { @@ -388,8 +410,7 @@ _dl_mseal_map_1 (struct link_map *l, bool dep) return; if (l->l_contiguous) - _dl_mseal ((void *) l->l_map_start, l->l_map_end - l->l_map_start, - l->l_name); + _dl_mseal_map_2 (l, l->l_map_start, l->l_map_end); else { /* We can use the PT_LOAD segments because even if relro splits the @@ -404,7 +425,7 @@ _dl_mseal_map_1 (struct link_map *l, bool dep) ElfW(Addr) mapstart = l->l_addr + (ph->p_vaddr & ~(GLRO(dl_pagesize) - 1)); ElfW(Addr) allocend = l->l_addr + ph->p_vaddr + ph->p_memsz; - _dl_mseal ((void *) mapstart, allocend - mapstart, l->l_name); + _dl_mseal_map_2 (l, mapstart, allocend); } break; } diff --git a/elf/dl-support.c b/elf/dl-support.c index ab74f3b51c..6227397237 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -334,6 +334,11 @@ _dl_non_dynamic_init (void) _dl_main_map.l_relro_addr = ph->p_vaddr; _dl_main_map.l_relro_size = ph->p_memsz; break; + + case PT_GNU_MUTABLE: + _dl_main_map.l_mutable_addr = ph->p_vaddr; + _dl_main_map.l_mutable_size = ph->p_memsz; + break; } /* Process program headers again, but scan them backwards so that PT_NOTE can be skipped if PT_GNU_PROPERTY exits. */ diff --git a/elf/elf.h b/elf/elf.h index f7d38eeffb..efde5bae73 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -729,6 +729,7 @@ typedef struct #define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ #define PT_GNU_PROPERTY 0x6474e553 /* GNU property */ #define PT_GNU_SFRAME 0x6474e554 /* SFrame segment. */ +#define PT_GNU_MUTABLE 0x6474f555 /* Like bss, but not immutable. */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ @@ -1352,6 +1353,7 @@ typedef struct /* Note section name of program property. */ #define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property" +#define GNU_MUTABLE_SECTION_NAME ".gnu.mutable" /* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */ diff --git a/elf/rtld.c b/elf/rtld.c index 25058cb242..c2e2904aad 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1209,6 +1209,11 @@ rtld_setup_main_map (struct link_map *main_map) main_map->l_relro_addr = ph->p_vaddr; main_map->l_relro_size = ph->p_memsz; break; + + case PT_GNU_MUTABLE: + main_map->l_mutable_addr = ph->p_vaddr; + main_map->l_mutable_size = ph->p_memsz; + break; } /* Process program headers again, but scan them backwards so that PT_NOTE can be skipped if PT_GNU_PROPERTY exits. */ diff --git a/include/link.h b/include/link.h index 677d82b38b..c77fbf10de 100644 --- a/include/link.h +++ b/include/link.h @@ -353,6 +353,10 @@ struct link_map ElfW(Addr) l_relro_addr; size_t l_relro_size; + /* Information used to not memory seal after relocations are done. */ + ElfW(Addr) l_mutable_addr; + size_t l_mutable_size; + unsigned long long int l_serial; }; diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 8fe74be95f..2faa377fd5 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -708,6 +708,8 @@ modules-names += \ tst-dl_mseal-dlopen-2-1 \ tst-dl_mseal-mod-1 \ tst-dl_mseal-mod-2 \ + tst-dl_mseal-mutable-dlopen \ + tst-dl_mseal-mutable-mod \ tst-dl_mseal-preload \ # modules-names @@ -731,6 +733,10 @@ $(objpfx)tst-dl_mseal-noseal.out: \ $(objpfx)tst-dl_mseal-dlopen-2.so \ $(objpfx)tst-dl_mseal-dlopen-2-1.so +$(objpfx)tst-dl_mseal-mutable.out: \ + $(objpfx)tst-dl_mseal-mutable-mod.so \ + $(objpfx)tst-dl_mseal-mutable-dlopen.so + ifeq ($(enable-memory-seal),yes) CFLAGS-tst-dl_mseal.c += -DDEFAULT_MEMORY_SEAL CFLAGS-tst-dl_mseal-noseal.c += -DDEFAULT_MEMORY_SEAL @@ -738,6 +744,8 @@ endif LDFLAGS-tst-dl_mseal = -Wl,--no-as-needed -Wl,-z,memory-seal LDFLAGS-tst-dl_mseal-static = -Wl,--no-as-needed -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-mutable = -Wl,--no-as-needed -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-mutable-static = -Wl,-z,memory-seal LDFLAGS-tst-dl_mseal-mod-1.so = -Wl,--no-as-needed -Wl,-z,memory-seal LDFLAGS-tst-dl_mseal-mod-2.so = -Wl,-z,memory-seal LDFLAGS-tst-dl_mseal-dlopen-1.so = -Wl,--no-as-needed @@ -763,6 +771,21 @@ tst-dl_mseal-ARGS = -- $(host-test-program-cmd) tst-dl_mseal-static-ARGS = -- $(host-test-program-cmd) tst-dl_mseal-noseal-ARGS = -- $(host-test-program-cmd) tst-dl_mseal-static-noseal-ARGS = -- $(host-test-program-cmd) + +ifeq ($(have-pt-gnu-mutable),yes) +tests-static += \ + tst-dl_mseal-mutable-static \ + # tests-static + +tests += \ + tst-dl_mseal-mutable \ + # tests + +LDFLAGS-tst-dl_mseal-mutable-mod.so = -Wl,-z,memory-seal +LDFLAGS-tst-dl_mseal-mutable-dlopen.so = -Wl,-z,memory-seal + +$(objpfx)tst-dl_mseal-mutable: $(objpfx)tst-dl_mseal-mutable-mod.so +endif # $(have-pt-gnu-mutable) == yes endif endif # $(subdir) == elf diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-dlopen.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-dlopen.c new file mode 100644 index 0000000000..325b2004b5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-dlopen.c @@ -0,0 +1 @@ +#include "tst-dl_mseal-mutable-mod.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.c new file mode 100644 index 0000000000..fb7cf03925 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.c @@ -0,0 +1,47 @@ +/* Check if PT_OPENBSD_MUTABLE is correctly applied. + Copyright (C) 2025 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 "tst-dl_mseal-mutable-mod.h" + +static unsigned char mutable_array1[128] + __attribute__ ((section (GNU_MUTABLE_SECTION_NAME))) + = { 0 }; +static unsigned char mutable_array2[256] + __attribute__ ((section (GNU_MUTABLE_SECTION_NAME))) + = { 0 }; + +static unsigned char immutable_array[256]; + +struct array_t +get_mutable_array1 (void) +{ + return (struct array_t) { mutable_array1, sizeof (mutable_array1) }; +} + +struct array_t +get_mutable_array2 (void) +{ + return (struct array_t) { mutable_array2, sizeof (mutable_array2) }; +} + +struct array_t +get_immutable_array (void) +{ + return (struct array_t) { immutable_array, sizeof (immutable_array) }; +} diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.h b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.h new file mode 100644 index 0000000000..cb0153756b --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-mod.h @@ -0,0 +1,33 @@ +/* Check if PT_OPENBSD_MUTABLE is correctly applied. + Copyright (C) 2025 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 + +#define LIB_DLOPEN "tst-dl_mseal-mutable-dlopen.so" + +struct array_t +{ + unsigned char *arr; + size_t size; +}; + +typedef struct array_t (*get_array_t)(void); + +struct array_t get_mutable_array1 (void); +struct array_t get_mutable_array2 (void); +struct array_t get_immutable_array (void); diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-static.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-static.c new file mode 100644 index 0000000000..550ef3f056 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable-static.c @@ -0,0 +1,2 @@ +#define TEST_STATIC 1 +#include "tst-dl_mseal-mutable.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable.c new file mode 100644 index 0000000000..2ea233d4d8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mutable.c @@ -0,0 +1,242 @@ +/* Check if PT_OPENBSD_MUTABLE is correctly applied. + Copyright (C) 2025 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "tst-dl_mseal-mutable-mod.h" + +static long int pagesize; + +/* To check if the protection flags are correctly set, the thread tries + read/writes on it and checks if a SIGSEGV is generated. */ + +static volatile sig_atomic_t signal_jump_set; +static sigjmp_buf signal_jmp_buf; + +static void +sigsegv_handler (int sig) +{ + if (signal_jump_set == 0) + return; + + siglongjmp (signal_jmp_buf, sig); +} + +static bool +try_access_buf (unsigned char *ptr, bool write) +{ + signal_jump_set = true; + + bool failed = sigsetjmp (signal_jmp_buf, 0) != 0; + if (!failed) + { + if (write) + *(volatile unsigned char *)(ptr) = 'x'; + else + *(volatile unsigned char *)(ptr); + } + + signal_jump_set = false; + return !failed; +} + +struct range_t +{ + const char *name; + unsigned char *start; + size_t size; + bool found; +}; + +static int +callback (struct dl_phdr_info *info, size_t size, void *data) +{ + struct range_t *range = data; + if (strcmp (info->dlpi_name, range->name) != 0) + return 0; + + for (size_t i = 0; i < info->dlpi_phnum; i++) + if (info->dlpi_phdr[i].p_type == PT_GNU_MUTABLE) + { + range->start = (unsigned char *) info->dlpi_phdr[i].p_vaddr; + range->size = info->dlpi_phdr[i].p_memsz; + range->found = true; + break; + } + + return 0; +} + +static bool +find_mutable_range (void *addr, struct range_t *range) +{ + struct dl_find_object dlfo; + if (_dl_find_object (addr, &dlfo) != 0) + return false; + + range->name = dlfo.dlfo_link_map->l_name; + range->found = false; + dl_iterate_phdr (callback, range); + if (range->found) + range->start = dlfo.dlfo_link_map->l_addr + range->start; + + return range->found; +} + +static bool +__attribute_used__ +try_read_buf (unsigned char *ptr) +{ + return try_access_buf (ptr, false); +} + +static bool +__attribute_used__ +try_write_buf (unsigned char *ptr) +{ + return try_access_buf (ptr, true); +} + +/* The GNU_MUTABLE_SECTION_NAME section is page-aligned and with a size + multiple of page size. */ + +unsigned char mutable_array1[64] + __attribute__ ((section (GNU_MUTABLE_SECTION_NAME))) + = { 0 }; +unsigned char mutable_array2[32] + __attribute__ ((section (GNU_MUTABLE_SECTION_NAME))) + = { 0 }; + +unsigned char immutable_array[128]; + +static void +check_array (struct array_t *arr) +{ + TEST_COMPARE (try_write_buf (arr->arr), false); + TEST_COMPARE (try_write_buf (&arr->arr[arr->size/2]), false); + TEST_COMPARE (try_write_buf (&arr->arr[arr->size-1]), false); +} + +static void +check_mutable (struct array_t *mut1, + struct array_t *mut2, + struct array_t *imut) +{ + struct range_t range1; + struct range_t range2; + + TEST_VERIFY_EXIT (find_mutable_range (mut1->arr, &range1)); + TEST_VERIFY (mut1->arr >= range1.start); + TEST_VERIFY (mut1->arr + mut1->size <= range1.start + range1.size); + + TEST_VERIFY_EXIT (find_mutable_range (mut2->arr, &range2)); + TEST_VERIFY (mut2->arr >= range2.start); + TEST_VERIFY (mut2->arr + mut2->size <= range2.start + range2.size); + + /* Assume that both array will be placed in the same page since their + combined size is less than pagesize. */ + TEST_VERIFY (range1.start == range2.start); + TEST_VERIFY (range2.size == range2.size); + + if (test_verbose > 0) + printf ("mutable region: %-30s - %p-%p\n", + range1.name[0] == '\0' ? "main program" : basename (range1.name), + range1.start, + range1.start + range1.size); + + memset (mut1->arr, 0xaa, mut1->size); + memset (mut2->arr, 0xbb, mut2->size); + memset (imut->arr, 0xcc, imut->size); + + /* Sanity check, imut should be immutable. */ + { + void *start = PTR_ALIGN_DOWN (imut->arr, pagesize); + TEST_COMPARE (mprotect (start, pagesize, PROT_READ), -1); + TEST_COMPARE (errno, EPERM); + } + + /* Change permission of mutable region to just allow read. */ + xmprotect ((void *)range1.start, range1.size, PROT_READ); + + check_array (mut1); + check_array (mut2); +} + +static int +do_test (void) +{ + pagesize = xsysconf (_SC_PAGESIZE); + + { + struct sigaction sa = { + .sa_handler = sigsegv_handler, + .sa_flags = SA_NODEFER, + }; + sigemptyset (&sa.sa_mask); + xsigaction (SIGSEGV, &sa, NULL); + } + +#define ARR_TO_RANGE(__arr) \ + &((struct array_t) { __arr, sizeof (__arr) }) + + check_mutable (ARR_TO_RANGE (mutable_array1), + ARR_TO_RANGE (mutable_array2), + ARR_TO_RANGE (immutable_array)); + +#ifndef TEST_STATIC + { + struct array_t mut1 = get_mutable_array1 (); + struct array_t mut2 = get_mutable_array2 (); + struct array_t imut = get_immutable_array (); + check_mutable (&mut1, &mut2, &imut); + } + + { + void *h = xdlopen (LIB_DLOPEN, RTLD_NOW | RTLD_NODELETE); + +#define GET_ARRAY_DLOPEN(__name) \ + ({ \ + get_array_t f = xdlsym (h, __name); \ + f(); \ + }) + + struct array_t mut1 = GET_ARRAY_DLOPEN ("get_mutable_array1"); + struct array_t mut2 = GET_ARRAY_DLOPEN ("get_mutable_array2"); + struct array_t imut = GET_ARRAY_DLOPEN ("get_immutable_array"); + check_mutable (&mut1, &mut2, &imut); + } +#endif + + return 0; +} + +#include From patchwork Tue Mar 11 17:09:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 872468 Delivered-To: patch@linaro.org Received: by 2002:a5d:64ce:0:b0:38f:210b:807b with SMTP id f14csp1597634wri; Tue, 11 Mar 2025 10:22:21 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVNo8XLvkjiX0sMNyhy2eQbEq2kPAHBqs6Dp5qWUd8EdXWQZdSaPVvdMbcUOhFTFXdMef+/Yg==@linaro.org X-Google-Smtp-Source: AGHT+IGb2Ekf9zcUZADEuXSYZPETuNEhphs3NxnVbDrXtkJidzR6j1Tz0sCiJpqzEMRb8Ed+CFru X-Received: by 2002:a05:6102:5491:b0:4ba:eb24:fb28 with SMTP id ada2fe7eead31-4c34d20cd1fmr4295070137.3.1741713741206; Tue, 11 Mar 2025 10:22:21 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1741713741; cv=pass; d=google.com; s=arc-20240605; b=eT0AXJmqWpqGcS/Lc/dA0Znbur7zoovgMgcX3cW7e2/CMCBfNhmQQJzVxjM8di66n2 GgOUEa8FYQAm/1hBWPGhwsV8sGuzESWR+QUAaBB86GPNxIOAv6isRrVD+2r6BH0HqYl0 UD8jv0xlWvwvdDrJ2NjFinOnscRLlv5tfsM6KnR1r0OJE8kjlYk/dUrxFI7NBEbhMwam qGu2TyvNoCFlnxwFiPytEtvdVxl42vm4F8rBkNioynkp5Izgtwhln4ZxesGCOr9iBnlT 7mAFhXNPxC3P5vKDLIOL4FezGYIl9OiIfz8qTr5uBa4OnupfPm4bHT2gDK3wm5S/jrXN /rQg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:dkim-filter:arc-filter:dmarc-filter :delivered-to:dkim-filter; bh=+s5cxJAth6uyLy+HaCEy986tW3ABQnWgByCcGKFmVbs=; fh=KcDe9xnl32Q8s5hC3CF4r26ysVeQspjxpbjrMk+PnIQ=; b=DsudWNCCmGr/FVrCsZAO8lvxJZbg7ngvQGBc8nsoXQY8yPKHpdnXOuv4c9ZBI1zlfG qnhGvBkZN4AuNKSwZCkt1V1/D/WAjIWw6/nlSpqAFYz7qtknzppjyhQ6wgStxbFqBd5p 6dwJ+na1iN7FKTYKazrISnKtMs6emEQG095M9jXGYhvpFb3Vu0NaNxurUO1QQ4mwa4Vw YZLXftQeZUVTGa+pmdzdQMpvofZRCCeRVX9RY+/W/sreRRItnU0ig/E8rBTCcsrVjzb7 bttBPwSL/q6QdXW0wsgVQknQQNeDt1x0lzockyPptp2z3+booYTzfB40UbnslhXMAeLz MJyA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VMCbIAry; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id ada2fe7eead31-4c2fbcc317fsi2912961137.374.2025.03.11.10.22.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:22:21 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VMCbIAry; arc=pass (i=1); spf=pass (google.com: domain of libc-alpha-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="libc-alpha-bounces~patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AB7313857734 for ; Tue, 11 Mar 2025 17:22:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB7313857734 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=VMCbIAry X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by sourceware.org (Postfix) with ESMTPS id 99BBB3857BA7 for ; Tue, 11 Mar 2025 17:13:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 99BBB3857BA7 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 99BBB3857BA7 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1030 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713213; cv=none; b=UYjQ4AeJcEMK0K00HzZVaXOANFfcAboRdsKVtwA242Y1WzJ4VvOkuDVmLlGXD0yaruQnKw7+MqGFc9Pi/8mgFl0z3EJcRvlOAA+uht5YW7UeTQo4ifr1T6bC81C21fsj+BGiWhM/AjuCDM/9AWp6XgS6C+NZpVinQdBnTCQs4fA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1741713213; c=relaxed/simple; bh=ik5Um592PPq0wPxCceg9WbQPKKFfLVkmZawV6qKbXSw=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=acKx9VQ4sfd4gMZW/w9nk1jWRb2wqbHrhLyIxOs0OMgUKLfElj+JXqJvD/Le+iZjcHWleJ011ev5EQl0HfhNfHu4xgqET/91uYrHKvkN+Pz/Z6p+XyoZmM3u4aKsEjmjYNmIfyyGCaGvPbTyE+tC/lv0vEVKRnlb9SkSfieilNQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 99BBB3857BA7 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2feb91a25bdso8990511a91.1 for ; Tue, 11 Mar 2025 10:13:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741713212; x=1742318012; 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=+s5cxJAth6uyLy+HaCEy986tW3ABQnWgByCcGKFmVbs=; b=VMCbIAry03PZ9BDz0uPdRQ1FkBN8wf0ocXUfHx0E0lp3PG8oS+bfcJJRQP5cD2vrpu iijJUj1+QUzSSP1y8V0bMhNwCNogu1LvyXYzKmcDTHN+DI4CxEXqyP8IILxLBws+gR2b YgLww11DkuAWmJgpmE1S/P7kmjOMaHUu+qfg9o+KZuc25CPhAdoqTtegrrZU3C7Hj6ic +l6j4c6hf75t3vDcUSX+JSVYchN7FrlTdSJY3q3QbysVP9WbkdgOYiythILxacivrGsp 2GjpWDRGjxWVT4Zd6daRA5onOtNcG0Ye193nrw8hHFpa+wHTi5v0EaWpuuTL1dFUgcm7 LW8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741713212; x=1742318012; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+s5cxJAth6uyLy+HaCEy986tW3ABQnWgByCcGKFmVbs=; b=w8pmKqrrxjKGC+etvvuGW2MNz1GZwnn9yv/31zZY98qsyopZpbMUx7ff9BXzTlD9aN tRJMOw3a8BdgTb+H9VcxgG1tChHDaopS3w6P39X6dLpxXIKXJIWHGnMxveRy95mkPA4O c/kCp9pNYW+bNHHbX+p0OTpTyfK0sY1yCvryuK2ydMa9LL3Vdf/F3hKDQtMDID6K+ETM b2ZYjK/ZHCSHbLhUe5L2D46+y/X8ZDvdDMQAMd5kfBk5GV6nz+E5BRlWCgq2oX1ZzjLt lH3AroTfMGJ3BXBafea/54oePYjwgjCS+VaRrJ66E0f5z4etTxKr5lnaHmpDksI5QkCs DReQ== X-Gm-Message-State: AOJu0YzvX0VWj3KQ9o+c65al7l7FCvZy4j9xMojpxJUa9oXLI97bZRm5 cV2ngc9wq/799SCbrfONnB+QdyOV/IqoePieOyM0ka54/gDI5Ovx97IhtKLC1yX1MrVjKlIGxw9 j X-Gm-Gg: ASbGncvl6cY5U+NcDx14vqAxZU5+cm5dwdGy8WWbvXBSc8UuIAsiX/t0p/7D13r1MbX bo0e+uoZ9DLD+ENVdv/tbtjiL/Cj47PqF78qQo5UoSEDPcNdaVaAIPv8YS0gyX9uTRUPfflTHs1 yzHN0kQ4sqAV9SgY990mxx5tQVpP3CPo/DRJJAHjfdotgD8y/Uw3+tQXTZvkfwjwpRikbngjFGp e+T0jZo+jD5ccnygaOM/wrBLaiScvkT/43I3EAiVs+SvU6vXYVAjU/c4Weq1lZinJ5Pt81BdZjY hRyRCRjbmGD5uI2WuWk6dQF1em+ltfRW3es+93QEfacyukvRYC+YPfU= X-Received: by 2002:a17:90b:5104:b0:2fe:85f0:e115 with SMTP id 98e67ed59e1d1-300ff34d533mr5202397a91.26.1741713212378; Tue, 11 Mar 2025 10:13:32 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1ebf:8b5:8f5b:dd39:866]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff693f8804sm11438131a91.47.2025.03.11.10.13.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 10:13:31 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Jeff Xu , Florian Weimer , "H . J . Lu" , Yury Khrustalev Subject: [PATCH v6 9/9] elf: Add glibc.rtld.seal tunable Date: Tue, 11 Mar 2025 14:09:56 -0300 Message-ID: <20250311171305.89091-10-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250311171305.89091-1-adhemerval.zanella@linaro.org> References: <20250311171305.89091-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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~patch=linaro.org@sourceware.org The new tunable can be used to disable memory sealing on the program and all its dependencies. This can be useful for debugging, patchable function entries (-fpatchable-function-entry), or profiling (-mfentry, -mnop-count, -minstrument-return) where the program might be run with or without changes to its text segment. Checked on x86_64-linux-gnu. --- NEWS | 6 ++++ elf/dl-tunables.list | 6 ++++ elf/tst-rtld-list-tunables.exp | 1 + manual/tunables.texi | 36 +++++++++++++++++++ sysdeps/unix/sysv/linux/Makefile | 27 +++++++------- sysdeps/unix/sysv/linux/dl-mseal.c | 9 +++++ sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c | 6 +++- .../unix/sysv/linux/tst-dl_mseal-skeleton.c | 3 ++ .../unix/sysv/linux/tst-dl_mseal-tunable.c | 24 +++++++++++++ 9 files changed, 103 insertions(+), 15 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-tunable.c diff --git a/NEWS b/NEWS index ff241b2863..e3362158dc 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,12 @@ Major new features: * A new configure option, "--enable-memory-sealing", can be used to build the GNU C Library libraries and programs with memory sealing. +* A new tunable, glibc.rtld.seal, can enable memory sealing on the program + and all its dependencies. The tunable accepts two different values, where + '0' disable memory sealing (even if the GNU_PROPERTY_MEMORY_SEAL attribute + is present), while '1' applies sealing accordingly to the sealing + attribute. + Deprecated and removed features, and other changes affecting compatibility: [Add deprecations, removals and changes affecting compatibility here] diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 0b6721bc51..43758f9755 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -141,6 +141,12 @@ glibc { maxval: 1 default: 1 } + seal { + type: INT_32 + minval: 0 + maxval: 1 + default: 1 + } } mem { diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp index 9f5990f340..e398b9f020 100644 --- a/elf/tst-rtld-list-tunables.exp +++ b/elf/tst-rtld-list-tunables.exp @@ -16,3 +16,4 @@ glibc.rtld.enable_secure: 0 (min: 0, max: 1) glibc.rtld.execstack: 1 (min: 0, max: 1) glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) +glibc.rtld.seal: 1 (min: 0, max: 1) diff --git a/manual/tunables.texi b/manual/tunables.texi index 7f0246c789..1af0956808 100644 --- a/manual/tunables.texi +++ b/manual/tunables.texi @@ -383,6 +383,42 @@ main program does not require an executable stack at loading time. This is enforced regardless of the tunable value. @end deftp +@deftp Tunable glibc.rtld.seal +Sets whether to enable memory sealing during program execution. The sealed +memory prevents further changes to the metadata associated with an ELF mapped +memory region, such as shrinking or expanding its size, mapping another +segment over a pre-existing region, or changing the memory protection flags +(check the @code{mseal} for more information). + +The sealing is done in multiple places where the memory is supposed to be +immutable over program execution: + +@itemize @bullet +@item +All shared library dependencies from the binary, including the read-only segments +after @code{PT_GNU_RELRO} setup. + +@item +The binary itself, including dynamic and static linked ones. In both cases, it is +up either to binary or the loader to set up the sealing. + +@item +Any preload libraries. + +@item +Any library loaded with @code{dlopen} with @code{RTLD_NODELETE} flag. + +@item +All audit modules and their dependencies. +@end itemize + +The tunable accepts two values: @samp{0} where sealing is disabled even if the +program has the GNU attribute @code{GNU_PROPERTY_MEMORY_SEAL} if present, +and @samp{1} where sealing is aplied accondingly to the GNU attribute existent. + +The default value of this tunable is @samp{1}. +@end deftp + @node Elision Tunables @section Elision Tunables @cindex elision tunables diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 2faa377fd5..9bb3eeb53e 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -698,6 +698,7 @@ tests += \ $(tests-static) \ tst-dl_mseal \ tst-dl_mseal-noseal \ + tst-dl_mseal-tunable \ # tests modules-names += \ @@ -713,25 +714,22 @@ modules-names += \ tst-dl_mseal-preload \ # modules-names -$(objpfx)tst-dl_mseal.out: \ +test-dl_mseal-mods = \ $(objpfx)tst-dl_mseal-auditmod.so \ - $(objpfx)tst-dl_mseal-preload.so \ - $(objpfx)tst-dl_mseal-mod-1.so \ - $(objpfx)tst-dl_mseal-mod-2.so \ - $(objpfx)tst-dl_mseal-dlopen-1.so \ $(objpfx)tst-dl_mseal-dlopen-1-1.so \ + $(objpfx)tst-dl_mseal-dlopen-1.so \ + $(objpfx)tst-dl_mseal-dlopen-2-1.so \ $(objpfx)tst-dl_mseal-dlopen-2.so \ - $(objpfx)tst-dl_mseal-dlopen-2-1.so - -$(objpfx)tst-dl_mseal-noseal.out: \ - $(objpfx)tst-dl_mseal-auditmod.so \ - $(objpfx)tst-dl_mseal-preload.so \ $(objpfx)tst-dl_mseal-mod-1.so \ $(objpfx)tst-dl_mseal-mod-2.so \ - $(objpfx)tst-dl_mseal-dlopen-1.so \ - $(objpfx)tst-dl_mseal-dlopen-1-1.so \ - $(objpfx)tst-dl_mseal-dlopen-2.so \ - $(objpfx)tst-dl_mseal-dlopen-2-1.so + $(objpfx)tst-dl_mseal-preload.so \ + # test-dl_mseal-mods + +$(objpfx)tst-dl_mseal.out: $(test-dl_mseal-mods) + +$(objpfx)tst-dl_mseal-noseal.out: $(test-dl_mseal-mods) + +$(objpfx)tst-dl_mseal-tunable.out: $(test-dl_mseal-mods) $(objpfx)tst-dl_mseal-mutable.out: \ $(objpfx)tst-dl_mseal-mutable-mod.so \ @@ -771,6 +769,7 @@ tst-dl_mseal-ARGS = -- $(host-test-program-cmd) tst-dl_mseal-static-ARGS = -- $(host-test-program-cmd) tst-dl_mseal-noseal-ARGS = -- $(host-test-program-cmd) tst-dl_mseal-static-noseal-ARGS = -- $(host-test-program-cmd) +tst-dl_mseal-tunable-ARGS = -- $(host-test-program-cmd) ifeq ($(have-pt-gnu-mutable),yes) tests-static += \ diff --git a/sysdeps/unix/sysv/linux/dl-mseal.c b/sysdeps/unix/sysv/linux/dl-mseal.c index 74ab688ef3..acdbf79f1b 100644 --- a/sysdeps/unix/sysv/linux/dl-mseal.c +++ b/sysdeps/unix/sysv/linux/dl-mseal.c @@ -22,9 +22,18 @@ #include #include +static inline bool +is_sealing_enable (void) +{ + return TUNABLE_GET (glibc, rtld, seal, int32_t, NULL) == 1; +} + void _dl_mseal (void *addr, size_t len, const char *object) { + if (__glibc_unlikely (!is_sealing_enable ())) + return; + int r = 0; bool fail = false; #if __ASSUME_MSEAL diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c index 686347c86e..a1d0f077c4 100644 --- a/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c @@ -32,6 +32,10 @@ #include "tst-dl_mseal-common.h" +#ifndef TEST_NAME +# define TEST_NAME "tst-dl_mseal-noseal" +#endif + /* Expected libraries that loader will seal. */ static const char *expected_sealed_vmas[] = { @@ -43,7 +47,7 @@ static const char *expected_non_sealed_vmas[] = { "libc.so", "ld.so", - "tst-dl_mseal-noseal", + TEST_NAME, LIB_PRELOAD, LIB_AUDIT, LIB_MODULE1, diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c index 570a0a867d..1be341df5f 100644 --- a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c @@ -235,6 +235,9 @@ do_test (int argc, char *argv[]) #endif #ifdef LD_AUDIT (char *) "LD_AUDIT=" LD_AUDIT, +#endif +#ifdef TUNABLE_ENV_VAR + TUNABLE_ENV_VAR, #endif NULL }; diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-tunable.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-tunable.c new file mode 100644 index 0000000000..df70132cd2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-tunable.c @@ -0,0 +1,24 @@ +/* Check glibc.rtld.seal tunable. + Copyright (C) 2025 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 + . */ + +/* Check if memory sealing is not applied if glibc.rtld.seal is set to 0. */ + +#define TUNABLE_ENV_VAR (char *)"GLIBC_TUNABLES=glibc.rtld.seal=0" + +#define TEST_NAME "tst-dl_mseal-tunable" +#include "tst-dl_mseal-noseal.c"