mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
fuzz: support for fork-based fuzzing.
fork() is a simple way to ensure that state does not leak in between fuzzing runs. Unfortunately, the fuzzer mutation engine relies on bitmaps which contain coverage information for each fuzzing run, and these bitmaps should be copied from the child to the parent(where the mutation occurs). These bitmaps are created through compile-time instrumentation and they are not shared with fork()-ed processes, by default. To address this, we create a shared memory region, adjust its size and map it _over_ the counter region. Furthermore, libfuzzer doesn't generally expose the globals that specify the location of the counters/coverage bitmap. As a workaround, we rely on a custom linker script which forces all of the bitmaps we care about to be placed in a contiguous region, which is easy to locate and mmap over. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-id: 20200220041118.23264-16-alxndr@bu.edu Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
d6919e4cb6
commit
cb06fdad05
4 changed files with 120 additions and 0 deletions
55
tests/qtest/fuzz/fork_fuzz.c
Normal file
55
tests/qtest/fuzz/fork_fuzz.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Fork-based fuzzing helpers
|
||||
*
|
||||
* Copyright Red Hat Inc., 2019
|
||||
*
|
||||
* Authors:
|
||||
* Alexander Bulekov <alxndr@bu.edu>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "fork_fuzz.h"
|
||||
|
||||
|
||||
void counter_shm_init(void)
|
||||
{
|
||||
char *shm_path = g_strdup_printf("/qemu-fuzz-cntrs.%d", getpid());
|
||||
int fd = shm_open(shm_path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
g_free(shm_path);
|
||||
|
||||
if (fd == -1) {
|
||||
perror("Error: ");
|
||||
exit(1);
|
||||
}
|
||||
if (ftruncate(fd, &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START) == -1) {
|
||||
perror("Error: ");
|
||||
exit(1);
|
||||
}
|
||||
/* Copy what's in the counter region to the shm.. */
|
||||
void *rptr = mmap(NULL ,
|
||||
&__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
memcpy(rptr,
|
||||
&__FUZZ_COUNTERS_START,
|
||||
&__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
|
||||
|
||||
munmap(rptr, &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
|
||||
|
||||
/* And map the shm over the counter region */
|
||||
rptr = mmap(&__FUZZ_COUNTERS_START,
|
||||
&__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (!rptr) {
|
||||
perror("Error: ");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue