Commit 97bb9cdc authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Ingo Molnar

efi/x86: Avoid RWX mappings for all of DRAM

The EFI code creates RWX mappings for all memory regions that are
occupied after the stub completes, and in the mixed mode case, it
even creates RWX mappings for all of the remaining DRAM as well.

Let's try to avoid this, by setting the NX bit for all memory
regions except the ones that are marked as EFI runtime services
code [which means text+rodata+data in practice, so we cannot mark
them read-only right away]. For cases of buggy firmware where boot
services code is called during SetVirtualAddressMap(), map those
regions with exec permissions as well - they will be unmapped in
efi_free_boot_services().
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20200113172245.27925-7-ardb@kernel.org
parent d9e3d2c4
...@@ -365,10 +365,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) ...@@ -365,10 +365,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
* as trim_bios_range() will reserve the first page and isolate it away * as trim_bios_range() will reserve the first page and isolate it away
* from memory allocators anyway. * from memory allocators anyway.
*/ */
pf = _PAGE_RW;
if (sev_active())
pf |= _PAGE_ENC;
if (kernel_map_pages_in_pgd(pgd, 0x0, 0x0, 1, pf)) { if (kernel_map_pages_in_pgd(pgd, 0x0, 0x0, 1, pf)) {
pr_err("Failed to create 1:1 mapping for the first page!\n"); pr_err("Failed to create 1:1 mapping for the first page!\n");
return 1; return 1;
...@@ -410,6 +406,22 @@ static void __init __map_region(efi_memory_desc_t *md, u64 va) ...@@ -410,6 +406,22 @@ static void __init __map_region(efi_memory_desc_t *md, u64 va)
unsigned long pfn; unsigned long pfn;
pgd_t *pgd = efi_mm.pgd; pgd_t *pgd = efi_mm.pgd;
/*
* EFI_RUNTIME_SERVICES_CODE regions typically cover PE/COFF
* executable images in memory that consist of both R-X and
* RW- sections, so we cannot apply read-only or non-exec
* permissions just yet. However, modern EFI systems provide
* a memory attributes table that describes those sections
* with the appropriate restricted permissions, which are
* applied in efi_runtime_update_mappings() below. All other
* regions can be mapped non-executable at this point, with
* the exception of boot services code regions, but those will
* be unmapped again entirely in efi_free_boot_services().
*/
if (md->type != EFI_BOOT_SERVICES_CODE &&
md->type != EFI_RUNTIME_SERVICES_CODE)
flags |= _PAGE_NX;
if (!(md->attribute & EFI_MEMORY_WB)) if (!(md->attribute & EFI_MEMORY_WB))
flags |= _PAGE_PCD; flags |= _PAGE_PCD;
......
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