[U-Boot] [PATCH v3] efi_loader: Check machine type in the image header
Ivan Gorinov
ivan.gorinov at intel.com
Fri Apr 6 01:32:06 UTC 2018
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 at intel.com>
---
include/pe.h | 4 +++
lib/efi_loader/efi_image_loader.c | 51 ++++++++++++++++++++++++++++++---------
2 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/include/pe.h b/include/pe.h
index c3a19ce..e7845bb 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -38,11 +38,15 @@ typedef struct _IMAGE_DOS_HEADER {
#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
+#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_ARM 0x01c0
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
+#define IMAGE_FILE_MACHINE_RISCV32 0x5032
+#define IMAGE_FILE_MACHINE_RISCV64 0x5064
+
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index f588576..d5fbba3 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);
--
2.7.4
More information about the U-Boot
mailing list