diff options
author | Ivan Gorinov | 2018-04-05 18:32:06 -0700 |
---|---|---|
committer | Alexander Graf | 2018-04-06 09:28:01 +0200 |
commit | 61a5ced6ad9376a0755ea2a920667e3a9072990c (patch) | |
tree | 2770f93a3032f95b0e959849209d7e4e231364fb /lib | |
parent | 0c5d2a3dac01a8d436639ab5b7e44f4218d62b84 (diff) |
efi_loader: Check machine type in the image header
Check FileHeader.Machine to make sure the EFI executable image is built
for the same architecture. For example, 32-bit U-Boot on x86 will print
an error message instead of loading an x86_64 image and crashing.
Signed-off-by: Ivan Gorinov <ivan.gorinov@intel.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_image_loader.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index f5885760d41..d5fbba31383 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -22,6 +22,30 @@ const efi_guid_t efi_simple_file_system_protocol_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID; +static int machines[] = { +#if defined(CONFIG_ARM64) + IMAGE_FILE_MACHINE_ARM64, +#elif defined(CONFIG_ARM) + IMAGE_FILE_MACHINE_ARM, + IMAGE_FILE_MACHINE_THUMB, + IMAGE_FILE_MACHINE_ARMNT, +#endif + +#if defined(CONFIG_X86_64) + IMAGE_FILE_MACHINE_AMD64, +#elif defined(CONFIG_X86) + IMAGE_FILE_MACHINE_I386, +#endif + +#if defined(CONFIG_CPU_RISCV_32) + IMAGE_FILE_MACHINE_RISCV32, +#endif + +#if defined(CONFIG_CPU_RISCV_64) + IMAGE_FILE_MACHINE_RISCV64, +#endif + 0 }; + /* * Print information about a loaded image. * @@ -172,14 +196,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) void *entry; uint64_t image_size; unsigned long virt_size = 0; - bool can_run_nt64 = true; - bool can_run_nt32 = true; - -#if defined(CONFIG_ARM64) - can_run_nt32 = false; -#elif defined(CONFIG_ARM) - can_run_nt64 = false; -#endif + int supported = 0; dos = efi; if (dos->e_magic != IMAGE_DOS_SIGNATURE) { @@ -193,6 +210,18 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) return NULL; } + for (i = 0; machines[i]; i++) + if (machines[i] == nt->FileHeader.Machine) { + supported = 1; + break; + } + + if (!supported) { + printf("%s: Machine type 0x%04x is not supported\n", + __func__, nt->FileHeader.Machine); + return NULL; + } + /* Calculate upper virtual address boundary */ num_sections = nt->FileHeader.NumberOfSections; sections = (void *)&nt->OptionalHeader + @@ -205,8 +234,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) } /* Read 32/64bit specific header bits */ - if (can_run_nt64 && - (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)) { + if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { IMAGE_NT_HEADERS64 *nt64 = (void *)nt; IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader; image_size = opt->SizeOfImage; @@ -222,8 +250,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) rel_size = opt->DataDirectory[rel_idx].Size; rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; virt_size = ALIGN(virt_size, opt->SectionAlignment); - } else if (can_run_nt32 && - (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) { + } else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader; image_size = opt->SizeOfImage; efi_set_code_and_data_type(loaded_image_info, opt->Subsystem); |