On Mon, Feb 11, 2019 at 09:57:02AM +0000, Ard Biesheuvel wrote: >On Mon, 11 Feb 2019 at 10:56, Chao Fan <fanc.fnst@xxxxxxxxxxxxxx> wrote: >> >> On Mon, Feb 11, 2019 at 09:46:03AM +0000, Ard Biesheuvel wrote: >> >On Mon, 11 Feb 2019 at 01:22, Borislav Petkov <bp@xxxxxxxxx> wrote: >> >> >> >> On Fri, Feb 08, 2019 at 10:53:22PM +0100, Borislav Petkov wrote: >> >> > On Fri, Feb 08, 2019 at 12:44:51PM -0800, Guenter Roeck wrote: >> >> > > Yes, the kernel boots if I comment out that function and have it return 0. >> >> > >> >> > Thanks, this localizes the issue significantly. >> >> >> >> Some observations: >> >> >> >> } else { >> >> efi_config_table_32_t *tmp_table; >> >> >> >> tmp_table = config_tables; >> >> guid = tmp_table->guid; <--- * >> >> table = tmp_table->table; >> >> } >> >> >> >> It blows up at that tmp_table->guid deref above. Singlestepping through >> >> it with gdb shows: >> >> >> >> # arch/x86/boot/compressed/acpi.c:114: guid = tmp_table->guid; >> >> movq (%rdi), %rax # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid >> >> movq 8(%rdi), %rsi # MEM[(struct efi_config_table_32_t *)config_tables_37].guid, guid >> >> # arch/x86/boot/compressed/acpi.c:115: table = tmp_table->table; >> >> movl 16(%rdi), %r10d # MEM[(struct efi_config_table_32_t *)config_tables_37].table, table >> >> jmp .L30 # >> >> >> >> and %rdi has: >> >> >> >> rdi 0x630646870 >> >> >> >> which is an address above 4G but we're using a 32-bit EFI BIOS. >> >> >> >> Which begs the question whether EFI system tables can even be mapped at >> >> something above 4G with a 32-bit EFI and whether that could work ok. >> >> Hmm. >> >> >> >> Lemme add Ard and mfleming for insight here. >> >> >> > >> >-ENOCONTEXT, but let me try in any case: >> > >> >linux/efi.h has >> > >> >typedef struct { >> > efi_guid_t guid; >> > u32 table; >> >} efi_config_table_32_t; >> > >> >so if we end up with more than 32 bits set in table, there is >> >something seriously wrong. >> > >> >The size of efi_config_table_32_t deviates from efi_config_table_64_t, >> >so you will have to ensure that you are using the correct stride when >> >iterating over config_tables. >> >> Here I use signature to judge it. >> If the signature is EFI64_LOADER_SIGNATURE, I will use efi_config_table_64_t, >> if the signature is EFI32_LOADER_SIGNATURE, I will use efi_config_table_32_t. >> But the efi32 whose signature is EFI32_LOADER_SIGNATURE points to a >> address above 4G, I am not sure whether this is normal and works well. >> > >This is impossible. The 'table' member of efi_config_table_32_t is >only 32 bits wide, so how can it contain an address over 4 GB ? Maybe I mislead you. In my code, I need to find the eficonfig_table_*. After that, I should type cast it to right efi_config_table_32_t or efi_config_table_64_t. Then my judgment is to compare its efi_info->efi_loader_signature. If it's EFI64_LOADER_SIGNATURE, I will type cast it to efi_config_table_64_t. If it's EFI32_LOADER_SIGNATURE, I will type cast it to efi_config_table_32_t. But here is a issue, its signature matches EFI32_LOADER_SIGNATURE, but it's table member is above 4G, but I use efi_config_table_32_t. That cause a problem. Thanks, Chao Fan > >
![]() |