* [PATCH AFL] Fuzzing the hypervisor
2017-08-17 9:58 [GSoC] Fuzzing the Hypervisor Felix Schmoll
@ 2017-08-17 10:15 ` Felix Schmoll
2017-08-17 10:21 ` [PATCH XTF] " Felix Schmoll
2017-08-17 10:25 ` [PATCH XEN] " Felix Schmoll
2 siblings, 0 replies; 5+ messages in thread
From: Felix Schmoll @ 2017-08-17 10:15 UTC (permalink / raw)
To: xen-devel; +Cc: wei.liu2, Felix Schmoll
Changes based on version 2.43b of AFL
---
Makefile | 2 +-
afl-fuzz.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
hash_map.h | 82 ++++++++++++++++++++++
3 files changed, 306 insertions(+), 11 deletions(-)
create mode 100644 hash_map.h
diff --git a/Makefile b/Makefile
index 44d1ffa..3a75c8c 100644
--- a/Makefile
+++ b/Makefile
@@ -70,7 +70,7 @@ afl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86
ln -sf afl-as as
afl-fuzz: afl-fuzz.c $(COMM_HDR) | test_x86
- $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)
+ $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) -lxenctrl
afl-showmap: afl-showmap.c $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)
diff --git a/afl-fuzz.c b/afl-fuzz.c
index 562fd50..08fa346 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -56,6 +56,10 @@
#include <sys/ioctl.h>
#include <sys/file.h>
+#include <xenctrl.h>
+#include <xen/public/trace_pc.h>
+#include "hash_map.h"
+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined (__OpenBSD__)
# include <sys/sysctl.h>
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
@@ -80,6 +84,25 @@
really makes no sense to haul them around as function parameters. */
+/* number of buckets in the hash map */
+#define NUM_BUCKETS 1000
+/* number of bytes written to xtf */
+#define SIZE_MEM_WRITE_TO_TESTCASE 80
+/* path for the file containing the last test case */
+#define TEST_CASE_LOG_PATH "/var/log/testcase"
+/* path for the file containing all test cases */
+#define OVERALL_LOG_PATH "/var/log/afl.log"
+#define XENCONSOLE_PATH "/usr/local/lib/xen/bin/xenconsole"
+
+int pipefd_to_xtf[2];
+int pipefd_from_xtf[2];
+char* domain;
+hash_map* map;
+
+long mem_write_to_testcase[SIZE_MEM_WRITE_TO_TESTCASE];
+
+FILE* log_file;
+
EXP_ST u8 *in_dir, /* Input directory with test cases */
*out_file, /* File to fuzz, if any */
*out_dir, /* Working & output directory */
@@ -2253,6 +2276,107 @@ EXP_ST void init_forkserver(char** argv) {
}
+/** Process program counters into format expected by AFL and
+ insert into trace_bits.
+
+ cur_location = <COMPILE_TIME_RANDOM>;
+ shared_mem[cur_location ^ prev_location]++;
+ prev_location = cur_location >> 1;
+*/
+void process_program_counters(uint64_t* pc_buffer, long pc_num) {
+
+ u32 cur_location = 0, prev_location = 0;
+ hash_bucket* bucket;
+
+ for(int i = 0; i < pc_num; ++i) {
+ bucket = _hash_map_lookup(map, pc_buffer[i]);
+
+ if( !bucket ) {
+ cur_location = UR(MAP_SIZE);
+ if(!_hash_map_insert(map, pc_buffer[i], cur_location))
+ FATAL("process_program_counters: Could not insert into hash map\n");
+ } else {
+ cur_location = bucket->val;
+ }
+
+ trace_bits[(cur_location ^ prev_location) % MAP_SIZE]++;
+ prev_location = cur_location >> 1;
+ }
+
+}
+
+/* Send test case to XTF-server. */
+
+static u8 send_test_to_xtf(char** argv, u32 timeout) {
+
+ size_t buf_size = 100;
+ char buffer[buf_size];
+
+ int pc_buffer_size = 100000;
+ uint64_t pc_buffer[pc_buffer_size];
+ long ret;
+
+ /* log the test case that is about to be send */
+ if( fprintf(log_file, "get_cur_time %ld %li %li %ld %ld %ld\n",
+ (long) get_cur_time(),
+ mem_write_to_testcase[0] % 41,
+ mem_write_to_testcase[1],
+ mem_write_to_testcase[2],
+ mem_write_to_testcase[3],
+ mem_write_to_testcase[4]) < 0 )
+ FATAL("send_test_to_xtf: Couldn't write to file\n");
+
+ fflush(log_file);
+ memset(trace_bits, 0, MAP_SIZE);
+
+ xc_interface *xch = xc_interface_open(NULL, NULL, 0);
+ if( xch == NULL ) {
+ fclose(log_file);
+ FATAL("send_test_to_xtf: Couldn't open xen interface\n");
+ }
+
+ if( xc_trace_pc(xch, atoi(domain), XEN_TRACE_PC_START,
+ pc_buffer_size, pc_buffer) < 0 ) {
+ fclose(log_file);
+ xc_interface_close(xch);
+ FATAL("send_test_to_xtf: Start edge_trace failed\n");
+ }
+
+ /* send tet case to XTF */
+ if( write(pipefd_to_xtf[1], (char*) mem_write_to_testcase,
+ SIZE_MEM_WRITE_TO_TESTCASE) <= 0 ) {
+ fclose(log_file);
+ xc_interface_close(xch);
+ FATAL("send_test_to_xtf: Couldn't write to XTF\n");
+ }
+
+ /* XTF will message us when it's hypercall returned */
+ if( read(pipefd_from_xtf[0], buffer, buf_size) < 0 ) {
+ fclose(log_file);
+ xc_interface_close(xch);
+ FATAL("send_test_to_xtf: Couldn't read from XTF\n");
+ }
+
+ ret = xc_trace_pc(xch, atoi(domain), 1, pc_buffer_size, pc_buffer);
+ xc_interface_close(xch);
+
+ if( ret < 0 ) {
+ fclose(log_file);
+ FATAL("send_test_to_xtf: Stop edge_trace failed\n");
+ }
+
+ process_program_counters(pc_buffer, ret);
+
+#ifdef __x86_64__
+ classify_counts((u64*)trace_bits);
+#else
+ classify_counts((u32*)trace_bits);
+#endif /* ^__x86_64__ */
+
+ return FAULT_NONE;
+}
+
+
/* Execute target application, monitoring for timeouts. Return status
information. The called program will update trace_bits[]. */
@@ -2455,13 +2579,21 @@ static u8 run_target(char** argv, u32 timeout) {
}
-
/* Write modified data to file for testing. If out_file is set, the old file
is unlinked and a new one is created. Otherwise, out_fd is rewound and
truncated. */
static void write_to_testcase(void* mem, u32 len) {
+ memset((char*) mem_write_to_testcase, 0, SIZE_MEM_WRITE_TO_TESTCASE);
+ memcpy((char*) mem_write_to_testcase, mem, (len < SIZE_MEM_WRITE_TO_TESTCASE)?len:SIZE_MEM_WRITE_TO_TESTCASE);
+
+ remove(TEST_CASE_LOG_PATH);
+ s32 my_file = open(TEST_CASE_LOG_PATH, O_WRONLY | O_CREAT | O_EXCL , 0600);
+ ck_write(my_file, mem, SIZE_MEM_WRITE_TO_TESTCASE, TEST_CASE_LOG_PATH);
+ fsync(my_file);
+ close(my_file);
+
s32 fd = out_fd;
if (out_file) {
@@ -2490,6 +2622,15 @@ static void write_to_testcase(void* mem, u32 len) {
static void write_with_gap(void* mem, u32 len, u32 skip_at, u32 skip_len) {
+ memset((char*) mem_write_to_testcase, 0, SIZE_MEM_WRITE_TO_TESTCASE);
+ memcpy((char*) mem_write_to_testcase, mem, (len < SIZE_MEM_WRITE_TO_TESTCASE)?len:SIZE_MEM_WRITE_TO_TESTCASE);
+
+ remove(TEST_CASE_LOG_PATH);
+ s32 my_file = open(TEST_CASE_LOG_PATH, O_WRONLY | O_CREAT | O_EXCL , 0600);
+ ck_write(my_file, mem, SIZE_MEM_WRITE_TO_TESTCASE, TEST_CASE_LOG_PATH);
+ fsync(my_file);
+ close(my_file);
+
s32 fd = out_fd;
u32 tail_len = len - skip_at - skip_len;
@@ -2568,7 +2709,7 @@ static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem,
write_to_testcase(use_mem, q->len);
- fault = run_target(argv, use_tmout);
+ fault = send_test_to_xtf(argv, use_tmout);
/* stop_soon is set by the handler for Ctrl+C. When it's pressed,
we want to bail out quickly. */
@@ -3198,7 +3339,7 @@ static u8 save_if_interesting(char** argv, void* mem, u32 len, u8 fault) {
u8 new_fault;
write_to_testcase(mem, len);
- new_fault = run_target(argv, hang_tmout);
+ new_fault = send_test_to_xtf(argv, hang_tmout);
if (stop_soon || new_fault != FAULT_TMOUT) return keeping;
@@ -4479,7 +4620,7 @@ static u8 trim_case(char** argv, struct queue_entry* q, u8* in_buf) {
write_with_gap(in_buf, q->len, remove_pos, trim_avail);
- fault = run_target(argv, exec_tmout);
+ fault = send_test_to_xtf(argv, exec_tmout);
trim_execs++;
if (stop_soon || fault == FAULT_ERROR) goto abort_trimming;
@@ -4572,7 +4713,7 @@ EXP_ST u8 common_fuzz_stuff(char** argv, u8* out_buf, u32 len) {
write_to_testcase(out_buf, len);
- fault = run_target(argv, exec_tmout);
+ fault = send_test_to_xtf(argv, exec_tmout);
if (stop_soon) return 1;
@@ -6701,7 +6842,7 @@ static void sync_fuzzers(char** argv) {
write_to_testcase(mem, st.st_size);
- fault = run_target(argv, exec_tmout);
+ fault = send_test_to_xtf(argv, exec_tmout);
if (stop_soon) return;
@@ -7665,6 +7806,73 @@ static void save_cmdline(u32 argc, char** argv) {
}
+/**
+ * @param domid_s Point to domid of XTF
+ *
+ * This function does initial setup needed for the fuzzing. It also
+ * sets up pipes such that stdout and stdin can be used to communicate
+ * with the XTF-server.
+ *
+ * TODO make this two separate functions
+ */
+static void setup_pipe_and_fork(char *domid_s) {
+ map = _hash_map_create(NUM_BUCKETS);
+
+ if(!map) {
+ FATAL("setup_pipe_and_fork: Hash map could not be created\n");
+ }
+
+ log_file = fopen(OVERALL_LOG_PATH, "w");
+
+ if(log_file < 0)
+ goto FAIL;
+
+ pid_t childpid;
+ int ret;
+
+ if( (ret = pipe(pipefd_to_xtf)) < 0)
+ goto FAIL;
+
+ if( (ret = pipe(pipefd_from_xtf)) < 0)
+ goto FAIL;
+
+ if((childpid = fork()) == -1)
+ FATAL("setup_pipe_and_fork: fork failed");
+
+ if (childpid == 0) { /* child */
+
+ /* close unnecessary pipe ends */
+ close(pipefd_to_xtf[1]);
+ close(pipefd_from_xtf[0]);
+
+ /* stdin */
+ close(0);
+ if( (ret = dup(pipefd_to_xtf[0])) < 0 )
+ goto FAIL;
+
+ /* stdout */
+ close(1);
+ if( (ret = dup(pipefd_from_xtf[1])) < 0 )
+ goto FAIL;
+
+ if( execl(XENCONSOLE_PATH, XENCONSOLE_PATH, domid_s, "--num", "0",
+ "--type", "pv", "--interactive", (void *)NULL) < 0 )
+ FATAL("setup_pipe_and_fork: execl");
+
+ } else { /* parent */
+
+ /* close unnecessary pipe ends */
+ close(pipefd_to_xtf[0]);
+ close(pipefd_from_xtf[1]);
+
+ }
+
+ return;
+
+ FAIL:
+ FATAL("setup_pipe_and_fork: Failed to setup pipes\n");
+}
+
#ifndef AFL_LIB
@@ -7690,7 +7898,7 @@ int main(int argc, char** argv) {
gettimeofday(&tv, &tz);
srandom(tv.tv_sec ^ tv.tv_usec ^ getpid());
- while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:Q")) > 0)
+ while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:Qr:")) > 0)
switch (opt) {
@@ -7858,6 +8066,12 @@ int main(int argc, char** argv) {
break;
+ case 'r': /* domain id for XTF server */
+
+ domain = optarg;
+ printf("domain set: %s\n", domain);
+ break;
+
default:
usage(argv[0]);
@@ -7935,8 +8149,6 @@ int main(int argc, char** argv) {
if (!out_file) setup_stdio_file();
- check_binary(argv[optind]);
-
start_time = get_cur_time();
if (qemu_mode)
@@ -7944,6 +8156,8 @@ int main(int argc, char** argv) {
else
use_argv = argv + optind;
+ setup_pipe_and_fork(domain);
+
perform_dry_run(use_argv);
cull_queue();
@@ -7966,7 +8180,6 @@ int main(int argc, char** argv) {
}
while (1) {
-
u8 skipped_fuzz;
cull_queue();
diff --git a/hash_map.h b/hash_map.h
new file mode 100644
index 0000000..e5e6602
--- /dev/null
+++ b/hash_map.h
@@ -0,0 +1,82 @@
+/* @file hash_map.h
+ *
+ */
+
+typedef struct hash_bucket {
+ struct hash_bucket* next;
+ uint64_t key;
+ uint64_t val;
+} hash_bucket;
+
+typedef struct hash_map {
+ hash_bucket** buckets;
+ int num_buckets;
+} hash_map;
+
+uint64_t _hash_function(hash_map* map, uint64_t key) {
+ return (key % map->num_buckets);
+}
+
+hash_map* _hash_map_create(int num_buckets) {
+ hash_map* map = (hash_map*) malloc(sizeof(hash_map));
+
+ if( map ) {
+ map->num_buckets = num_buckets;
+ map->buckets = (hash_bucket**) malloc(sizeof(hash_bucket*) * num_buckets);
+
+ if( !map->buckets ) {
+ free(map);
+ return NULL;
+ }
+
+ for(int i = 0; i < num_buckets; ++i)
+ map->buckets[i] = NULL;
+ }
+
+ return map;
+}
+
+void _hash_map_destroy(hash_map* map) {
+ //not implemented
+}
+
+hash_bucket* _hash_map_lookup(hash_map* map, uint64_t key) {
+ uint64_t hash = _hash_function(map, key);
+
+ if(map->buckets[hash] == NULL) {
+ return NULL;
+ } else {
+ hash_bucket* cur = map->buckets[hash];
+
+ while(cur->key != key && cur->next)
+ cur = cur->next;
+
+ return cur;
+ }
+}
+
+bool _hash_map_insert(hash_map* map, uint64_t key, uint64_t val) {
+ uint64_t hash = _hash_function(map, key);
+
+ hash_bucket* bucket = (hash_bucket*) malloc(sizeof(hash_bucket));
+
+ if(!bucket)
+ return false;
+
+ bucket->next = NULL;
+ bucket->key = key;
+ bucket->val = val;
+
+ if(map->buckets[hash] == NULL) {
+ map->buckets[hash] = bucket;
+ } else {
+ hash_bucket* cur = map->buckets[hash];
+ while(cur->next) {
+ cur = cur->next;
+ }
+
+ cur->next = bucket;
+ }
+
+ return true;
+}
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH XTF] Fuzzing the hypervisor
2017-08-17 9:58 [GSoC] Fuzzing the Hypervisor Felix Schmoll
2017-08-17 10:15 ` [PATCH AFL] Fuzzing the hypervisor Felix Schmoll
@ 2017-08-17 10:21 ` Felix Schmoll
2017-08-17 12:41 ` Wei Liu
2017-08-17 10:25 ` [PATCH XEN] " Felix Schmoll
2 siblings, 1 reply; 5+ messages in thread
From: Felix Schmoll @ 2017-08-17 10:21 UTC (permalink / raw)
To: xen-devel; +Cc: wei.liu2, Felix Schmoll
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
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:
+ */
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH XEN] Fuzzing the hypervisor
2017-08-17 9:58 [GSoC] Fuzzing the Hypervisor Felix Schmoll
2017-08-17 10:15 ` [PATCH AFL] Fuzzing the hypervisor Felix Schmoll
2017-08-17 10:21 ` [PATCH XTF] " Felix Schmoll
@ 2017-08-17 10:25 ` Felix Schmoll
2 siblings, 0 replies; 5+ messages in thread
From: Felix Schmoll @ 2017-08-17 10:25 UTC (permalink / raw)
To: xen-devel; +Cc: wei.liu2, Felix Schmoll
Based on commit 6c9abf0e8022807bb7d677570d0775659950ff1a
---
xen/Kconfig.debug | 7 +++-
xen/Rules.mk | 4 ++
xen/arch/arm/traps.c | 1 +
xen/arch/x86/Makefile | 2 +
xen/arch/x86/hvm/hypercall.c | 1 +
xen/arch/x86/hypercall.c | 1 +
xen/arch/x86/pv/Makefile | 2 +
xen/arch/x86/pv/hypercall.c | 1 +
xen/common/Makefile | 13 ++++++
xen/common/domain.c | 4 ++
xen/common/trace_pc.c | 96 +++++++++++++++++++++++++++++++++++++++++++
xen/common/trace_pc_stub.c | 39 ++++++++++++++++++
xen/include/public/trace_pc.h | 38 +++++++++++++++++
xen/include/public/xen.h | 1 +
xen/include/xen/hypercall.h | 7 ++++
xen/include/xen/sched.h | 6 +++
xen/include/xen/trace_pc.h | 31 ++++++++++++++
17 files changed, 253 insertions(+), 1 deletion(-)
create mode 100644 xen/common/trace_pc.c
create mode 100644 xen/common/trace_pc_stub.c
create mode 100644 xen/include/public/trace_pc.h
create mode 100644 xen/include/xen/trace_pc.h
diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
index 689f2974c0..d87dcd78f4 100644
--- a/xen/Kconfig.debug
+++ b/xen/Kconfig.debug
@@ -98,7 +98,6 @@ config PERF_ARRAYS
---help---
Enables software performance counter array histograms.
-
config VERBOSE_DEBUG
bool "Verbose debug messages"
default DEBUG
@@ -114,6 +113,12 @@ config DEVICE_TREE_DEBUG
logged in the Xen ring buffer.
If unsure, say N here.
+config TRACE_PC
+ bool "Enable pc-tracing"
+ default false
+ ---help---
+ Adds tracing support to the hypervisor (needed for the trace_pc hypercall).
+
endif # DEBUG || EXPERT
endmenu
diff --git a/xen/Rules.mk b/xen/Rules.mk
index 77bcd44922..dde14e3228 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -170,6 +170,10 @@ clean:: $(addprefix _clean_, $(subdir-all))
_clean_%/: FORCE
$(MAKE) -f $(BASEDIR)/Rules.mk -C $* clean
+ifeq ($(CONFIG_TRACE_PC),y)
+$(objs-need-tracing): CFLAGS += -fsanitize-coverage=trace-pc
+endif
+
%.o: %.c Makefile
$(CC) $(CFLAGS) -c $< -o $@
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index c07999b518..247a68c964 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1419,6 +1419,7 @@ static arm_hypercall_t arm_hypercall_table[] = {
HYPERCALL(platform_op, 1),
HYPERCALL_ARM(vcpu_op, 3),
HYPERCALL(vm_assist, 2),
+ HYPERCALL(trace_pc, 4),
};
#ifndef NDEBUG
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 93ead6e5dd..b283c3e22c 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -74,6 +74,8 @@ efi-y := $(shell if [ ! -r $(BASEDIR)/include/xen/compile.h -o \
-O $(BASEDIR)/include/xen/compile.h ]; then \
echo '$(TARGET).efi'; fi)
+objs-need-tracing := cpuid.o hypercall.o
+
ifneq ($(build_id_linker),)
notes_phdrs = --notes
else
diff --git a/xen/arch/x86/hvm/hypercall.c b/xen/arch/x86/hvm/hypercall.c
index e7238ce293..b59d7d481e 100644
--- a/xen/arch/x86/hvm/hypercall.c
+++ b/xen/arch/x86/hvm/hypercall.c
@@ -132,6 +132,7 @@ static const hypercall_table_t hvm_hypercall_table[] = {
COMPAT_CALL(mmuext_op),
HYPERCALL(xenpmu_op),
COMPAT_CALL(dm_op),
+ HYPERCALL(trace_pc),
HYPERCALL(arch_1)
};
diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c
index e30181817a..672ffe7ef5 100644
--- a/xen/arch/x86/hypercall.c
+++ b/xen/arch/x86/hypercall.c
@@ -68,6 +68,7 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] =
ARGS(xenpmu_op, 2),
ARGS(dm_op, 3),
ARGS(mca, 1),
+ ARGS(trace_pc, 4),
ARGS(arch_1, 1),
};
diff --git a/xen/arch/x86/pv/Makefile b/xen/arch/x86/pv/Makefile
index 4e15484471..8c3eccdfd7 100644
--- a/xen/arch/x86/pv/Makefile
+++ b/xen/arch/x86/pv/Makefile
@@ -11,3 +11,5 @@ obj-y += traps.o
obj-bin-y += dom0_build.init.o
obj-bin-y += gpr_switch.o
+
+objs-need-tracing += hypercall.o
diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c
index f79f7eef62..13eb2e86a2 100644
--- a/xen/arch/x86/pv/hypercall.c
+++ b/xen/arch/x86/pv/hypercall.c
@@ -80,6 +80,7 @@ static const hypercall_table_t pv_hypercall_table[] = {
HYPERCALL(xenpmu_op),
COMPAT_CALL(dm_op),
HYPERCALL(mca),
+ HYPERCALL(trace_pc),
HYPERCALL(arch_1),
};
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 26c5a64337..4e39dc66e0 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -55,6 +55,8 @@ obj-y += tasklet.o
obj-y += time.o
obj-y += timer.o
obj-y += trace.o
+obj-y += trace_pc.o
+obj-$(CONFIG_TRACE_PC) += trace_pc_stub.o
obj-y += version.o
obj-y += virtual_region.o
obj-y += vm_event.o
@@ -80,3 +82,14 @@ subdir-$(CONFIG_GCOV) += gcov
subdir-y += libelf
subdir-$(CONFIG_HAS_DEVICE_TREE) += libfdt
+
+objs-need-tracing := bsearch.o \
+ decompress.o device_tree.o domain.o domctl.o earlycpio.o grant_table.o \
+ guestcopy.o gunzip.o inflate.o kernel.o kexec.o keyhandler.o kimage.o \
+ lib.o livepatch.o lzo.o mem_access.o memory.o multicall.o notifier.o \
+ page_alloc.o pdx.o perfc.o radix_tree.o rangeset.o \
+ rbtree.o shutdown.o sort.o stop_machine.o \
+ symbols.o symbols-dummy.o sysctl.o time.o tmem.o \
+ tmem_control.o tmem_xen.o trace.o unlz4.o unlzo.o unxz.o version.o \
+ virtual_region.o vmap.o vm_event.o warning.o xenoprof.o \
+ xmalloc_tlsf.o
diff --git a/xen/common/domain.c b/xen/common/domain.c
index b22aacc57e..c98a0a94ec 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -874,6 +874,10 @@ void domain_destroy(struct domain *d)
rcu_assign_pointer(*pd, d->next_in_hashbucket);
spin_unlock(&domlist_update_lock);
+#ifdef CONFIG_TRACE_PC
+ xfree(d->tracing_buffer);
+#endif
+
/* Schedule RCU asynchronous completion of domain destroy. */
call_rcu(&d->rcu, complete_domain_destroy);
}
diff --git a/xen/common/trace_pc.c b/xen/common/trace_pc.c
new file mode 100644
index 0000000000..722572c500
--- /dev/null
+++ b/xen/common/trace_pc.c
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * trace_pc.c
+ *
+ * Implementation of the program counter tracing hypercall.
+ *
+ * Copyright (c) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/guest_access.h>
+#include <xen/sched.h>
+#include <xen/xmalloc.h>
+#include <public/trace_pc.h>
+
+long do_trace_pc(domid_t dom, int mode, unsigned int size,
+ XEN_GUEST_HANDLE_PARAM(uint64_t) buf)
+{
+#ifdef CONFIG_TRACE_PC
+ int ret = 0;
+ struct domain *d;
+
+ if ( dom == DOMID_SELF )
+ d = current->domain;
+ else
+ d = get_domain_by_id(dom);
+
+ if ( !d )
+ return -ESRCH; /* invalid domain */
+
+ switch ( mode )
+ {
+ case XEN_TRACE_PC_START:
+ {
+ if ( d->tracing_buffer )
+ {
+ ret = -EBUSY; /* domain already being traced */
+ break;
+ }
+
+ d->tracing_buffer_pos = 0;
+ d->tracing_buffer_size = size;
+ d->tracing_buffer = xmalloc_array(uint64_t, size);
+
+ if ( !d->tracing_buffer )
+ ret = -ENOMEM;
+ break;
+ }
+
+ case XEN_TRACE_PC_STOP:
+ {
+ uint64_t *temp = d->tracing_buffer;
+ d->tracing_buffer = NULL;
+
+ if ( copy_to_guest(buf, temp, d->tracing_buffer_pos) )
+ ret = -EFAULT;
+ else
+ ret = d->tracing_buffer_pos;
+
+ xfree(temp);
+
+ break;
+ }
+
+ default:
+ ret = -ENOSYS;
+ }
+
+ if ( dom != DOMID_SELF )
+ put_domain(d);
+
+ return ret;
+#else
+ return -EOPNOTSUPP;
+#endif
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/common/trace_pc_stub.c b/xen/common/trace_pc_stub.c
new file mode 100644
index 0000000000..4aba7dba9f
--- /dev/null
+++ b/xen/common/trace_pc_stub.c
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * trace_pc_stub.c
+ *
+ * Edge function/stub for the program counter tracing hypercall.
+ *
+ * Copyright (c) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/trace_pc.h>
+#include <xen/kernel.h>
+
+void __sanitizer_cov_trace_pc(void)
+{
+ struct domain *d;
+
+ if ( system_state < SYS_STATE_active )
+ return;
+
+ d = current->domain;
+
+ if ( d->tracing_buffer &&
+ (d->tracing_buffer_pos < d->tracing_buffer_size) )
+ {
+ d->tracing_buffer[d->tracing_buffer_pos++] =
+ (uint64_t) __builtin_return_address(0);
+ }
+}
diff --git a/xen/include/public/trace_pc.h b/xen/include/public/trace_pc.h
new file mode 100644
index 0000000000..54e430a561
--- /dev/null
+++ b/xen/include/public/trace_pc.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * trace_pc.h
+ *
+ * Macros for program counter tracing hypercall.
+ *
+ * Copyright (C) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_TRACE_PC_H__
+#define __XEN_PUBLIC_TRACE_PC_H__
+
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+
+#define XEN_TRACE_PC_START 0
+#define XEN_TRACE_PC_STOP 1
+
+#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
+
+#endif /* __XEN_PUBLIC_TRACE_PC_H__ */
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index 2ac6b1e24d..95d83c21ce 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -121,6 +121,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
#define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */
#define __HYPERVISOR_xenpmu_op 40
#define __HYPERVISOR_dm_op 41
+#define __HYPERVISOR_trace_pc 42
/* Architecture-specific hypercall definitions. */
#define __HYPERVISOR_arch_0 48
diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
index cc99aea57d..aa6269e7b7 100644
--- a/xen/include/xen/hypercall.h
+++ b/xen/include/xen/hypercall.h
@@ -83,6 +83,13 @@ do_xen_version(
XEN_GUEST_HANDLE_PARAM(void) arg);
extern long
+do_trace_pc(
+ domid_t dom_id,
+ int mode,
+ unsigned int size,
+ XEN_GUEST_HANDLE_PARAM(uint64_t) buf);
+
+extern long
do_console_io(
int cmd,
int count,
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 6673b27d88..4bd3fe2417 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -483,6 +483,12 @@ struct domain
unsigned int guest_request_enabled : 1;
unsigned int guest_request_sync : 1;
} monitor;
+
+#ifdef CONFIG_TRACE_PC
+ uint64_t* tracing_buffer;
+ unsigned int tracing_buffer_pos;
+ unsigned int tracing_buffer_size;
+#endif
};
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
diff --git a/xen/include/xen/trace_pc.h b/xen/include/xen/trace_pc.h
new file mode 100644
index 0000000000..631815de30
--- /dev/null
+++ b/xen/include/xen/trace_pc.h
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * trace_pc.h
+ *
+ * Declarations for the program counter tracing hypercall
+ *
+ * Copyright (C) 2017 Felix Schmoll <eggi.innovations@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TRACE_PC_H__
+#define __TRACE_PC_H__
+
+#include <xen/sched.h>
+#include <xen/types.h>
+
+#include <asm/current.h>
+
+void __sanitizer_cov_trace_pc(void);
+
+#endif /* __TRACE_PC_H__ */
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 5+ messages in thread