Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/i386 Mitigation for CVE-2018-8897 on i386. Con...



details:   https://anonhg.NetBSD.org/src/rev/0af080224e43
branches:  trunk
changeset: 322760:0af080224e43
user:      maxv <maxv%NetBSD.org@localhost>
date:      Wed May 16 08:16:36 2018 +0000

description:
Mitigation for CVE-2018-8897 on i386. Contrary to amd64 there is no clear
way to determine if we are in kernel mode but with the user context; so we
go the hard way, and scan the IDT.

On i386 the bug is less of a problem, since we don't have GSBASE. All an
attacker can do is panicking the system.

diffstat:

 sys/arch/i386/i386/i386_trap.S |  45 ++++++++++++++++++++++++++++++++++++++++-
 sys/arch/i386/i386/trap.c      |  24 ++++++++++++++++++++-
 2 files changed, 65 insertions(+), 4 deletions(-)

diffs (121 lines):

diff -r b411bd5b9b49 -r 0af080224e43 sys/arch/i386/i386/i386_trap.S
--- a/sys/arch/i386/i386/i386_trap.S    Wed May 16 08:08:24 2018 +0000
+++ b/sys/arch/i386/i386/i386_trap.S    Wed May 16 08:16:36 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i386_trap.S,v 1.13 2018/03/16 12:48:54 maxv Exp $      */
+/*     $NetBSD: i386_trap.S,v 1.14 2018/05/16 08:16:36 maxv Exp $      */
 
 /*
  * Copyright 2002 (c) Wasabi Systems, Inc.
@@ -66,7 +66,7 @@
 
 #if 0
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: i386_trap.S,v 1.13 2018/03/16 12:48:54 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i386_trap.S,v 1.14 2018/05/16 08:16:36 maxv Exp $");
 #endif
 
 /*
@@ -88,8 +88,49 @@
        ZTRAP(T_DIVIDE)
 IDTVEC_END(trap00)
 
+/*
+ * Handle the SS shadow, CVE-2018-8897.
+ *
+ * We scan the IDT to determine if we hit an entry point. If so, we leave
+ * without restoring the segregs, because we could fault while doing that.
+ */
 IDTVEC(trap01)
+#ifndef XEN
+       pushl   $0
+       pushl   $T_TRCTRAP
+       INTRENTRY
+
+       testb   $SEL_UPL,TF_CS(%esp)
+       jnz     .Lnormal_dbentry
+
+       pushl   %esp
+       call    ss_shadow
+       addl    $4,%esp
+
+       cmpl    $1,%eax
+       jne     .Lnormal_dbentry
+
+       /* SS shadow, ignore the exception. */
+       xorl    %eax,%eax
+       movl    %eax,%dr6
+
+       /* INTRFASTEXIT, but without segregs. */
+       movl    TF_EDI(%esp),%edi
+       movl    TF_ESI(%esp),%esi
+       movl    TF_EBP(%esp),%ebp
+       movl    TF_EBX(%esp),%ebx
+       movl    TF_EDX(%esp),%edx
+       movl    TF_ECX(%esp),%ecx
+       movl    TF_EAX(%esp),%eax
+       addl    $(TF_PUSHSIZE+8),%esp
+       iret
+
+.Lnormal_dbentry:
+       STI(%eax)
+       jmp _C_LABEL(calltrap)
+#else
        ZTRAP(T_TRCTRAP)
+#endif
 IDTVEC_END(trap01)
 
 /*
diff -r b411bd5b9b49 -r 0af080224e43 sys/arch/i386/i386/trap.c
--- a/sys/arch/i386/i386/trap.c Wed May 16 08:08:24 2018 +0000
+++ b/sys/arch/i386/i386/trap.c Wed May 16 08:16:36 2018 +0000
@@ -1,5 +1,5 @@
 
-/*     $NetBSD: trap.c,v 1.293 2018/02/13 01:05:18 christos Exp $      */
+/*     $NetBSD: trap.c,v 1.294 2018/05/16 08:16:36 maxv Exp $  */
 
 /*-
  * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.293 2018/02/13 01:05:18 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.294 2018/05/16 08:16:36 maxv Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -128,6 +128,7 @@
 void trap(struct trapframe *);
 void trap_tss(struct i386tss *, int, int);
 void trap_return_fault_return(struct trapframe *) __dead;
+int ss_shadow(struct trapframe *tf);
 
 const char * const trap_type[] = {
        "privileged instruction fault",         /*  0 T_PRIVINFLT */
@@ -236,6 +237,25 @@
            l, l->l_proc->p_pid, l->l_lid, KSTACK_LOWEST_ADDR(l));
 }
 
+int
+ss_shadow(struct trapframe *tf)
+{
+       struct gate_descriptor *gd;
+       uintptr_t eip, func;
+       size_t i;
+
+       eip = tf->tf_eip;
+
+       for (i = 0; i < 256; i++) {
+               gd = &idt[i];
+               func = (gd->gd_hioffset << 16) | gd->gd_looffset;
+               if (eip == func)
+                       return 1;
+       }
+
+       return 0;
+}
+
 /*
  * trap(frame): exception, fault, and trap interface to BSD kernel.
  *



Home | Main Index | Thread Index | Old Index