Message ID | 20241016170435.1404114-2-adhemerval.zanella@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | elf: Add GNU_PROPERTY_MEMORY_SEAL gnu property | expand |
On Thu, Oct 17, 2024, 1:04 AM Adhemerval Zanella < adhemerval.zanella@linaro.org> wrote: > On a glibc recent proposal [1] to add Linux mseal support [2], > Mike Hommey raised that this feature might potentially break Firefox > on Linux. The issue is Firefox is built with DT_RELR support, and > post-processed with a tool to both remove the GLIBC_ABI_DT_RELR > dependency and instrument the binaries to apply the relocation > themselves so they can deploy Firefox regardless if loader supports > DT_RELR or not (some more details at [3]). > > To accomplish it, the instrumentation mimics the dynamic loader and > temporarily undo the RELRO segment to be able to apply those > relocations, and redo it afterward. This will break if mseal is > applied as default. > > The GNU_PROPERTY_MEMORY_SEAL gnu property is a way to mark such > objects to no be sealed by glibc. When linked with > -Wl,-z,noseal (the default), glibc will not seal either the binary or > the shared library. > > 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://sourceware.org/pipermail/libc-alpha/2024-June/157359.html > [2] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 > [3] https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html > [4] https://glandium.org/blog/?p=4297 > --- > bfd/elf-properties.c | 100 ++++++++++++++++++++------ > 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, 246 insertions(+), 22 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 ee8bd37f2bd..c6acdb60ba2 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) > @@ -258,6 +272,12 @@ 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: > + /* Memory seal is controlled only by the linker. */ > + if (aprop != NULL) > + aprop->pr_kind = property_remove; > + return true; + > default: > updated = false; > if (pr_type >= GNU_PROPERTY_UINT32_OR_LO > @@ -607,6 +627,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 +703,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,10 +721,6 @@ _bfd_elf_link_setup_gnu_properties (struct > bfd_link_info *info) > |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; > } > > - /* Do nothing if there is no .note.gnu.property section. */ > - if (!has_properties) > - return NULL; > This change looks odd. Now we merge properties even when there is no property. - > /* Merge .note.gnu.property sections. */ > info->callbacks->minfo (_("\n")); > info->callbacks->minfo (_("Merging program properties\n")); > @@ -737,6 +764,37 @@ _bfd_elf_link_setup_gnu_properties (struct > bfd_link_info *info) > } > } > > + 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) > What are possible kind values? Do we have tests to cover them? + { > + /* 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; > + } > + else > + elf_find_and_remove_property (&elf_properties (elf_bfd), > + GNU_PROPERTY_MEMORY_SEAL, true); > Shouldn't the input seal property have been removed already? + } > + > + /* Do nothing if there is no .note.gnu.property section. */ > + if (!has_properties) > + return NULL; > + > /* Rewrite .note.gnu.property section so that GNU properties are > always sorted by type even if input GNU properties aren't sorted. */ > if (first_pbfd != 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 (_("<corrupt length: %#x> "), datasz); > goto next; > > + case GNU_PROPERTY_MEMORY_SEAL: > + printf ("memory seal "); > + if (datasz) > + printf (_("<corrupt length: %#x> "), 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 <<EOF > link_info.combreloc = false; > else if (strcmp (optarg, "nocopyreloc") == 0) > link_info.nocopyreloc = true; > + else if (strcmp (optarg, "memory-seal") == 0) > + link_info.memory_seal = true; > + else if (strcmp (optarg, "nomemory-seal") == 0) > + link_info.memory_seal = false; > EOF > if test -n "$COMMONPAGESIZE"; then > fragment <<EOF > diff --git a/ld/ld.texi b/ld/ld.texi > index 90182c436ec..b8957d3027e 100644 > --- a/ld/ld.texi > +++ b/ld/ld.texi > @@ -1591,6 +1591,14 @@ Disable relocation overflow check. This can be > used to disable > relocation overflow check if there will be no dynamic relocation > overflow at run-time. Supported for x86_64. > > +@item memory-seal > +@item nomemory-seal > +Instruct the executable or shared library that the all PT_LOAD segments > +should be sealed to avoid further manipulation (such as changing the > +protection flags, the segment size, or remove the mapping). > +This is a security hardening that requires system support. This > +generates GNU_PROPERTY_MEMORY_SEAL in .note.gnu.property section > + > @item now > When generating an executable or shared library, mark it to tell the > dynamic linker to resolve all symbols when the program is started, or > diff --git a/ld/lexsup.c b/ld/lexsup.c > index 8982073bc91..d82d3631a09 100644 > --- a/ld/lexsup.c > +++ b/ld/lexsup.c > @@ -2271,6 +2271,10 @@ elf_shlib_list_options (FILE *file) > fprintf (file, _("\ > -z textoff Don't treat DT_TEXTREL in output as > error\n")); > } > + fprintf (file, _("\ > + -z memory-seal Mark object be memory sealed\n")); > + fprintf (file, _("\ > + -z nomemory-seal Don't mark oject to be memory sealed > (default)\n")); > } > > static void > diff --git a/ld/testsuite/ld-elf/property-seal-1.d > b/ld/testsuite/ld-elf/property-seal-1.d > new file mode 100644 > index 00000000000..a0b1feedf31 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-1.d > @@ -0,0 +1,16 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_DYN. > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -shared > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > Please check if there no seal property instead. This applies to all such tests. +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-1.s > b/ld/testsuite/ld-elf/property-seal-1.s > new file mode 100644 > index 00000000000..aa28a3d0516 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-1.s > @@ -0,0 +1,11 @@ > + .section ".note.gnu.property", "a" > + .p2align ALIGN > + .long 1f - 0f /* name length */ > + .long 3f - 2f /* data length */ > + .long 5 /* note type */ > +0: .asciz "GNU" /* vendor name */ > +1: > + .p2align ALIGN > +2: .long 3 /* pr_type. */ > + .long 0 /* pr_datasz. */ > +3: > diff --git a/ld/testsuite/ld-elf/property-seal-2.d > b/ld/testsuite/ld-elf/property-seal-2.d > new file mode 100644 > index 00000000000..ebdaa623e0c > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-2.d > @@ -0,0 +1,17 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_DYN. > +#source: empty.s > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -shared > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-3.d > b/ld/testsuite/ld-elf/property-seal-3.d > new file mode 100644 > index 00000000000..969729ee0f4 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-3.d > @@ -0,0 +1,16 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_EXEC. > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -e _start > +#warning: .*: warning: cannot find entry symbol .* > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-4.d > b/ld/testsuite/ld-elf/property-seal-4.d > new file mode 100644 > index 00000000000..3dd990dd68a > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-4.d > @@ -0,0 +1,16 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_EXEC. > +#source: empty.s > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -e _start > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-5.d > b/ld/testsuite/ld-elf/property-seal-5.d > new file mode 100644 > index 00000000000..0b92a8eb6eb > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-5.d > @@ -0,0 +1,15 @@ > +#source: empty.s > +#ld: -shared -z memory-seal > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal There may be other properties. X86 assembler may be configured to generate instruction info property note by default. This applies to other such tests. > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-6.d > b/ld/testsuite/ld-elf/property-seal-6.d > new file mode 100644 > index 00000000000..725911acae7 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-6.d > @@ -0,0 +1,16 @@ > +#source: empty.s > +#source: property-seal-1.s > +#ld: -shared -z memory-seal > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-7.d > b/ld/testsuite/ld-elf/property-seal-7.d > new file mode 100644 > index 00000000000..12339e83ebd > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-7.d > @@ -0,0 +1,14 @@ > +#source: empty.s > +#ld: -z memory-seal > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-8.d > b/ld/testsuite/ld-elf/property-seal-8.d > new file mode 100644 > index 00000000000..0c4c4e4907e > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-8.d > @@ -0,0 +1,15 @@ > +#source: empty.s > +#source: property-seal-1.s > +#ld: -z memory-seal > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal > +#pass > -- > 2.43.0 > > > H.J.
On 16/10/24 18:39, H.J. Lu wrote: > > On Thu, Oct 17, 2024, 1:04 AM Adhemerval Zanella <adhemerval.zanella@linaro.org <mailto:adhemerval.zanella@linaro.org>> wrote: > > On a glibc recent proposal [1] to add Linux mseal support [2], > Mike Hommey raised that this feature might potentially break Firefox > on Linux. The issue is Firefox is built with DT_RELR support, and > post-processed with a tool to both remove the GLIBC_ABI_DT_RELR > dependency and instrument the binaries to apply the relocation > themselves so they can deploy Firefox regardless if loader supports > DT_RELR or not (some more details at [3]). > > To accomplish it, the instrumentation mimics the dynamic loader and > temporarily undo the RELRO segment to be able to apply those > relocations, and redo it afterward. This will break if mseal is > applied as default. > > The GNU_PROPERTY_MEMORY_SEAL gnu property is a way to mark such > objects to no be sealed by glibc. When linked with > -Wl,-z,noseal (the default), glibc will not seal either the binary or > the shared library. > > 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://sourceware.org/pipermail/libc-alpha/2024-June/157359.html <https://sourceware.org/pipermail/libc-alpha/2024-June/157359.html> > [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370> > [3] https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html <https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html> > [4] https://glandium.org/blog/?p=4297 <https://glandium.org/blog/?p=4297> > --- > bfd/elf-properties.c | 100 ++++++++++++++++++++------ > 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, 246 insertions(+), 22 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 ee8bd37f2bd..c6acdb60ba2 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) > @@ -258,6 +272,12 @@ 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: > + /* Memory seal is controlled only by the linker. */ > + if (aprop != NULL) > + aprop->pr_kind = property_remove; > + return true; > > + > default: > updated = false; > if (pr_type >= GNU_PROPERTY_UINT32_OR_LO > @@ -607,6 +627,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 +703,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,10 +721,6 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) > |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; > } > > - /* Do nothing if there is no .note.gnu.property section. */ > - if (!has_properties) > - return NULL; > > > This change looks odd. Now we merge properties even when > there is no property. The problem this change is handling is how to remove a GNU_PROPERTY_MEMORY_SEAL present in ET_REL objects if '-z memory-seal' is not issues. If we add the property beforehand, then merge can no determine whether it can came from the ET_REL or if was added by 'info->memory_seal'. > > - > /* Merge .note.gnu.property sections. */ > info->callbacks->minfo (_("\n")); > info->callbacks->minfo (_("Merging program properties\n")); > @@ -737,6 +764,37 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) > } > } > > + 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) > > > What are possible kind values? Do we have tests to cover them? From _bfd_elf_get_property, property_unknown is returned for a new property if the type one is not found (from the memset after bfd_alloc). Afaiu, property_ignored/property_corrupt are only returned by the architectures hooks. The property_remove should not matter here, since with info->memory_seal the attribute should always be added, and property_number should not happen because elf_merge_gnu_properties will change GNU_PROPERTY_MEMORY_SEAL to property_remove. > > + { > + /* 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; > + } > + else > + elf_find_and_remove_property (&elf_properties (elf_bfd), > + GNU_PROPERTY_MEMORY_SEAL, true); > > > Shouldn't the input seal property have been removed already? The problem is when we have only one ET_REL with a gnu property, in this case elf_merge_gnu_property_list won't be called (since there is need to merge operation); but we do need to remove the property is 'info->memory_seal' is not set. Both property-seal-1 and property-seal-3 tests this. > > + } > + > + /* Do nothing if there is no .note.gnu.property section. */ > + if (!has_properties) > + return NULL; > + > /* Rewrite .note.gnu.property section so that GNU properties are > always sorted by type even if input GNU properties aren't sorted. */ > if (first_pbfd != 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 (_("<corrupt length: %#x> "), datasz); > goto next; > > + case GNU_PROPERTY_MEMORY_SEAL: > + printf ("memory seal "); > + if (datasz) > + printf (_("<corrupt length: %#x> "), 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 <<EOF > link_info.combreloc = false; > else if (strcmp (optarg, "nocopyreloc") == 0) > link_info.nocopyreloc = true; > + else if (strcmp (optarg, "memory-seal") == 0) > + link_info.memory_seal = true; > + else if (strcmp (optarg, "nomemory-seal") == 0) > + link_info.memory_seal = false; > EOF > if test -n "$COMMONPAGESIZE"; then > fragment <<EOF > diff --git a/ld/ld.texi b/ld/ld.texi > index 90182c436ec..b8957d3027e 100644 > --- a/ld/ld.texi > +++ b/ld/ld.texi > @@ -1591,6 +1591,14 @@ Disable relocation overflow check. This can be used to disable > relocation overflow check if there will be no dynamic relocation > overflow at run-time. Supported for x86_64. > > +@item memory-seal > +@item nomemory-seal > +Instruct the executable or shared library that the all PT_LOAD segments > +should be sealed to avoid further manipulation (such as changing the > +protection flags, the segment size, or remove the mapping). > +This is a security hardening that requires system support. This > +generates GNU_PROPERTY_MEMORY_SEAL in .note.gnu.property section > + > @item now > When generating an executable or shared library, mark it to tell the > dynamic linker to resolve all symbols when the program is started, or > diff --git a/ld/lexsup.c b/ld/lexsup.c > index 8982073bc91..d82d3631a09 100644 > --- a/ld/lexsup.c > +++ b/ld/lexsup.c > @@ -2271,6 +2271,10 @@ elf_shlib_list_options (FILE *file) > fprintf (file, _("\ > -z textoff Don't treat DT_TEXTREL in output as error\n")); > } > + fprintf (file, _("\ > + -z memory-seal Mark object be memory sealed\n")); > + fprintf (file, _("\ > + -z nomemory-seal Don't mark oject to be memory sealed (default)\n")); > } > > static void > diff --git a/ld/testsuite/ld-elf/property-seal-1.d b/ld/testsuite/ld-elf/property-seal-1.d > new file mode 100644 > index 00000000000..a0b1feedf31 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-1.d > @@ -0,0 +1,16 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_DYN. > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -shared > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > > > Please check if there no seal property instead. This applies to > all such tests. It is doing this, isn't? The readelf -n check here expects no output, i.e, not memory sealing. > > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-1.s b/ld/testsuite/ld-elf/property-seal-1.s > new file mode 100644 > index 00000000000..aa28a3d0516 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-1.s > @@ -0,0 +1,11 @@ > + .section ".note.gnu.property", "a" > + .p2align ALIGN > + .long 1f - 0f /* name length */ > + .long 3f - 2f /* data length */ > + .long 5 /* note type */ > +0: .asciz "GNU" /* vendor name */ > +1: > + .p2align ALIGN > +2: .long 3 /* pr_type. */ > + .long 0 /* pr_datasz. */ > +3: > diff --git a/ld/testsuite/ld-elf/property-seal-2.d b/ld/testsuite/ld-elf/property-seal-2.d > new file mode 100644 > index 00000000000..ebdaa623e0c > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-2.d > @@ -0,0 +1,17 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_DYN. > +#source: empty.s > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -shared > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-3.d b/ld/testsuite/ld-elf/property-seal-3.d > new file mode 100644 > index 00000000000..969729ee0f4 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-3.d > @@ -0,0 +1,16 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_EXEC. > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -e _start > +#warning: .*: warning: cannot find entry symbol .* > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-4.d b/ld/testsuite/ld-elf/property-seal-4.d > new file mode 100644 > index 00000000000..3dd990dd68a > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-4.d > @@ -0,0 +1,16 @@ > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on > +# ET_EXEC. > +#source: empty.s > +#source: property-seal-1.s > +#as: --generate-missing-build-notes=no > +#ld: -e _start > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#failif > +#... > +Displaying notes found in: .note.gnu.property > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-5.d b/ld/testsuite/ld-elf/property-seal-5.d > new file mode 100644 > index 00000000000..0b92a8eb6eb > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-5.d > @@ -0,0 +1,15 @@ > +#source: empty.s > +#ld: -shared -z memory-seal > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal > > > There may be other properties. X86 assembler > may be configured to generate instruction > info property note by default. > This applies to other such tests. The testsuite adds '-mx86-used-note=no' for the testcase (from ld/testsuite/ld-elf/elf.exp) and this is indeed what I see with RUNTESTFLAGS="-v -v". Do I need to add something else? > > > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-6.d b/ld/testsuite/ld-elf/property-seal-6.d > new file mode 100644 > index 00000000000..725911acae7 > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-6.d > @@ -0,0 +1,16 @@ > +#source: empty.s > +#source: property-seal-1.s > +#ld: -shared -z memory-seal > +#readelf: -n > +#xfail: ![check_shared_lib_support] > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-7.d b/ld/testsuite/ld-elf/property-seal-7.d > new file mode 100644 > index 00000000000..12339e83ebd > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-7.d > @@ -0,0 +1,14 @@ > +#source: empty.s > +#ld: -z memory-seal > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal > +#pass > diff --git a/ld/testsuite/ld-elf/property-seal-8.d b/ld/testsuite/ld-elf/property-seal-8.d > new file mode 100644 > index 00000000000..0c4c4e4907e > --- /dev/null > +++ b/ld/testsuite/ld-elf/property-seal-8.d > @@ -0,0 +1,15 @@ > +#source: empty.s > +#source: property-seal-1.s > +#ld: -z memory-seal > +#readelf: -n > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > +# Assembly source file for the HPPA assembler is renamed and modifed by > +# sed. mn10300 has relocations in .note.gnu.property section which > +# elf_parse_notes doesn't support. > + > +#... > +Displaying notes found in: .note.gnu.property > +[ ]+Owner[ ]+Data size[ ]+Description > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > + Properties: memory seal > +#pass > -- > 2.43.0 > > > H.J.
On Thu, Oct 24, 2024, 3:33 AM Adhemerval Zanella Netto < adhemerval.zanella@linaro.org> wrote: > > > On 16/10/24 18:39, H.J. Lu wrote: > > > > On Thu, Oct 17, 2024, 1:04 AM Adhemerval Zanella < > adhemerval.zanella@linaro.org <mailto:adhemerval.zanella@linaro.org>> > wrote: > > > > On a glibc recent proposal [1] to add Linux mseal support [2], > > Mike Hommey raised that this feature might potentially break Firefox > > on Linux. The issue is Firefox is built with DT_RELR support, and > > post-processed with a tool to both remove the GLIBC_ABI_DT_RELR > > dependency and instrument the binaries to apply the relocation > > themselves so they can deploy Firefox regardless if loader supports > > DT_RELR or not (some more details at [3]). > > > > To accomplish it, the instrumentation mimics the dynamic loader and > > temporarily undo the RELRO segment to be able to apply those > > relocations, and redo it afterward. This will break if mseal is > > applied as default. > > > > The GNU_PROPERTY_MEMORY_SEAL gnu property is a way to mark such > > objects to no be sealed by glibc. When linked with > > -Wl,-z,noseal (the default), glibc will not seal either the binary or > > the shared library. > > > > 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://sourceware.org/pipermail/libc-alpha/2024-June/157359.html < > https://sourceware.org/pipermail/libc-alpha/2024-June/157359.html> > > [2] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 > < > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 > > > > [3] > https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html < > https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html> > > [4] https://glandium.org/blog/?p=4297 < > https://glandium.org/blog/?p=4297> > > --- > > bfd/elf-properties.c | 100 > ++++++++++++++++++++------ > > 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, 246 insertions(+), 22 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 ee8bd37f2bd..c6acdb60ba2 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) > > @@ -258,6 +272,12 @@ 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: > > + /* Memory seal is controlled only by the linker. */ > > + if (aprop != NULL) > > + aprop->pr_kind = property_remove; > > + return true; > > > > + > > default: > > updated = false; > > if (pr_type >= GNU_PROPERTY_UINT32_OR_LO > > @@ -607,6 +627,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 +703,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,10 +721,6 @@ _bfd_elf_link_setup_gnu_properties (struct > bfd_link_info *info) > > |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; > > } > > > > - /* Do nothing if there is no .note.gnu.property section. */ > > - if (!has_properties) > > - return NULL; > > > > > > This change looks odd. Now we merge properties even when > > there is no property. > > The problem this change is handling is how to remove a > GNU_PROPERTY_MEMORY_SEAL > present in ET_REL objects if '-z memory-seal' is not issues. If we add > the > property beforehand, then merge can no determine whether it can came from > the ET_REL or if was added by 'info->memory_seal'. > > > > > - > > /* Merge .note.gnu.property sections. */ > > info->callbacks->minfo (_("\n")); > > info->callbacks->minfo (_("Merging program properties\n")); > > @@ -737,6 +764,37 @@ _bfd_elf_link_setup_gnu_properties (struct > bfd_link_info *info) > > } > > } > > > > + 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) > > > > > > What are possible kind values? Do we have tests to cover them? > > From _bfd_elf_get_property, property_unknown is returned for a new > property if the type one is not found (from the memset after bfd_alloc). > Afaiu, property_ignored/property_corrupt are only returned by the > architectures hooks. The property_remove should not matter here, since > with info->memory_seal the attribute should always be added, and > property_number should not happen because elf_merge_gnu_properties > will change GNU_PROPERTY_MEMORY_SEAL to property_remove. > > > > > + { > > + /* 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; > > + } > > + else > > + elf_find_and_remove_property (&elf_properties (elf_bfd), > > + GNU_PROPERTY_MEMORY_SEAL, > true); > > > > > > Shouldn't the input seal property have been removed already? > > The problem is when we have only one ET_REL with a gnu property, > in this case elf_merge_gnu_property_list won't be called (since there is > need to merge operation); but we do need to remove the property is > 'info->memory_seal' is not set. > > Both property-seal-1 and property-seal-3 tests this. > > > > > + } > > + > > + /* Do nothing if there is no .note.gnu.property section. */ > > + if (!has_properties) > > + return NULL; > > + > > /* Rewrite .note.gnu.property section so that GNU properties are > > always sorted by type even if input GNU properties aren't > sorted. */ > > if (first_pbfd != 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 (_("<corrupt length: %#x> "), datasz); > > goto next; > > > > + case GNU_PROPERTY_MEMORY_SEAL: > > + printf ("memory seal "); > > + if (datasz) > > + printf (_("<corrupt length: %#x> "), 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 <<EOF > > link_info.combreloc = false; > > else if (strcmp (optarg, "nocopyreloc") == 0) > > link_info.nocopyreloc = true; > > + else if (strcmp (optarg, "memory-seal") == 0) > > + link_info.memory_seal = true; > > + else if (strcmp (optarg, "nomemory-seal") == 0) > > + link_info.memory_seal = false; > > EOF > > if test -n "$COMMONPAGESIZE"; then > > fragment <<EOF > > diff --git a/ld/ld.texi b/ld/ld.texi > > index 90182c436ec..b8957d3027e 100644 > > --- a/ld/ld.texi > > +++ b/ld/ld.texi > > @@ -1591,6 +1591,14 @@ Disable relocation overflow check. This can > be used to disable > > relocation overflow check if there will be no dynamic relocation > > overflow at run-time. Supported for x86_64. > > > > +@item memory-seal > > +@item nomemory-seal > > +Instruct the executable or shared library that the all PT_LOAD > segments > > +should be sealed to avoid further manipulation (such as changing the > > +protection flags, the segment size, or remove the mapping). > > +This is a security hardening that requires system support. This > > +generates GNU_PROPERTY_MEMORY_SEAL in .note.gnu.property section > > + > > @item now > > When generating an executable or shared library, mark it to tell the > > dynamic linker to resolve all symbols when the program is started, > or > > diff --git a/ld/lexsup.c b/ld/lexsup.c > > index 8982073bc91..d82d3631a09 100644 > > --- a/ld/lexsup.c > > +++ b/ld/lexsup.c > > @@ -2271,6 +2271,10 @@ elf_shlib_list_options (FILE *file) > > fprintf (file, _("\ > > -z textoff Don't treat DT_TEXTREL in output as > error\n")); > > } > > + fprintf (file, _("\ > > + -z memory-seal Mark object be memory sealed\n")); > > + fprintf (file, _("\ > > + -z nomemory-seal Don't mark oject to be memory sealed > (default)\n")); > > } > > > > static void > > diff --git a/ld/testsuite/ld-elf/property-seal-1.d > b/ld/testsuite/ld-elf/property-seal-1.d > > new file mode 100644 > > index 00000000000..a0b1feedf31 > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-1.d > > @@ -0,0 +1,16 @@ > > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated > on > > +# ET_DYN. > > +#source: property-seal-1.s > > +#as: --generate-missing-build-notes=no > > +#ld: -shared > > +#readelf: -n > > +#xfail: ![check_shared_lib_support] > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#failif > > +#... > > +Displaying notes found in: .note.gnu.property > > > > > > Please check if there no seal property instead. This applies to > > all such tests. > > It is doing this, isn't? The readelf -n check here expects no output, i.e, > not memory sealing. > There is a configure-time option to generate x86 ISA note automatically. Please try it. > > > > +#pass > > diff --git a/ld/testsuite/ld-elf/property-seal-1.s > b/ld/testsuite/ld-elf/property-seal-1.s > > new file mode 100644 > > index 00000000000..aa28a3d0516 > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-1.s > > @@ -0,0 +1,11 @@ > > + .section ".note.gnu.property", "a" > > + .p2align ALIGN > > + .long 1f - 0f /* name length */ > > + .long 3f - 2f /* data length */ > > + .long 5 /* note type */ > > +0: .asciz "GNU" /* vendor name */ > > +1: > > + .p2align ALIGN > > +2: .long 3 /* pr_type. */ > > + .long 0 /* pr_datasz. */ > > +3: > > diff --git a/ld/testsuite/ld-elf/property-seal-2.d > b/ld/testsuite/ld-elf/property-seal-2.d > > new file mode 100644 > > index 00000000000..ebdaa623e0c > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-2.d > > @@ -0,0 +1,17 @@ > > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated > on > > +# ET_DYN. > > +#source: empty.s > > +#source: property-seal-1.s > > +#as: --generate-missing-build-notes=no > > +#ld: -shared > > +#readelf: -n > > +#xfail: ![check_shared_lib_support] > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#failif > > +#... > > +Displaying notes found in: .note.gnu.property > > +#pass > > diff --git a/ld/testsuite/ld-elf/property-seal-3.d > b/ld/testsuite/ld-elf/property-seal-3.d > > new file mode 100644 > > index 00000000000..969729ee0f4 > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-3.d > > @@ -0,0 +1,16 @@ > > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated > on > > +# ET_EXEC. > > +#source: property-seal-1.s > > +#as: --generate-missing-build-notes=no > > +#ld: -e _start > > +#warning: .*: warning: cannot find entry symbol .* > > +#readelf: -n > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#failif > > +#... > > +Displaying notes found in: .note.gnu.property > > +#pass > > diff --git a/ld/testsuite/ld-elf/property-seal-4.d > b/ld/testsuite/ld-elf/property-seal-4.d > > new file mode 100644 > > index 00000000000..3dd990dd68a > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-4.d > > @@ -0,0 +1,16 @@ > > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated > on > > +# ET_EXEC. > > +#source: empty.s > > +#source: property-seal-1.s > > +#as: --generate-missing-build-notes=no > > +#ld: -e _start > > +#readelf: -n > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#failif > > +#... > > +Displaying notes found in: .note.gnu.property > > +#pass > > diff --git a/ld/testsuite/ld-elf/property-seal-5.d > b/ld/testsuite/ld-elf/property-seal-5.d > > new file mode 100644 > > index 00000000000..0b92a8eb6eb > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-5.d > > @@ -0,0 +1,15 @@ > > +#source: empty.s > > +#ld: -shared -z memory-seal > > +#readelf: -n > > +#xfail: ![check_shared_lib_support] > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#... > > +Displaying notes found in: .note.gnu.property > > +[ ]+Owner[ ]+Data size[ ]+Description > > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > > + Properties: memory seal > > > > > > There may be other properties. X86 assembler > > may be configured to generate instruction > > info property note by default. > > This applies to other such tests. > > The testsuite adds '-mx86-used-note=no' for the testcase (from > ld/testsuite/ld-elf/elf.exp) and this is indeed what I see with > RUNTESTFLAGS="-v -v". Do I need to add something else? > > > > > > > +#pass > > diff --git a/ld/testsuite/ld-elf/property-seal-6.d > b/ld/testsuite/ld-elf/property-seal-6.d > > new file mode 100644 > > index 00000000000..725911acae7 > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-6.d > > @@ -0,0 +1,16 @@ > > +#source: empty.s > > +#source: property-seal-1.s > > +#ld: -shared -z memory-seal > > +#readelf: -n > > +#xfail: ![check_shared_lib_support] > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#... > > +Displaying notes found in: .note.gnu.property > > +[ ]+Owner[ ]+Data size[ ]+Description > > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > > + Properties: memory seal > > +#pass > > diff --git a/ld/testsuite/ld-elf/property-seal-7.d > b/ld/testsuite/ld-elf/property-seal-7.d > > new file mode 100644 > > index 00000000000..12339e83ebd > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-7.d > > @@ -0,0 +1,14 @@ > > +#source: empty.s > > +#ld: -z memory-seal > > +#readelf: -n > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#... > > +Displaying notes found in: .note.gnu.property > > +[ ]+Owner[ ]+Data size[ ]+Description > > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > > + Properties: memory seal > > +#pass > > diff --git a/ld/testsuite/ld-elf/property-seal-8.d > b/ld/testsuite/ld-elf/property-seal-8.d > > new file mode 100644 > > index 00000000000..0c4c4e4907e > > --- /dev/null > > +++ b/ld/testsuite/ld-elf/property-seal-8.d > > @@ -0,0 +1,15 @@ > > +#source: empty.s > > +#source: property-seal-1.s > > +#ld: -z memory-seal > > +#readelf: -n > > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* > > +# Assembly source file for the HPPA assembler is renamed and > modifed by > > +# sed. mn10300 has relocations in .note.gnu.property section which > > +# elf_parse_notes doesn't support. > > + > > +#... > > +Displaying notes found in: .note.gnu.property > > +[ ]+Owner[ ]+Data size[ ]+Description > > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 > > + Properties: memory seal > > +#pass > > -- > > 2.43.0 > > > > > > H.J. > > >
On Thu, Oct 24, 2024, 5:24 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Thu, Oct 24, 2024, 3:33 AM Adhemerval Zanella Netto < > adhemerval.zanella@linaro.org> wrote: > >> >> >> On 16/10/24 18:39, H.J. Lu wrote: >> > >> > On Thu, Oct 17, 2024, 1:04 AM Adhemerval Zanella < >> adhemerval.zanella@linaro.org <mailto:adhemerval.zanella@linaro.org>> >> wrote: >> > >> > On a glibc recent proposal [1] to add Linux mseal support [2], >> > Mike Hommey raised that this feature might potentially break Firefox >> > on Linux. The issue is Firefox is built with DT_RELR support, and >> > post-processed with a tool to both remove the GLIBC_ABI_DT_RELR >> > dependency and instrument the binaries to apply the relocation >> > themselves so they can deploy Firefox regardless if loader supports >> > DT_RELR or not (some more details at [3]). >> > >> > To accomplish it, the instrumentation mimics the dynamic loader and >> > temporarily undo the RELRO segment to be able to apply those >> > relocations, and redo it afterward. This will break if mseal is >> > applied as default. >> > >> > The GNU_PROPERTY_MEMORY_SEAL gnu property is a way to mark such >> > objects to no be sealed by glibc. When linked with >> > -Wl,-z,noseal (the default), glibc will not seal either the binary >> or >> > the shared library. >> > >> > 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://sourceware.org/pipermail/libc-alpha/2024-June/157359.html < >> https://sourceware.org/pipermail/libc-alpha/2024-June/157359.html> >> > [2] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 >> < >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 >> > >> > [3] >> https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html < >> https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html> >> > [4] https://glandium.org/blog/?p=4297 < >> https://glandium.org/blog/?p=4297> >> > --- >> > bfd/elf-properties.c | 100 >> ++++++++++++++++++++------ >> > 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, 246 insertions(+), 22 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 ee8bd37f2bd..c6acdb60ba2 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) >> > @@ -258,6 +272,12 @@ 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: >> > + /* Memory seal is controlled only by the linker. */ >> > + if (aprop != NULL) >> > + aprop->pr_kind = property_remove; >> > + return true; >> > >> > + >> > default: >> > updated = false; >> > if (pr_type >= GNU_PROPERTY_UINT32_OR_LO >> > @@ -607,6 +627,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 +703,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,10 +721,6 @@ _bfd_elf_link_setup_gnu_properties (struct >> bfd_link_info *info) >> > |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; >> > } >> > >> > - /* Do nothing if there is no .note.gnu.property section. */ >> > - if (!has_properties) >> > - return NULL; >> > >> > >> > This change looks odd. Now we merge properties even when >> > there is no property. >> >> The problem this change is handling is how to remove a >> GNU_PROPERTY_MEMORY_SEAL >> present in ET_REL objects if '-z memory-seal' is not issues. If we add >> the >> property beforehand, then merge can no determine whether it can came from >> the ET_REL or if was added by 'info->memory_seal'. >> > X86 backend can adds STSTK note after input notes have been processed. We should first remove input memory seal notes as usual, then add money seal note if needed. >> > >> > - >> > /* Merge .note.gnu.property sections. */ >> > info->callbacks->minfo (_("\n")); >> > info->callbacks->minfo (_("Merging program properties\n")); >> > @@ -737,6 +764,37 @@ _bfd_elf_link_setup_gnu_properties (struct >> bfd_link_info *info) >> > } >> > } >> > >> > + 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) >> > >> > >> > What are possible kind values? Do we have tests to cover them? >> >> From _bfd_elf_get_property, property_unknown is returned for a new >> property if the type one is not found (from the memset after bfd_alloc). >> Afaiu, property_ignored/property_corrupt are only returned by the >> architectures hooks. The property_remove should not matter here, since >> with info->memory_seal the attribute should always be added, and >> property_number should not happen because elf_merge_gnu_properties >> will change GNU_PROPERTY_MEMORY_SEAL to property_remove. >> >> > >> > + { >> > + /* 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; >> > + } >> > + else >> > + elf_find_and_remove_property (&elf_properties (elf_bfd), >> > + GNU_PROPERTY_MEMORY_SEAL, >> true); >> > >> > >> > Shouldn't the input seal property have been removed already? >> >> The problem is when we have only one ET_REL with a gnu property, >> in this case elf_merge_gnu_property_list won't be called (since there is >> need to merge operation); but we do need to remove the property is >> 'info->memory_seal' is not set. >> >> Both property-seal-1 and property-seal-3 tests this. >> >> > >> > + } >> > + >> > + /* Do nothing if there is no .note.gnu.property section. */ >> > + if (!has_properties) >> > + return NULL; >> > + >> > /* Rewrite .note.gnu.property section so that GNU properties are >> > always sorted by type even if input GNU properties aren't >> sorted. */ >> > if (first_pbfd != 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 (_("<corrupt length: %#x> "), datasz); >> > goto next; >> > >> > + case GNU_PROPERTY_MEMORY_SEAL: >> > + printf ("memory seal "); >> > + if (datasz) >> > + printf (_("<corrupt length: %#x> "), 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 <<EOF >> > link_info.combreloc = false; >> > else if (strcmp (optarg, "nocopyreloc") == 0) >> > link_info.nocopyreloc = true; >> > + else if (strcmp (optarg, "memory-seal") == 0) >> > + link_info.memory_seal = true; >> > + else if (strcmp (optarg, "nomemory-seal") == 0) >> > + link_info.memory_seal = false; >> > EOF >> > if test -n "$COMMONPAGESIZE"; then >> > fragment <<EOF >> > diff --git a/ld/ld.texi b/ld/ld.texi >> > index 90182c436ec..b8957d3027e 100644 >> > --- a/ld/ld.texi >> > +++ b/ld/ld.texi >> > @@ -1591,6 +1591,14 @@ Disable relocation overflow check. This can >> be used to disable >> > relocation overflow check if there will be no dynamic relocation >> > overflow at run-time. Supported for x86_64. >> > >> > +@item memory-seal >> > +@item nomemory-seal >> > +Instruct the executable or shared library that the all PT_LOAD >> segments >> > +should be sealed to avoid further manipulation (such as changing >> the >> > +protection flags, the segment size, or remove the mapping). >> > +This is a security hardening that requires system support. This >> > +generates GNU_PROPERTY_MEMORY_SEAL in .note.gnu.property section >> > + >> > @item now >> > When generating an executable or shared library, mark it to tell >> the >> > dynamic linker to resolve all symbols when the program is started, >> or >> > diff --git a/ld/lexsup.c b/ld/lexsup.c >> > index 8982073bc91..d82d3631a09 100644 >> > --- a/ld/lexsup.c >> > +++ b/ld/lexsup.c >> > @@ -2271,6 +2271,10 @@ elf_shlib_list_options (FILE *file) >> > fprintf (file, _("\ >> > -z textoff Don't treat DT_TEXTREL in output as >> error\n")); >> > } >> > + fprintf (file, _("\ >> > + -z memory-seal Mark object be memory sealed\n")); >> > + fprintf (file, _("\ >> > + -z nomemory-seal Don't mark oject to be memory sealed >> (default)\n")); >> > } >> > >> > static void >> > diff --git a/ld/testsuite/ld-elf/property-seal-1.d >> b/ld/testsuite/ld-elf/property-seal-1.d >> > new file mode 100644 >> > index 00000000000..a0b1feedf31 >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-1.d >> > @@ -0,0 +1,16 @@ >> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not >> replicated on >> > +# ET_DYN. >> > +#source: property-seal-1.s >> > +#as: --generate-missing-build-notes=no >> > +#ld: -shared >> > +#readelf: -n >> > +#xfail: ![check_shared_lib_support] >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#failif >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > >> > >> > Please check if there no seal property instead. This applies to >> > all such tests. >> >> It is doing this, isn't? The readelf -n check here expects no output, i.e, >> not memory sealing. >> > > There is a configure-time option to generate x86 ISA note > automatically. Please try it. > > >> > >> > +#pass >> > diff --git a/ld/testsuite/ld-elf/property-seal-1.s >> b/ld/testsuite/ld-elf/property-seal-1.s >> > new file mode 100644 >> > index 00000000000..aa28a3d0516 >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-1.s >> > @@ -0,0 +1,11 @@ >> > + .section ".note.gnu.property", "a" >> > + .p2align ALIGN >> > + .long 1f - 0f /* name length */ >> > + .long 3f - 2f /* data length */ >> > + .long 5 /* note type */ >> > +0: .asciz "GNU" /* vendor name */ >> > +1: >> > + .p2align ALIGN >> > +2: .long 3 /* pr_type. */ >> > + .long 0 /* pr_datasz. */ >> > +3: >> > diff --git a/ld/testsuite/ld-elf/property-seal-2.d >> b/ld/testsuite/ld-elf/property-seal-2.d >> > new file mode 100644 >> > index 00000000000..ebdaa623e0c >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-2.d >> > @@ -0,0 +1,17 @@ >> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not >> replicated on >> > +# ET_DYN. >> > +#source: empty.s >> > +#source: property-seal-1.s >> > +#as: --generate-missing-build-notes=no >> > +#ld: -shared >> > +#readelf: -n >> > +#xfail: ![check_shared_lib_support] >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#failif >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > +#pass >> > diff --git a/ld/testsuite/ld-elf/property-seal-3.d >> b/ld/testsuite/ld-elf/property-seal-3.d >> > new file mode 100644 >> > index 00000000000..969729ee0f4 >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-3.d >> > @@ -0,0 +1,16 @@ >> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not >> replicated on >> > +# ET_EXEC. >> > +#source: property-seal-1.s >> > +#as: --generate-missing-build-notes=no >> > +#ld: -e _start >> > +#warning: .*: warning: cannot find entry symbol .* >> > +#readelf: -n >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#failif >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > +#pass >> > diff --git a/ld/testsuite/ld-elf/property-seal-4.d >> b/ld/testsuite/ld-elf/property-seal-4.d >> > new file mode 100644 >> > index 00000000000..3dd990dd68a >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-4.d >> > @@ -0,0 +1,16 @@ >> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not >> replicated on >> > +# ET_EXEC. >> > +#source: empty.s >> > +#source: property-seal-1.s >> > +#as: --generate-missing-build-notes=no >> > +#ld: -e _start >> > +#readelf: -n >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#failif >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > +#pass >> > diff --git a/ld/testsuite/ld-elf/property-seal-5.d >> b/ld/testsuite/ld-elf/property-seal-5.d >> > new file mode 100644 >> > index 00000000000..0b92a8eb6eb >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-5.d >> > @@ -0,0 +1,15 @@ >> > +#source: empty.s >> > +#ld: -shared -z memory-seal >> > +#readelf: -n >> > +#xfail: ![check_shared_lib_support] >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > +[ ]+Owner[ ]+Data size[ ]+Description >> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >> > + Properties: memory seal >> > >> > >> > There may be other properties. X86 assembler >> > may be configured to generate instruction >> > info property note by default. >> > This applies to other such tests. >> >> The testsuite adds '-mx86-used-note=no' for the testcase (from >> ld/testsuite/ld-elf/elf.exp) and this is indeed what I see with >> RUNTESTFLAGS="-v -v". Do I need to add something else? >> >> > >> > >> > +#pass >> > diff --git a/ld/testsuite/ld-elf/property-seal-6.d >> b/ld/testsuite/ld-elf/property-seal-6.d >> > new file mode 100644 >> > index 00000000000..725911acae7 >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-6.d >> > @@ -0,0 +1,16 @@ >> > +#source: empty.s >> > +#source: property-seal-1.s >> > +#ld: -shared -z memory-seal >> > +#readelf: -n >> > +#xfail: ![check_shared_lib_support] >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > +[ ]+Owner[ ]+Data size[ ]+Description >> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >> > + Properties: memory seal >> > +#pass >> > diff --git a/ld/testsuite/ld-elf/property-seal-7.d >> b/ld/testsuite/ld-elf/property-seal-7.d >> > new file mode 100644 >> > index 00000000000..12339e83ebd >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-7.d >> > @@ -0,0 +1,14 @@ >> > +#source: empty.s >> > +#ld: -z memory-seal >> > +#readelf: -n >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > +[ ]+Owner[ ]+Data size[ ]+Description >> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >> > + Properties: memory seal >> > +#pass >> > diff --git a/ld/testsuite/ld-elf/property-seal-8.d >> b/ld/testsuite/ld-elf/property-seal-8.d >> > new file mode 100644 >> > index 00000000000..0c4c4e4907e >> > --- /dev/null >> > +++ b/ld/testsuite/ld-elf/property-seal-8.d >> > @@ -0,0 +1,15 @@ >> > +#source: empty.s >> > +#source: property-seal-1.s >> > +#ld: -z memory-seal >> > +#readelf: -n >> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >> > +# Assembly source file for the HPPA assembler is renamed and >> modifed by >> > +# sed. mn10300 has relocations in .note.gnu.property section which >> > +# elf_parse_notes doesn't support. >> > + >> > +#... >> > +Displaying notes found in: .note.gnu.property >> > +[ ]+Owner[ ]+Data size[ ]+Description >> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >> > + Properties: memory seal >> > +#pass >> > -- >> > 2.43.0 >> > >> > >> > H.J. >> >> >>
On Thu, Oct 24, 2024 at 5:39 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > On Thu, Oct 24, 2024, 5:24 AM H.J. Lu <hjl.tools@gmail.com> wrote: >> >> >> On Thu, Oct 24, 2024, 3:33 AM Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> wrote: >>> >>> >>> >>> On 16/10/24 18:39, H.J. Lu wrote: >>> > >>> > On Thu, Oct 17, 2024, 1:04 AM Adhemerval Zanella <adhemerval.zanella@linaro.org <mailto:adhemerval.zanella@linaro.org>> wrote: >>> > >>> > On a glibc recent proposal [1] to add Linux mseal support [2], >>> > Mike Hommey raised that this feature might potentially break Firefox >>> > on Linux. The issue is Firefox is built with DT_RELR support, and >>> > post-processed with a tool to both remove the GLIBC_ABI_DT_RELR >>> > dependency and instrument the binaries to apply the relocation >>> > themselves so they can deploy Firefox regardless if loader supports >>> > DT_RELR or not (some more details at [3]). >>> > >>> > To accomplish it, the instrumentation mimics the dynamic loader and >>> > temporarily undo the RELRO segment to be able to apply those >>> > relocations, and redo it afterward. This will break if mseal is >>> > applied as default. >>> > >>> > The GNU_PROPERTY_MEMORY_SEAL gnu property is a way to mark such >>> > objects to no be sealed by glibc. When linked with >>> > -Wl,-z,noseal (the default), glibc will not seal either the binary or >>> > the shared library. >>> > >>> > 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://sourceware.org/pipermail/libc-alpha/2024-June/157359.html <https://sourceware.org/pipermail/libc-alpha/2024-June/157359.html> >>> > [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370 <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8be7258aad44b5e25977a98db136f677fa6f4370> >>> > [3] https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html <https://sourceware.org/pipermail/libc-alpha/2024-June/157668.html> >>> > [4] https://glandium.org/blog/?p=4297 <https://glandium.org/blog/?p=4297> >>> > --- >>> > bfd/elf-properties.c | 100 ++++++++++++++++++++------ >>> > 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, 246 insertions(+), 22 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 ee8bd37f2bd..c6acdb60ba2 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) >>> > @@ -258,6 +272,12 @@ 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: >>> > + /* Memory seal is controlled only by the linker. */ >>> > + if (aprop != NULL) >>> > + aprop->pr_kind = property_remove; >>> > + return true; >>> > >>> > + >>> > default: >>> > updated = false; >>> > if (pr_type >= GNU_PROPERTY_UINT32_OR_LO >>> > @@ -607,6 +627,33 @@ elf_write_gnu_properties (struct bfd_link_info *info, >>> > } >>> > } >>> > >>> > +static asection * Since function return value is unused, please change it to void. >>> > +_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 +703,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,10 +721,6 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) >>> > |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; >>> > } >>> > >>> > - /* Do nothing if there is no .note.gnu.property section. */ >>> > - if (!has_properties) >>> > - return NULL; >>> > >>> > >>> > This change looks odd. Now we merge properties even when >>> > there is no property. >>> >>> The problem this change is handling is how to remove a GNU_PROPERTY_MEMORY_SEAL >>> present in ET_REL objects if '-z memory-seal' is not issues. If we add the >>> property beforehand, then merge can no determine whether it can came from >>> the ET_REL or if was added by 'info->memory_seal'. > > > X86 backend can adds STSTK note after input notes have been processed. > We should first remove input memory seal notes as usual, > then add money seal note if needed. > > >>> >>> > >>> > - >>> > /* Merge .note.gnu.property sections. */ >>> > info->callbacks->minfo (_("\n")); >>> > info->callbacks->minfo (_("Merging program properties\n")); >>> > @@ -737,6 +764,37 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) >>> > } >>> > } >>> > >>> > + 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) >>> > >>> > >>> > What are possible kind values? Do we have tests to cover them? >>> >>> From _bfd_elf_get_property, property_unknown is returned for a new >>> property if the type one is not found (from the memset after bfd_alloc). >>> Afaiu, property_ignored/property_corrupt are only returned by the >>> architectures hooks. The property_remove should not matter here, since >>> with info->memory_seal the attribute should always be added, and >>> property_number should not happen because elf_merge_gnu_properties >>> will change GNU_PROPERTY_MEMORY_SEAL to property_remove. >>> >>> > >>> > + { >>> > + /* 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; This isn't needed. If there is a GNU_PROPERTY_MEMORY_SEAL note, p->u.number must be GNU_PROPERTY_MEMORY_SEAL. >>> > + } >>> > + else >>> > + elf_find_and_remove_property (&elf_properties (elf_bfd), >>> > + GNU_PROPERTY_MEMORY_SEAL, true); >>> > >>> > >>> > Shouldn't the input seal property have been removed already? >>> >>> The problem is when we have only one ET_REL with a gnu property, >>> in this case elf_merge_gnu_property_list won't be called (since there is >>> need to merge operation); but we do need to remove the property is >>> 'info->memory_seal' is not set. >>> >>> Both property-seal-1 and property-seal-3 tests this. >>> >>> > >>> > + } >>> > + >>> > + /* Do nothing if there is no .note.gnu.property section. */ >>> > + if (!has_properties) >>> > + return NULL; >>> > + >>> > /* Rewrite .note.gnu.property section so that GNU properties are >>> > always sorted by type even if input GNU properties aren't sorted. */ >>> > if (first_pbfd != 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 (_("<corrupt length: %#x> "), datasz); >>> > goto next; >>> > >>> > + case GNU_PROPERTY_MEMORY_SEAL: >>> > + printf ("memory seal "); >>> > + if (datasz) >>> > + printf (_("<corrupt length: %#x> "), 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 <<EOF >>> > link_info.combreloc = false; >>> > else if (strcmp (optarg, "nocopyreloc") == 0) >>> > link_info.nocopyreloc = true; >>> > + else if (strcmp (optarg, "memory-seal") == 0) >>> > + link_info.memory_seal = true; >>> > + else if (strcmp (optarg, "nomemory-seal") == 0) >>> > + link_info.memory_seal = false; >>> > EOF >>> > if test -n "$COMMONPAGESIZE"; then >>> > fragment <<EOF >>> > diff --git a/ld/ld.texi b/ld/ld.texi >>> > index 90182c436ec..b8957d3027e 100644 >>> > --- a/ld/ld.texi >>> > +++ b/ld/ld.texi >>> > @@ -1591,6 +1591,14 @@ Disable relocation overflow check. This can be used to disable >>> > relocation overflow check if there will be no dynamic relocation >>> > overflow at run-time. Supported for x86_64. >>> > >>> > +@item memory-seal >>> > +@item nomemory-seal >>> > +Instruct the executable or shared library that the all PT_LOAD segments >>> > +should be sealed to avoid further manipulation (such as changing the >>> > +protection flags, the segment size, or remove the mapping). >>> > +This is a security hardening that requires system support. This >>> > +generates GNU_PROPERTY_MEMORY_SEAL in .note.gnu.property section >>> > + >>> > @item now >>> > When generating an executable or shared library, mark it to tell the >>> > dynamic linker to resolve all symbols when the program is started, or >>> > diff --git a/ld/lexsup.c b/ld/lexsup.c >>> > index 8982073bc91..d82d3631a09 100644 >>> > --- a/ld/lexsup.c >>> > +++ b/ld/lexsup.c >>> > @@ -2271,6 +2271,10 @@ elf_shlib_list_options (FILE *file) >>> > fprintf (file, _("\ >>> > -z textoff Don't treat DT_TEXTREL in output as error\n")); >>> > } >>> > + fprintf (file, _("\ >>> > + -z memory-seal Mark object be memory sealed\n")); >>> > + fprintf (file, _("\ >>> > + -z nomemory-seal Don't mark oject to be memory sealed (default)\n")); >>> > } >>> > >>> > static void >>> > diff --git a/ld/testsuite/ld-elf/property-seal-1.d b/ld/testsuite/ld-elf/property-seal-1.d >>> > new file mode 100644 >>> > index 00000000000..a0b1feedf31 >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-1.d >>> > @@ -0,0 +1,16 @@ >>> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on >>> > +# ET_DYN. >>> > +#source: property-seal-1.s >>> > +#as: --generate-missing-build-notes=no >>> > +#ld: -shared >>> > +#readelf: -n >>> > +#xfail: ![check_shared_lib_support] >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#failif >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > >>> > >>> > Please check if there no seal property instead. This applies to >>> > all such tests. >>> >>> It is doing this, isn't? The readelf -n check here expects no output, i.e, >>> not memory sealing. >> >> >> There is a configure-time option to generate x86 ISA note >> automatically. Please try it. >> >>> >>> > >>> > +#pass >>> > diff --git a/ld/testsuite/ld-elf/property-seal-1.s b/ld/testsuite/ld-elf/property-seal-1.s >>> > new file mode 100644 >>> > index 00000000000..aa28a3d0516 >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-1.s >>> > @@ -0,0 +1,11 @@ >>> > + .section ".note.gnu.property", "a" >>> > + .p2align ALIGN >>> > + .long 1f - 0f /* name length */ >>> > + .long 3f - 2f /* data length */ >>> > + .long 5 /* note type */ >>> > +0: .asciz "GNU" /* vendor name */ >>> > +1: >>> > + .p2align ALIGN >>> > +2: .long 3 /* pr_type. */ >>> > + .long 0 /* pr_datasz. */ >>> > +3: >>> > diff --git a/ld/testsuite/ld-elf/property-seal-2.d b/ld/testsuite/ld-elf/property-seal-2.d >>> > new file mode 100644 >>> > index 00000000000..ebdaa623e0c >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-2.d >>> > @@ -0,0 +1,17 @@ >>> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on >>> > +# ET_DYN. >>> > +#source: empty.s >>> > +#source: property-seal-1.s >>> > +#as: --generate-missing-build-notes=no >>> > +#ld: -shared >>> > +#readelf: -n >>> > +#xfail: ![check_shared_lib_support] >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#failif >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > +#pass >>> > diff --git a/ld/testsuite/ld-elf/property-seal-3.d b/ld/testsuite/ld-elf/property-seal-3.d >>> > new file mode 100644 >>> > index 00000000000..969729ee0f4 >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-3.d >>> > @@ -0,0 +1,16 @@ >>> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on >>> > +# ET_EXEC. >>> > +#source: property-seal-1.s >>> > +#as: --generate-missing-build-notes=no >>> > +#ld: -e _start >>> > +#warning: .*: warning: cannot find entry symbol .* >>> > +#readelf: -n >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#failif >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > +#pass >>> > diff --git a/ld/testsuite/ld-elf/property-seal-4.d b/ld/testsuite/ld-elf/property-seal-4.d >>> > new file mode 100644 >>> > index 00000000000..3dd990dd68a >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-4.d >>> > @@ -0,0 +1,16 @@ >>> > +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on >>> > +# ET_EXEC. >>> > +#source: empty.s >>> > +#source: property-seal-1.s >>> > +#as: --generate-missing-build-notes=no >>> > +#ld: -e _start >>> > +#readelf: -n >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#failif >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > +#pass >>> > diff --git a/ld/testsuite/ld-elf/property-seal-5.d b/ld/testsuite/ld-elf/property-seal-5.d >>> > new file mode 100644 >>> > index 00000000000..0b92a8eb6eb >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-5.d >>> > @@ -0,0 +1,15 @@ >>> > +#source: empty.s >>> > +#ld: -shared -z memory-seal >>> > +#readelf: -n >>> > +#xfail: ![check_shared_lib_support] >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > +[ ]+Owner[ ]+Data size[ ]+Description >>> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >>> > + Properties: memory seal >>> > >>> > >>> > There may be other properties. X86 assembler >>> > may be configured to generate instruction >>> > info property note by default. >>> > This applies to other such tests. >>> >>> The testsuite adds '-mx86-used-note=no' for the testcase (from >>> ld/testsuite/ld-elf/elf.exp) and this is indeed what I see with >>> RUNTESTFLAGS="-v -v". Do I need to add something else? >>> >>> > >>> > >>> > +#pass >>> > diff --git a/ld/testsuite/ld-elf/property-seal-6.d b/ld/testsuite/ld-elf/property-seal-6.d >>> > new file mode 100644 >>> > index 00000000000..725911acae7 >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-6.d >>> > @@ -0,0 +1,16 @@ >>> > +#source: empty.s >>> > +#source: property-seal-1.s >>> > +#ld: -shared -z memory-seal >>> > +#readelf: -n >>> > +#xfail: ![check_shared_lib_support] >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > +[ ]+Owner[ ]+Data size[ ]+Description >>> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >>> > + Properties: memory seal >>> > +#pass >>> > diff --git a/ld/testsuite/ld-elf/property-seal-7.d b/ld/testsuite/ld-elf/property-seal-7.d >>> > new file mode 100644 >>> > index 00000000000..12339e83ebd >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-7.d >>> > @@ -0,0 +1,14 @@ >>> > +#source: empty.s >>> > +#ld: -z memory-seal >>> > +#readelf: -n >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > +[ ]+Owner[ ]+Data size[ ]+Description >>> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >>> > + Properties: memory seal >>> > +#pass >>> > diff --git a/ld/testsuite/ld-elf/property-seal-8.d b/ld/testsuite/ld-elf/property-seal-8.d >>> > new file mode 100644 >>> > index 00000000000..0c4c4e4907e >>> > --- /dev/null >>> > +++ b/ld/testsuite/ld-elf/property-seal-8.d >>> > @@ -0,0 +1,15 @@ >>> > +#source: empty.s >>> > +#source: property-seal-1.s >>> > +#ld: -z memory-seal >>> > +#readelf: -n >>> > +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* >>> > +# Assembly source file for the HPPA assembler is renamed and modifed by >>> > +# sed. mn10300 has relocations in .note.gnu.property section which >>> > +# elf_parse_notes doesn't support. >>> > + >>> > +#... >>> > +Displaying notes found in: .note.gnu.property >>> > +[ ]+Owner[ ]+Data size[ ]+Description >>> > + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 >>> > + Properties: memory seal >>> > +#pass >>> > -- >>> > 2.43.0 >>> > >>> > >>> > H.J. >>> >>>
diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index ee8bd37f2bd..c6acdb60ba2 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) @@ -258,6 +272,12 @@ 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: + /* Memory seal is controlled only by the linker. */ + if (aprop != NULL) + aprop->pr_kind = property_remove; + return true; + default: updated = false; if (pr_type >= GNU_PROPERTY_UINT32_OR_LO @@ -607,6 +627,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 +703,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,10 +721,6 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS; } - /* Do nothing if there is no .note.gnu.property section. */ - if (!has_properties) - return NULL; - /* Merge .note.gnu.property sections. */ info->callbacks->minfo (_("\n")); info->callbacks->minfo (_("Merging program properties\n")); @@ -737,6 +764,37 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) } } + 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 + p->u.number |= GNU_PROPERTY_MEMORY_SEAL; + } + 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; + /* Rewrite .note.gnu.property section so that GNU properties are always sorted by type even if input GNU properties aren't sorted. */ if (first_pbfd != 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 (_("<corrupt length: %#x> "), datasz); goto next; + case GNU_PROPERTY_MEMORY_SEAL: + printf ("memory seal "); + if (datasz) + printf (_("<corrupt length: %#x> "), 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 <<EOF link_info.combreloc = false; else if (strcmp (optarg, "nocopyreloc") == 0) link_info.nocopyreloc = true; + else if (strcmp (optarg, "memory-seal") == 0) + link_info.memory_seal = true; + else if (strcmp (optarg, "nomemory-seal") == 0) + link_info.memory_seal = false; EOF if test -n "$COMMONPAGESIZE"; then fragment <<EOF diff --git a/ld/ld.texi b/ld/ld.texi index 90182c436ec..b8957d3027e 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -1591,6 +1591,14 @@ Disable relocation overflow check. This can be used to disable relocation overflow check if there will be no dynamic relocation overflow at run-time. Supported for x86_64. +@item memory-seal +@item nomemory-seal +Instruct the executable or shared library that the all PT_LOAD segments +should be sealed to avoid further manipulation (such as changing the +protection flags, the segment size, or remove the mapping). +This is a security hardening that requires system support. This +generates GNU_PROPERTY_MEMORY_SEAL in .note.gnu.property section + @item now When generating an executable or shared library, mark it to tell the dynamic linker to resolve all symbols when the program is started, or diff --git a/ld/lexsup.c b/ld/lexsup.c index 8982073bc91..d82d3631a09 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -2271,6 +2271,10 @@ elf_shlib_list_options (FILE *file) fprintf (file, _("\ -z textoff Don't treat DT_TEXTREL in output as error\n")); } + fprintf (file, _("\ + -z memory-seal Mark object be memory sealed\n")); + fprintf (file, _("\ + -z nomemory-seal Don't mark oject to be memory sealed (default)\n")); } static void diff --git a/ld/testsuite/ld-elf/property-seal-1.d b/ld/testsuite/ld-elf/property-seal-1.d new file mode 100644 index 00000000000..a0b1feedf31 --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-1.d @@ -0,0 +1,16 @@ +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on +# ET_DYN. +#source: property-seal-1.s +#as: --generate-missing-build-notes=no +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#failif +#... +Displaying notes found in: .note.gnu.property +#pass diff --git a/ld/testsuite/ld-elf/property-seal-1.s b/ld/testsuite/ld-elf/property-seal-1.s new file mode 100644 index 00000000000..aa28a3d0516 --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-1.s @@ -0,0 +1,11 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 3f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 3 /* pr_type. */ + .long 0 /* pr_datasz. */ +3: diff --git a/ld/testsuite/ld-elf/property-seal-2.d b/ld/testsuite/ld-elf/property-seal-2.d new file mode 100644 index 00000000000..ebdaa623e0c --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-2.d @@ -0,0 +1,17 @@ +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on +# ET_DYN. +#source: empty.s +#source: property-seal-1.s +#as: --generate-missing-build-notes=no +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#failif +#... +Displaying notes found in: .note.gnu.property +#pass diff --git a/ld/testsuite/ld-elf/property-seal-3.d b/ld/testsuite/ld-elf/property-seal-3.d new file mode 100644 index 00000000000..969729ee0f4 --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-3.d @@ -0,0 +1,16 @@ +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on +# ET_EXEC. +#source: property-seal-1.s +#as: --generate-missing-build-notes=no +#ld: -e _start +#warning: .*: warning: cannot find entry symbol .* +#readelf: -n +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#failif +#... +Displaying notes found in: .note.gnu.property +#pass diff --git a/ld/testsuite/ld-elf/property-seal-4.d b/ld/testsuite/ld-elf/property-seal-4.d new file mode 100644 index 00000000000..3dd990dd68a --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-4.d @@ -0,0 +1,16 @@ +# Check if a GNU_PROPERTY_MEMORY_SEAL on a ET_REL is not replicated on +# ET_EXEC. +#source: empty.s +#source: property-seal-1.s +#as: --generate-missing-build-notes=no +#ld: -e _start +#readelf: -n +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#failif +#... +Displaying notes found in: .note.gnu.property +#pass diff --git a/ld/testsuite/ld-elf/property-seal-5.d b/ld/testsuite/ld-elf/property-seal-5.d new file mode 100644 index 00000000000..0b92a8eb6eb --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-5.d @@ -0,0 +1,15 @@ +#source: empty.s +#ld: -shared -z memory-seal +#readelf: -n +#xfail: ![check_shared_lib_support] +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#... +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: memory seal +#pass diff --git a/ld/testsuite/ld-elf/property-seal-6.d b/ld/testsuite/ld-elf/property-seal-6.d new file mode 100644 index 00000000000..725911acae7 --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-6.d @@ -0,0 +1,16 @@ +#source: empty.s +#source: property-seal-1.s +#ld: -shared -z memory-seal +#readelf: -n +#xfail: ![check_shared_lib_support] +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#... +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: memory seal +#pass diff --git a/ld/testsuite/ld-elf/property-seal-7.d b/ld/testsuite/ld-elf/property-seal-7.d new file mode 100644 index 00000000000..12339e83ebd --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-7.d @@ -0,0 +1,14 @@ +#source: empty.s +#ld: -z memory-seal +#readelf: -n +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#... +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: memory seal +#pass diff --git a/ld/testsuite/ld-elf/property-seal-8.d b/ld/testsuite/ld-elf/property-seal-8.d new file mode 100644 index 00000000000..0c4c4e4907e --- /dev/null +++ b/ld/testsuite/ld-elf/property-seal-8.d @@ -0,0 +1,15 @@ +#source: empty.s +#source: property-seal-1.s +#ld: -z memory-seal +#readelf: -n +#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-* +# Assembly source file for the HPPA assembler is renamed and modifed by +# sed. mn10300 has relocations in .note.gnu.property section which +# elf_parse_notes doesn't support. + +#... +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: memory seal +#pass