]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
tools/insn-fuzz: Fix a stability bug in afl-clang-fast mode
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 20 Mar 2017 19:17:33 +0000 (19:17 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 6 Apr 2017 17:42:49 +0000 (18:42 +0100)
The fuzzing harness conditionally disables hooks to test error paths in the
emulator.  However, fuzz_emulops is a static structure.

c/s 69f4633 "tools/insn-fuzz: Support AFL's afl-clang-fast mode" introduced
persistent mode, but because fuzz_emulops is static, the clobbering of hooks
accumulates over repeated input, meaning that previous corpora influence the
execution over the current corpus.

Move the partially clobbered struct x86_emulate_ops into struct fuzz_state,
which is re-initialised from full on each call to LLVMFuzzerTestOneInput()

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
tools/fuzz/x86_instruction_emulator/fuzz-emul.c

index db0719e194ce7c8e32e94a8ad115213bbd9cd577..a20212e0777b237d939a345295830a8c9b8de151 100644 (file)
@@ -47,6 +47,9 @@ struct fuzz_state
 
     /* Amount of corpus->data[] consumed thus far. */
     size_t data_index;
+
+    /* Emulation ops, some of which are disabled based on corpus->options. */
+    struct x86_emulate_ops ops;
 };
 
 /*
@@ -461,7 +464,7 @@ static int fuzz_write_msr(
 }
 
 #define SET(h) .h = fuzz_##h
-static struct x86_emulate_ops fuzz_emulops = {
+static const struct x86_emulate_ops all_fuzzer_ops = {
     SET(read),
     SET(insn_fetch),
     SET(write),
@@ -603,7 +606,7 @@ enum {
 #define MAYBE_DISABLE_HOOK(h)                          \
     if ( bitmap & (1 << HOOK_##h) )                    \
     {                                                  \
-        fuzz_emulops.h = NULL;                         \
+        s->ops.h = NULL;                               \
         printf("Disabling hook "#h"\n");               \
     }
 
@@ -709,7 +712,9 @@ int LLVMFuzzerInitialize(int *argc, char ***argv)
 int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
 {
     struct cpu_user_regs regs = {};
-    struct fuzz_state state = {};
+    struct fuzz_state state = {
+        .ops = all_fuzzer_ops,
+    };
     struct x86_emulate_ctxt ctxt = {
         .data = &state,
         .regs = &regs,
@@ -749,7 +754,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
         set_sizes(&ctxt);
         dump_state(&ctxt);
 
-        rc = x86_emulate(&ctxt, &fuzz_emulops);
+        rc = x86_emulate(&ctxt, &state.ops);
         printf("Emulation result: %d\n", rc);
     } while ( rc == X86EMUL_OKAY );