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>
This commit is contained in:
parent
0c5d2a3dac
commit
61a5ced6ad
2 changed files with 43 additions and 12 deletions
|
@ -38,11 +38,15 @@ typedef struct _IMAGE_DOS_HEADER {
|
||||||
#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
|
#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
|
||||||
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
|
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
|
||||||
|
|
||||||
|
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||||
#define IMAGE_FILE_MACHINE_ARM 0x01c0
|
#define IMAGE_FILE_MACHINE_ARM 0x01c0
|
||||||
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
|
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
|
||||||
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
|
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
|
||||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||||
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
|
#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_HDR32_MAGIC 0x10b
|
||||||
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
||||||
#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
|
#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
|
||||||
|
|
|
@ -22,6 +22,30 @@ const efi_guid_t efi_simple_file_system_protocol_guid =
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
|
||||||
const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_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.
|
* 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;
|
void *entry;
|
||||||
uint64_t image_size;
|
uint64_t image_size;
|
||||||
unsigned long virt_size = 0;
|
unsigned long virt_size = 0;
|
||||||
bool can_run_nt64 = true;
|
int supported = 0;
|
||||||
bool can_run_nt32 = true;
|
|
||||||
|
|
||||||
#if defined(CONFIG_ARM64)
|
|
||||||
can_run_nt32 = false;
|
|
||||||
#elif defined(CONFIG_ARM)
|
|
||||||
can_run_nt64 = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dos = efi;
|
dos = efi;
|
||||||
if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
|
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;
|
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 */
|
/* Calculate upper virtual address boundary */
|
||||||
num_sections = nt->FileHeader.NumberOfSections;
|
num_sections = nt->FileHeader.NumberOfSections;
|
||||||
sections = (void *)&nt->OptionalHeader +
|
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 */
|
/* Read 32/64bit specific header bits */
|
||||||
if (can_run_nt64 &&
|
if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||||
(nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)) {
|
|
||||||
IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
|
IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
|
||||||
IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader;
|
IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader;
|
||||||
image_size = opt->SizeOfImage;
|
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_size = opt->DataDirectory[rel_idx].Size;
|
||||||
rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
|
rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
|
||||||
virt_size = ALIGN(virt_size, opt->SectionAlignment);
|
virt_size = ALIGN(virt_size, opt->SectionAlignment);
|
||||||
} else if (can_run_nt32 &&
|
} else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||||
(nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) {
|
|
||||||
IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
|
IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
|
||||||
image_size = opt->SizeOfImage;
|
image_size = opt->SizeOfImage;
|
||||||
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
|
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
|
||||||
|
|
Loading…
Reference in a new issue