[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
> +
>
- [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects, (continued)
- [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects, Oleinik, Alexander, 2019/07/24
- [Qemu-devel] [RFC 02/19] fuzz: add FUZZ_TARGET type to qemu module system, Oleinik, Alexander, 2019/07/24
- [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c, Oleinik, Alexander, 2019/07/24
- [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init, Oleinik, Alexander, 2019/07/24
- Re: [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init,
Paolo Bonzini <=
- [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator, Oleinik, Alexander, 2019/07/24
- [Qemu-devel] [RFC 05/19] fuzz: expose qemu_savevm_state & skip state header, Oleinik, Alexander, 2019/07/24
- [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload, Oleinik, Alexander, 2019/07/24