From: Darren Kenny <darren.kenny@oracle.com>
To: Alexander Bulekov <alxndr@bu.edu>
Cc: Laurent Vivier <lvivier@redhat.com>,
Thomas Huth <thuth@redhat.com>,
qemu-devel@nongnu.org, bsd@redhat.com, stefanha@redhat.com,
pbonzini@redhat.com
Subject: Re: [PATCH v10 15/22] fuzz: support for fork-based fuzzing.
Date: Thu, 20 Feb 2020 10:34:38 +0000 [thread overview]
Message-ID: <20200220103438.3kjy7jchmnjvsop5@starbug-mbp> (raw)
In-Reply-To: <20200220041118.23264-16-alxndr@bu.edu>
On Wed, Feb 19, 2020 at 11:11:11PM -0500, Alexander Bulekov wrote:
>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>
>---
> tests/qtest/fuzz/Makefile.include | 5 +++
> tests/qtest/fuzz/fork_fuzz.c | 55 +++++++++++++++++++++++++++++++
> tests/qtest/fuzz/fork_fuzz.h | 23 +++++++++++++
> tests/qtest/fuzz/fork_fuzz.ld | 37 +++++++++++++++++++++
> 4 files changed, 120 insertions(+)
> create mode 100644 tests/qtest/fuzz/fork_fuzz.c
> create mode 100644 tests/qtest/fuzz/fork_fuzz.h
> create mode 100644 tests/qtest/fuzz/fork_fuzz.ld
>
>diff --git a/tests/qtest/fuzz/Makefile.include b/tests/qtest/fuzz/Makefile.include
>index 8632bb89f4..a90915d56d 100644
>--- a/tests/qtest/fuzz/Makefile.include
>+++ b/tests/qtest/fuzz/Makefile.include
>@@ -2,5 +2,10 @@ QEMU_PROG_FUZZ=qemu-fuzz-$(TARGET_NAME)$(EXESUF)
>
> fuzz-obj-y += tests/qtest/libqtest.o
> fuzz-obj-y += tests/qtest/fuzz/fuzz.o # Fuzzer skeleton
>+fuzz-obj-y += tests/qtest/fuzz/fork_fuzz.o
>
> FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
>+
>+# Linker Script to force coverage-counters into known regions which we can mark
>+# shared
>+FUZZ_LDFLAGS += -Xlinker -T$(SRC_PATH)/tests/qtest/fuzz/fork_fuzz.ld
>diff --git a/tests/qtest/fuzz/fork_fuzz.c b/tests/qtest/fuzz/fork_fuzz.c
>new file mode 100644
>index 0000000000..2bd0851903
>--- /dev/null
>+++ b/tests/qtest/fuzz/fork_fuzz.c
>@@ -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);
>+ }
>+}
>+
>+
>diff --git a/tests/qtest/fuzz/fork_fuzz.h b/tests/qtest/fuzz/fork_fuzz.h
>new file mode 100644
>index 0000000000..9ecb8b58ef
>--- /dev/null
>+++ b/tests/qtest/fuzz/fork_fuzz.h
>@@ -0,0 +1,23 @@
>+/*
>+ * 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.
>+ *
>+ */
>+
>+#ifndef FORK_FUZZ_H
>+#define FORK_FUZZ_H
>+
>+extern uint8_t __FUZZ_COUNTERS_START;
>+extern uint8_t __FUZZ_COUNTERS_END;
>+
>+void counter_shm_init(void);
>+
>+#endif
>+
>diff --git a/tests/qtest/fuzz/fork_fuzz.ld b/tests/qtest/fuzz/fork_fuzz.ld
>new file mode 100644
>index 0000000000..b23a59f194
>--- /dev/null
>+++ b/tests/qtest/fuzz/fork_fuzz.ld
>@@ -0,0 +1,37 @@
>+/* We adjust linker script modification to place all of the stuff that needs to
>+ * persist across fuzzing runs into a contiguous seciton of memory. Then, it is
>+ * easy to re-map the counter-related memory as shared.
>+*/
>+
>+SECTIONS
>+{
>+ .data.fuzz_start : ALIGN(4K)
>+ {
>+ __FUZZ_COUNTERS_START = .;
>+ __start___sancov_cntrs = .;
>+ *(_*sancov_cntrs);
>+ __stop___sancov_cntrs = .;
>+
>+ /* Lowest stack counter */
>+ *(__sancov_lowest_stack);
>+ }
>+ .data.fuzz_ordered :
>+ {
>+ /* Coverage counters. They're not necessary for fuzzing, but are useful
>+ * for analyzing the fuzzing performance
>+ */
>+ __start___llvm_prf_cnts = .;
>+ *(*llvm_prf_cnts);
>+ __stop___llvm_prf_cnts = .;
>+
>+ /* Internal Libfuzzer TracePC object which contains the ValueProfileMap */
>+ FuzzerTracePC*(.bss*);
>+ }
>+ .data.fuzz_end : ALIGN(4K)
>+ {
>+ __FUZZ_COUNTERS_END = .;
>+ }
>+}
>+/* Dont overwrite the SECTIONS in the default linker script. Instead insert the
>+ * above into the default script */
>+INSERT AFTER .data;
>--
>2.25.0
>
next prev parent reply other threads:[~2020-02-20 10:37 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-20 4:10 [PATCH v10 00/22] Add virtual device fuzzing support Alexander Bulekov
2020-02-20 4:10 ` [PATCH v10 01/22] softmmu: move vl.c to softmmu/ Alexander Bulekov
2020-02-20 10:33 ` Darren Kenny
2020-02-21 13:56 ` Stefan Hajnoczi
2020-02-20 4:10 ` [PATCH v10 02/22] softmmu: split off vl.c:main() into main.c Alexander Bulekov
2020-02-20 4:10 ` [PATCH v10 03/22] module: check module wasn't already initialized Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 04/22] fuzz: add FUZZ_TARGET module type Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 05/22] qtest: add qtest_server_send abstraction Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 06/22] libqtest: add a layer of abstraction to send/recv Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 07/22] libqtest: make bufwrite rely on the TransportOps Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 08/22] qtest: add in-process incoming command handler Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 09/22] libqos: rename i2c_send and i2c_recv Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 10/22] libqos: split qos-test and libqos makefile vars Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 11/22] libqos: move useful qos-test funcs to qos_external Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 12/22] fuzz: add fuzzer skeleton Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 13/22] exec: keep ram block across fork when using qtest Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 14/22] main: keep rcu_atfork callback enabled for qtest Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 15/22] fuzz: support for fork-based fuzzing Alexander Bulekov
2020-02-20 10:34 ` Darren Kenny [this message]
2020-02-20 4:11 ` [PATCH v10 16/22] fuzz: add support for qos-assisted fuzz targets Alexander Bulekov
2020-02-20 10:35 ` Darren Kenny
2020-02-20 4:11 ` [PATCH v10 17/22] fuzz: add target/fuzz makefile rules Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 18/22] fuzz: add configure flag --enable-fuzzing Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 19/22] fuzz: add i440fx fuzz targets Alexander Bulekov
2020-02-20 4:11 ` [PATCH v10 20/22] fuzz: add virtio-net fuzz target Alexander Bulekov
2020-02-20 10:35 ` Darren Kenny
2020-02-20 4:11 ` [PATCH v10 21/22] fuzz: add virtio-scsi " Alexander Bulekov
2020-02-20 10:38 ` Darren Kenny
2020-02-21 13:57 ` Stefan Hajnoczi
2020-02-20 4:11 ` [PATCH v10 22/22] fuzz: add documentation to docs/devel/ Alexander Bulekov
2020-02-21 15:17 ` [PATCH v10 00/22] Add virtual device fuzzing support Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200220103438.3kjy7jchmnjvsop5@starbug-mbp \
--to=darren.kenny@oracle.com \
--cc=alxndr@bu.edu \
--cc=bsd@redhat.com \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.