diff mbox

[XTF] Fuzzing the hypervisor

Message ID 20170817102149.1556-1-eggi.innovations@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Felix Schmoll Aug. 17, 2017, 10:21 a.m. UTC
Changes based on commit 8956f82ce1321b89deda6895d58e5788d2198477
---
 include/xen/xen.h          |   1 +
 include/xtf/hypercall.h    |   8 +-
 tests/mk_hcall/.main.c.swo | Bin 0 -> 12288 bytes
 tests/mk_hcall/Makefile    |   9 +++
 tests/mk_hcall/main.c      |  51 +++++++++++++
 tests/xtf-server/Makefile  |   9 +++
 tests/xtf-server/main.c    | 183 +++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 257 insertions(+), 4 deletions(-)
 create mode 100644 tests/mk_hcall/.main.c.swo
 create mode 100644 tests/mk_hcall/Makefile
 create mode 100644 tests/mk_hcall/main.c
 create mode 100644 tests/xtf-server/Makefile
 create mode 100644 tests/xtf-server/main.c

Comments

Wei Liu Aug. 17, 2017, 12:41 p.m. UTC | #1
On Thu, Aug 17, 2017 at 12:21:49PM +0200, Felix Schmoll wrote:
> Changes based on commit 8956f82ce1321b89deda6895d58e5788d2198477
> ---
>  include/xen/xen.h          |   1 +
>  include/xtf/hypercall.h    |   8 +-
>  tests/mk_hcall/.main.c.swo | Bin 0 -> 12288 bytes

This should not be included.
diff mbox

Patch

diff --git a/include/xen/xen.h b/include/xen/xen.h
index 85aaba8..33eb23d 100644
--- a/include/xen/xen.h
+++ b/include/xen/xen.h
@@ -51,6 +51,7 @@ 
 #define __HYPERVISOR_tmem_op              38
 #define __HYPERVISOR_xc_reserved_op       39 /* reserved for XenClient */
 #define __HYPERVISOR_xenpmu_op            40
+#define __HYPERVISOR_trace_pc             42
 
 /* Architecture-specific hypercall definitions. */
 #define __HYPERVISOR_arch_0               48
diff --git a/include/xtf/hypercall.h b/include/xtf/hypercall.h
index be4a01e..3fa9b3c 100644
--- a/include/xtf/hypercall.h
+++ b/include/xtf/hypercall.h
@@ -151,16 +151,16 @@  static inline long hypercall_shutdown(unsigned int reason)
     return hypercall_sched_op(SCHEDOP_shutdown, &reason);
 }
 
+/* hypercall_yield and hypercall_poll are dummies so that printing to
+   console doesn't interfere with tracing determinism */
 static inline void hypercall_yield(void)
 {
-    hypercall_sched_op(SCHEDOP_yield, NULL);
+    return;
 }
 
 static inline long hypercall_poll(evtchn_port_t port)
 {
-    struct sched_poll poll = { .ports = &port, .nr_ports = 1 };
-
-    return hypercall_sched_op(SCHEDOP_poll, &poll);
+    return 0;
 }
 
 static inline int hypercall_register_callback(const xen_callback_register_t *arg)
diff --git a/tests/mk_hcall/.main.c.swo b/tests/mk_hcall/.main.c.swo
new file mode 100644
index 0000000000000000000000000000000000000000..153f8f050b2ad8647ad69fc2bf398e0309a2145d
GIT binary patch
literal 12288
zcmeI2&2Jk;7{(_E4nPA4PQYc@D3$Hn*^fB3<CHdOVi&7v5}c%vrqMFqolRER>{`3)
zuqbK}M-CuFFI<s;1405JIDz1Tgy4VR1UI<QD+uw-`lBCC8!B;$G!y-_@yt8VJM-+j
zD_NeFcBOHdmM4k??I}VIe|vjlbnIdB&7*`k+;bDre@wG^%VqvCK^Q(v1=UyA>V=D|
z!MqytD2~*<U314`o~Q0H*PpPCmyr?D0qMYlI?#!oLS>Xp8oDN?jwvtDXP#bvP!$<3
z9gq%42c!ei0qKBrKsq2DkPe(+2jcb!c@yh@sJDl?-gV@zYwx4HNC%_?(gEp!bU->F
z9gq%42c!ei0qKBrKss;&9bh&gr|?^U{xK{bzyJ5Y|Ns3YA-{kh!4Kdg@F92$9D>)t
zHE;<S;5qOt`0EKmz6ald8{mBqgC<x4mp~3Y0!F|;qlEklz6GCxPr%3EJ@77Y!7Jb*
zsDqoQ2>BD-0At|m#|ilgTm>88Ja``5#D4w&zk{E_PvA@N1^66%20j4qfPKKg%b)@@
zkos`~@26a{bU->F9gq%42c!eif&bG1no|kQ(VA~p#nts~?#G3gwW7jaVDl>VT~7?4
zr|`OK$2(P86rZg^i$$(g2plKk@u1UjJzj|7H$2Q#F03vnBDO0uFaBK&a4eMWv(RNN
zk4IIa<_Nh?C|VLbX4J7P9z~g@^~J^P3`zUjq3g%H86}E?c9o8MHofL6dCL5#AJLsJ
zH2SgQ3SDV7l2VZ>-QY0Xbhi*Mf}9}Cc!9r7UHT%`W^g$x)Mn_JGj5h1q%i{_&%Qew
zLNV{9jg?w+er|EGm}=#zX{KFQ8mr4qGY*->&9;@N3(J=q3+8HVv7V=To~||L=4<AK
z^?JS5G*=r}YuHE__BS#lswEo7A9FO(bY_(4I4wd418Ktm*D;{8TYcRTO*2HC=yuR5
zhOJdJqga|WT0I|B^@w~%S!Y53!c62I<P$k`Wa}<PONDXn@Q&8YXS9%|SkaKt5V?o*
z8Aq9hIx=zWxU(Jd?K~}2%EqK#(saF4o;J#*%JkHrv#3v(^s-TzoSvMb_cZT6+!5^J
z{&ys^AGmflEswM=(z@wZfYz<14yv<MG-GieH;2TwX2<~%8dMyNHpOx1t|TF<dL4*@
z6qU~tH_l)yw|X4rdYzDG6uyr~(iF$3Tg=);Ii_K$DEDo%9R}MW+v~0L01CHB_v=`Q
zMa<#!NSXfVAj$p3(ghu@bmv+JGQ<k}D5lm93%f?dZtU^REj&od8jPX+1LF!F`Z1e3
zuFvVpa${+&*32YXn#m;e93IxBUaxB!J$;%ccxbgmPYW<h&r^+7X_6hx9l8;8O2Zjh
zRULDE%j?*jDt#v=b`&z`J)3Y}-REKC2L8m(x!VU~M|AYwm$MP)=}v~vy3?F^(apwz
t9ngiqip2XS4K4IHiSaa~&9=KDgOPy`{g9A5Lv!h@c+1`+yPC_9e*rg5=j{Lh

literal 0
HcmV?d00001

diff --git a/tests/mk_hcall/Makefile b/tests/mk_hcall/Makefile
new file mode 100644
index 0000000..7e0eda2
--- /dev/null
+++ b/tests/mk_hcall/Makefile
@@ -0,0 +1,9 @@ 
+include $(ROOT)/build/common.mk
+
+NAME      := mk_hcall
+CATEGORY  := utility
+TEST-ENVS := pv64
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/mk_hcall/main.c b/tests/mk_hcall/main.c
new file mode 100644
index 0000000..87f52d7
--- /dev/null
+++ b/tests/mk_hcall/main.c
@@ -0,0 +1,51 @@ 
+/**
+ * @file tests/mk_hcall/main.c
+ * @ref test-mk_hcall
+ *
+ * @page test-mk_hcall mk_hcall
+ *
+ * This test case is a helper to debug tracing and
+ * fuzzing. It executes a particular hypercall and
+ * prints the information obtained from tracing to
+ * the console..
+ *
+ * @see tests/mk_hcall/main.c
+ */
+#include <xtf.h>
+#include <xen/version.h>
+
+#define TRACE_BUFFER_SIZE 500
+#define POINTER(x) ((x >= 0xFFF00 && x < 0x110000) ? 0 : x)
+
+const char test_title[] = "Test mk_hcall";
+
+void test_main(void)
+{
+    uint64_t arr[TRACE_BUFFER_SIZE];
+    long ans;
+
+    HYPERCALL4(long, __HYPERVISOR_trace_pc, DOMID_SELF, 0, TRACE_BUFFER_SIZE, arr);
+
+    /* the actual hypercall that should be traced */
+    HYPERCALL3(long, __HYPERVISOR_grant_table_op, 0, POINTER(63974), 7);
+
+    ans = HYPERCALL4(long, __HYPERVISOR_trace_pc, DOMID_SELF, 1, TRACE_BUFFER_SIZE, arr);
+
+    for(long i = 0; i < ans; ++i) {
+        printk("%" PRIx64 "\n", arr[i]);
+    }
+
+    printk("stop: %ld \n", ans);
+
+    xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tests/xtf-server/Makefile b/tests/xtf-server/Makefile
new file mode 100644
index 0000000..d0ff533
--- /dev/null
+++ b/tests/xtf-server/Makefile
@@ -0,0 +1,9 @@ 
+include $(ROOT)/build/common.mk
+
+NAME      := xtf-server
+CATEGORY  := utility
+TEST-ENVS := pv64
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/xtf-server/main.c b/tests/xtf-server/main.c
new file mode 100644
index 0000000..8742e11
--- /dev/null
+++ b/tests/xtf-server/main.c
@@ -0,0 +1,183 @@ 
+/**
+ * @file tests/xtf-server/main.c
+ * @ref test-xtf-server
+ *
+ * @page test-xtf-server xtf-server
+ *
+ * This is the XTF-server for fuzzing
+ * the hypervisor. It waits for input
+ * via the console (thus in form of a
+ * string) and parses it into a test case.
+ *
+ * There are some information encoded about
+ * the hypercalls, i.e. some are excluded as
+ * they might not return for certain arguments
+ * or as they might stop the domain. Also, the
+ * pointer macro is used to prevent the overwriting
+ * of the code segments when passing buffers into Xen.
+ *
+ * Further improvements here would be to provide valid
+ * buffers, etc. and encode more information about hypercalls.
+ *
+ * Hypercalls annotated mostly according to xen/xen/include/xen/hypercall.h
+ *
+ * @see tests/xtf-server/main.c
+ */
+#include <xtf.h>
+
+#define TEST_CASE_STR_SIZE 1000
+
+/* avoid overwriting the code section in XTF when passing
+   buffers to Xen */
+#define POINTER(x) ((x >= 0xFFF00 && x < 0x110000) ? 0 : x)
+
+const char test_title[] = "Test xtf-server";
+
+char test_case_str[TEST_CASE_STR_SIZE];
+
+void test_main(void)
+{
+    int ret;
+
+    while( 1 )
+    {
+        /* receive test case */
+        memset(test_case_str, 0, TEST_CASE_STR_SIZE);
+        ret = pv_console_read_some(test_case_str, TEST_CASE_STR_SIZE);
+
+        if(ret <= 0)
+            xtf_failure("Couldn't read from AFL");
+
+        long hypercall_num, arg1, arg2, arg3, arg4;
+        hypercall_num = (*(long*) test_case_str) % 41;
+        arg1 = *(((long*) test_case_str) + 1);
+        arg2 = *(((long*) test_case_str) + 2);
+        arg3 = *(((long*) test_case_str) + 3);
+        arg4 = *(((long*) test_case_str) + 4);
+
+        /* execute test case */
+        switch(hypercall_num)
+        {
+            case __HYPERVISOR_set_trap_table:
+                (void) HYPERCALL1(long, __HYPERVISOR_set_trap_table, POINTER(arg1));
+                break;
+            case __HYPERVISOR_mmu_update:
+                break;
+            case __HYPERVISOR_set_gdt:
+                (void) HYPERCALL2(long, __HYPERVISOR_set_gdt, POINTER(arg1), arg2);
+                break;
+            case __HYPERVISOR_stack_switch:
+                (void) HYPERCALL2(long, __HYPERVISOR_stack_switch, arg1, arg2);
+                break;
+            case __HYPERVISOR_set_callbacks:
+                (void) HYPERCALL4(long, __HYPERVISOR_set_callbacks, arg1, arg2, arg3, arg4);
+                break;
+            case __HYPERVISOR_fpu_taskswitch:
+                (void) HYPERCALL1(long, __HYPERVISOR_fpu_taskswitch, arg1);
+                break;
+            case __HYPERVISOR_sched_op_compat:
+                break;
+            case __HYPERVISOR_platform_op:
+                (void) HYPERCALL4(long, __HYPERVISOR_platform_op, arg1, arg2, arg3, arg4);
+                break;
+            case __HYPERVISOR_set_debugreg:
+                (void) HYPERCALL2(long, __HYPERVISOR_set_debugreg, arg1, arg2);
+                break;
+            case __HYPERVISOR_get_debugreg:
+                (void) HYPERCALL1(long, __HYPERVISOR_get_debugreg, arg1);
+                break;
+            case __HYPERVISOR_update_descriptor:
+                (void) HYPERCALL1(long, __HYPERVISOR_update_descriptor, arg1);
+                break;
+            case __HYPERVISOR_memory_op:
+                break;
+            case __HYPERVISOR_multicall:
+                break;
+            case __HYPERVISOR_update_va_mapping:
+                break;
+            case __HYPERVISOR_set_timer_op:
+                break;
+            case __HYPERVISOR_event_channel_op_compat:
+                break;
+            case __HYPERVISOR_xen_version:
+                (void) HYPERCALL2(long, __HYPERVISOR_xen_version, arg1, POINTER(arg2));
+                break;
+            case __HYPERVISOR_console_io:
+                break;
+            case __HYPERVISOR_physdev_op_compat:
+                break;
+            case __HYPERVISOR_grant_table_op:
+                break;
+            case __HYPERVISOR_vm_assist:
+                (void) HYPERCALL2(long, __HYPERVISOR_vm_assist, arg1, arg2);
+                break;
+            case __HYPERVISOR_update_va_mapping_otherdomain:
+                (void) HYPERCALL4(long, __HYPERVISOR_update_va_mapping_otherdomain, arg1, arg2, arg3, arg4);
+                break;
+            case __HYPERVISOR_iret:
+                break;
+            case __HYPERVISOR_vcpu_op:
+                break;
+            case __HYPERVISOR_set_segment_base:
+                break;
+            case __HYPERVISOR_mmuext_op:
+                 (void) HYPERCALL4(long, __HYPERVISOR_mmuext_op, arg1, arg2, arg3, arg4);
+                break;
+           case __HYPERVISOR_xsm_op:
+                (void) HYPERCALL1(long, __HYPERVISOR_xsm_op, POINTER(arg1));
+                break;
+            case __HYPERVISOR_nmi_op:
+                (void) HYPERCALL2(long, __HYPERVISOR_nmi_op, arg1, POINTER(arg2));
+                break;
+            case __HYPERVISOR_sched_op:
+                break;
+            case __HYPERVISOR_callback_op:
+                (void) HYPERCALL4(long, __HYPERVISOR_callback_op, arg1, arg2, arg3, arg4);
+                break;
+            case __HYPERVISOR_xenoprof_op:
+                (void) HYPERCALL2(long, __HYPERVISOR_xenoprof_op, arg1, POINTER(arg2));
+                break;
+            case __HYPERVISOR_event_channel_op:
+                break;
+            case __HYPERVISOR_physdev_op:
+                break;
+            case __HYPERVISOR_hvm_op:
+                (void) HYPERCALL2(long, __HYPERVISOR_hvm_op, arg1, POINTER(arg2));
+                break;
+            case __HYPERVISOR_sysctl:
+                break;
+            case __HYPERVISOR_domctl:
+                break;
+            case __HYPERVISOR_kexec_op:
+                (void) HYPERCALL2(long, __HYPERVISOR_kexec_op, arg1, POINTER(arg2));
+                break;
+            case __HYPERVISOR_tmem_op:
+                (void) HYPERCALL1(long, __HYPERVISOR_tmem_op, arg1);
+                break;
+            case __HYPERVISOR_xc_reserved_op:
+                (void) HYPERCALL4(long, __HYPERVISOR_xc_reserved_op, arg1, arg2, arg3, arg4);
+                break;
+            case __HYPERVISOR_xenpmu_op:
+                break;
+            default:
+                break;
+        }
+
+        /* A string to inform AFL that the hypercall has finished. Has
+           to be shorter than 80 characters inorder to guarantee reading
+           with a single read() call in AFL. */
+        printk("Executed\n");
+    }
+
+    xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */