From patchwork Mon Sep 30 20:08:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 831571 Delivered-To: patch@linaro.org Received: by 2002:a5d:66c8:0:b0:367:895a:4699 with SMTP id k8csp2120293wrw; Mon, 30 Sep 2024 13:09:04 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUo6g8cL/idDSH8CEomy2TSdv8G1ZMSIov92KrxXt0WyPABMDwdx2rsNFd4elyJwDLcnQDqoQ==@linaro.org X-Google-Smtp-Source: AGHT+IGck1fP7/VQJL68ZjqFfiNitvBikSb+l2Whe1FrRlW8vIynZbaae7NrsjjMRnuu4jQuDFl5 X-Received: by 2002:a05:620a:4408:b0:7a9:ad7b:c8db with SMTP id af79cd13be357-7ae378dc775mr2104986785a.62.1727726943912; Mon, 30 Sep 2024 13:09:03 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1727726943; cv=pass; d=google.com; s=arc-20240605; b=g0PXe27EsSMPc1p2hcvfRF4tRuhZ7BqlQgce0qHF74JS0UyLjzIHLjNgtYKdqNw1LI 74LqnPftpTmW4KOIZzxEfhKv/3rUULpGudidjn7WtmJJlsVEw/4WQgenM84riRJL0UwA ugNdSRVS5hXp5JafpAqLt5vv01AJd7lbGoKR6+p7FvGH/xWelY6qyjQQKYRzytMc2Rg6 YIdzIZcTYixkK0Xj+JW8FI15/R+bXftFCIPpJ9cg6YlQeJTpHzlTDGR1MYinHTmDjbpL DcF2Lg6Ey5l7D65zJF6ucRYhykExEP8SXLn7dRMSHrxS/6STGbAwVOsBK74pRCbMMoRS qukg== 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=rcAMEy/gQDVDkzSX7JPGuyERSO+AT9bghXdWr6eZjDI=; fh=jV+RmF17NVd0KO+x04CXEAt2ahoCnMlV5/fgLD2kZ2g=; b=JwshSrch86XLZ6kuIQ/5PVp4HqHDac+VaTiXCdc2qVysuO8Z98IdjXlsMYVKunUhkl QcX56DpLzSVGdyZgWdqHf6lvPinRBhVj2BQ4fsHY4CkHbOo1cn2iGRWrsF9vESy22vHp jvr1uyYBhkkziZCQKYUPBxTA6EGXp8Da/HOUQW4H6wOmy8Mf6GQrUU0COHtugZQPGDXc zlJK0QFS8LKrTAz1g+cn+8bPBIxDt112fy/c/b1rrIyz1CCRTH6fBqjXRG3m9gif+YiD zp9rwVdKZqJG1UyK25op3GdvqcA5oSQVGHw6v9XP4ZIKz2Q8fh19suZmXdHB4s8+dYvD VXkA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OdrtnMiM; arc=pass (i=1); spf=pass (google.com: domain of binutils-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-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 af79cd13be357-7ae3da3ddcdsi739082585a.238.2024.09.30.13.09.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 13:09:03 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-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=OdrtnMiM; arc=pass (i=1); spf=pass (google.com: domain of binutils-bounces~patch=linaro.org@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-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 885CD38460BD for ; Mon, 30 Sep 2024 20:09:03 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@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 CFBEC3846459 for ; Mon, 30 Sep 2024 20:08:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CFBEC3846459 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 CFBEC3846459 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=1727726923; cv=none; b=DOviqRz9k7EUs7kNew8mTIYbu506Q9s/Jhu2x9Op1KbZE2/kMYoqUiVjKnQE8hGm3e9d3pGXAnIzxM0S8G/ipNWHZlx0jsdCeWF/ZrKJUPhEZqezqs4tBUMmEVC2UkkKmJ8dfjZ3G91FU7/RiVu9AXbhAaA08FNFBS17Mp/LatE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727726923; c=relaxed/simple; bh=6pv1rXGXYW9XVELZOV33biAdRMjAcG3W2dlEghzDKi0=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=U5rdHa/xnmQ/8vcQ76pzQVi/C4kAoO1LlTbz5+zNwrsuG9ab3FWPHU3bhcLfCBXqTcWnuQIlagthT5s8vrpZDGEU/S2pNcZwyEf44huA9GvYm0ABQwGHU5qDOlPhFKlskEXCIe6gVmKqaRcjFibMUaFqjFnJarwJIv+XdBowWwE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2e09fe0a878so3145644a91.1 for ; Mon, 30 Sep 2024 13:08:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1727726917; x=1728331717; 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=rcAMEy/gQDVDkzSX7JPGuyERSO+AT9bghXdWr6eZjDI=; b=OdrtnMiMFpOOEE1bYB3+dbzDjznlEutxa0qZ0RylgWksLrxLg8cpyWXLoexne7/9uZ kK+jWKEyOZmpzDOb4HxD3j+8av+HWtbw/gPfKFzTp9N72eVjkeCJ61KwwcLobiTyxN2J pij9X3SZF5SXnh0LAoioHlyKosGkRWJQgqSC+Uij5mpg5YaLxODHO4mm46tPRPLVw2BQ FlUtPaCS0M/jNWgYRyHqSqnPYw7t7q5pR2QOJNB3Yb8iY3r7XePK4stPMmL/+Ox7Mq7B Zo4hS8I62SfPMGRZtAfYNb72I9oasWaF9KpD4BfE21EWDJBqnsQJ90OnSmLZ0JoWaknn CcqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727726917; x=1728331717; 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=rcAMEy/gQDVDkzSX7JPGuyERSO+AT9bghXdWr6eZjDI=; b=F5ShdOsZ8X4xV9FNBec9tf3ghbZGfQfKwbiRlcVO+gsmGEEw56+4mvZFa3dHsE52nW XrNsTNcyBs+PHg81WIc1REbgK87Eop3YmrnSahNuWsKUHGzjtbdpIHALXKkRr+gIpPEB kqLj769sHNNtHpzVyXLBncjursGEh/LgibbURC3ySMGY7meS0qDcW3WWCAh4MmVT3moz HNYEtjGfh42sZUgggAM7bfdLvjuqTPjLYsZzPAOLHTd7Pnf88D1Buv9ssQn0YrjfFXYF awv0BBLNhok162BHRgHzgvlbSEJs8ToACqQpF/vny8ShoAjWhx5uW7KjqtGidPClNmo/ +pCg== X-Gm-Message-State: AOJu0YwHW+K3q+1ULjajNLC64EwZNtiPx1oOuNrVJSE3wZ4+KCB14ysX 74jfpfRZ/el7O4CyliCTY0e0KbY5GdgLbvrMJtWu2Em+0+gE4RHdIn0CfBD4jInvjkqhkIxmXtF Il6o= X-Received: by 2002:a17:90a:fd84:b0:2d8:27c3:87d7 with SMTP id 98e67ed59e1d1-2e0b866cdc7mr14088380a91.8.1727726917181; Mon, 30 Sep 2024 13:08:37 -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 98e67ed59e1d1-2e0b6c9b438sm8464787a91.28.2024.09.30.13.08.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 13:08:36 -0700 (PDT) From: Adhemerval Zanella To: binutils@sourceware.org Cc: Stephen Roettger , Jeff Xu , Florian Weimer , Mike Hommey , Adhemerval Zanella Subject: [PATCH v2 1/3] elf: Add GNU_PROPERTY_MEMORY_SEAL gnu property Date: Mon, 30 Sep 2024 17:08:20 -0300 Message-Id: <20240930200822.1669666-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240930200822.1669666-1-adhemerval.zanella@linaro.org> References: <20240930200822.1669666-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patch=linaro.org@sourceware.org Along with -Wl,memory-seal/-Wl,nomemory-seal options to ld.bfd. The new attribute indicates that an ET_EXEC or ET_DYN ELF object should be memory-sealed if the loader supports it. Memory sealing is useful as a hardening mechanism to avoid either remapping the memory segments or changing the memory protection segments layout by the dynamic loader (for instance, the RELRO hardening). The Linux 6.10 (8be7258aad44b5e25977a98db136f677fa6f4370) added the mseal syscall accomplishes it. A GNU property is used instead of a new dynamic section tag (like the one proposed for DT_GNU_FLAGS_1) because the memory sealing should be selectable for ET_EXEC and not only for ET_DYN. It also fits new opt-in security features like x86 CET or AArch64 BTI. --- bfd/elf-properties.c | 72 ++++++++++++++++++++------- bfd/elfxx-x86.c | 3 +- binutils/readelf.c | 6 +++ include/bfdlink.h | 3 ++ include/elf/common.h | 1 + ld/NEWS | 3 ++ ld/emultempl/elf.em | 4 ++ ld/ld.texi | 8 +++ ld/lexsup.c | 4 ++ ld/testsuite/ld-elf/property-seal-1.d | 15 ++++++ ld/testsuite/ld-elf/property-seal-2.d | 14 ++++++ 11 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 ld/testsuite/ld-elf/property-seal-1.d create mode 100644 ld/testsuite/ld-elf/property-seal-2.d diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index ee8bd37f2bd..17c89d9e876 100644 --- a/bfd/elf-properties.c +++ b/bfd/elf-properties.c @@ -177,6 +177,9 @@ _bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note) prop->pr_kind = property_number; goto next; + case GNU_PROPERTY_MEMORY_SEAL: + goto next; + default: if ((type >= GNU_PROPERTY_UINT32_AND_LO && type <= GNU_PROPERTY_UINT32_AND_HI) @@ -258,6 +261,9 @@ elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, bfd *bbfd, be added to ABFD. */ return aprop == NULL; + case GNU_PROPERTY_MEMORY_SEAL: + return aprop == NULL; + default: updated = false; if (pr_type >= GNU_PROPERTY_UINT32_OR_LO @@ -607,6 +613,33 @@ elf_write_gnu_properties (struct bfd_link_info *info, } } +static asection * +_bfd_elf_link_create_gnu_property_sec (struct bfd_link_info *info, bfd *elf_bfd, + unsigned int elfclass) +{ + asection *sec; + + sec = bfd_make_section_with_flags (elf_bfd, + NOTE_GNU_PROPERTY_SECTION_NAME, + (SEC_ALLOC + | SEC_LOAD + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_HAS_CONTENTS + | SEC_DATA)); + if (sec == NULL) + info->callbacks->einfo (_("%F%P: failed to create GNU property section\n")); + + if (!bfd_set_section_alignment (sec, + elfclass == ELFCLASS64 ? 3 : 2)) + info->callbacks->einfo (_("%F%pA: failed to align section\n"), + sec); + + elf_section_type (sec) = SHT_NOTE; + return sec; +} + + /* Set up GNU properties. Return the first relocatable ELF input with GNU properties if found. Otherwise, return NULL. */ @@ -656,23 +689,7 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) /* Support -z indirect-extern-access. */ if (first_pbfd == NULL) { - sec = bfd_make_section_with_flags (elf_bfd, - NOTE_GNU_PROPERTY_SECTION_NAME, - (SEC_ALLOC - | SEC_LOAD - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_HAS_CONTENTS - | SEC_DATA)); - if (sec == NULL) - info->callbacks->einfo (_("%F%P: failed to create GNU property section\n")); - - if (!bfd_set_section_alignment (sec, - elfclass == ELFCLASS64 ? 3 : 2)) - info->callbacks->einfo (_("%F%pA: failed to align section\n"), - sec); - - elf_section_type (sec) = SHT_NOTE; + sec = _bfd_elf_link_create_gnu_property_sec (info, elf_bfd, elfclass); first_pbfd = elf_bfd; has_properties = true; } @@ -690,6 +707,27 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; } + if (info->memory_seal && elf_bfd != NULL) + { + /* Support -z no-memory-seal. */ + if (first_pbfd == NULL) + { + sec = _bfd_elf_link_create_gnu_property_sec (info, elf_bfd, elfclass); + first_pbfd = elf_bfd; + has_properties = true; + } + + p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_MEMORY_SEAL, 0); + if (p->pr_kind == property_unknown) + { + /* Create GNU_PROPERTY_NO_MEMORY_SEAL. */ + p->u.number = GNU_PROPERTY_MEMORY_SEAL; + p->pr_kind = property_number; + } + else + p->u.number |= GNU_PROPERTY_MEMORY_SEAL; + } + /* Do nothing if there is no .note.gnu.property section. */ if (!has_properties) return NULL; diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index dd951b91f50..8a4405c8a79 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -4815,7 +4815,8 @@ _bfd_x86_elf_link_fixup_gnu_properties for (p = *listp; p; p = p->next) { unsigned int type = p->property.pr_type; - if (type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED + if (type == GNU_PROPERTY_MEMORY_SEAL + || type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED || type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED || (type >= GNU_PROPERTY_X86_UINT32_AND_LO && type <= GNU_PROPERTY_X86_UINT32_AND_HI) diff --git a/binutils/readelf.c b/binutils/readelf.c index 0f8dc1b9716..bf25425bb8d 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -21464,6 +21464,12 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote) printf (_(" "), datasz); goto next; + case GNU_PROPERTY_MEMORY_SEAL: + printf ("memory seal "); + if (datasz) + printf (_(" "), datasz); + goto next; + default: if ((type >= GNU_PROPERTY_UINT32_AND_LO && type <= GNU_PROPERTY_UINT32_AND_HI) diff --git a/include/bfdlink.h b/include/bfdlink.h index f802ec627ef..8b9e391e6ff 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -429,6 +429,9 @@ struct bfd_link_info /* TRUE if only one read-only, non-code segment should be created. */ unsigned int one_rosegment: 1; + /* TRUE if GNU_PROPERTY_MEMORY_SEAL should be generated. */ + unsigned int memory_seal: 1; + /* Nonzero if .eh_frame_hdr section and PT_GNU_EH_FRAME ELF segment should be created. 1 for DWARF2 tables, 2 for compact tables. */ unsigned int eh_frame_hdr_type: 2; diff --git a/include/elf/common.h b/include/elf/common.h index c9920e7731a..8938e2f4754 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -890,6 +890,7 @@ /* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */ #define GNU_PROPERTY_STACK_SIZE 1 #define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 +#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/ld/NEWS b/ld/NEWS index 1f14dd6bc77..4a28592fa32 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -23,6 +23,9 @@ Changes in 2.43: * Add -plugin-save-temps to store plugin intermediate files permanently. +* Add -z memory-seal/-z nomemory-seal options to ELF linker to mark the + object to memory sealed. + Changes in 2.42: * Add -z mark-plt/-z nomark-plt options to x86-64 ELF linker to mark PLT diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index 2e865728587..ccd43531237 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -1075,6 +1075,10 @@ fragment <