[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 07/12] fuzz/x86_emulate: Move all state into fuzz_state
This is in preparation for adding the option for a more "compact" interpretation of the fuzzing data, in which we only change select bits of the state. Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxx> Acked-by: Jan Beulich <jbeulich@xxxxxxxx> --- v3: - Move DATA_OFFSET inside the structure - Remove a stray blank line v2: Port over previous changes CC: Ian Jackson <ian.jackson@xxxxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Jan Beulich <jbeulich@xxxxxxxx> --- tools/fuzz/x86_instruction_emulator/fuzz-emul.c | 89 +++++++++++++------------ 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c index 8998f21fe1..20d52b33f8 100644 --- a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c +++ b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c @@ -24,14 +24,8 @@ /* Layout of data expected as fuzzing input. */ struct fuzz_corpus { - 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 fuzz_corpus, data) /* * Internal state of the fuzzing harness. Calculated initially from the input @@ -39,7 +33,14 @@ struct fuzz_corpus */ struct fuzz_state { + unsigned long options; + unsigned long cr[5]; + uint64_t msr[MSR_INDEX_MAX]; + struct segment_register segments[SEG_NUM]; + struct cpu_user_regs regs; + /* Fuzzer's input data. */ +#define DATA_OFFSET offsetof(struct fuzz_state, corpus) struct fuzz_corpus *corpus; /* Real amount of data backing corpus->data[]. */ @@ -392,11 +393,10 @@ static int fuzz_read_segment( struct x86_emulate_ctxt *ctxt) { const struct fuzz_state *s = ctxt->data; - const struct fuzz_corpus *c = s->corpus; assert(is_x86_user_segment(seg) || is_x86_system_segment(seg)); - *reg = c->segments[seg]; + *reg = s->segments[seg]; return X86EMUL_OKAY; } @@ -407,7 +407,6 @@ static int fuzz_write_segment( struct x86_emulate_ctxt *ctxt) { struct fuzz_state *s = ctxt->data; - struct fuzz_corpus *c = s->corpus; int rc; assert(is_x86_user_segment(seg) || is_x86_system_segment(seg)); @@ -415,7 +414,7 @@ static int fuzz_write_segment( rc = maybe_fail(ctxt, "write_segment", true); if ( rc == X86EMUL_OKAY ) - c->segments[seg] = *reg; + s->segments[seg] = *reg; return rc; } @@ -426,12 +425,11 @@ static int fuzz_read_cr( struct x86_emulate_ctxt *ctxt) { const struct fuzz_state *s = ctxt->data; - const struct fuzz_corpus *c = s->corpus; - if ( reg >= ARRAY_SIZE(c->cr) ) + if ( reg >= ARRAY_SIZE(s->cr) ) return X86EMUL_UNHANDLEABLE; - *val = c->cr[reg]; + *val = s->cr[reg]; return X86EMUL_OKAY; } @@ -442,17 +440,16 @@ static int fuzz_write_cr( struct x86_emulate_ctxt *ctxt) { struct fuzz_state *s = ctxt->data; - struct fuzz_corpus *c = s->corpus; int rc; - if ( reg >= ARRAY_SIZE(c->cr) ) + if ( reg >= ARRAY_SIZE(s->cr) ) return X86EMUL_UNHANDLEABLE; rc = maybe_fail(ctxt, "write_cr", true); if ( rc != X86EMUL_OKAY ) return rc; - c->cr[reg] = val; + s->cr[reg] = val; return X86EMUL_OKAY; } @@ -487,7 +484,6 @@ static int fuzz_read_msr( struct x86_emulate_ctxt *ctxt) { const struct fuzz_state *s = ctxt->data; - const struct fuzz_corpus *c = s->corpus; unsigned int idx; switch ( reg ) @@ -501,10 +497,10 @@ static int fuzz_read_msr( */ return data_read(ctxt, x86_seg_none, "read_msr", val, sizeof(*val)); case MSR_EFER: - *val = c->msr[MSRI_EFER]; + *val = s->msr[MSRI_EFER]; *val &= ~EFER_LMA; - if ( (*val & EFER_LME) && (c->cr[4] & X86_CR4_PAE) && - (c->cr[0] & X86_CR0_PG) ) + if ( (*val & EFER_LME) && (s->cr[4] & X86_CR4_PAE) && + (s->cr[0] & X86_CR0_PG) ) { printf("Setting EFER_LMA\n"); *val |= EFER_LMA; @@ -516,7 +512,7 @@ static int fuzz_read_msr( { if ( msr_index[idx] == reg ) { - *val = c->msr[idx]; + *val = s->msr[idx]; return X86EMUL_OKAY; } } @@ -531,7 +527,6 @@ static int fuzz_write_msr( struct x86_emulate_ctxt *ctxt) { struct fuzz_state *s = ctxt->data; - struct fuzz_corpus *c = s->corpus; unsigned int idx; int rc; @@ -550,7 +545,7 @@ static int fuzz_write_msr( { if ( msr_index[idx] == reg ) { - c->msr[idx] = val; + s->msr[idx] = val; return X86EMUL_OKAY; } } @@ -600,15 +595,14 @@ static void setup_fpu_exception_handler(void) static void dump_state(struct x86_emulate_ctxt *ctxt) { struct fuzz_state *s = ctxt->data; - const struct fuzz_corpus *c = s->corpus; struct cpu_user_regs *regs = ctxt->regs; uint64_t val = 0; printf(" -- State -- \n"); printf("addr / sp size: %d / %d\n", ctxt->addr_size, ctxt->sp_size); - printf(" cr0: %lx\n", c->cr[0]); - printf(" cr3: %lx\n", c->cr[3]); - printf(" cr4: %lx\n", c->cr[4]); + printf(" cr0: %lx\n", s->cr[0]); + printf(" cr3: %lx\n", s->cr[3]); + printf(" cr4: %lx\n", s->cr[4]); printf(" rip: %"PRIx64"\n", regs->rip); @@ -629,15 +623,13 @@ static bool long_mode_active(struct x86_emulate_ctxt *ctxt) static bool in_longmode(struct x86_emulate_ctxt *ctxt) { const struct fuzz_state *s = ctxt->data; - const struct fuzz_corpus *c = s->corpus; - return long_mode_active(ctxt) && c->segments[x86_seg_cs].l; + return long_mode_active(ctxt) && s->segments[x86_seg_cs].l; } static void set_sizes(struct x86_emulate_ctxt *ctxt) { struct fuzz_state *s = ctxt->data; - const struct fuzz_corpus *c = s->corpus; ctxt->lma = long_mode_active(ctxt); @@ -645,11 +637,20 @@ static void set_sizes(struct x86_emulate_ctxt *ctxt) ctxt->addr_size = ctxt->sp_size = 64; else { - ctxt->addr_size = c->segments[x86_seg_cs].db ? 32 : 16; - ctxt->sp_size = c->segments[x86_seg_ss].db ? 32 : 16; + ctxt->addr_size = s->segments[x86_seg_cs].db ? 32 : 16; + ctxt->sp_size = s->segments[x86_seg_ss].db ? 32 : 16; } } +static void setup_state(struct x86_emulate_ctxt *ctxt) +{ + struct fuzz_state *s = ctxt->data; + + /* Fuzz all of the state in one go */ + if (!input_read(s, s, DATA_OFFSET)) + exit(-1); +} + #define CANONICALIZE(x) \ do { \ uint64_t _y = (x); \ @@ -709,8 +710,7 @@ enum { static void disable_hooks(struct x86_emulate_ctxt *ctxt) { struct fuzz_state *s = ctxt->data; - const struct fuzz_corpus *c = s->corpus; - unsigned long bitmap = c->options; + unsigned long bitmap = s->options; /* See also sanitize_input, some hooks can't be disabled. */ MAYBE_DISABLE_HOOK(read); @@ -760,12 +760,11 @@ static void disable_hooks(struct x86_emulate_ctxt *ctxt) static void sanitize_input(struct x86_emulate_ctxt *ctxt) { struct fuzz_state *s = ctxt->data; - struct fuzz_corpus *c = s->corpus; - struct cpu_user_regs *regs = &c->regs; - unsigned long bitmap = c->options; + struct cpu_user_regs *regs = ctxt->regs; + unsigned long bitmap = s->options; /* Some hooks can't be disabled. */ - c->options &= ~((1<<HOOK_read)|(1<<HOOK_insn_fetch)); + s->options &= ~((1<<HOOK_read)|(1<<HOOK_insn_fetch)); /* Zero 'private' entries */ regs->error_code = 0; @@ -779,8 +778,8 @@ static void sanitize_input(struct x86_emulate_ctxt *ctxt) * CR0.PG can't be set if CR0.PE isn't set. Set is more interesting, so * set PE if PG is set. */ - if ( c->cr[0] & X86_CR0_PG ) - c->cr[0] |= X86_CR0_PE; + if ( s->cr[0] & X86_CR0_PG ) + s->cr[0] |= X86_CR0_PE; /* EFLAGS.VM not available in long mode */ if ( long_mode_active(ctxt) ) @@ -789,8 +788,8 @@ static void sanitize_input(struct x86_emulate_ctxt *ctxt) /* EFLAGS.VM implies 16-bit mode */ if ( regs->rflags & X86_EFLAGS_VM ) { - c->segments[x86_seg_cs].db = 0; - c->segments[x86_seg_ss].db = 0; + s->segments[x86_seg_cs].db = 0; + s->segments[x86_seg_ss].db = 0; } } @@ -812,7 +811,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size) }; struct x86_emulate_ctxt ctxt = { .data = &state, - .regs = &input.regs, + .regs = &state.regs, .addr_size = 8 * sizeof(void *), .sp_size = 8 * sizeof(void *), }; @@ -836,7 +835,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size) memcpy(&input, data_p, size); state.corpus = &input; - state.data_num = size - DATA_OFFSET; + state.data_num = size; + + setup_state(&ctxt); sanitize_input(&ctxt); -- 2.14.2 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |