Commit 50d7cdf7 authored by Ard Biesheuvel's avatar Ard Biesheuvel

efi/x86: Avoid physical KASLR on older Dell systems

River reports boot hangs with v6.6 and v6.7, and the bisect points to
commit

  a1b87d54 ("x86/efistub: Avoid legacy decompressor when doing EFI boot")

which moves the memory allocation and kernel decompression from the
legacy decompressor (which executes *after* ExitBootServices()) to the
EFI stub, using boot services for allocating the memory. The memory
allocation succeeds but the subsequent call to decompress_kernel() never
returns, resulting in a failed boot and a hanging system.

As it turns out, this issue only occurs when physical address
randomization (KASLR) is enabled, and given that this is a feature we
can live without (virtual KASLR is much more important), let's disable
the physical part of KASLR when booting on AMI UEFI firmware claiming to
implement revision v2.0 of the specification (which was released in
2006), as this is the version these systems advertise.

Fixes: a1b87d54 ("x86/efistub: Avoid legacy decompressor when doing EFI boot")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218173Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 271f2a4a
......@@ -307,17 +307,20 @@ static void setup_unaccepted_memory(void)
efi_err("Memory acceptance protocol failed\n");
}
static efi_char16_t *efistub_fw_vendor(void)
{
unsigned long vendor = efi_table_attr(efi_system_table, fw_vendor);
return (efi_char16_t *)vendor;
}
static const efi_char16_t apple[] = L"Apple";
static void setup_quirks(struct boot_params *boot_params)
{
efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long)
efi_table_attr(efi_system_table, fw_vendor);
if (!memcmp(fw_vendor, apple, sizeof(apple))) {
if (IS_ENABLED(CONFIG_APPLE_PROPERTIES))
retrieve_apple_device_properties(boot_params);
}
if (IS_ENABLED(CONFIG_APPLE_PROPERTIES) &&
!memcmp(efistub_fw_vendor(), apple, sizeof(apple)))
retrieve_apple_device_properties(boot_params);
}
/*
......@@ -765,11 +768,25 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {
u64 range = KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR - kernel_total_size;
static const efi_char16_t ami[] = L"American Megatrends";
efi_get_seed(seed, sizeof(seed));
virt_addr += (range * seed[1]) >> 32;
virt_addr &= ~(CONFIG_PHYSICAL_ALIGN - 1);
/*
* Older Dell systems with AMI UEFI firmware v2.0 may hang
* while decompressing the kernel if physical address
* randomization is enabled.
*
* https://bugzilla.kernel.org/show_bug.cgi?id=218173
*/
if (efi_system_table->hdr.revision <= EFI_2_00_SYSTEM_TABLE_REVISION &&
!memcmp(efistub_fw_vendor(), ami, sizeof(ami))) {
efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n");
seed[0] = 0;
}
}
status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment