qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alexander Oleinik <alxndr@bu.edu>
To: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Cc: "pbonzini@redhat.com" <pbonzini@redhat.com>,
	"bsd@redhat.com" <bsd@redhat.com>,
	"stefanha@redhat.com" <stefanha@redhat.com>,
	Richard Henderson <rth@twiddle.net>
Subject: Re: [PATCH v3 17/22] fuzz: add support for fork-based fuzzing.
Date: Mon, 30 Sep 2019 11:17:59 -0400	[thread overview]
Message-ID: <b8d441a3-dc3b-8c91-7516-3c8162cc5a4d@bu.edu> (raw)
In-Reply-To: <20190918231846.22538-18-alxndr@bu.edu>

On 9/18/19 7:19 PM, Oleinik, Alexander 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 there seems to be no simple way to re-map them as
> shared memory. As a workaround, we use a linker script modification to
> place all of the bitmaps together and add some markers around them which
> we can observe from our code. Then, we map shared memory and copy the
> bimaps to the SHM (in the child) and out of the SHM(in the parent) after
> each fuzzing run. Ram blocks are marked as DONTFORK in exec.c, which
> breaks this approach. For now, avoid this with an #ifdef.
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>   exec.c                      |  2 ++
>   tests/fuzz/Makefile.include |  3 +++
>   tests/fuzz/fork_fuzz.c      | 27 ++++++++++++++++++++++
>   tests/fuzz/fork_fuzz.h      | 12 ++++++++++
>   tests/fuzz/fork_fuzz.ld     | 46 +++++++++++++++++++++++++++++++++++++
>   5 files changed, 90 insertions(+)
>   create mode 100644 tests/fuzz/fork_fuzz.c
>   create mode 100644 tests/fuzz/fork_fuzz.h
>   create mode 100644 tests/fuzz/fork_fuzz.ld
> 
> diff --git a/exec.c b/exec.c
> index 235d6bc883..d3838f4ea4 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -2295,7 +2295,9 @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared)
>           qemu_ram_setup_dump(new_block->host, new_block->max_length);
>           qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE);
>           /* MADV_DONTFORK is also needed by KVM in absence of synchronous MMU */
> +#ifndef CONFIG_FUZZ /* This conflicts with fork-based fuzzing */
>           qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK);
> +#endif
>           ram_block_notify_add(new_block->host, new_block->max_length);
>       }
>   }
> diff --git a/tests/fuzz/Makefile.include b/tests/fuzz/Makefile.include
> index b415b056b0..687dacce04 100644
> --- a/tests/fuzz/Makefile.include
> +++ b/tests/fuzz/Makefile.include
> @@ -2,3 +2,6 @@ QEMU_PROG_FUZZ=qemu-fuzz-$(TARGET_NAME)$(EXESUF)
>   fuzz-obj-y = $(libqos-obj-y)
>   fuzz-obj-y += tests/libqtest.o
>   fuzz-obj-y += tests/fuzz/fuzz.o
> +fuzz-obj-y += tests/fuzz/fork_fuzz.o
> +
> +FUZZ_LDFLAGS += -Xlinker -T$(SRC_PATH)/tests/fuzz/fork_fuzz.ld
> diff --git a/tests/fuzz/fork_fuzz.c b/tests/fuzz/fork_fuzz.c
> new file mode 100644
> index 0000000000..26d0b4b42e
> --- /dev/null
> +++ b/tests/fuzz/fork_fuzz.c
> @@ -0,0 +1,27 @@
> +#include "qemu/osdep.h"
> +#include "fork_fuzz.h"
> +
> +uintptr_t feature_shm;
> +
> +void counter_shm_init(void)
> +{
> +    feature_shm = (uintptr_t)mmap(NULL,
> +            &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START,
> +            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
> +    return;
> +}
> +
> +void counter_shm_store(void)
> +{
> +    memcpy((void *)feature_shm,
> +            &__FUZZ_COUNTERS_START,
> +            &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
> +}
> +
> +void counter_shm_load(void)
> +{
> +    memcpy(&__FUZZ_COUNTERS_START,
> +            (void *)feature_shm,
> +            &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
> +}
> +
> diff --git a/tests/fuzz/fork_fuzz.h b/tests/fuzz/fork_fuzz.h
> new file mode 100644
> index 0000000000..b5f8b35015
> --- /dev/null
> +++ b/tests/fuzz/fork_fuzz.h
> @@ -0,0 +1,12 @@
> +#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);
> +void counter_shm_store(void);
> +void counter_shm_load(void);
> +
> +#endif
> +
> diff --git a/tests/fuzz/fork_fuzz.ld b/tests/fuzz/fork_fuzz.ld
> new file mode 100644
> index 0000000000..ba0ba79570
> --- /dev/null
> +++ b/tests/fuzz/fork_fuzz.ld
> @@ -0,0 +1,46 @@
> +/* 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 copy it to and from shared memory.
> + *
> + * Total Size : A5A00
> + * Sancov counters: B26F
> + * Coverage counters: 56D60
> + * TracePC Object: 43C00
> +*/
> +
> +SECTIONS
> +{
> +  .data.fuzz_start : ALIGN(4K)
> +  {
> +        __FUZZ_COUNTERS_START = .;
> +  }
> +  .data.fuzz_ordered :
> +  {
> +      /* Internal Libfuzzer TracePC object which contains the ValueProfileMap.
> +       * Not optimal that we have to copy the rest of the TracePC object.
> +       * */
> +      __start___sancov_cntrs = .;
> +      *(__sancov_cntrs*)
> +      __stop___sancov_cntrs = .;
> +  }
> +  .data.fuzz_unordered :
> +  {
> +      /* 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 = .;
> +
> +      /* Lowest stack counter */
> +      *(__sancov_lowest_stack);
> +      /* Internal Libfuzzer TracePC object which contains the ValueProfileMap.
> +       * Not optimal that we have to copy the rest of the TracePC object.
> +       * */
> +      *FuzzerTracePC*(.bss._ZN6fuzzer*)
> +      __FUZZ_COUNTERS_END = .;
> +  }
> +}
> +/* Dont overwrite the SECTIONS in the default linker script. Instead insert the
> + * above into the default script */
> +INSERT AFTER .data;
> 
The obvious issue with this are that we lose the threads created prior 
to fork(). Over the past days I've been coverage of existing virtio-net 
tests with and without fork(). With fork(), virtio_net_tx_bh doesn't get 
scheduled, and never runs. Could this be due to the missing RCU thread?
This is probably an even bigger problem for iothread devices, such as 
virtio-blk...

Does anyone have suggestions for how to approach the thread problem, or 
at least the RCU part of it?
I know Paolo made some fork-related changes in 
21b7cf9e07e5991c57b461181cfb5bbb6fe7a9d6 rcu: handle forks safely
and
2a96a552f9502ac34c29da2f3a39788db5ee5692 ,
but from what I can tell, this is mostly for qemu-user.

-Alex


  parent reply	other threads:[~2019-09-30 15:33 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-18 23:19 [Qemu-devel] [PATCH v3 00/22] Add virtual device fuzzing support Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 01/22] softmmu: split off vl.c:main() into main.c Oleinik, Alexander
2019-09-19 10:03   ` Stefan Hajnoczi
2019-09-19 13:01     ` Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 02/22] libqos: Rename i2c_send and i2c_recv Oleinik, Alexander
2019-09-19  6:01   ` Thomas Huth
2019-09-19 10:05   ` Stefan Hajnoczi
2019-09-19 11:15   ` Paolo Bonzini
2019-09-19 13:23     ` Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 03/22] fuzz: Add FUZZ_TARGET module type Oleinik, Alexander
2019-09-19 10:06   ` Stefan Hajnoczi
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 04/22] qtest: add qtest_server_send abstraction Oleinik, Alexander
2019-09-19 10:10   ` Stefan Hajnoczi
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 05/22] libqtest: Add a layer of abstraciton to send/recv Oleinik, Alexander
2019-09-19 10:24   ` Stefan Hajnoczi
2019-09-19 11:18   ` Paolo Bonzini
2019-09-19 13:27     ` Oleinik, Alexander
2019-09-19 14:27       ` Paolo Bonzini
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 06/22] fuzz: add configure flag --enable-fuzzing Oleinik, Alexander
2019-09-19 10:28   ` Stefan Hajnoczi
2019-09-19 13:07     ` Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 07/22] fuzz: Add target/fuzz makefile rules Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 08/22] module: check module wasn't already initialized Oleinik, Alexander
2019-09-19 10:30   ` Stefan Hajnoczi
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 09/22] qtest: add in-process incoming command handler Oleinik, Alexander
2019-09-19 10:31   ` Stefan Hajnoczi
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 10/22] tests: provide test variables to other targets Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 11/22] libqos: split qos-test and libqos makefile vars Oleinik, Alexander
2019-09-26 12:04   ` Thomas Huth
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 12/22] libqos: move useful qos-test funcs to qos_external Oleinik, Alexander
2019-09-19 10:34   ` Stefan Hajnoczi
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 13/22] libqtest: make qtest_bufwrite send "atomic" Oleinik, Alexander
2019-09-19 10:37   ` Stefan Hajnoczi
2019-09-19 18:56     ` John Snow
2019-09-19 19:36       ` Oleinik, Alexander
2019-09-20  0:49         ` John Snow
2019-09-19 19:50       ` Alexander Oleinik
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 14/22] libqtest: add in-process qtest.c tx/rx handlers Oleinik, Alexander
2019-09-19 10:42   ` Stefan Hajnoczi
2019-09-19 13:22     ` Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 15/22] fuzz: Add target/fuzz makefile rules Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 16/22] fuzz: add fuzzer skeleton Oleinik, Alexander
2019-09-19 12:48   ` Stefan Hajnoczi
2019-09-19 13:49     ` Oleinik, Alexander
2019-09-20  9:30       ` Stefan Hajnoczi
2019-09-23 14:55   ` Darren Kenny
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 17/22] fuzz: add support for fork-based fuzzing Oleinik, Alexander
2019-09-19 12:54   ` Stefan Hajnoczi
2019-09-19 14:01     ` Oleinik, Alexander
2019-09-20  9:33       ` Stefan Hajnoczi
2019-09-30 15:17   ` Alexander Oleinik [this message]
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 18/22] fuzz: expose fuzz target name Oleinik, Alexander
2019-09-24  7:49   ` Darren Kenny
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 19/22] fuzz: add support for qos-assisted fuzz targets Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 20/22] fuzz: add i440fx " Oleinik, Alexander
2019-09-19 13:08   ` Stefan Hajnoczi
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 21/22] fuzz: add virtio-net fuzz target Oleinik, Alexander
2019-09-18 23:19 ` [Qemu-devel] [PATCH v3 22/22] fuzz: add documentation to docs/devel/ Oleinik, Alexander
2019-09-23 14:54   ` Darren Kenny
2019-09-19 10:33 ` [Qemu-devel] [PATCH v3 00/22] Add virtual device fuzzing support Stefan Hajnoczi
2019-09-19 13:10 ` Stefan Hajnoczi
2019-09-20  0:19 ` no-reply
2019-09-20  0:19 ` no-reply
2019-09-20  0:21 ` no-reply
2019-09-20  0:24 ` no-reply

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=b8d441a3-dc3b-8c91-7516-3c8162cc5a4d@bu.edu \
    --to=alxndr@bu.edu \
    --cc=bsd@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=stefanha@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).