• S
    x86/mm: Populate KASAN shadow for entire per-CPU range of CPU entry area · 97650148
    Sean Christopherson 提交于
    Populate a KASAN shadow for the entire possible per-CPU range of the CPU
    entry area instead of requiring that each individual chunk map a shadow.
    Mapping shadows individually is error prone, e.g. the per-CPU GDT mapping
    was left behind, which can lead to not-present page faults during KASAN
    validation if the kernel performs a software lookup into the GDT.  The DS
    buffer is also likely affected.
    
    The motivation for mapping the per-CPU areas on-demand was to avoid
    mapping the entire 512GiB range that's reserved for the CPU entry area,
    shaving a few bytes by not creating shadows for potentially unused memory
    was not a goal.
    
    The bug is most easily reproduced by doing a sigreturn with a garbage
    CS in the sigcontext, e.g.
    
      int main(void)
      {
        struct sigcontext regs;
    
        syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
        syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
        syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
    
        memset(&regs, 0, sizeof(regs));
        regs.cs = 0x1d0;
        syscall(__NR_rt_sigreturn);
        return 0;
      }
    
    to coerce the kernel into doing a GDT lookup to compute CS.base when
    reading the instruction bytes on the subsequent #GP to determine whether
    or not the #GP is something the kernel should handle, e.g. to fixup UMIP
    violations or to emulate CLI/STI for IOPL=3 applications.
    
      BUG: unable to handle page fault for address: fffffbc8379ace00
      #PF: supervisor read access in kernel mode
      #PF: error_code(0x0000) - not-present page
      PGD 16c03a067 P4D 16c03a067 PUD 15b990067 PMD 15b98f067 PTE 0
      Oops: 0000 [#1] PREEMPT SMP KASAN
      CPU: 3 PID: 851 Comm: r2 Not tainted 6.1.0-rc3-next-20221103+ #432
      Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
      RIP: 0010:kasan_check_range+0xdf/0x190
      Call Trace:
       <TASK>
       get_desc+0xb0/0x1d0
       insn_get_seg_base+0x104/0x270
       insn_fetch_from_user+0x66/0x80
       fixup_umip_exception+0xb1/0x530
       exc_general_protection+0x181/0x210
       asm_exc_general_protection+0x22/0x30
      RIP: 0003:0x0
      Code: Unable to access opcode bytes at 0xffffffffffffffd6.
      RSP: 0003:0000000000000000 EFLAGS: 00000202
      RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000000001d0
      RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
      RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
      R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
      R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
       </TASK>
    
    Fixes: 9fd429c28073 ("x86/kasan: Map shadow for percpu pages on demand")
    Reported-by: syzbot+ffb4f000dc2872c93f62@syzkaller.appspotmail.com
    Suggested-by: NAndrey Ryabinin <ryabinin.a.a@gmail.com>
    Signed-off-by: NSean Christopherson <seanjc@google.com>
    Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: NAndrey Ryabinin <ryabinin.a.a@gmail.com>
    Link: https://lkml.kernel.org/r/20221110203504.1985010-3-seanjc@google.com
    97650148
cpu_entry_area.c 7.8 KB