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

Re: [Xen-devel] [PATCH RFC v2 5/7] tools/fuzz: introduce x86 instruction emulator target



>>> On 09.12.16 at 13:23, <wei.liu2@xxxxxxxxxx> wrote:
> +static int fuzz_cpuid(
> +    unsigned int *eax,
> +    unsigned int *ebx,
> +    unsigned int *ecx,
> +    unsigned int *edx,
> +    struct x86_emulate_ctxt *ctxt)
> +{
> +    return emul_test_cpuid(eax, ebx, ecx, edx, ctxt);
> +}

Please use emul_test_cpuid directly for the hook (same for
fuzz_read_cr() then).

> +#define cpu_has_mmx ({ \
> +    unsigned int eax = 1, ecx = 0, edx; \
> +    fuzz_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
> +    (edx & (1U << 23)) != 0; \
> +})
> +
> +#define cpu_has_sse ({ \
> +    unsigned int eax = 1, ecx = 0, edx; \
> +    fuzz_cpuid(&eax, &ecx, &ecx, &edx, NULL); \
> +    (edx & (1U << 25)) != 0; \
> +})
> +
> +static inline uint64_t xgetbv(uint32_t xcr)
> +{
> +    uint32_t lo, hi;
> +
> +    asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) );
> +
> +    return ((uint64_t)hi << 32) | lo;
> +}
> +
> +#define cpu_has_avx ({ \
> +    unsigned int eax = 1, ecx = 0; \
> +    fuzz_cpuid(&eax, &eax, &ecx, &eax, NULL); \
> +    if ( !(ecx & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
> +        ecx = 0; \
> +    (ecx & (1U << 28)) != 0; \
> +})

See my comment on the earlier patch regarding sharing more of
the cpu_has_*.

> +static int fuzz_get_fpu(
> +    void (*exception_callback)(void *, struct cpu_user_regs *),
> +    void *exception_callback_arg,
> +    enum x86_emulate_fpu_type type,
> +    struct x86_emulate_ctxt *ctxt)
> +{
> +    switch ( type )
> +    {
> +    case X86EMUL_FPU_fpu:
> +        break;
> +    case X86EMUL_FPU_mmx:
> +        if ( cpu_has_mmx )
> +            break;
> +    case X86EMUL_FPU_xmm:
> +        if ( cpu_has_sse )
> +            break;
> +    case X86EMUL_FPU_ymm:
> +        if ( cpu_has_avx )
> +            break;
> +    default:
> +        return X86EMUL_UNHANDLEABLE;
> +    }
> +    return X86EMUL_OKAY;
> +}

This looks to be identical to the test harness'es variant too.

> +int LLVMFuzzerTestOneInput(const uint8_t *data_p, size_t size)
> +{
> +    bool stack_exec;
> +    struct cpu_user_regs regs = {};
> +    struct x86_emulate_ctxt ctxt =
> +        {
> +            .regs = &regs,
> +            .addr_size = 8 * sizeof(void *),
> +            .sp_size = 8 * sizeof(void *),
> +        };
> +
> +    int nr = 0;

unsigned?

> +    int rc;
> +    unsigned x;
> +    const uint8_t *p = data_p;
> +
> +    stack_exec = emul_test_make_stack_executable();
> +    if (!stack_exec)
> +        printf("Warning: Stack could not be made executable (%d).\n", errno);

I don't think it's worth continuing in case of failure here (as fuzzed
input is too likely to hit one of the cases needing an on-stack stub).

> +    /* Reset all global states */
> +    memset(data, 0, sizeof(data));
> +    data_index = 0;
> +    data_max = 0;
> +
> +    nr = size < sizeof(regs) ? size : sizeof(regs);
> +
> +    memcpy(&regs, p, nr);
> +    p += sizeof(regs);
> +    nr += sizeof(regs);
> +
> +    if (nr <= size) {

Please use hypervisor coding style in this directory, just like
test_x86_emulator.c at least attempts to do.

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