Kernel - Additional cpu bug hardening part 2/2
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 11 Jun 2018 21:30:40 +0000 (14:30 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 11 Jun 2018 21:37:29 +0000 (14:37 -0700)
* Due to speculative instruction execution, the kernel may
  speculatively execute instructions using data from registers that
  still contain userland-controlled content.

  Reduce the chance of this situation arising by proactively clearing
  all user registers after saving them for syscalls, exceptions, and
  interrupts.  In addition, for system calls, zero-out any
  unrestored registers on-return to avoid leaking kernel data back to
  userland.

* This was discussed over the last few months in various
  OS groups and I've decided to implement it.  After the FP
  debacle, it is prudent to also give general registers similar
  protections.

sys/cpu/x86_64/include/asmacros.h
sys/platform/pc64/x86_64/exception.S

index ba7f468..25965d5 100644 (file)
        movq    %r12,TF_R12(%rsp) ;                                     \
        movq    %r13,TF_R13(%rsp) ;                                     \
        movq    %r14,TF_R14(%rsp) ;                                     \
-       movq    %r15,TF_R15(%rsp)
+       movq    %r15,TF_R15(%rsp) ;                                     \
+                                       /* SECURITY CLEAR REGS */       \
+       xorq    %rax,%rax ;                                             \
+       movq    %rax,%rbx ;                                             \
+       movq    %rax,%rcx ;                                             \
+       movq    %rax,%rdx ;                                             \
+       movq    %rax,%rdi ;                                             \
+       movq    %rax,%rsi ;                                             \
+       movq    %rax,%rbp ;                                             \
+       movq    %rax,%r8 ;                                              \
+       movq    %rax,%r9 ;                                              \
+       movq    %rax,%r10 ;                                             \
+       movq    %rax,%r11 ;                                             \
+       movq    %rax,%r12 ;                                             \
+       movq    %rax,%r13 ;                                             \
+       movq    %rax,%r14 ;                                             \
+       movq    %rax,%r15                                               \
+
 
 /*
  * PUSH_FRAME is the first thing executed upon interrupt entry.  We are
index 944d220..235f9e4 100644 (file)
@@ -428,6 +428,23 @@ IDTVEC(fast_syscall)
        movq    %r13,TF_R13(%rsp)       /* C preserved */
        movq    %r14,TF_R14(%rsp)       /* C preserved */
        movq    %r15,TF_R15(%rsp)       /* C preserved */
+
+       xorq    %rax,%rax               /* SECURITY CLEAR REGS */
+       movq    %rax,%rbx
+       movq    %rax,%rcx
+       movq    %rax,%rdx
+       movq    %rax,%rsi
+       movq    %rax,%rdi
+       movq    %rax,%rbp
+       movq    %rax,%r8
+       movq    %rax,%r9
+       movq    %rax,%r10
+       movq    %rax,%r11
+       movq    %rax,%r12
+       movq    %rax,%r13
+       movq    %rax,%r14
+       movq    %rax,%r15
+
        sti
        FAKE_MCOUNT(TF_RIP(%rsp))
        movq    %rsp, %rdi
@@ -442,7 +459,20 @@ IDTVEC(fast_syscall)
        testl   $RQF_QUICKRET,PCPU(reqflags)
        jz      1f
        MEXITCOUNT
-       movq    TF_RDI(%rsp),%rdi
+
+       movq    TF_RBX(%rsp),%rbx       /* SECURITY RESTORE */
+       movq    TF_RCX(%rsp),%rcx
+       movq    TF_RBP(%rsp),%rbp
+       movq    TF_R8(%rsp),%r8
+       movq    TF_R9(%rsp),%r9
+       xorq    %r10,%r10               /* (security - clear scratch) */
+       movq    %r10,%r11
+       movq    TF_R12(%rsp),%r12
+       movq    TF_R13(%rsp),%r13
+       movq    TF_R14(%rsp),%r14
+       movq    TF_R15(%rsp),%r15
+
+       movq    TF_RDI(%rsp),%rdi       /* NORMAL RESTORE */
        movq    TF_RSI(%rsp),%rsi
        movq    TF_RDX(%rsp),%rdx
        movq    TF_RAX(%rsp),%rax