All of lore.kernel.org
 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 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.