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 ?
![]() |