From patchwork Mon Sep 30 20:08:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 831583 Delivered-To: patch@linaro.org Received: by 2002:a5d:66c8:0:b0:367:895a:4699 with SMTP id k8csp2122224wrw; Mon, 30 Sep 2024 13:14:27 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCX2QBeuhCzZcxLxVSipOXnOsu/TfFrSxcCAD1HVqPkM/5NFoNURGVFoKFbK+OgbUc3wjX3qNQ==@linaro.org X-Google-Smtp-Source: AGHT+IEBRibPJrQTHa9D149+SOOL2PWLLzL6x5RUlYaQIn1vDYFdW74Qy7EYFN3cvRkdcNDI8P6x X-Received: by 2002:ac8:590c:0:b0:458:2f54:3bb5 with SMTP id d75a77b69052e-45c9f1b6ad0mr197515191cf.7.1727727267054; Mon, 30 Sep 2024 13:14:27 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1727727267; cv=pass; d=google.com; s=arc-20240605; b=L2gmUNMYkmwb6dhFtG0ixG0uxOLxhvhXsQY1O6Hhvihafn+x8B2PStzojqpiGn1x6R DcDskS2H+sDmy1BYmvXwSCvGwzLvxR8ljc5qGg7CKEq62buyJ2fhBBp7/5UYTkenE36R 6nV60tj5qo62Im2tKhEcEtpl+jmFLkikaCiQu7Py09G+xTWEVHDN4aIVk/Z0/LW2mjd5 uNqz81aYAsYqv9XYNpqoez0f5WxvWjA+ihymgV9i6lhYM1d7xLrLlelo9QOmwlLZ1ha2 8zgaYC1J+0ALBW3IDTcFR51nAjS4csKUrVLHsFF78O/TuC10fr5ocPz9C6eR/ni7Zmek XYkA== 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:arc-filter:dmarc-filter:delivered-to; bh=ZkRcoEqR/25SEAMrW4BsX0yjIkkSQGE+0esw2BI5mts=; fh=3tUIaab7WH3k5DYf15UFmY7vUQNGmrLDHVJFJrkNDfY=; b=Lkbwlct1GwG5UmODg1OfrcT2GLeGzjmTjwWHd1lMvcbCpwqtM3BNuwk1liOmq3r8Jw GYSYMyzog05uaaoVbg/jiCwMxH30DhfcvIxjhbMldGaWTWD2IRVcknvLhiJHpAkEXVvc tn3EfrD8qDcyuspnT6oN8X+bqnQFK73tey73qNBJ/49dGWzkAxMmgFBpGPB/0svWsFON EaMx2YiBlTpjPW4/M+DbRtop+B4hS9dfn9b7hl75jPdzG6MQ6A/oCX3of1fMbEeo8hgy qHcq0MpRxBjBQcUQZfLPSPweNVd6aohSOdmQ3Chc+CwChwZmdICBWMTO53BW9MCjlFCZ BHzg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=IMkNma5j; 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-45c9f328fd3si90356721cf.353.2024.09.30.13.14.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 13:14:27 -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=IMkNma5j; 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 AB0323849AC4 for ; Mon, 30 Sep 2024 20:14:26 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-io1-xd2b.google.com (mail-io1-xd2b.google.com [IPv6:2607:f8b0:4864:20::d2b]) by sourceware.org (Postfix) with ESMTPS id F133D384A487 for ; Mon, 30 Sep 2024 20:09:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F133D384A487 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 F133D384A487 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::d2b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727726953; cv=none; b=M7xC/JK/s7pIEVnkQokL318xuD7AZhRV8i+EmAks7IeZAY6NrAmPrUeWDBpkgzzao2U9ZFxwVmLtt87NMrOsisS5h35Wk3ZsGuO8zhErS7ZxT9kG/VDSuLXogzU6IGgP85jp9YoiSNEaRo6eOQxcGhcRnDNUmMV+OMwD7+8Egmw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727726953; c=relaxed/simple; bh=brkUsjS4YSm9BF8SFM5keIiSFMrra1r15wdeUibZvVU=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=gNF+8+kTxFYd9qoe+9XLW2G2dRkJVi3NjzVIYjnm2My6vVPnMWLmI69OhUQrtyv+e4nuEZE3CQHSDI9dygCvyMl0gNBrcbCPYk2UBXqN+gzs1QPIjrkyyXmJWvUXoamHLvSGb8zE4Gugv7n58LN4UGTSsx12kd4VYYhje5SkRS4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-io1-xd2b.google.com with SMTP id ca18e2360f4ac-82cd93a6617so196464439f.3 for ; Mon, 30 Sep 2024 13:09:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1727726944; x=1728331744; 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=ZkRcoEqR/25SEAMrW4BsX0yjIkkSQGE+0esw2BI5mts=; b=IMkNma5j2a4i0sYZNAs/L02gkQvwskNPeUS1wSpQ5hvgWpP+fGKIuxtpauddbrWK+e 0n67KfaYq7CmzjMiK1wI0MWcSh6rbbXfGYm9Abd7N0dJ8axrsSjuS2HF3iFgdkmKtEx1 sN3uYUbZ7z5cWtrfkeAdzLwEgBwbHbAGhou2BAFNr3Wh0riFB69TlcgO9SiRlPoNnRbt afSYhtsfi4QO3ZykEdujynjPdlGgJS+AZFmVg2wnTV3Vm5Tsg0eaUTOqBEK0zgcMRi9B vjHV9EiGfr9YWN5683x0Zo5heFBh6oXQGuwloD58RGgEkBgMWguO4U7cm+Qvl5sQ1/Dw gmQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727726944; x=1728331744; 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=ZkRcoEqR/25SEAMrW4BsX0yjIkkSQGE+0esw2BI5mts=; b=AwFq80wOb1Et+c4jyhaP1FLlARn8dFQuePlXv0ckoffc4uSv/fPe5AWS+Ig0x/0Yna 521qG9OlBqvt38PytMfxHwz25O2w0uZaJbCJ+RnZVC8xuiGG3h8iBb72UGXEmnmgkHFL lyisCUUXKjM4Aze66MXq/vvBeheJz6P5nUme/kfRfWm+FtZQ+7V1AWcij4JG6MZ/WycX 7fXoF7J4npzvSnREtY3ETq9tcpsObeBG6hAbilgmM1uhdmW/taKiKpDp1Rapf5h0kyI4 k7TPLDHEGT7l8xYjvtOwlT8b5FKaAj4IwgCkbt+peC8L1hPR/o+hnysGdX9lWbn57dyK 4Urw== X-Gm-Message-State: AOJu0YxzYceMeHwLvbeEJ/uMD2q4601i1IH5+7gZm+vYrnOvzYGzF3GK nWeubkoCdBJvgetTnWIxkAwaTcNh9YgBqpLDlCkwOM5d+2gSkuUQsQ6YBqgvV8IxwF990NucubB y05I= X-Received: by 2002:a05:6e02:1fcd:b0:39d:1ca5:3904 with SMTP id e9e14a558f8ab-3a34517f9bbmr97690265ab.14.1727726943603; Mon, 30 Sep 2024 13:09:03 -0700 (PDT) Received: from ubuntu-vm.. (201-92-183-102.dsl.telesp.net.br. [201.92.183.102]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7e6db2c4845sm6869565a12.43.2024.09.30.13.09.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 13:09:03 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Stephen Roettger , Jeff Xu , Florian Weimer , Mike Hommey , Adhemerval Zanella Subject: [PATCH v3 9/9] elf: Add glibc.rtld.seal tunable Date: Mon, 30 Sep 2024 17:08:31 -0300 Message-Id: <20240930200831.1669010-10-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240930200831.1669010-1-adhemerval.zanella@linaro.org> References: <20240930200831.1669010-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patch=linaro.org@sourceware.org The new tunable can be used to enforce memory sealing on the program and all its dependencies. The tunable accepts two different values: * '0' where loaders follow the GNU_PROPERTY_MEMORY_SEAL attribute if present. This is the default and no sealing would be applied if the object does not have the memory sealing attribute. * '1' where sealing is enforced even if the object does not have the GNU_PROPERTY_MEMORY_SEAL. Also, any syscall failure on memory sealing aborts the programs. Checked on x86_64-linux-gnu and aarch64-linux-gnu. --- NEWS | 6 ++ elf/dl-load.c | 3 + elf/dl-mseal-mode.h | 28 +++++++ elf/dl-reloc.c | 13 ++++ elf/dl-support.c | 2 + elf/dl-tunables.list | 6 ++ elf/rtld.c | 5 ++ elf/tst-rtld-list-tunables.exp | 1 + manual/tunables.texi | 35 +++++++++ sysdeps/generic/ldsodefs.h | 6 ++ sysdeps/unix/sysv/linux/Makefile | 15 ++++ sysdeps/unix/sysv/linux/dl-mseal.c | 7 ++ .../unix/sysv/linux/tst-dl_mseal-skeleton.c | 5 +- .../unix/sysv/linux/tst-dl_mseal-tunable.c | 76 +++++++++++++++++++ 14 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 elf/dl-mseal-mode.h create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-tunable.c diff --git a/NEWS b/NEWS index ad1b05e015..728ff91ab1 100644 --- a/NEWS +++ b/NEWS @@ -45,6 +45,12 @@ Major new features: memory sealing by default if the toochain supports it. A new configure option, --disable-default-memory-seal, disables it. +* A new tunable, glibc.rtld.seal, can enable memory sealing on the program + and all its dependencies. The tunable accepts two different values, + with '0' applying the GNU attribute GNU_PROPERTY_MEMORY_SEAL (if present), + or '1' to enforce sealing the program and its dependencies (including + preload, audit modules, and objects opened with RTLD_NODELETE). + Deprecated and removed features, and other changes affecting compatibility: * The big-endian ARC port (arceb-linux-gnu) has been removed. diff --git a/elf/dl-load.c b/elf/dl-load.c index 41165287ae..f3bec94fe3 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1315,6 +1315,9 @@ cannot enable executable stack as shared object requires"); break; } + /* Update the sealing mode based on the tunable. */ + _dl_mseal_update_map (l, mode); + /* We are done mapping in the file. We no longer need the descriptor. */ if (__glibc_unlikely (__close_nocancel (fd) != 0)) { diff --git a/elf/dl-mseal-mode.h b/elf/dl-mseal-mode.h new file mode 100644 index 0000000000..745ca60064 --- /dev/null +++ b/elf/dl-mseal-mode.h @@ -0,0 +1,28 @@ +/* Memory sealing tunable. Generic definitions. + Copyright (C) 2024 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_MODE_H +#define _DL_MSEAL_MODE_H + +enum dl_seal_mode +{ + DL_SEAL_DEFAULT = 0, + DL_SEAL_ENFORCE = 1, +}; + +#endif diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 637870d0c7..6a10cb431b 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -29,6 +29,8 @@ #include #include "dynamic-link.h" #include +#include +#include /* Statistics function. */ #ifdef SHARED @@ -375,6 +377,17 @@ cannot apply additional memory protection after relocation"); } } +void +_dl_mseal_update_map (struct link_map *map, int mode) +{ + /* Also enable forced sealing on audit modules, loader will apply it + after the modules is being loaded and validated. */ + if (TUNABLE_GET (glibc, rtld, seal, int32_t, NULL) == DL_SEAL_ENFORCE + && (!(mode & __RTLD_DLOPEN) + || (mode & RTLD_NODELETE) || (mode & __RTLD_AUDIT))) + map->l_seal = lt_seal_toseal; +} + static void _dl_mseal_map_1 (struct link_map *l, bool force) { diff --git a/elf/dl-support.c b/elf/dl-support.c index 9fb185fb30..1aea1aa6cd 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -349,6 +349,8 @@ _dl_non_dynamic_init (void) _dl_process_pt_gnu_property (&_dl_main_map, -1, &ph[-1]); break; } + /* Update the sealing mode based on the tunable. */ + _dl_mseal_update_map (&_dl_main_map, 0); call_function_static_weak (_dl_find_object_init); diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 40ac5b3776..4bc694bee5 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -135,6 +135,12 @@ glibc { maxval: 1 default: 0 } + seal { + type: INT_32 + minval: 0 + maxval: 1 + default: 0 + } } mem { diff --git a/elf/rtld.c b/elf/rtld.c index 90eb798013..027e43ce1b 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1247,6 +1247,9 @@ rtld_setup_main_map (struct link_map *main_map) break; } + /* Update the sealing mode based on the tunable. */ + _dl_mseal_update_map (main_map, 0); + /* 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) @@ -1766,6 +1769,8 @@ dl_main (const ElfW(Phdr) *phdr, break; } + _dl_mseal_update_map (&GL(dl_rtld_map), 0); + /* Add the dynamic linker to the TLS list if it also uses TLS. */ if (GL(dl_rtld_map).l_tls_blocksize != 0) /* Assign a module ID. Do this before loading any audit modules. */ diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp index db0e1c86e9..01e614646c 100644 --- a/elf/tst-rtld-list-tunables.exp +++ b/elf/tst-rtld-list-tunables.exp @@ -15,3 +15,4 @@ glibc.rtld.dynamic_sort: 2 (min: 1, max: 2) glibc.rtld.enable_secure: 0 (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: 0 (min: 0, max: 1) diff --git a/manual/tunables.texi b/manual/tunables.texi index 0b1b2898c0..4dbbdf4ac2 100644 --- a/manual/tunables.texi +++ b/manual/tunables.texi @@ -355,6 +355,41 @@ tests for @code{AT_SECURE} programs and not meant to be a security feature. The default value of this tunable is @samp{0}. @end deftp +@deftp Tunable glibc.rtld.seal +Sets whether to enable memory sealing during program execution. The sealed +memory prevents further changes to the mapped memory region, such as shrinking +or expanding, 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 applies the GNU attribute +@code{GNU_PROPERTY_MEMORY_SEAL} if present, and @samp{1} where sealing is +enforced on the binary and its dependencies. For the enforced mode, +if the memory can not be sealed the process terminates the execution. + +The default value of this tunable is @samp{0}. +@end deftp + @node Elision Tunables @section Elision Tunables @cindex elision tunables diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index e528b7ff83..926c615941 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1017,6 +1017,12 @@ extern void _dl_relocate_object (struct link_map *map, /* Protect PT_GNU_RELRO area. */ extern void _dl_protect_relro (struct link_map *map) attribute_hidden; +/* The the sealing mode of MAP based on open MODE and on the rtld.seal + tunable. */ +extern void _dl_mseal_update_map (struct link_map *map, + int mode) + 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 diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index a5e8843e6a..b4a12ad6ce 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -667,6 +667,7 @@ tests += \ $(tests-static) \ tst-dl_mseal \ tst-dl_mseal-noseal \ + tst-dl_mseal-tunable \ # tests modules-names += \ @@ -706,6 +707,16 @@ $(objpfx)tst-dl_mseal-noseal.out: \ $(objpfx)tst-dl_mseal-dlopen-2-noseal.so \ $(objpfx)tst-dl_mseal-dlopen-2-1-noseal.so +$(objpfx)tst-dl_mseal-tunable.out: \ + $(objpfx)tst-dl_mseal-auditmod-noseal.so \ + $(objpfx)tst-dl_mseal-preload-noseal.so \ + $(objpfx)tst-dl_mseal-mod-1-noseal.so \ + $(objpfx)tst-dl_mseal-mod-2-noseal.so \ + $(objpfx)tst-dl_mseal-dlopen-1.so \ + $(objpfx)tst-dl_mseal-dlopen-1-1.so \ + $(objpfx)tst-dl_mseal-dlopen-2-noseal.so \ + $(objpfx)tst-dl_mseal-dlopen-2-1-noseal.so + LDFLAGS-tst-dl_mseal = -Wl,--no-as-needed LDFLAGS-tst-dl_mseal-mod-1.so = -Wl,--no-as-needed LDFLAGS-tst-dl_mseal-dlopen-1.so = -Wl,--no-as-needed @@ -738,10 +749,14 @@ $(objpfx)tst-dl_mseal-dlopen-2-noseal.so: $(objpfx)tst-dl_mseal-dlopen-2-1-nosea tst-dl_mseal-static-noseal-no-memory-seal = yes +tst-dl_mseal-tunable-no-memory-seal = yes +$(objpfx)tst-dl_mseal-tunable: $(objpfx)tst-dl_mseal-mod-1-noseal.so + 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) endif endif diff --git a/sysdeps/unix/sysv/linux/dl-mseal.c b/sysdeps/unix/sysv/linux/dl-mseal.c index c99fd991cb..e4da0c32d2 100644 --- a/sysdeps/unix/sysv/linux/dl-mseal.c +++ b/sysdeps/unix/sysv/linux/dl-mseal.c @@ -17,6 +17,7 @@ . */ #include +#include #include #include #include @@ -37,5 +38,11 @@ _dl_mseal (void *addr, size_t len) atomic_store_relaxed (&mseal_supported, false); } #endif + if (TUNABLE_GET (glibc, rtld, seal, int32_t, NULL) == DL_SEAL_ENFORCE + && r != 0) + _dl_fatal_printf ("Fatal error: sealing is enforced and an error " + "ocurred for the 0x%lx-0x%lx range\n", + (long unsigned int) addr, + (long unsigned int) addr + len); return r; } diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c index b1b5f4226e..0562907560 100644 --- a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c @@ -39,8 +39,6 @@ # define PTR_FMT "#010" PRIxPTR #endif -#pragma GCC optimize ("O0") - static int new_flags (const char flags[4]) { @@ -249,6 +247,9 @@ do_test (int argc, char *argv[]) #ifndef TEST_STATIC (char *) "LD_PRELOAD=" LIB_PRELOAD, (char *) "LD_AUDIT=" LIB_AUDIT, +#endif +#ifdef TUNABLE_ENV_VAR + (char *) "GLIBC_TUNABLES=" 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..a1069164bb --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-tunable.c @@ -0,0 +1,76 @@ +/* Basic tests for sealing. Check the tunable in enforce mode. + Copyright (C) 2024 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 glibc.rtld.seal enforces sealing on multiple + places: + + - On the binary itself. + - On a LD_PRELOAD library. + - On a depedency module (tst-dl_mseal-mod-2-noseal.so). + - On a audit modules (tst-dl_mseal-auditmod-noeal.so). + - On a dlopen dependency opened with RTLD_NODELET + (tst-dl_mseal-dlopen-2-noseal.so). +*/ + +#define TUNABLE_ENV_VAR "glibc.rtld.seal=1" + +#define LIB_PRELOAD "tst-dl_mseal-preload-noseal.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-noseal.so" +#define LIB_DLOPEN_NODELETE_DEP "tst-dl_mseal-dlopen-2-1-noseal.so" + +#define LIB_AUDIT "tst-dl_mseal-auditmod-noseal.so" + +/* Expected libraries that loader will seal. */ +static const char *expected_sealed_vmas[] = +{ + "tst-dl_mseal-tunable", + "libc.so", + "ld.so", + "tst-dl_mseal-mod-1-noseal.so", + "tst-dl_mseal-mod-2-noseal.so", + LIB_DLOPEN_NODELETE, + LIB_DLOPEN_NODELETE_DEP, + LIB_AUDIT, + LIB_PRELOAD, +}; + +/* Expected non sealed libraries. */ +static const char *expected_non_sealed_vmas[] = +{ + LIB_DLOPEN_DEFAULT, + LIB_DLOPEN_DEFAULT_DEP, + /* Auxiary 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]", +}; + +#include "tst-dl_mseal-skeleton.c"