summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/trap.c
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2018-05-08 13:01:44 -0300
committerRenato Botelho <renato@netgate.com>2018-05-08 13:01:44 -0300
commit70d1caf0ad967030b2ce835dc0f116ed1733c82c (patch)
treed8d3e5c39f96c4f1a230eb163d57b858f4339f57 /sys/amd64/amd64/trap.c
parent77c0e2e68638110a69edb20c8beaf1f288912b09 (diff)
downloadFreeBSD-src-70d1caf0ad967030b2ce835dc0f116ed1733c82c.zip
FreeBSD-src-70d1caf0ad967030b2ce835dc0f116ed1733c82c.tar.gz
Proposed fix for CVE-2018-8897
Diffstat (limited to 'sys/amd64/amd64/trap.c')
-rw-r--r--sys/amd64/amd64/trap.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index a553fc5..af4925a 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
*/
#include "opt_clock.h"
+#include "opt_compat.h"
#include "opt_cpu.h"
#include "opt_hwpmc_hooks.h"
#include "opt_isa.h"
@@ -99,6 +100,11 @@ PMC_SOFT_DEFINE( , , page_fault, write);
#include <sys/dtrace_bsd.h>
#endif
+extern inthand_t IDTVEC(bpt), IDTVEC(bpt_pti), IDTVEC(dbg),
+ IDTVEC(fast_syscall), IDTVEC(fast_syscall_pti), IDTVEC(fast_syscall32),
+ IDTVEC(int0x80_syscall_pti), IDTVEC(int0x80_syscall);
+
+
void __noinline trap(struct trapframe *frame);
void trap_check(struct trapframe *frame);
void dblfault_handler(struct trapframe *frame);
@@ -535,6 +541,52 @@ trap(struct trapframe *frame)
load_dr6(rdr6() & ~0xf);
return;
}
+
+ /*
+ * Malicious user code can configure a debug
+ * register watchpoint to trap on data access
+ * to the top of stack and then execute 'pop
+ * %ss; int 3'. Due to exception deferral for
+ * 'pop %ss', the CPU will not interrupt 'int
+ * 3' to raise the DB# exception for the debug
+ * register but will postpone the DB# until
+ * execution of the first instruction of the
+ * BP# handler (in kernel mode). Normally the
+ * previous check would ignore DB# exceptions
+ * for watchpoints on user addresses raised in
+ * kernel mode. However, some CPU errata
+ * include cases where DB# exceptions do not
+ * properly set bits in %dr6, e.g. Haswell
+ * HSD23 and Skylake-X SKZ24.
+ *
+ * A deferred DB# can also be raised on the
+ * first instructions of system call entry
+ * points or single-step traps via similar use
+ * of 'pop %ss' or 'mov xxx, %ss'.
+ */
+ if (pti) {
+ if (frame->tf_rip ==
+ (uintptr_t)IDTVEC(fast_syscall_pti) ||
+#ifdef COMPAT_FREEBSD32
+ frame->tf_rip ==
+ (uintptr_t)IDTVEC(int0x80_syscall_pti) ||
+#endif
+ frame->tf_rip == (uintptr_t)IDTVEC(bpt_pti))
+ return;
+ } else {
+ if (frame->tf_rip ==
+ (uintptr_t)IDTVEC(fast_syscall) ||
+#ifdef COMPAT_FREEBSD32
+ frame->tf_rip ==
+ (uintptr_t)IDTVEC(int0x80_syscall) ||
+#endif
+ frame->tf_rip == (uintptr_t)IDTVEC(bpt))
+ return;
+ }
+ if (frame->tf_rip == (uintptr_t)IDTVEC(dbg) ||
+ /* Needed for AMD. */
+ frame->tf_rip == (uintptr_t)IDTVEC(fast_syscall32))
+ return;
/*
* FALLTHROUGH (TRCTRAP kernel mode, kernel address)
*/
OpenPOWER on IntegriCloud