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

Re: [Xen-devel] [PATCH v3 09/11] fuzz/x86emul: update fuzzer



On Thu, Feb 02, 2017 at 05:20:56AM -0700, Jan Beulich wrote:
> >>> On 01.02.17 at 13:02, <wei.liu2@xxxxxxxxxx> wrote:
> > @@ -16,26 +17,78 @@
> >  
> >  #include "x86_emulate.h"
> >  
> > -static unsigned char data[4096];
> > +#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)
> 
> static?

Done.

> 
> > +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;
> > +
> > +    switch ( rc )
> > +    {
> > +    case X86EMUL_UNHANDLEABLE:
> > +        /* No work is done in this case */
> > +        *reps = 0;
> > +        break;
> > +    case X86EMUL_EXCEPTION:
> > +    case X86EMUL_RETRY:
> > +        /* Halve the amount in this case */
> > +        *reps /= 2;
> > +    }
> 
> Even if not strictly needed at this point in time, adding a break
> statement here would be nice.
> 

Done.

> > +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);
> > +}
> 
> Can these two reasonably fail? I wonder if we shouldn't perhaps make
> the hooks return void.
> 

Both can generate exceptions in some cases according to manual, so I
think it makes sense to leave them as-is, provided they fit in the model
you want to use (like in_realmode).

Of course if you end up changing the hooks to return void, I'm fine with
just removing these two hooks from fuzzer altogether.

> > +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 )
> > +        *reg = input.segments[seg];
> > +
> > +    return rc;
> > +}
> 
> Just like with ->read_cr(), this must not vary in returned state
> between multiple invocations.
> 

Fixed for both read_segment and write_segment.

> > +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));
> 
> Strictly speaking the above applies to TSC_AUX too. And TSC should
> return monotonically increasing values. I don't think though that
> producing random output here matters right now. A comment may
> be worthwhile.
> 

Right, I will add the following:

        /*                                                                      
                         
         * TSC should return monotonically increasing values, but               
                         
         * returning random values is fine in fuzzer.                           
                         
         */

> > +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;
> 
> This, otoh, again needs to strictly follow the revised read_cr() model.

Fixed. And then merge _fuzz_read_msr and fuzz_read_msr.

> 
> > +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] = {
> 
> As (I think) said before - please don't put blank lines between
> declarations; they're supposed to separate declarations from
> statements.
> 

Fixed.

> > +/*
> > + * 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, 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) {
> 
> static? And { on its own line.
> 

Done.

> >      do {
> > +        setup_fpu_exception_handler();
> 
> I'm sorry for having mislead you regarding the comment which was
> here: As said elsewhere, I was - based on the function's name -
> assuming this to be a one time action, while in fact this is being done
> before every emulated insn. Once this becomes a one time thing, it
> indeed needs moving out of the loop, so leaving a comment here is
> warranted.
> 

No problem, I add back the original comment.

Wei.

> 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®.