qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init
Date: Thu, 25 Jul 2019 10:21:18 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0

On 25/07/19 05:23, Oleinik, Alexander wrote:
> Intercept coverage buffer registration calls and use this information to
> copy them to shared memory, if using fork() to avoid resetting device
> state.
> 
> Signed-off-by: Alexander Oleinik <address@hidden>
> ---
>  tests/fuzz/fuzzer_hooks.c | 106 ++++++++++++++++++++++++++++++++++++++
>  tests/fuzz/fuzzer_hooks.h |   9 ++++
>  2 files changed, 115 insertions(+)
>  create mode 100644 tests/fuzz/fuzzer_hooks.c
>  create mode 100644 tests/fuzz/fuzzer_hooks.h
> 
> diff --git a/tests/fuzz/fuzzer_hooks.c b/tests/fuzz/fuzzer_hooks.c
> new file mode 100644
> index 0000000000..5a0bbec413
> --- /dev/null
> +++ b/tests/fuzz/fuzzer_hooks.c
> @@ -0,0 +1,106 @@
> +#include "qemu/osdep.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "qemu-common.h"
> +#include "fuzzer_hooks.h"
> +
> +#include <dlfcn.h>
> +#include <elf.h>
> +
> +
> +extern void* _ZN6fuzzer3TPCE;

Would it make sense to make this a C++ source, so that you can avoid
using the mangled names (in this case, "namespace fuzzer { extern void
*TPC; }" and then using fuzzer::TPC)?  Even if it's just a single symbol.

> +// The libfuzzer handlers
> +void __real___sanitizer_cov_8bit_counters_init(uint8_t*, uint8_t*);
> +void __real___sanitizer_cov_trace_pc_guard_init(uint8_t*, uint8_t*);
> +
> +void __wrap___sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t 
> *Stop);
> +void __wrap___sanitizer_cov_trace_pc_guard_init(uint8_t *Start, uint8_t 
> *Stop);
> +
> +
> +void* counter_shm;
> +
> +typedef struct CoverageRegion {
> +    uint8_t* start;
> +    size_t length;
> +    bool store; /* Set this if it needs to be copied to the forked process */
> +} CoverageRegion;
> +
> +CoverageRegion regions[10];
> +int region_index = 0;
> +
> +void __wrap___sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop)
> +{
> +    regions[region_index].start = Start;
> +    regions[region_index].length = Stop-Start;
> +    regions[region_index].store = true;
> +    region_index++;
> +    __real___sanitizer_cov_8bit_counters_init(Start, Stop);
> +}
> +
> +void __wrap___sanitizer_cov_trace_pc_guard_init(uint8_t *Start, uint8_t 
> *Stop)
> +{
> +    regions[region_index].start = Start;
> +    regions[region_index++].length = Stop-Start;
> +    regions[region_index].store = true;
> +    region_index++;
> +    __real___sanitizer_cov_trace_pc_guard_init(Start, Stop);
> +}
> +
> +static void add_tpc_region(void)
> +{
> +    /* Got symbol and length from readelf. Horrible way to do this! */
> +    regions[region_index].start = (uint8_t*)(&_ZN6fuzzer3TPCE);
> +    regions[region_index].length = 0x443c00; 
> +    regions[region_index].store = true;
> +    region_index++;
> +}
> +
> +void counter_shm_init(void)
> +{
> +    /*
> +     * Add the  internal libfuzzer object that gets modified by cmp, etc
> +     * callbacks
> +     */
> +    add_tpc_region(); 
> +
> +    size_t length = 0;
> +    for(int i=0; i<region_index; i++){
> +        printf("%d %lx\n", i, length);
> +        length += regions[i].length;
> +    }
> +
> +    /* 
> +     * Map some shared memory. When we use a fork-server we can copy the
> +     * libfuzzer-related counters
> +     * */
> +    counter_shm = mmap(NULL, length, PROT_READ | PROT_WRITE, 
> +            MAP_SHARED | MAP_ANONYMOUS, -1, 0);
> +    if(counter_shm == MAP_FAILED) {
> +        printf("mmap() failed\n");
> +        do { perror("error:"); exit(EXIT_FAILURE); } while (0);
> +        exit(-1);
> +    }
> +}
> +
> +void counter_shm_store(void)
> +{
> +    size_t offset = 0;
> +    for(int i=0; i<region_index; i++) {
> +        if(regions[i].store) {
> +            memcpy(counter_shm + offset, regions[i].start, 
> regions[i].length);
> +        }
> +        offset+=regions[i].length;
> +    }
> +}
> +
> +void counter_shm_load(void)
> +{
> +    size_t offset = 0;
> +    for(int i=0; i<region_index; i++) {
> +        if(regions[i].store) {
> +            memcpy(regions[i].start, counter_shm + offset, 
> regions[i].length);
> +        }
> +        offset+=regions[i].length;
> +    }
> +}
> +
> diff --git a/tests/fuzz/fuzzer_hooks.h b/tests/fuzz/fuzzer_hooks.h
> new file mode 100644
> index 0000000000..90dca254d4
> --- /dev/null
> +++ b/tests/fuzz/fuzzer_hooks.h
> @@ -0,0 +1,9 @@
> +#ifndef FUZZER_HOOKS_H
> +#define FUZZER_HOOKS_H
> +
> +void counter_shm_init(void);
> +void counter_shm_store(void);
> +void counter_shm_load(void);
> +
> +#endif
> +
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]