efi/x86: avoid KASAN false positives when accessing the 1: 1 mapping
authorArd Biesheuvel <ardb@kernel.org>
Sat, 18 Jan 2020 16:57:03 +0000 (17:57 +0100)
committerIngo Molnar <mingo@kernel.org>
Mon, 20 Jan 2020 07:14:29 +0000 (08:14 +0100)
When installing the EFI virtual address map during early boot, we
access the EFI system table to retrieve the 1:1 mapped address of
the SetVirtualAddressMap() EFI runtime service. This memory is not
known to KASAN, so on KASAN enabled builds, this may result in a
splat like

  ==================================================================
  BUG: KASAN: user-memory-access in efi_set_virtual_address_map+0x141/0x354
  Read of size 4 at addr 000000003fbeef38 by task swapper/0/0

  CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.5.0-rc5+ #758
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  Call Trace:
   dump_stack+0x8b/0xbb
   ? efi_set_virtual_address_map+0x141/0x354
   ? efi_set_virtual_address_map+0x141/0x354
   __kasan_report+0x176/0x192
   ? efi_set_virtual_address_map+0x141/0x354
   kasan_report+0xe/0x20
   efi_set_virtual_address_map+0x141/0x354
   ? efi_thunk_runtime_setup+0x148/0x148
   ? __inc_numa_state+0x19/0x90
   ? memcpy+0x34/0x50
   efi_enter_virtual_mode+0x5fd/0x67d
   start_kernel+0x5cd/0x682
   ? mem_encrypt_init+0x6/0x6
   ? x86_family+0x5/0x20
   ? load_ucode_bsp+0x46/0x154
   secondary_startup_64+0xa4/0xb0
  ==================================================================

Since this code runs only a single time during early boot, let's annotate
it as __no_sanitize_address so KASAN disregards it entirely.

Fixes: 698294704573 ("efi/x86: Split SetVirtualAddresMap() wrappers into ...")
Reported-by: Qian Cai <cai@lca.pw>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/platform/efi/efi_64.c

index 8d1869f..e2accfe 100644 (file)
@@ -543,7 +543,7 @@ static DEFINE_SPINLOCK(efi_runtime_lock);
        __s;                                                            \
 })
 
-static efi_status_t __init
+static efi_status_t __init __no_sanitize_address
 efi_thunk_set_virtual_address_map(unsigned long memory_map_size,
                                  unsigned long descriptor_size,
                                  u32 descriptor_version,
@@ -882,10 +882,11 @@ void __init efi_thunk_runtime_setup(void)
        efi.query_capsule_caps = efi_thunk_query_capsule_caps;
 }
 
-efi_status_t __init efi_set_virtual_address_map(unsigned long memory_map_size,
-                                               unsigned long descriptor_size,
-                                               u32 descriptor_version,
-                                               efi_memory_desc_t *virtual_map)
+efi_status_t __init __no_sanitize_address
+efi_set_virtual_address_map(unsigned long memory_map_size,
+                           unsigned long descriptor_size,
+                           u32 descriptor_version,
+                           efi_memory_desc_t *virtual_map)
 {
        efi_status_t status;
        unsigned long flags;