From 11786740f6800c4ed3ce5f0ff88f28ed72c3012b Mon Sep 17 00:00:00 2001 From: deraadt Date: Thu, 6 Jul 2023 09:52:37 +0000 Subject: [PATCH] teach the BFD tools how to handle NOBTCFI, quite similar to WXNEEDED ok kettenis --- gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h | 3 +++ gnu/usr.bin/binutils-2.17/bfd/elf.c | 26 +++++++++++++++++++ gnu/usr.bin/binutils-2.17/binutils/readelf.c | 2 ++ gnu/usr.bin/binutils-2.17/include/bfdlink.h | 3 +++ .../binutils-2.17/include/elf/common.h | 1 + .../binutils-2.17/ld/emultempl/elf32.em | 2 ++ gnu/usr.bin/binutils-2.17/ld/ld.texinfo | 5 ++++ gnu/usr.bin/binutils-2.17/ld/ldgram.y | 2 ++ 8 files changed, 44 insertions(+) diff --git a/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h b/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h index 2abac0e34c6..e4a2f5f5aab 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h +++ b/gnu/usr.bin/binutils-2.17/bfd/elf-bfd.h @@ -1318,6 +1318,9 @@ struct elf_obj_tdata /* TRUE if output program should be marked to request W^X permission */ bfd_boolean wxneeded; + /* TRUE if output program should be marked to stop branch target CFI enforcement */ + bfd_boolean nobtcfi; + /* Symbol version definitions in external objects. */ Elf_Internal_Verdef *verdef; diff --git a/gnu/usr.bin/binutils-2.17/bfd/elf.c b/gnu/usr.bin/binutils-2.17/bfd/elf.c index a2804f5a068..6c1454c8b70 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elf.c +++ b/gnu/usr.bin/binutils-2.17/bfd/elf.c @@ -1102,6 +1102,7 @@ get_segment_type (unsigned int p_type) case PT_GNU_RELRO: pt = "RELRO"; break; case PT_OPENBSD_RANDOMIZE: pt = "OPENBSD_RANDOMIZE"; break; case PT_OPENBSD_WXNEEDED: pt = "OPENBSD_WXNEEDED"; break; + case PT_OPENBSD_NOBTCFI: pt = "PT_OPENBSD_NOBTCFI"; break; case PT_OPENBSD_BOOTDATA: pt = "OPENBSD_BOOTDATA"; break; case PT_OPENBSD_MUTABLE: pt = "OPENBSD_MUTABLE"; break; default: pt = NULL; break; @@ -2646,6 +2647,10 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index) return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "openbsd_wxneeded"); + case PT_OPENBSD_NOBTCFI: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, + "openbsd_nobtcfi"); + case PT_OPENBSD_MUTABLE: return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "openbsd_mutable"); @@ -3988,6 +3993,21 @@ map_sections_to_segments (bfd *abfd) pm = &m->next; } + if (elf_tdata (abfd)->nobtcfi) + { + amt = sizeof (struct elf_segment_map); + m = bfd_zalloc (abfd, amt); + if (m == NULL) + goto error_return; + m->next = NULL; + m->p_type = PT_OPENBSD_NOBTCFI; + m->p_flags = 1; + m->p_flags_valid = 1; + + *pm = m; + pm = &m->next; + } + /* If there is a .openbsd.randomdata section, throw in a PT_OPENBSD_RANDOMIZE segment. */ randomdata = bfd_get_section_by_name (abfd, ".openbsd.randomdata"); @@ -4800,6 +4820,12 @@ get_program_header_size (bfd *abfd) ++segs; } + if (elf_tdata (abfd)->nobtcfi) + { + /* We need a PT_OPENBSD_NOBTCFI segment. */ + ++segs; + } + for (s = abfd->sections; s != NULL; s = s->next) { if ((s->flags & SEC_LOAD) != 0 diff --git a/gnu/usr.bin/binutils-2.17/binutils/readelf.c b/gnu/usr.bin/binutils-2.17/binutils/readelf.c index a45527f65fc..262a0b3967c 100644 --- a/gnu/usr.bin/binutils-2.17/binutils/readelf.c +++ b/gnu/usr.bin/binutils-2.17/binutils/readelf.c @@ -2711,6 +2711,8 @@ get_segment_type (unsigned long p_type) return "OPENBSD_BOOTDATA"; case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE"; + case PT_OPENBSD_NOBTCFI: + return "OPENBSD_NOBTCFI"; default: if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC)) diff --git a/gnu/usr.bin/binutils-2.17/include/bfdlink.h b/gnu/usr.bin/binutils-2.17/include/bfdlink.h index 8c17bf888bc..15b97b6d2fe 100644 --- a/gnu/usr.bin/binutils-2.17/include/bfdlink.h +++ b/gnu/usr.bin/binutils-2.17/include/bfdlink.h @@ -270,6 +270,9 @@ struct bfd_link_info /* TRUE if output program should be marked to request W^X permission */ unsigned int wxneeded: 1; + /* TRUE if output program should be marked to stop branch target CFI enforcement */ + unsigned int nobtcfi: 1; + /* TRUE if ok to have version with no definition. */ unsigned int allow_undefined_version: 1; diff --git a/gnu/usr.bin/binutils-2.17/include/elf/common.h b/gnu/usr.bin/binutils-2.17/include/elf/common.h index 9d1c84a8fc3..a494372473a 100644 --- a/gnu/usr.bin/binutils-2.17/include/elf/common.h +++ b/gnu/usr.bin/binutils-2.17/include/elf/common.h @@ -312,6 +312,7 @@ #define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* Fill with random data. */ #define PT_OPENBSD_WXNEEDED 0x65a3dbe7 /* Program does W^X violations */ +#define PT_OPENBSD_NOBTCFI 0x65a3dbe8 /* no branch target CFI */ #define PT_OPENBSD_BOOTDATA 0x65a41be6 /* Section for boot arguments */ #define PT_OPENBSD_MUTABLE 0x65a3dbe5 /* Like bss, but not immutable */ diff --git a/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em b/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em index 6786e6049e5..6d17020999a 100644 --- a/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em +++ b/gnu/usr.bin/binutils-2.17/ld/emultempl/elf32.em @@ -2206,6 +2206,8 @@ cat >>e${EMULATION_NAME}.c <