Skip to content
  • Ard Biesheuvel's avatar
    efi/x86: Don't remap text<->rodata gap read-only for mixed mode · f6103162
    Ard Biesheuvel authored
    Commit
    
      d9e3d2c4 ("efi/x86: Don't map the entire kernel text RW for mixed mode")
    
    updated the code that creates the 1:1 memory mapping to use read-only
    attributes for the 1:1 alias of the kernel's text and rodata sections, to
    protect it from inadvertent modification. However, it failed to take into
    account that the unused gap between text and rodata is given to the page
    allocator for general use.
    
    If the vmap'ed stack happens to be allocated from this region, any by-ref
    output arguments passed to EFI runtime services that are allocated on the
    stack (such as the 'datasize' argument taken by GetVariable() when invoked
    from efivar_entry_size()) will be referenced via a read-only mapping,
    resulting in a page fault if the EFI code tries to write to it:
    
      BUG: unable to handle page fault for address: 00000000386aae88
      #PF: supervisor write access in kernel mode
      #PF: error_code(0x0003) - permissions violation
      PGD fd61063 P4D fd61063 PUD fd62063 PMD 386000e1
      Oops: 0003 [#1] SMP PTI
      CPU: 2 PID: 255 Comm: systemd-sysv-ge Not tainted 5.6.0-rc4-default+ #22
      Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
      RIP: 0008:0x3eaeed95
      Code: ...  <89> 03 be 05 00 00 80 a1 74 63 b1 3e 83 c0 48 e8 44 d2 ff ff eb 05
      RSP: 0018:000000000fd73fa0 EFLAGS: 00010002
      RAX: 0000000000000001 RBX: 00000000386aae88 RCX: 000000003e9f1120
      RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000001
      RBP: 000000000fd73fd8 R08: 00000000386aae88 R09: 0000000000000000
      R10: 0000000000000002 R11: 0000000000000000 R12: 0000000000000000
      R13: ffffc0f040220000 R14: 0000000000000000 R15: 0000000000000000
      FS:  00007f21160ac940(0000) GS:ffff9cf23d500000(0000) knlGS:0000000000000000
      CS:  0008 DS: 0018 ES: 0018 CR0: 0000000080050033
      CR2: 00000000386aae88 CR3: 000000000fd6c004 CR4: 00000000003606e0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
      Call Trace:
      Modules linked in:
      CR2: 00000000386aae88
      ---[ end trace a8bfbd202e712834 ]---
    
    Let's fix this by remapping text and rodata individually, and leave the
    gaps mapped read-write.
    
    Fixes: d9e3d2c4
    
     ("efi/x86: Don't map the entire kernel text RW for mixed mode")
    Reported-by: default avatarJiri Slaby <jslaby@suse.cz>
    Tested-by: default avatarJiri Slaby <jslaby@suse.cz>
    Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    Link: https://lore.kernel.org/r/20200409130434.6736-10-ardb@kernel.org
    f6103162