From: Wei Liu <wei.liu2@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: Wei Liu <wei.liu2@citrix.com>,
George Dunlap <george.dunlap@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Ian Jackson <ian.jackson@eu.citrix.com>,
George Dunlap <george.dunlap@citrix.com>,
Jan Beulich <jbeulich@suse.com>
Subject: [PATCH v2 10/12] fuzz/x86emul: update fuzzer
Date: Tue, 31 Jan 2017 11:08:07 +0000 [thread overview]
Message-ID: <20170131110809.30001-11-wei.liu2@citrix.com> (raw)
In-Reply-To: <20170131110809.30001-1-wei.liu2@citrix.com>
Provide the fuzzer with more ops, and more sophisticated input
structure.
Based on a patch originally written by Andrew and George.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@eu.citrix.com>
v2:
1. Address comments from Jan.
2. Provide architecturally correct behaviour for rep stub.
---
.../x86-insn-emulator-fuzzer.c | 660 +++++++++++++++++++--
1 file changed, 598 insertions(+), 62 deletions(-)
diff --git a/tools/fuzz/x86_instruction_emulator/x86-insn-emulator-fuzzer.c b/tools/fuzz/x86_instruction_emulator/x86-insn-emulator-fuzzer.c
index 7d7f731677..ef223e856d 100644
--- a/tools/fuzz/x86_instruction_emulator/x86-insn-emulator-fuzzer.c
+++ b/tools/fuzz/x86_instruction_emulator/x86-insn-emulator-fuzzer.c
@@ -4,6 +4,7 @@
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
+#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -16,26 +17,79 @@
#include "x86_emulate.h"
-static unsigned char data[4096];
+#include "../../../xen/include/asm-x86/msr-index.h"
+
+#define MSR_INDEX_MAX 16
+
+#define SEG_NUM x86_seg_none
+
+struct input_struct {
+ unsigned long cr[5];
+ uint64_t msr[MSR_INDEX_MAX];
+ struct cpu_user_regs regs;
+ struct segment_register segments[SEG_NUM];
+ unsigned long options;
+ unsigned char data[4096];
+} input;
+#define DATA_OFFSET offsetof(struct input_struct, data)
static unsigned int data_index;
-static unsigned int data_max;
+static unsigned int data_num;
+
+/* Randomly return success or failure when processing data. If
+ * `exception` is false, this function turns _EXCEPTION to _OKAY.
+ */
+int maybe_fail(const char *why, bool exception)
+{
+ int rc;
+
+ if ( data_index + 1 > data_num )
+ rc = X86EMUL_EXCEPTION;
+ else
+ {
+ /* Randomly returns value:
+ * 50% okay
+ * 25% unhandlable
+ * 25% exception
+ */
+ if ( input.data[data_index] > 0xc0 )
+ rc = X86EMUL_EXCEPTION;
+ else if ( input.data[data_index] > 0x80 )
+ rc = X86EMUL_UNHANDLEABLE;
+ else
+ rc = X86EMUL_OKAY;
+ data_index++;
+ }
+
+ if ( rc == X86EMUL_EXCEPTION && !exception )
+ rc = X86EMUL_OKAY;
+
+ printf("maybe_fail %s: %d\n", why, rc);
+
+ return rc;
+}
static int data_read(const char *why, void *dst, unsigned int bytes)
{
unsigned int i;
+ int rc;
- if ( data_index + bytes > data_max )
- return X86EMUL_EXCEPTION;
+ if ( data_index + bytes > data_num )
+ rc = X86EMUL_EXCEPTION;
+ else
+ rc = maybe_fail(why, true);
- memcpy(dst, data + data_index, bytes);
- data_index += bytes;
+ if ( rc == X86EMUL_OKAY )
+ {
+ memcpy(dst, input.data + data_index, bytes);
+ data_index += bytes;
- printf("%s: ", why);
- for ( i = 0; i < bytes; i++ )
- printf(" %02x", *(unsigned char *)(dst + i));
- printf("\n");
+ printf("%s: ", why);
+ for ( i = 0; i < bytes; i++ )
+ printf(" %02x", *(unsigned char *)(dst + i));
+ printf("\n");
+ }
- return X86EMUL_OKAY;
+ return rc;
}
static int fuzz_read(
@@ -48,14 +102,96 @@ static int fuzz_read(
return data_read("read", p_data, bytes);
}
-static int fuzz_fetch(
+static int fuzz_read_io(
+ unsigned int port,
+ unsigned int bytes,
+ unsigned long *val,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return data_read("read_io", val, bytes);
+}
+
+static int fuzz_insn_fetch(
unsigned int seg,
unsigned long offset,
void *p_data,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
- return data_read("fetch", p_data, bytes);
+ return data_read("insn_fetch", p_data, bytes);
+}
+
+static int _fuzz_rep_read(const char *why, unsigned long *reps)
+{
+ int rc;
+ unsigned long bytes_read = 0;
+
+ rc = data_read(why, &bytes_read, sizeof(bytes_read));
+
+ if ( bytes_read < *reps )
+ *reps -= bytes_read;
+
+ /* Indicate we haven't done any work if emulation has failed */
+ if ( rc != X86EMUL_OKAY )
+ *reps = 0;
+
+ return rc;
+}
+
+static int _fuzz_rep_write(const char *why, unsigned long *reps)
+{
+ int rc = maybe_fail(why, true);
+
+ /* Indicate we haven't done any work if emulation has failed */
+ if ( rc != X86EMUL_OKAY )
+ *reps = 0;
+
+ return rc;
+}
+
+static int fuzz_rep_ins(
+ uint16_t src_port,
+ enum x86_segment dst_seg,
+ unsigned long dst_offset,
+ unsigned int bytes_per_rep,
+ unsigned long *reps,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return _fuzz_rep_read("rep_in", reps);
+}
+
+static int fuzz_rep_movs(
+ enum x86_segment src_seg,
+ unsigned long src_offset,
+ enum x86_segment dst_seg,
+ unsigned long dst_offset,
+ unsigned int bytes_per_rep,
+ unsigned long *reps,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return _fuzz_rep_read("rep_movs", reps);
+}
+
+static int fuzz_rep_outs(
+ enum x86_segment src_seg,
+ unsigned long src_offset,
+ uint16_t dst_port,
+ unsigned int bytes_per_rep,
+ unsigned long *reps,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return _fuzz_rep_write("rep_outs", reps);
+}
+
+static int fuzz_rep_stos(
+ void *p_data,
+ enum x86_segment seg,
+ unsigned long offset,
+ unsigned int bytes_per_rep,
+ unsigned long *reps,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return _fuzz_rep_write("rep_stos", reps);
}
static int fuzz_write(
@@ -65,7 +201,7 @@ static int fuzz_write(
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
- return X86EMUL_OKAY;
+ return maybe_fail("write", true);
}
static int fuzz_cmpxchg(
@@ -76,18 +212,294 @@ static int fuzz_cmpxchg(
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
- return X86EMUL_OKAY;
+ return maybe_fail("cmpxchg", true);
+}
+
+static int fuzz_invlpg(
+ enum x86_segment seg,
+ unsigned long offset,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return maybe_fail("invlpg", false);
+}
+
+static int fuzz_wbinvd(
+ struct x86_emulate_ctxt *ctxt)
+{
+ return maybe_fail("wbinvd", true);
+}
+
+static int fuzz_write_io(
+ unsigned int port,
+ unsigned int bytes,
+ unsigned long val,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return maybe_fail("write_io", true);
+}
+
+static int fuzz_cpuid(
+ uint32_t leaf,
+ uint32_t subleaf,
+ struct cpuid_leaf *res,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return emul_test_cpuid(leaf, subleaf, res, ctxt);
+}
+
+static int fuzz_read_segment(
+ enum x86_segment seg,
+ struct segment_register *reg,
+ struct x86_emulate_ctxt *ctxt)
+{
+ int rc;
+
+ if ( seg > SEG_NUM )
+ return X86EMUL_UNHANDLEABLE;
+
+ rc = maybe_fail("read_segment", true);
+
+ if ( rc == X86EMUL_OKAY )
+ memcpy(reg, input.segments+seg, sizeof(struct segment_register));
+
+ return rc;
+}
+
+static int fuzz_write_segment(
+ enum x86_segment seg,
+ const struct segment_register *reg,
+ struct x86_emulate_ctxt *ctxt)
+{
+ int rc;
+
+ if ( seg > SEG_NUM )
+ return X86EMUL_UNHANDLEABLE;
+
+ rc = maybe_fail("write_segment", true);
+
+ if ( rc == X86EMUL_OKAY )
+ memcpy(input.segments+seg, reg, sizeof(struct segment_register));
+
+ return rc;
+}
+
+static int fuzz_read_cr(
+ unsigned int reg,
+ unsigned long *val,
+ struct x86_emulate_ctxt *ctxt)
+{
+ int rc;
+
+ if ( reg > ARRAY_SIZE(input.cr) )
+ return X86EMUL_UNHANDLEABLE;
+
+ rc = maybe_fail("read_cr", true);
+
+ if ( rc == X86EMUL_OKAY )
+ *val = input.cr[reg];
+
+ return rc;
+}
+
+static int fuzz_write_cr(
+ unsigned int reg,
+ unsigned long val,
+ struct x86_emulate_ctxt *ctxt)
+{
+ int rc;
+
+ if ( reg > ARRAY_SIZE(input.cr) )
+ return X86EMUL_UNHANDLEABLE;
+
+ rc = maybe_fail("write_cr", true);
+
+ if ( rc == X86EMUL_OKAY )
+ input.cr[reg] = val;
+
+ return rc;
+}
+
+enum {
+ MSRI_IA32_SYSENTER_CS,
+ MSRI_IA32_SYSENTER_ESP,
+ MSRI_IA32_SYSENTER_EIP,
+ MSRI_EFER,
+ MSRI_STAR,
+ MSRI_LSTAR,
+ MSRI_CSTAR,
+ MSRI_SYSCALL_MASK
+};
+
+const static unsigned int msr_index[MSR_INDEX_MAX] = {
+ [MSRI_IA32_SYSENTER_CS] = MSR_IA32_SYSENTER_CS,
+ [MSRI_IA32_SYSENTER_ESP] = MSR_IA32_SYSENTER_ESP,
+ [MSRI_IA32_SYSENTER_EIP] = MSR_IA32_SYSENTER_EIP,
+ [MSRI_EFER] = MSR_EFER,
+ [MSRI_STAR] = MSR_STAR,
+ [MSRI_LSTAR] = MSR_LSTAR,
+ [MSRI_CSTAR] = MSR_CSTAR,
+ [MSRI_SYSCALL_MASK] = MSR_SYSCALL_MASK
+};
+
+static int _fuzz_read_msr(
+ unsigned int reg,
+ uint64_t *val,
+ struct x86_emulate_ctxt *ctxt)
+{
+ unsigned int idx;
+
+ switch ( reg )
+ {
+ case MSR_TSC_AUX:
+ case MSR_IA32_TSC:
+ return data_read("read_msr", val, sizeof(*val));
+ case MSR_EFER:
+ *val = input.msr[MSRI_EFER];
+ *val &= ~EFER_LMA;
+ if ( (*val & EFER_LME) && (input.cr[4] & X86_CR4_PAE) &&
+ (input.cr[0] & X86_CR0_PG) )
+ {
+ printf("Setting EFER_LMA\n");
+ *val |= EFER_LMA;
+ }
+ return X86EMUL_OKAY;
+ }
+
+ for ( idx = 0; idx < MSR_INDEX_MAX; idx++ )
+ {
+ if ( msr_index[idx] == reg )
+ {
+ *val = input.msr[idx];
+ return X86EMUL_OKAY;
+ }
+ }
+
+ return X86EMUL_EXCEPTION;
+}
+
+static int fuzz_read_msr(
+ unsigned int reg,
+ uint64_t *val,
+ struct x86_emulate_ctxt *ctxt) {
+ int rc;
+
+ rc = maybe_fail("read_msr", true);
+ if ( rc != X86EMUL_OKAY )
+ return rc;
+ else
+ return _fuzz_read_msr(reg, val, ctxt);
+}
+
+static int fuzz_write_msr(
+ unsigned int reg,
+ uint64_t val,
+ struct x86_emulate_ctxt *ctxt)
+{
+ unsigned int idx;
+ int rc;
+
+ rc = maybe_fail("write_ms", true);
+ if ( rc != X86EMUL_OKAY )
+ return rc;
+
+ switch ( reg )
+ {
+ case MSR_TSC_AUX:
+ case MSR_IA32_TSC:
+ return X86EMUL_OKAY;
+ }
+
+ for ( idx = 0; idx < MSR_INDEX_MAX; idx++ )
+ {
+ if ( msr_index[idx] == reg )
+ {
+ input.msr[idx] = val;
+ return X86EMUL_OKAY;
+ }
+ }
+
+ return X86EMUL_EXCEPTION;
}
+#define SET(h) .h = fuzz_##h
static struct x86_emulate_ops fuzz_emulops = {
- .read = fuzz_read,
- .insn_fetch = fuzz_fetch,
- .write = fuzz_write,
- .cmpxchg = fuzz_cmpxchg,
- .cpuid = emul_test_cpuid,
- .read_cr = emul_test_read_cr,
+ SET(read),
+ SET(insn_fetch),
+ SET(write),
+ SET(cmpxchg),
+ SET(rep_ins),
+ SET(rep_outs),
+ SET(rep_movs),
+ SET(rep_stos),
+ SET(read_segment),
+ SET(write_segment),
+ SET(read_io),
+ SET(write_io),
+ SET(read_cr),
+ SET(write_cr),
+ SET(read_msr),
+ SET(write_msr),
+ SET(wbinvd),
+ SET(cpuid),
+ SET(invlpg),
.get_fpu = emul_test_get_fpu,
};
+#undef SET
+
+static void setup_fpu_exception_handler(void)
+{
+ /* FIXME - just disable exceptions for now */
+ unsigned long a;
+
+ asm volatile ( "fnclex");
+ a=0x37f; /* FCW_DEFAULT in Xen */
+ asm volatile ( "fldcw %0" :: "m" (a));
+ a=0x1f80; /* MXCSR_DEFAULT in Xen */
+ asm volatile ( "ldmxcsr %0" :: "m" (a) );
+}
+
+static void dump_state(struct x86_emulate_ctxt *ctxt)
+{
+ struct cpu_user_regs *regs = ctxt->regs;
+ uint64_t val;
+
+ printf(" -- State -- \n");
+ printf("addr / sp size: %d / %d\n", ctxt->addr_size, ctxt->sp_size);
+ printf(" cr0: %lx\n", input.cr[0]);
+ printf(" cr3: %lx\n", input.cr[3]);
+ printf(" cr4: %lx\n", input.cr[4]);
+
+ printf(" rip: %"PRIx64"\n", regs->rip);
+
+ _fuzz_read_msr(MSR_EFER, &val, ctxt);
+ printf("EFER: %"PRIx64"\n", val);
+}
+
+static bool long_mode_active(struct x86_emulate_ctxt *ctxt)
+{
+ uint64_t val;
+
+ if ( _fuzz_read_msr(MSR_EFER, &val, ctxt) != X86EMUL_OKAY )
+ return false;
+
+ return val & EFER_LMA;
+}
+
+static bool in_longmode(struct x86_emulate_ctxt *ctxt)
+{
+ return long_mode_active(ctxt) && input.segments[x86_seg_cs].attr.fields.l;
+}
+
+static void set_sizes(struct x86_emulate_ctxt *ctxt)
+{
+ if ( in_longmode(ctxt) )
+ ctxt->addr_size = ctxt->sp_size = 64;
+ else
+ {
+ ctxt->addr_size = input.segments[x86_seg_cs].attr.fields.db ? 32 : 16;
+ ctxt->sp_size = input.segments[x86_seg_ss].attr.fields.db ? 32 : 16;
+ }
+}
#define CANONICALIZE(x) \
do { \
@@ -100,10 +512,150 @@ static struct x86_emulate_ops fuzz_emulops = {
(x) = _y; \
} while( 0 )
-#define ADDR_SIZE_SHIFT 60
-#define ADDR_SIZE_64 (2ULL << ADDR_SIZE_SHIFT)
-#define ADDR_SIZE_32 (1ULL << ADDR_SIZE_SHIFT)
-#define ADDR_SIZE_16 (0)
+/* Expects bitmap and regs to be defined */
+#define CANONICALIZE_MAYBE(reg) \
+ if ( !(bitmap & (1 << CANONICALIZE_##reg)) ) \
+ CANONICALIZE(regs->reg); \
+
+enum {
+ HOOK_read,
+ HOOK_insn_fetch,
+ HOOK_write,
+ HOOK_cmpxchg,
+ HOOK_rep_ins,
+ HOOK_rep_outs,
+ HOOK_rep_movs,
+ HOOK_rep_stos,
+ HOOK_read_segment,
+ HOOK_write_segment,
+ HOOK_read_io,
+ HOOK_write_io,
+ HOOK_read_cr,
+ HOOK_write_cr,
+ HOOK_read_dr,
+ HOOK_write_dr,
+ HOOK_read_msr,
+ HOOK_write_msr,
+ HOOK_wbinvd,
+ HOOK_cpuid,
+ HOOK_inject_hw_exception,
+ HOOK_inject_sw_interrupt,
+ HOOK_get_fpu,
+ HOOK_put_fpu,
+ HOOK_invlpg,
+ HOOK_vmfunc,
+ OPTION_swint_emulation, /* Two bits */
+ CANONICALIZE_rip = OPTION_swint_emulation + 2,
+ CANONICALIZE_rsp,
+ CANONICALIZE_rbp
+};
+
+/* Expects bitmap to be defined */
+#define MAYBE_DISABLE_HOOK(h) \
+ if ( bitmap & (1 << HOOK_##h) ) \
+ { \
+ fuzz_emulops.h = NULL; \
+ printf("Disabling hook "#h"\n"); \
+ }
+
+static void disable_hooks(void)
+{
+ unsigned long bitmap = input.options;
+
+ /* See also sanitize_input, some hooks can't be disabled. */
+ MAYBE_DISABLE_HOOK(read);
+ MAYBE_DISABLE_HOOK(insn_fetch);
+ MAYBE_DISABLE_HOOK(write);
+ MAYBE_DISABLE_HOOK(cmpxchg);
+ MAYBE_DISABLE_HOOK(rep_ins);
+ MAYBE_DISABLE_HOOK(rep_outs);
+ MAYBE_DISABLE_HOOK(rep_movs);
+ MAYBE_DISABLE_HOOK(rep_stos);
+ MAYBE_DISABLE_HOOK(read_segment);
+ MAYBE_DISABLE_HOOK(write_segment);
+ MAYBE_DISABLE_HOOK(read_io);
+ MAYBE_DISABLE_HOOK(write_io);
+ MAYBE_DISABLE_HOOK(read_cr);
+ MAYBE_DISABLE_HOOK(write_cr);
+ MAYBE_DISABLE_HOOK(read_msr);
+ MAYBE_DISABLE_HOOK(write_msr);
+ MAYBE_DISABLE_HOOK(wbinvd);
+ MAYBE_DISABLE_HOOK(cpuid);
+ MAYBE_DISABLE_HOOK(get_fpu);
+ MAYBE_DISABLE_HOOK(invlpg);
+}
+
+static void set_swint_support(struct x86_emulate_ctxt *ctxt)
+{
+ unsigned int swint_opt = (input.options >> OPTION_swint_emulation) & 3;
+
+ static const enum x86_swint_emulation map[4] = {
+ x86_swint_emulate_none,
+ x86_swint_emulate_none,
+ x86_swint_emulate_icebp,
+ x86_swint_emulate_all };
+
+ ctxt->swint_emulate = map[swint_opt];
+}
+
+/*
+ * Constrain input to architecturally-possible states where
+ * the emulator relies on these
+ *
+ * In general we want the emulator to be as absolutely robust as
+ * possible; which means that we want to minimize the number of things
+ * it assumes about the input state. Tesing this means minimizing and
+ * removing as much of the input constraints as possible.
+ *
+ * So we only add constraints that (in general) have been proven to
+ * cause crashes in the emulator.
+ *
+ * For future reference: other constraints which might be necessary at
+ * some point:
+ *
+ * - EFER.LMA => !EFLAGS.NT
+ * - In VM86 mode (and real mode?), force segment...
+ * - ...access rights to 0xf3
+ * - ...limits to 0xffff
+ * - ...bases to below 1Mb, 16-byte aligned
+ * - ...selectors to (base >> 4)
+ */
+void sanitize_input(struct x86_emulate_ctxt *ctxt) {
+ struct cpu_user_regs *regs = &input.regs;
+ unsigned long bitmap = input.options;
+
+ /* Some hooks can't be disabled. */
+ input.options &= ~((1<<HOOK_read)|(1<<HOOK_insn_fetch));
+
+ /* Zero 'private' entries */
+ regs->error_code = 0;
+ regs->entry_vector = 0;
+
+ CANONICALIZE_MAYBE(rip);
+ CANONICALIZE_MAYBE(rsp);
+ CANONICALIZE_MAYBE(rbp);
+
+ /*
+ * CR0.PG can't be set if CR0.PE isn't set. Set is more interesting, so
+ * set PE if PG is set.
+ */
+ if ( input.cr[0] & X86_CR0_PG )
+ input.cr[0] |= X86_CR0_PE;
+
+ /*
+ * EFLAGS.VM not available in long mode
+ */
+ if ( long_mode_active(ctxt) )
+ regs->rflags &= ~X86_EFLAGS_VM;
+
+ /*
+ * EFLAGS.VM implies 16-bit mode
+ */
+ if ( regs->rflags & X86_EFLAGS_VM ) {
+ input.segments[x86_seg_cs].attr.fields.db = 0;
+ input.segments[x86_seg_ss].attr.fields.db = 0;
+ }
+}
int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
{
@@ -114,10 +666,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
.addr_size = 8 * sizeof(void *),
.sp_size = 8 * sizeof(void *),
};
- unsigned int nr = 0;
int rc;
- unsigned int x;
- const uint8_t *p = data_p;
stack_exec = emul_test_make_stack_executable();
if ( !stack_exec )
@@ -127,52 +676,39 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
}
/* Reset all global state variables */
- memset(data, 0, sizeof(data));
+ memset(&input, 0, sizeof(input));
data_index = 0;
- data_max = 0;
-
- nr = size < sizeof(regs) ? size : sizeof(regs);
+ data_num = 0;
- memcpy(®s, p, nr);
- p += sizeof(regs);
+ if ( size <= DATA_OFFSET )
+ {
+ printf("Input too small\n");
+ return 1;
+ }
- if ( nr < size )
+ if ( size > sizeof(input) )
{
- memcpy(data, p, size - nr);
- data_max = size - nr;
+ printf("Input too large\n");
+ return 1;
}
- ctxt.force_writeback = false;
+ memcpy(&input, data_p, size);
- /* Zero 'private' fields */
- regs.error_code = 0;
- regs.entry_vector = 0;
+ data_num = size - DATA_OFFSET;
- /* Use the upper bits of regs.eip to determine addr_size */
- x = (regs.rip >> ADDR_SIZE_SHIFT) & 0x3;
- if ( x == 3 )
- x = 2;
- ctxt.addr_size = 16 << x;
- printf("addr_size: %d\n", ctxt.addr_size);
+ sanitize_input(&ctxt);
- /* Use the upper bit of regs.rsp to determine sp_size (if appropriate) */
- if ( ctxt.addr_size == 64 )
- ctxt.sp_size = 64;
- else
- {
- /* If addr_size isn't 64-bits, sp_size can only be 16 or 32 bits */
- x = (regs.rsp >> ADDR_SIZE_SHIFT) & 0x1;
- ctxt.sp_size = 16 << x;
- }
- printf("sp_size: %d\n", ctxt.sp_size);
- CANONICALIZE(regs.rip);
- CANONICALIZE(regs.rsp);
- CANONICALIZE(regs.rbp);
+ disable_hooks();
- /* Zero all segments for now */
- regs.cs = regs.ss = regs.es = regs.ds = regs.fs = regs.gs = 0;
+ set_swint_support(&ctxt);
do {
+ /* FIXME: Until we actually implement SIGFPE handling properly */
+ setup_fpu_exception_handler();
+
+ set_sizes(&ctxt);
+ dump_state(&ctxt);
+
rc = x86_emulate(&ctxt, &fuzz_emulops);
printf("Emulation result: %d\n", rc);
} while ( rc == X86EMUL_OKAY );
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-01-31 11:16 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-31 11:07 [PATCH v2 00/12] fuzz: update x86emul fuzzer Wei Liu
2017-01-31 11:07 ` [PATCH v2 01/12] fuzz: don't buffer stdout in afl stubs Wei Liu
2017-01-31 12:44 ` Jan Beulich
2017-01-31 11:07 ` [PATCH v2 02/12] x86: extract macros to x86-defns.h Wei Liu
2017-01-31 12:45 ` Jan Beulich
2017-01-31 13:28 ` Wei Liu
2017-01-31 11:08 ` [PATCH v2 03/12] x86: extract vendor numeric id to x86-vendors.h Wei Liu
2017-01-31 12:48 ` Jan Beulich
2017-01-31 11:08 ` [PATCH v2 04/12] x86emul/test: use x86-vendors.h Wei Liu
2017-01-31 12:50 ` Jan Beulich
2017-01-31 14:36 ` Wei Liu
2017-01-31 15:16 ` Jan Beulich
2017-01-31 15:16 ` Wei Liu
2017-01-31 11:08 ` [PATCH v2 05/12] x86emul: use eflags definitions in x86-defns.h Wei Liu
2017-01-31 12:56 ` Jan Beulich
2017-01-31 14:55 ` Wei Liu
2017-01-31 15:16 ` Jan Beulich
2017-01-31 11:08 ` [PATCH v2 06/12] x86emul: use msr definitions in msr-index.h Wei Liu
2017-01-31 12:59 ` Jan Beulich
2017-01-31 11:08 ` [PATCH v2 07/12] x86: add UMIP CR4 bit Wei Liu
2017-01-31 13:00 ` Jan Beulich
2017-01-31 11:08 ` [PATCH v2 08/12] x86emul: use CR definitions in x86-defns.h Wei Liu
2017-01-31 13:01 ` Jan Beulich
2017-01-31 11:08 ` [PATCH v2 09/12] x86emul: use TRAP " Wei Liu
2017-01-31 11:26 ` Andrew Cooper
2017-01-31 11:08 ` Wei Liu [this message]
2017-01-31 13:33 ` [PATCH v2 10/12] fuzz/x86emul: update fuzzer Jan Beulich
2017-01-31 15:51 ` Wei Liu
2017-01-31 15:57 ` Andrew Cooper
2017-01-31 16:01 ` George Dunlap
2017-01-31 16:05 ` Jan Beulich
2017-01-31 16:02 ` Jan Beulich
2017-01-31 17:37 ` Wei Liu
2017-01-31 11:08 ` [PATCH v2 11/12] fuzz/x86emul: print out minimal input size Wei Liu
2017-01-31 13:33 ` Jan Beulich
2017-01-31 11:08 ` [PATCH v2 12/12] fuzz: update README.afl example Wei Liu
2017-01-31 13:34 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170131110809.30001-11-wei.liu2@citrix.com \
--to=wei.liu2@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=george.dunlap@citrix.com \
--cc=george.dunlap@eu.citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).