[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v4 10/12] fuzz/x86_emulate: Add --rerun option to try to track down instability



>>> On 11.10.17 at 19:52, <george.dunlap@xxxxxxxxxx> wrote:
> @@ -884,20 +891,146 @@ int LLVMFuzzerInitialize(int *argc, char ***argv)
>      return 0;
>  }
>  
> -int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
> +static void setup_fuzz_state(struct fuzz_state *state, const void *data_p, 
> size_t size)
>  {
> -    struct fuzz_state state = {
> -        .ops = all_fuzzer_ops,
> -    };
> -    struct x86_emulate_ctxt ctxt = {
> -        .data = &state,
> -        .regs = &state.regs,
> -        .addr_size = 8 * sizeof(void *),
> -        .sp_size = 8 * sizeof(void *),
> -    };
> +    memset(state, 0, sizeof(*state));
> +    state->corpus = data_p;
> +    state->data_num = size;
> +}
> +
> +static int runtest(struct fuzz_state *state) {
>      int rc;
>  
> -    if ( size <= fuzz_minimal_input_size() )
> +    struct x86_emulate_ctxt *ctxt = &state->ctxt;

Please don't leave a blank line between declarations.

> +static void compare_states(struct fuzz_state state[2])
> +{
> +    /* First zero any "internal" pointers */
> +    state[0].corpus = state[1].corpus = NULL;
> +    state[0].ctxt.data = state[1].ctxt.data = NULL;
> +    state[0].ctxt.regs = state[1].ctxt.regs = NULL;
> +
> +    if ( memcmp(&state[0], &state[1], sizeof(struct fuzz_state)) )
> +    {
> +        unsigned int i;
> +
> +        printf("State mismatch\n");
> +
> +        for ( i = 0; i < ARRAY_SIZE(state[0].cr); i++ )
> +            if ( state[0].cr[i] != state[1].cr[i] )
> +                printf("cr[%u]: %lx != %lx\n",
> +                       i, state[0].cr[i], state[1].cr[i]);
> +        
> +        for ( i = 0; i < ARRAY_SIZE(state[0].msr); i++ )
> +            if ( state[0].msr[i] != state[1].msr[i] )
> +                printf("msr[%u]: %lx != %lx\n",
> +                       i, state[0].msr[i], state[1].msr[i]);
> +        
> +        for ( i = 0; i < ARRAY_SIZE(state[0].segments); i++ )
> +            if ( memcmp(&state[0].segments[i], &state[1].segments[i],
> +                        sizeof(state[0].segments[0])) )
> +                printf("segments[%u]: [%x:%x:%x:%lx] != [%x:%x:%x:%lx]!\n", 
> i,
> +                       (unsigned)state[0].segments[i].sel,
> +                       (unsigned)state[0].segments[i].attr,
> +                       state[0].segments[i].limit,
> +                       state[0].segments[i].base,
> +                       (unsigned)state[1].segments[i].sel,
> +                       (unsigned)state[1].segments[i].attr,
> +                       state[1].segments[i].limit,
> +                       state[1].segments[i].base);
> +
> +        if ( state[0].data_num != state[1].data_num )
> +            printf("data_num: %lx !=  %lx\n", state[0].data_num,
> +                   state[1].data_num);
> +        if ( state[0].data_index != state[1].data_index )
> +            printf("data_index: %lx !=  %lx\n", state[0].data_index,
> +                   state[1].data_index);
> +
> +        if ( memcmp(&state[0].regs, &state[1].regs, sizeof(state[0].regs)) )
> +        {
> +            printf("registers differ!\n");
> +            /* Print If Not Equal */
> +#define PRINT_NE(elem)\
> +            if ( state[0].elem != state[1].elem ) \
> +                printf(#elem " differ: %lx != %lx\n", \
> +                       (unsigned long)state[0].elem, \
> +                       (unsigned long)state[1].elem)
> +            PRINT_NE(regs.r15);
> +            PRINT_NE(regs.r14);
> +            PRINT_NE(regs.r13);
> +            PRINT_NE(regs.r12);
> +            PRINT_NE(regs.rbp);
> +            PRINT_NE(regs.rbx);
> +            PRINT_NE(regs.r10);
> +            PRINT_NE(regs.r11);
> +            PRINT_NE(regs.r9);
> +            PRINT_NE(regs.r8);
> +            PRINT_NE(regs.rax);
> +            PRINT_NE(regs.rcx);
> +            PRINT_NE(regs.rdx);
> +            PRINT_NE(regs.rsi);
> +            PRINT_NE(regs.rdi);

Aren't these register fields all of the same type? If so, why do you
need to casts to unsigned long in the macro?

Additionally iirc Andrew had asked for eflags (and perhaps also
selector register values) to be printed separately for ease of
recognition - I support this request.

> +            for ( i = offsetof(struct cpu_user_regs, error_code) / 
> sizeof(unsigned);
> +                  i < sizeof(state[1].regs)/sizeof(unsigned); i++ )

Blanks around binary operators please (also elsewhere).

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.