]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
XSA-451 PoC
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 21 Feb 2024 16:59:29 +0000 (16:59 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 28 Feb 2024 17:26:58 +0000 (17:26 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/include/arch/lib.h
arch/x86/include/arch/processor.h
docs/all-tests.dox
tests/xsa-451/Makefile [new file with mode: 0644]
tests/xsa-451/main.c [new file with mode: 0644]

index 0a9b23dba4b70591ff1628b09ddfc9cb6195192e..600e5346584b042777fc38ec2e417e87a776e8b7 100644 (file)
@@ -305,6 +305,20 @@ static inline void write_cr8(unsigned long cr8)
     asm volatile ("mov %0, %%cr8" :: "r" (cr8));
 }
 
+static inline uint32_t read_mxcsr(void)
+{
+    uint32_t mxcsr;
+
+    asm volatile ("stmxcsr %0" : "=m" (mxcsr));
+
+    return mxcsr;
+}
+
+static inline void write_mxcsr(uint32_t mxcsr)
+{
+    asm volatile ("ldmxcsr %0" :: "m" (mxcsr));
+}
+
 static inline void invlpg(const void *va)
 {
     asm volatile ("invlpg (%0)" :: "r" (va));
index 1c7e6554681cdec6b9b3731d3846f3b205ec2fab..9cf2fe08669fab0bfe7c46a3603522a6d8b023d7 100644 (file)
 #define _XSTATE_LWP               62
 #define XSTATE_LWP                (1ULL << _XSTATE_LWP)
 
+/*
+ * Media eXtentions Control and Status Register.
+ */
+#define X86_MXCSR_IE            0x00000001  /* Invalid-Operation Exception  */
+#define X86_MXCSR_DE            0x00000002  /* Denormal-Operation Exception */
+#define X86_MXCSR_ZE            0x00000004  /* Zero-divide Exception        */
+#define X86_MXCSR_OE            0x00000008  /* Overflow Exception           */
+#define X86_MXCSR_UE            0x00000010  /* Underflow Exception          */
+#define X86_MXCSR_PE            0x00000020  /* Precision Exception          */
+#define X86_MXCSR_STATUS_MASK   0x0000003f  /* `- All of the above          */
+
 /*
  * Exception mnemonics.
  */
index 892a9e4747438e78610334068bac88fdd365236d..ab88c15c2b9f364daf96ce6d9b79189f816bb701 100644 (file)
@@ -167,6 +167,8 @@ states.
 
 @subpage test-xsa-444 - x86/AMD: Debug Mask handling.
 
+@subpage test-xsa-451 - x86: shadow stack vs exceptions from emulation stubs.
+
 
 @section index-utility Utilities
 
diff --git a/tests/xsa-451/Makefile b/tests/xsa-451/Makefile
new file mode 100644 (file)
index 0000000..f904866
--- /dev/null
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := xsa-451
+CATEGORY  := xsa
+TEST-ENVS := hvm64
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/xsa-451/main.c b/tests/xsa-451/main.c
new file mode 100644 (file)
index 0000000..896d370
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * @file tests/xsa-451/main.c
+ * @ref test-xsa-451
+ *
+ * @page test-xsa-451 XSA-451
+ *
+ * Advisory: [XSA-451](https://xenbits.xen.org/xsa/advisory-451.html)
+ *
+ * When CET Shadow Stack support was added to Xen, the logic which performs
+ * exception recovery from the emulation stubs wasn't adjusted correctly.
+ *
+ * As a consequence, when an exception is taken in the emulation stubs and Xen
+ * is using CET-SS, Xen will crash with a control-flow integrity violation.
+ *
+ * From a testing point of view, we have no idea if Xen is using CET Shadow
+ * Stacks or not.  All we can do is emulate an instruction which will generate
+ * an unmasked exception, and hope that we're still alive to report success.
+ *
+ * @see tests/xsa-451/main.c
+ */
+#include <xtf.h>
+
+const char test_title[] = "XSA-451 PoC";
+bool test_needs_fep = true;
+
+void test_main(void)
+{
+    exinfo_t fault = 0;
+    unsigned int status;
+
+    /* Enable SEE, clear and unmask all exceptions. */
+    write_cr4(read_cr4() | X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT);
+    write_mxcsr(0);
+
+    /*
+     * As we're compiled with -mno-sse, SSE register constraints aren't
+     * tolerated.  Just use %xmm0 behind the back of the compiler; it's not
+     * going to interfere with anything.
+     */
+    asm volatile ("xorps %%xmm0, %%xmm0\n\t"
+                  _ASM_XEN_FEP "1: divss %%xmm0, %%xmm0\n\t"
+                  "2: "
+                  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
+                  : "+a" (fault)
+                  : [rec] "p" (ex_record_fault_eax));
+
+    /*
+     * If we're still alive here, Xen didn't crash.  Cross-check that the
+     * emulator did hand us back the right exception.
+     *
+     * Note: 0.0 / 0.0 yields #I (Invalid), not #Z (Zero-div).
+     */
+    if ( fault != EXINFO_SYM(XM, 0) )
+        return xtf_error("Error: expecting #XM, got %pe\n", _p(fault));
+
+    status = read_mxcsr() & X86_MXCSR_STATUS_MASK;
+    if ( status != X86_MXCSR_IE )
+        return xtf_error("Error: expecting #I, got %#x\n", status);
+
+    xtf_success("Success: not vulnerable to XSA-451\n");
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */