From 6c299acf48fde3811c027b6ceddd0c0eb97ba38f Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sun, 26 Mar 2023 10:38:01 +0200 Subject: [PATCH] BaseTools/GenFw: Parse IBT/BTI support status from ELF note REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4405 When performing ELF to PE/COFF conversion, parse any notes sections to decide whether the image supports forward CFI landing pads. This will be used to set the associated DllCharacteristicsEx flag in a subsequent patch. Signed-off-by: Ard Biesheuvel Reviewed-by: Leif Lindholm Reviewed-by: Oliver Smith-Denny Acked-by: Michael Kubacki Reviewed-by: Liming Gao --- BaseTools/Source/C/GenFw/Elf64Convert.c | 50 +++++++++++++++++++++++++ BaseTools/Source/C/GenFw/elf_common.h | 9 +++++ 2 files changed, 59 insertions(+) diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c index 8b50774beb..2a810e835d 100644 --- a/BaseTools/Source/C/GenFw/Elf64Convert.c +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c @@ -770,6 +770,49 @@ WriteSectionRiscV64 ( } } +STATIC UINT16 mDllCharacteristicsEx; + +STATIC +VOID +ParseNoteSection ( + CONST Elf_Shdr *Shdr + ) +{ + CONST Elf_Note *Note; + CONST UINT32 *Prop; + UINT32 Prop0; + UINT32 Prop2; + + Note = (Elf_Note *)((UINT8 *)mEhdr + Shdr->sh_offset); + + if ((Note->n_type == NT_GNU_PROPERTY_TYPE_0) && + (Note->n_namesz == sizeof ("GNU")) && + (strcmp ((CHAR8 *)(Note + 1), "GNU") == 0) && + (Note->n_descsz > sizeof (UINT32[2]))) { + Prop = (UINT32 *)((UINT8 *)(Note + 1) + sizeof("GNU")); + + switch (mEhdr->e_machine) { + case EM_AARCH64: + Prop0 = GNU_PROPERTY_AARCH64_FEATURE_1_AND; + Prop2 = GNU_PROPERTY_AARCH64_FEATURE_1_BTI; + break; + + case EM_X86_64: + Prop0 = GNU_PROPERTY_X86_FEATURE_1_AND; + Prop2 = GNU_PROPERTY_X86_FEATURE_1_IBT; + break; + + default: + return; + } + if ((Prop[0] == Prop0) && + (Prop[1] >= sizeof (UINT32)) && + ((Prop[2] & Prop2) != 0)) { + mDllCharacteristicsEx |= EFI_IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT; + } + } +} + // // Elf functions interface implementation // @@ -826,6 +869,13 @@ ScanSections64 ( } } + for (i = 0; i < mEhdr->e_shnum; i++) { + Elf_Shdr *shdr = GetShdrByIndex(i); + if (shdr->sh_type == SHT_NOTE) { + ParseNoteSection (shdr); + } + } + // // Check if mCoffAlignment is larger than MAX_COFF_ALIGNMENT // diff --git a/BaseTools/Source/C/GenFw/elf_common.h b/BaseTools/Source/C/GenFw/elf_common.h index 7b7fdeb329..ccd32804b0 100644 --- a/BaseTools/Source/C/GenFw/elf_common.h +++ b/BaseTools/Source/C/GenFw/elf_common.h @@ -59,6 +59,15 @@ typedef struct { UINT32 n_type; /* Type of this note. */ } Elf_Note; +#define NT_GNU_PROPERTY_TYPE_0 5 + +#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 +#define GNU_PROPERTY_X86_FEATURE_1_IBT 0x1 + +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 0x1 +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 0x2 + /* Indexes into the e_ident array. Keep synced with http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ #define EI_MAG0 0 /* Magic number, byte 0. */