blob: 0bf1b611a091e76284d2413bf119c23d2ecfc83c [file] [log] [blame]
Index: sys/amd64/amd64/trap.c
===================================================================
--- sys/amd64/amd64/trap.c.orig
+++ sys/amd64/amd64/trap.c (working copy)
@@ -972,4 +972,21 @@
syscallname(td->td_proc, sa.code)));
syscallret(td, error, &sa);
+
+ /*
+ * If the user-supplied value of %rip is not a canonical
+ * address, then some CPUs will trigger a ring 0 #GP during
+ * the sysret instruction. However, the fault handler would
+ * execute with the user's %gs and %rsp in ring 0 which would
+ * not be safe. Instead, preemptively kill the thread with a
+ * SIGBUS.
+ */
+ if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)td->td_frame->tf_rip;
+ trapsignal(td, &ksi);
+ }
}