From patchwork Thu Jan 2 19:19:28 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: 854747 Delivered-To: patch@linaro.org Received: by 2002:a5d:4888:0:b0:385:e875:8a9e with SMTP id g8csp7928828wrq; Thu, 2 Jan 2025 11:20:49 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVbpeczDvn/SKEV/XMyhpzOW88QR+3FDjKK+rWO8+IKqHh2aclEmelHsXGRac88JUVFoMCQcQ==@linaro.org X-Google-Smtp-Source: AGHT+IH3vNewkDaKO3zS6J8ej4Xl4Xw0cUYWOOPmRQuyvOg+F3BaBEFtoWgdAFOPMdmF/r1fRM3G X-Received: by 2002:ac8:7e89:0:b0:467:43c1:f0ea with SMTP id d75a77b69052e-46a4a8e4636mr763843201cf.16.1735845649093; Thu, 02 Jan 2025 11:20:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1735845649; cv=pass; d=google.com; s=arc-20240605; b=gJaeBLt6iJbAMS+F0qMTJEFtFMLR5uvLtQjrcX5jUQicLsfuSwIJYSY/q9qOkAuCmu oNTeiUKN12EpoGXalKkyjDsdq/pHrFYcIt9ngi3jbdJ5uc1yHG5OR1aXB3OQpGOFdAIl l1azYsAftRTl094wvXpf4dvX9+vggRwvMyadtTQ4D6WoluRaVg0p6KjZtOvEGHKNdh/3 9ocfBmJRZg0yAKYSi1ou83BtasSOq4y+qneiZ7kN1PtZnWAhP291vO6+ys2xtUr/et7y ybZYuKgqkdx5JkWxAAifhPeeB/EMzuja3+31C7QvSvrkrnYdyH+9mmGoC9+XnnrlTrX6 BsgA== 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=z5/D4cRVeeJqevZoNEmNAv6L6BpEh2YpnbIWe9cl2Qs=; fh=JruiOR+n5wiv4jZbtXJYp9lJ8UkedxUHyGOCC37Fjus=; b=NB2GxWISgOjQ2UyLNDe/YjD0WHD8HgFQ0Qjz9SEl9vuDecmegT0RAtcRGJXg3QG3oJ dpwpsgdhuOWGymGmJ87XMj32Thm+nVbf4yLjNqXOdaMElclFQZoIBTJwhHp3u0NgJ9yT klkcSRP0PcHCdIIsJMv18/+PrxcIAO+NSMJuyiRIgw3SJqJo+6hKuxevR1vBuJhxyhPM /aK9tcusXzGY9c+Vb/V7kTkUsvguOhGFSmyw4IO+U8dcELSGoHYQ7J+H1BVVsEy0kkK7 SE21KqmyHjsTsWnRE6yriKbmU9Y1iDyyYOHVH/CfabqlQySBArKrBppVyp15JVljn2Oj F53A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=nA51NZVw; 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 6a1803df08f44-6dd18137a31si376562246d6.176.2025.01.02.11.20.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Jan 2025 11:20:49 -0800 (PST) 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=nA51NZVw; 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 A18783858C5F for ; Thu, 2 Jan 2025 19:20:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A18783858C5F 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=nA51NZVw X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id EC7DD3858CDA for ; Thu, 2 Jan 2025 19:20:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EC7DD3858CDA 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 EC7DD3858CDA Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1735845615; cv=none; b=iiQT767dFVpA3NJm3kQi7VipzsHo3K1YKgOmCAld8/SgDgVCNEZkzpb3/ZQhI27NT8J2tSs0Ty6JI6GdOvbHr12weWpyE/3Z/3CMZYwgh4m8FCIkdZNaN/jkZqyG9xxCxwBlMMsWAtlheoeyhUNbtDEscunY4vDbal05/lZP0NU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1735845615; c=relaxed/simple; bh=zfE4ej5SFnSH4nQVzfQ25bGE4Wxu9QGkBK5J7xSTcqU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=C5GcwPgdavfwYfjDC1zhEkt4Dqy0SC9nspT7dSbh21Po13JgA9A7K4WG//nK4SfYGXrJMpuNq9PNPg9KAfjyLlYJtw9k/1TYGYDCkbckRweRU3e93DYCpmPcGBfJtbtCqCky3WHJDR+UVS9B0mHk/E9PAxR387jo/Dnv8U28pfM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EC7DD3858CDA Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-2166f1e589cso193443305ad.3 for ; Thu, 02 Jan 2025 11:20:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1735845613; x=1736450413; 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=z5/D4cRVeeJqevZoNEmNAv6L6BpEh2YpnbIWe9cl2Qs=; b=nA51NZVwImRELYXMYOytHlvTofg5FSNb0B+EQSD3J6IJ4kiryjy5wyJ7VM6MLm9jEY EWzdaVoV4a9x6QASBz6UbZtMWl8X+MyAZOVZ0P2pzHM3ONkrE7UgUE16//q78cj7PKW8 3K871IuX1csfqJKlWFLQABHq4iNNrbwbY6QIqeEDl5kCpVcpvpNP+coqlVK52efy1rOd 3gwxx6rnN+xUGVYM3QxfRWGSz+jBkp/838T3JcrNyd33C5Cod3kNGBKXyQr8B4E42Ckn zfi2KkI7LSZpt9Ya2ld4LC/Zq/kx33oqbLnfCVdnvEpxwnfOuB1Z2xJYbWSTNv/ZzE9D ya1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735845613; x=1736450413; 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=z5/D4cRVeeJqevZoNEmNAv6L6BpEh2YpnbIWe9cl2Qs=; b=f/UWCJwFQH8DprET+Pa63cLRCwaJll4SbGoVbAQYbNZ3VEd5+TVDlz3Y6iG7Tj7b6O wbZp68o9V7NZ88zYtv4EGw42RKn2D4llK4rTVcRgnnfawWBVF0hnF+l6s40Lfuqhl2Z/ p0oDTkJBD7oWrLMuXmuZs/kMdCCebKb5L8QVGOyTeutU/Id/MJM3o6nrd/DGVVwkRugV AhIl92qmJmSHCT0BlUA1BASly0fD9ZUwVgcdC/ta2hX9TNAe21LNhYI0fTjnw8cVuoJh lNcoRVJNXk/MkKeIXoC/yCXqi8pgsyGEqJ7T7fXscYQPvvNX5C2zKA6Al3QLW+Bhf2+q vG3Q== X-Gm-Message-State: AOJu0YwkQl7jMm88ZJlUbXNrltdxsjtypkCm5vpqET3WDLI01rKLUIdP ho0jsha3tbq3ICKZ1QJtsjljuXCjzpaSCTm1q8wW3Dz8oGsQDN6hW3RP6PZOED1Prq6P8KvcUzp T X-Gm-Gg: ASbGnct4MEg3tgFAHh07xdpf0qLANkIvXuXT5FhVOv8Iu1mYmQjpot+D5qIwZ2WJi5z GF54cYRqpqIe41aggQOxkl/qp0XQSxWB2flrwkr9l8CMxXeTCW8b0PeZv77SuUZqoHLCTWSXdIZ chzKgT4ieaj2T3lYHdt4k9CGBnTv9z9j5FEYxToUt9/UjLYSpNwK8c8T9Q7JdVPRZ1cpj29uKJG 8/WgdQmSdxs0RbO1EfrsOpuM97FPmfCtWLLdm/351KUARQBC/6nL4KdzTUB6zTHnAFBx6sYGkuY sB+PNYSLnX28T5kyxb0JLKMyxKBT X-Received: by 2002:a05:6a21:4986:b0:1e6:44b4:78ab with SMTP id adf61e73a8af0-1e644b478fbmr31526881637.8.1735845613295; Thu, 02 Jan 2025 11:20:13 -0800 (PST) Received: from ubuntu-vm.. (201-92-186-201.dsl.telesp.net.br. [201.92.186.201]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-842b85efb58sm22604630a12.34.2025.01.02.11.20.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Jan 2025 11:20:12 -0800 (PST) From: Adhemerval Zanella To: binutils@sourceware.org Cc: Jeff Xu , "H . J . Lu" Subject: [PATCH v5 1/3] elf: Add GNU_PROPERTY_MEMORY_SEAL gnu property Date: Thu, 2 Jan 2025 16:19:28 -0300 Message-ID: <20250102192006.1318325-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250102192006.1318325-1-adhemerval.zanella@linaro.org> References: <20250102192006.1318325-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 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 The GNU_PROPERTY_MEMORY_SEAL gnu property is a way to mark binaries to be memory sealed by the loader, to avoid further changes of PT_LOAD segments (such as unmapping or change permission flags). This is done along with Linux kernel (the mseal syscall [1]), and C runtime supports to instruct the kernel on the correct time during program startup (for instance, after RELRO handling). This support is added along the glibc support to handle the new gnu property [2]. This is a opt-in security features, like other security hardening ones like NX-stack or RELRO. The new property is ignored if present on ET_REL objects, and only added on ET_EXEC/ET_DYN if the linker option is used. A gnu property is used instead of DT_FLAGS_1 flag to allow memory sealing to work with ET_EXEC without PT_DYNAMIC support (at least on glibc some ports still do no support static-pie). [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 [2] https://sourceware.org/pipermail/libc-alpha/2024-September/160291.html Change-Id: Id47fadabecd24be0e83cff45653f7ce9a900ecf4 --- bfd/elf-properties.c | 85 +++++++++++++++++++++------ 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 | 16 +++++ ld/testsuite/ld-elf/property-seal-1.s | 11 ++++ ld/testsuite/ld-elf/property-seal-2.d | 17 ++++++ ld/testsuite/ld-elf/property-seal-3.d | 16 +++++ ld/testsuite/ld-elf/property-seal-4.d | 16 +++++ ld/testsuite/ld-elf/property-seal-5.d | 15 +++++ ld/testsuite/ld-elf/property-seal-6.d | 16 +++++ ld/testsuite/ld-elf/property-seal-7.d | 14 +++++ ld/testsuite/ld-elf/property-seal-8.d | 15 +++++ 18 files changed, 235 insertions(+), 18 deletions(-) create mode 100644 ld/testsuite/ld-elf/property-seal-1.d create mode 100644 ld/testsuite/ld-elf/property-seal-1.s create mode 100644 ld/testsuite/ld-elf/property-seal-2.d create mode 100644 ld/testsuite/ld-elf/property-seal-3.d create mode 100644 ld/testsuite/ld-elf/property-seal-4.d create mode 100644 ld/testsuite/ld-elf/property-seal-5.d create mode 100644 ld/testsuite/ld-elf/property-seal-6.d create mode 100644 ld/testsuite/ld-elf/property-seal-7.d create mode 100644 ld/testsuite/ld-elf/property-seal-8.d diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index 61f01bf5380..23634a9d9c9 100644 --- a/bfd/elf-properties.c +++ b/bfd/elf-properties.c @@ -177,6 +177,20 @@ _bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note) prop->pr_kind = property_number; goto next; + case GNU_PROPERTY_MEMORY_SEAL: + if (datasz != 0) + { + _bfd_error_handler + (_("warning: %pB: corrupt memory sealing size: 0x%x"), + abfd, datasz); + /* Clear all properties. */ + elf_properties (abfd) = NULL; + return false; + } + prop = _bfd_elf_get_property (abfd, type, datasz); + prop->pr_kind = property_number; + goto next; + default: if ((type >= GNU_PROPERTY_UINT32_AND_LO && type <= GNU_PROPERTY_UINT32_AND_HI) @@ -254,6 +268,7 @@ elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, bfd *bbfd, /* FALLTHROUGH */ case GNU_PROPERTY_NO_COPY_ON_PROTECTED: + case GNU_PROPERTY_MEMORY_SEAL: /* Return TRUE if APROP is NULL to indicate that BPROP should be added to ABFD. */ return aprop == NULL; @@ -607,6 +622,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 +698,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 +716,31 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; } + if (elf_bfd != NULL) + { + if (info->memory_seal) + { + /* 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 + elf_find_and_remove_property (&elf_properties (elf_bfd), + GNU_PROPERTY_MEMORY_SEAL, true); + } + /* 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 60e81f518a7..7c164e9c131 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -4892,7 +4892,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 4f8f879cf91..0f29b65fe30 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -21476,6 +21476,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 85e7da84406..ae451075996 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 6077db7a8b7..2e2c486bf8d 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 4a19f5a7d5d..5d5fec4aed3 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -33,6 +33,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 4d431995d2e..9a14eae749e 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -1083,6 +1083,10 @@ fragment <