• Ard Biesheuvel's avatar
    ARM: 8591/1: mm: use fully constructed struct pages for EFI pgd allocations · 61444cde
    Ard Biesheuvel authored
    The late_alloc() PTE allocation function used by create_mapping_late()
    does not call pgtable_page_ctor() on PTE pages it allocates, leaving
    the per-page spinlock uninitialized.
    
    Since generic page table manipulation code may assume that translation
    table pages that are not owned by init_mm are covered by fully
    constructed struct pages, the following crash may occur with the new
    UEFI memory attributes table code.
    
      efi: memattr: Processing EFI Memory Attributes table:
      efi: memattr:  0x0000ffa16000-0x0000ffa82fff [Runtime Code       |RUN|  |  |XP|  |  |  |   |  |  |  |  ]
      Unable to handle kernel NULL pointer dereference at virtual address 00000010
      pgd = c0204000
      [00000010] *pgd=00000000
      Internal error: Oops: 5 [#1] SMP ARM
      Modules linked in:
      CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.7.0-rc4-00063-g3882aa7b340b #361
      Hardware name: Generic DT based system
      task: ed858000 ti: ed842000 task.ti: ed842000
      PC is at __lock_acquire+0xa0/0x19a8
      ...
      [<c038c830>] (__lock_acquire) from [<c038e4f8>] (lock_acquire+0x6c/0x88)
      [<c038e4f8>] (lock_acquire) from [<c0c06134>] (_raw_spin_lock+0x2c/0x3c)
      [<c0c06134>] (_raw_spin_lock) from [<c0410384>] (apply_to_page_range+0xe8/0x238)
      [<c0410384>] (apply_to_page_range) from [<c1205f34>] (efi_set_mapping_permissions+0x54/0x5c)
      [<c1205f34>] (efi_set_mapping_permissions) from [<c1247474>] (efi_memattr_apply_permissions+0x2b8/0x378)
      [<c1247474>] (efi_memattr_apply_permissions) from [<c1248258>] (arm_enable_runtime_services+0x1f0/0x22c)
      [<c1248258>] (arm_enable_runtime_services) from [<c0301f0c>] (do_one_initcall+0x44/0x174)
      [<c0301f0c>] (do_one_initcall) from [<c1200d10>] (kernel_init_freeable+0x90/0x1e8)
      [<c1200d10>] (kernel_init_freeable) from [<c0bff690>] (kernel_init+0x8/0x114)
      [<c0bff690>] (kernel_init) from [<c0307ed0>] (ret_from_fork+0x14/0x24)
    
    The crash is due to the fact that the UEFI page tables are not owned by
    init_mm, but are not covered by fully constructed struct pages.
    
    Given that the UEFI subsystem is currently the only user of
    create_mapping_late(), add an unconditional call to pgtable_page_ctor() to
    late_alloc().
    
    Fixes: 9fc68b71 ("ARM/efi: Apply strict permissions for UEFI Runtime Services regions")
    Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    61444cde
mmu.c 44.6 KB