qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Darren Kenny <darren.kenny@oracle.com>
To: "Oleinik, Alexander" <alxndr@bu.edu>
Cc: "pbonzini@redhat.com" <pbonzini@redhat.com>,
	"bsd@redhat.com" <bsd@redhat.com>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	"stefanha@redhat.com" <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v3 22/22] fuzz: add documentation to docs/devel/
Date: Mon, 23 Sep 2019 15:54:33 +0100	[thread overview]
Message-ID: <20190923145433.xnpfmjfzaqvedltp@starbug-lenovo.ie.oracle.com> (raw)
In-Reply-To: <20190918231846.22538-23-alxndr@bu.edu>

Hi Alexander,

Some comments, and questions below...

On Wed, Sep 18, 2019 at 11:19:48PM +0000, Oleinik, Alexander wrote:
>Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
>---
> docs/devel/fuzzing.txt | 114 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 114 insertions(+)
> create mode 100644 docs/devel/fuzzing.txt
>
>diff --git a/docs/devel/fuzzing.txt b/docs/devel/fuzzing.txt
>new file mode 100644
>index 0000000000..53a1f858f5
>--- /dev/null
>+++ b/docs/devel/fuzzing.txt
>@@ -0,0 +1,114 @@
>+= Fuzzing =
>+
>+== Introduction ==
>+
>+This document describes the virtual-device fuzzing infrastructure in QEMU and
>+how to use it to implement additional fuzzers.
>+
>+== Basics ==
>+
>+Fuzzing operates by passing inputs to an entry point/target function. The
>+fuzzer tracks the code coverage triggered by the input. Based on these
>+findings, the fuzzer mutates the input and repeats the fuzzing.
>+
>+To fuzz QEMU, we rely on libfuzzer. Unlike other fuzzers such as AFL, libfuzzer
>+is an _in-process_ fuzzer. For the developer, this means that it is their
>+responsibility to ensure that state is reset between fuzzing-runs.
>+
>+== Building the fuzzers ==
>+
>+NOTE: If possible, build a 32-bit binary. When forking, the page map ends up
>+being much smaller. On 64-bit AddressSanitizer consumes 20 Terabytes of virtual
>+memory.

It might be worth having a little more on this, since I would
imagine most people would be more interested in 64-bit these days,
but are unlikely to have 20Tb available :)

But if there is little to be gained by the 64-bit vs 32-bit if
fuzzing a device, then it might be worth explaining why.

>+
>+To build the fuzzers, install a recent version of clang:
>+Configure with (substitute the clang binaries with the version you installed):
>+
>+    CC=clang-8 CXX=clang++-8 /path/to/configure --enable-fuzzing
>+
>+Fuzz targets are built similarily to system/softmmu:

Typo: s/similarily/similarly/

>+
>+    make i386-softmmu/fuzz
>+
>+This builds ./i386-softmmu/qemu-fuzz-i386

Reading this, it kind of implies that it should be also possible to
build i386-softmmu/all still - which from what I can see it isn't,
the build fails with an undefined 'main' - most likely the main.o
object is not being linked in for this target?

Unfortunately, also doing the above build command is also failing
for me after applying this set of patches:

  qemu-upstream-libfuzz/tests/fuzz/fuzz.c:149:28: error: expected expression
      fuzz_qts = qtest_setup(void);
                             ^
  1 error generated.
  make[1]: *** [tests/fuzz/fuzz.o] Error 1

This is due to the (void) in the calling of the function, will comment on the
patch separately.

>+
>+The first option to this command is: --FUZZER_NAME
>+To list all of the available fuzzers run qemu-fuzz-i386 with no arguments.
>+
>+Libfuzzer parses all arguments that do not begin with "--". Information about
>+these is available by passing -help=1
>+
>+Now the only thing left to do is wait for the fuzzer to trigger potential
>+crashes.

I would suggest adding an example of doing a run for this here.

>+
>+== Adding a new fuzzer ==
>+Coverage over virtual devices can be improved by adding additional fuzzers.
>+Fuzzers are kept in tests/fuzz/ and should be added to
>+tests/fuzz/Makefile.include
>+
>+Fuzzers can rely on both qtest and libqos to communicate with virtual devices.
>+
>+1. Create a new source file. For example ``tests/fuzz/fuzz-foo-device.c``.
>+
>+2. Write the fuzzing code using the libqtest/libqos API. See existing fuzzers
>+for reference.
>+
>+3. Register the fuzzer in ``tests/fuzz/Makefile.include`` by appending the
>+corresponding object to fuzz-obj-y
>+
>+Fuzzers can be more-or-less thought of as special qtest programs which can
>+modify the qtest commands and/or qtest command arguments based on inputs
>+provided by libfuzzer. Libfuzzer passes a byte array and length. Commonly the
>+fuzzer loops over the byte-array interpreting it as a list of qtest commands,
>+addresses, or values.
>+
>+
>+= Implmentation Details =
>+
>+== The Fuzzer's Lifecycle ==
>+
>+The fuzzer has two entrypoints that libfuzzer calls.
>+
>+LLVMFuzzerInitialize: called prior to fuzzing. Used to initialize all of the
>+necessary state
>+
>+LLVMFuzzerTestOneInput: called for each fuzzing run. Processes the input and
>+resets the state at the end of each run.

It might be worth explicitly mentioning that Libfuzzer provides it's
own main() function which calls these.

>+
>+In more detail:
>+
>+LLVMFuzzerInitialize parses the arguments to the fuzzer (must start with two
>+dashes, so they are ignored by libfuzzer main()). Currently, the arguments
>+select the fuzz target. Then, the qtest client is initialized. If the target
>+requires qos, qgraph is set up and the QOM/LIBQOS modules are initailized.
>+Then the QGraph is walked and the QEMU cmd_line is determined and saved.
>+
>+After this, the vl.c:real_main is called to set up the guest. After this, the
>+fuzzer saves the initial vm/device state to ram, after which the initilization
>+is complete.

Is this still true with this patchset? I don't see real_main being
defined any more in vl.c.

>+
>+LLVMFuzzerTestOneInput: Uses qtest/qos functions to act based on the fuzz
>+input. It is also responsible for manually calling the main loop/main_loop_wait
>+to ensure that bottom halves are executed. Finally, it calls reset() which
>+restores state from the ramfile and/or resets the guest.
>+
>+
>+Since the same process is reused for many fuzzing runs, QEMU state needs to
>+be reset at the end of each run. There are currently two implemented
>+options for resetting state:
>+1. Reboot the guest between runs.
>+   Pros: Straightforward and fast for simple fuzz targets.
>+   Cons: Depending on the device, does not reset all device state. If the
>+   device requires some initialization prior to being ready for fuzzing
>+   (common for QOS-based targets), this initialization needs to be done after
>+   each reboot.
>+   Example target: --virtio-net-ctrl-fuzz
>+2. Run each test case in a separate forked process and copy the coverage
>+   information back to the parent. This is fairly similar to AFL's "deferred"
>+   fork-server mode [3]
>+   Pros: Relatively fast. Devices only need to be initialized once. No need
>+   to do slow reboots or vmloads.
>+   Cons: Not officially supported by libfuzzer and the implementation is very
>+   flimsy. Does not work well for devices that rely on dedicated threads.
>+   Example target: --qtest-fork-fuzz
>+

Thanks,

Darren.



  reply	other threads:[~2019-09-23 14:58 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
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 [this message]
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=20190923145433.xnpfmjfzaqvedltp@starbug-lenovo.ie.oracle.com \
    --to=darren.kenny@oracle.com \
    --cc=alxndr@bu.edu \
    --cc=bsd@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --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).