qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support
@ 2019-07-25  3:23 Oleinik, Alexander
  2019-07-25  3:23 ` [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects Oleinik, Alexander
                   ` (21 more replies)
  0 siblings, 22 replies; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

As part of Google Summer of Code 2019, I'm working on integrating
fuzzing of virtual devices into QEMU [1]. This is a highly WIP patchset
adding this functionality.

Fuzzers provide random data to a program and monitor its execution for
errors. Coverage-guided fuzzers also observe the parts of the program
that are exercised by each input, and use this information to
mutate/guide the inputs to reach additional parts of the program. They
are quite effective for finding bugs in a wide range of software. 

Summary:
 - The virtual-device fuzzers use libfuzzer [2] for coverage-guided
   in-process fuzzing.
 - To fuzz a device, create a new fuzz "target" - i.e. a function that
   exercises QEMU based on inputs provided by the fuzzer.
 - Fuzz targets rely on qtest and libqos to turn inputs into actions.
 - Since libfuzzer does in-process fuzzing, the QEMU state needs to be
   reset after each fuzz run. These patches provide three methods for
   resetting state.
 - There are currently few targets, but they have already helped
   discover bugs in the console, and virtio-net, and have reproduced
   previously-reported vulnerabilities.

Here are some main implementation details:
 - The fuzzing occurs within a single process. QTest and QOS are
   modified so the QTest client and server coexist within the same
   process. They communicate with each other through direct function
   calls. Similar to qtest, the fuzzer uses a lightweight accelerator to
   skip CPU emulation. The fuzzing target is responsible for manually
   executing the main loop.
 - 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 three
   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. vmsave the state to RAM, once, and restore it after each run.
      Alternatively, only save the device state
      (savevm.c:qemu_save_device_state)
      Pros: Do not need to initialize devices prior to each run.
      VMStateDescriptions often specify more state than the device
      resetting functions called during reboots.
      Cons: Restoring state is often slower than rebooting. There is
      currently no way to save the QOS object state, so the objects
      usually needs to be re-allocated, defeating the purpose of
      one-time device initialization.
      Example target: --qtest-fuzz
   3. 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
 - Fuzz targets are registered using QEMU's module system, similar to
   QOS test cases. Base qtest targets are registed with fuzz_add_target
   and QOS-based targets with fuzz_add_qos_target.
 - There are two entry points for the fuzzer:
    LLVMFuzzerInitialize: Run once, prior to fuzzing. Here, we set up
   qtest/qos, register the fuzz targets and partially execute vl.c:main.
   This is also where we would take a snapshot, if using the vmsave
   approach to resetting.
    LLVMFuzzerTestOneInput: Run for each fuzzing input. This function is
   responsible for taking care of device initialization, calling the
   actual fuzz target, and resetting state at the end of each run.
   Both of these functions are defined in tests/fuzz/fuzz.c
 - There are many libfuzzer flags which should be used to configure the
   coverage metrics and storage of interesting fuzz inputs. [2] These
   flags can also be helpful in evaluating fuzzing performance through
   metrics such as inputs/seconds and line-coverage.

Here are some key issues with the current state of the code:
 - The patches change vl.c, main-loop.c, qtest.c, tests/libqtest.c,
   savevm.c, memory.c. I wrapped the changes with #ifdef CONFIG_FUZZ,
   but many of these changes can and should be avoided.
 - tests/fuzz/qos_helpers.c is largely a copy of tests/qos-test.c.
 - The fuzzer is not properly integrated into the build system.
   Currently I simply added all of the necessary objects to
   target/i386/Makefile.objs, but there should be a simple way to build
   for other arches. The binary needs to be linked against libqemuutil,
   libqtest, qos and the qos objects, and the requirements for softmmu
   targets.
 - Some of the fuzz targets leak memory during state-resetting that need
   to be tracked down and fixed. 
 - As mentioned already, running each test in a separate process does
   not seem to be supported by libfuzzer, and the implementation
   reflects this (tests/fuzz/fuzzer_hooks.c)
 - The existing fuzz targets should be cleaned up as they have issues
   with memory alignment and contain redundant checks. The should also
   use qtest's clock_step. The fork fuzz targets are dependant on
   a hard-coded section size.

Building and running:
Libfuzzer requires clang.
  $ CC=clang-7 CXX=clang++-7 ./configure --enable-fuzzing
  $ make i386-softmmu/all
  $ i386-softmmu/qemu-system-i386 --qtest-dma-fuzz -detect_leaks=0

Here "qtest-dma-fuzz" is the fuzz target name. Running qemu-system-i386
without any arguments should print all of the available fuzz targets.
The -help=1 command prints out the available libfuzzer options.

There are more details, including instructions for adding new fuzz
targets in docs/devel/fuzzing.txt

In the coming weeks I would like to fix the issues listed above, more
fuzzing targets, and ideally work on getting QEMU into oss-fuzz[4],
where it can be fuzzed continuously.

I appreciate any feedback. Thanks
-Alex

[1] https://wiki.qemu.org/Internships/ProjectIdeas/QtestOssFuzz
[2] Trophy Case section: http://lcamtuf.coredump.cx/afl/
[3] https://llvm.org/docs/LibFuzzer.html
[4] https://github.com/mirrorer/afl/blob/master/llvm_mode/README.llvm#L82
[5] https://github.com/google/oss-fuzz


Alexander Oleinik (19):
  fuzz: add configure option and linker objects
  fuzz: add FUZZ_TARGET type to qemu module system
  fuzz: add fuzz accelerator
  fuzz: Add qos support to fuzz targets
  fuzz: expose qemu_savevm_state & skip state header
  fuzz: Add ramfile for fast vmstate/vmload
  fuzz: Modify libqtest to directly invoke qtest.c
  fuzz: add shims to intercept libfuzzer init
  fuzz: use mtree_info to find mapped addresses
  fuzz: expose real_main (aka regular vl.c:main)
  fuzz: add direct send/receive in qtest client
  fuzz: hard-code all of the needed files for build
  fuzz: add ctrl vq support to virtio-net in libqos
  fuzz: hard-code a main-loop timeout
  fuzz: add fuzz accelerator type
  fuzz: add general fuzzer entrypoints
  fuzz: add general qtest fuzz target
  fuzz: Add virtio-net tx and ctrl fuzz targets
  fuzz: Add documentation about the fuzzer to docs/

 accel/fuzz.c                 |  47 ++++++
 configure                    |  11 ++
 docs/devel/fuzzing.txt       | 145 +++++++++++++++++
 include/qemu/module.h        |   7 +-
 include/sysemu/fuzz.h        |  15 ++
 include/sysemu/qtest.h       |   7 +-
 include/sysemu/sysemu.h      |   4 +
 memory.c                     |  34 ++++
 migration/savevm.c           |   8 +-
 migration/savevm.h           |   3 +
 qtest.c                      |  19 ++-
 target/i386/Makefile.objs    |  19 +++
 tests/fuzz/fuzz.c            | 262 +++++++++++++++++++++++++++++++
 tests/fuzz/fuzz.h            |  96 ++++++++++++
 tests/fuzz/fuzzer_hooks.c    | 106 +++++++++++++
 tests/fuzz/fuzzer_hooks.h    |   9 ++
 tests/fuzz/qos_fuzz.c        |  63 ++++++++
 tests/fuzz/qos_fuzz.h        |  29 ++++
 tests/fuzz/qos_helpers.c     | 295 +++++++++++++++++++++++++++++++++++
 tests/fuzz/qos_helpers.h     |  17 ++
 tests/fuzz/qtest_fuzz.c      | 261 +++++++++++++++++++++++++++++++
 tests/fuzz/qtest_fuzz.h      |  38 +++++
 tests/fuzz/ramfile.c         | 127 +++++++++++++++
 tests/fuzz/ramfile.h         |  20 +++
 tests/fuzz/virtio-net-fuzz.c | 226 +++++++++++++++++++++++++++
 tests/libqos/virtio-net.c    |   2 +-
 tests/libqtest.c             |  53 ++++++-
 tests/libqtest.h             |   6 +
 util/main-loop.c             |   3 +
 vl.c                         |  21 ++-
 30 files changed, 1945 insertions(+), 8 deletions(-)
 create mode 100644 accel/fuzz.c
 create mode 100644 docs/devel/fuzzing.txt
 create mode 100644 include/sysemu/fuzz.h
 create mode 100644 tests/fuzz/fuzz.c
 create mode 100644 tests/fuzz/fuzz.h
 create mode 100644 tests/fuzz/fuzzer_hooks.c
 create mode 100644 tests/fuzz/fuzzer_hooks.h
 create mode 100644 tests/fuzz/qos_fuzz.c
 create mode 100644 tests/fuzz/qos_fuzz.h
 create mode 100644 tests/fuzz/qos_helpers.c
 create mode 100644 tests/fuzz/qos_helpers.h
 create mode 100644 tests/fuzz/qtest_fuzz.c
 create mode 100644 tests/fuzz/qtest_fuzz.h
 create mode 100644 tests/fuzz/ramfile.c
 create mode 100644 tests/fuzz/ramfile.h
 create mode 100644 tests/fuzz/virtio-net-fuzz.c

-- 
2.20.1



^ permalink raw reply	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  9:39   ` Paolo Bonzini
  2019-07-25  3:23 ` [Qemu-devel] [RFC 02/19] fuzz: add FUZZ_TARGET type to qemu module system Oleinik, Alexander
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, Oleinik, Alexander, bsd, superirishdonkey,
	stefanha, pbonzini, Richard Henderson

Add -Wl,--wraps for the libfuzzer callees that we need to intercept

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 configure                 | 11 +++++++++++
 target/i386/Makefile.objs | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/configure b/configure
index 714e7fb6a1..0a40e77053 100755
--- a/configure
+++ b/configure
@@ -499,6 +499,7 @@ docker="no"
 debug_mutex="no"
 libpmem=""
 default_devices="yes"
+fuzzing="no"
 
 # cross compilers defaults, can be overridden with --cross-cc-ARCH
 cross_cc_aarch64="aarch64-linux-gnu-gcc"
@@ -1543,6 +1544,8 @@ for opt do
   ;;
   --disable-libpmem) libpmem=no
   ;;
+  --enable-fuzzing) fuzzing=yes
+  ;;
   *)
       echo "ERROR: unknown option $opt"
       echo "Try '$0 --help' for more information"
@@ -6481,6 +6484,7 @@ echo "docker            $docker"
 echo "libpmem support   $libpmem"
 echo "libudev           $libudev"
 echo "default devices   $default_devices"
+echo "fuzzing support   $fuzzing"
 
 if test "$supported_cpu" = "no"; then
     echo
@@ -7306,6 +7310,13 @@ fi
 if test "$sheepdog" = "yes" ; then
   echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
 fi
+if test "$fuzzing" = "yes" ; then
+  QEMU_CFLAGS="$QEMU_CFLAGS -fsanitize=fuzzer,address  -fprofile-instr-generate"
+  QEMU_INCLUDES="-iquote \$(SRC_PATH)/tests $QEMU_INCLUDES"
+  QEMU_LDFLAGS="$LDFLAGS -fsanitize=fuzzer,address"
+  QEMU_LDFLAGS="$LDFLAGS -Wl,--wrap=__sanitizer_cov_8bit_counters_init,--wrap=__sanitizer_cov_trace_pc_guard_init "
+  echo "CONFIG_FUZZ=y" >> $config_host_mak
+fi
 
 if test "$tcg_interpreter" = "yes"; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index 48e0c28434..3d646848ef 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -18,5 +18,24 @@ endif
 obj-$(CONFIG_HVF) += hvf/
 obj-$(CONFIG_WHPX) += whpx-all.o
 endif
+
+# Need to link against target, qtest and qos.. Just list everything here, until
+# I find a better way to integrate into the build system
+ifeq ($(CONFIG_FUZZ),y)
+obj-$(CONFIG_FUZZ) += ../../tests/fuzz/ramfile.o ../../accel/fuzz.o
+obj-$(CONFIG_FUZZ) += ../../tests/fuzz/fuzz.o
+obj-$(CONFIG_FUZZ) += ../../tests/fuzz/virtio-net-fuzz.o 
+obj-$(CONFIG_FUZZ) += ../../tests/fuzz/qtest_fuzz.o
+obj-$(CONFIG_FUZZ) += ../../tests/libqtest.o
+obj-$(CONFIG_FUZZ) += ../../tests/libqos/qgraph.o ../../tests/libqos/libqos.o 
+obj-$(CONFIG_FUZZ) += ../../tests/fuzz/qos_fuzz.o ../../tests/fuzz/qos_helpers.o
+obj-$(CONFIG_FUZZ) +=  ../../tests/libqos/malloc.o ../../tests/libqos/pci-pc.o \
+	../../tests/libqos/virtio-pci.o ../../tests/libqos/malloc-pc.o \
+	../../tests/libqos/libqos-pc.o ../../tests/libqos/fw_cfg.o \
+	../../tests/libqos/e1000e.o ../../tests/libqos/pci.o \
+	../../tests/libqos/pci-pc.o ../../tests/libqos/virtio.o \
+	../../tests/libqos/virtio-net.o ../../tests/libqos/x86_64_pc-machine.o
+endif
+
 obj-$(CONFIG_SEV) += sev.o
 obj-$(call lnot,$(CONFIG_SEV)) += sev-stub.o
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 02/19] fuzz: add FUZZ_TARGET type to qemu module system
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
  2019-07-25  3:23 ` [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-26 12:32   ` Stefan Hajnoczi
  2019-07-25  3:23 ` [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator Oleinik, Alexander
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 include/qemu/module.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/qemu/module.h b/include/qemu/module.h
index db3065381d..531fe7ae29 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -46,6 +46,9 @@ typedef enum {
     MODULE_INIT_TRACE,
     MODULE_INIT_XEN_BACKEND,
     MODULE_INIT_LIBQOS,
+#ifdef CONFIG_FUZZ
+    MODULE_INIT_FUZZ_TARGET,
+#endif
     MODULE_INIT_MAX
 } module_init_type;
 
@@ -56,7 +59,9 @@ typedef enum {
 #define xen_backend_init(function) module_init(function, \
                                                MODULE_INIT_XEN_BACKEND)
 #define libqos_init(function) module_init(function, MODULE_INIT_LIBQOS)
-
+#ifdef CONFIG_FUZZ
+#define fuzz_target_init(function) module_init(function, MODULE_INIT_FUZZ_TARGET)
+#endif
 #define block_module_load_one(lib) module_load_one("block-", lib)
 #define ui_module_load_one(lib) module_load_one("ui-", lib)
 #define audio_module_load_one(lib) module_load_one("audio-", lib)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
  2019-07-25  3:23 ` [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects Oleinik, Alexander
  2019-07-25  3:23 ` [Qemu-devel] [RFC 02/19] fuzz: add FUZZ_TARGET type to qemu module system Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-26 10:33   ` Paolo Bonzini
  2019-07-26 12:35   ` Stefan Hajnoczi
  2019-07-25  3:23 ` [Qemu-devel] [RFC 04/19] fuzz: Add qos support to fuzz targets Oleinik, Alexander
                   ` (18 subsequent siblings)
  21 siblings, 2 replies; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Much like the qtest accelerator, the fuzz accelerator skips the CPU
emulation

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 include/sysemu/qtest.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index cd114b8d80..adfbd10d20 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -23,7 +23,12 @@ static inline bool qtest_enabled(void)
 }
 
 bool qtest_driver(void);
-
+#ifdef CONFIG_FUZZ
+/* Both the client and the server have qtest_init's, Rename on of them... */
+void qtest_init_server(const char *qtest_chrdev, const char *qtest_log, Error **errp);
+void qtest_server_recv(GString *inbuf); /* Client sends commands using this */
+#else
 void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
+#endif
 
 #endif
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 04/19] fuzz: Add qos support to fuzz targets
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (2 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-26 10:39   ` Paolo Bonzini
  2019-07-25  3:23 ` [Qemu-devel] [RFC 05/19] fuzz: expose qemu_savevm_state & skip state header Oleinik, Alexander
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

qos_helpers.c is largely a copy of tests/qos-test.c

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/fuzz/qos_fuzz.c    |  63 +++++++++
 tests/fuzz/qos_fuzz.h    |  29 ++++
 tests/fuzz/qos_helpers.c | 295 +++++++++++++++++++++++++++++++++++++++
 tests/fuzz/qos_helpers.h |  17 +++
 4 files changed, 404 insertions(+)
 create mode 100644 tests/fuzz/qos_fuzz.c
 create mode 100644 tests/fuzz/qos_fuzz.h
 create mode 100644 tests/fuzz/qos_helpers.c
 create mode 100644 tests/fuzz/qos_helpers.h

diff --git a/tests/fuzz/qos_fuzz.c b/tests/fuzz/qos_fuzz.c
new file mode 100644
index 0000000000..ac7bb735ac
--- /dev/null
+++ b/tests/fuzz/qos_fuzz.c
@@ -0,0 +1,63 @@
+
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+
+#include "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "libqos/qgraph_internal.h"
+
+#include "hw/virtio/virtio-net.h"
+#include "hw/virtio/virtio.h"
+#include "libqos/virtio-net.h"
+#include "fuzz.h"
+#include "qos_fuzz.h"
+#include "qos_helpers.h"
+#include "tests/libqos/qgraph.h"
+#include "tests/libqtest.h"
+
+
+fuzz_memory_region *fuzz_memory_region_head;
+fuzz_memory_region *fuzz_memory_region_tail;
+
+uint64_t total_io_mem = 0;
+uint64_t total_ram_mem = 0;
+
+
+//TODO: Put arguments in a neater struct
+void fuzz_add_qos_target(const char* name,
+		const char* description,
+		const char* interface,
+		QOSGraphTestOptions* opts,
+		void(*init_pre_main)(void),
+		void(*init_pre_save)(void),
+		void(*save_state)(void),
+		void(*reset)(void),
+		void(*pre_fuzz)(void),
+		void(*fuzz)(const unsigned char*, size_t),
+		void(*post_fuzz)(void))
+{
+	qos_add_test(name, interface, NULL, opts);
+	fuzz_add_target(name, description, init_pre_main, init_pre_save,
+			save_state, reset, pre_fuzz, fuzz, post_fuzz, &qos_argc, &qos_argv);
+}
+
+
+// Do what is normally done in qos_test.c:main
+void qos_setup(void){
+	qtest_setup();
+	qos_set_machines_devices_available();
+	qos_graph_foreach_test_path(walk_path);
+	qos_build_main_args();
+}
+
+void qos_init_path(void)
+{
+	qos_obj = qos_allocate_objects(global_qtest, &qos_alloc);
+}
diff --git a/tests/fuzz/qos_fuzz.h b/tests/fuzz/qos_fuzz.h
new file mode 100644
index 0000000000..098f81f570
--- /dev/null
+++ b/tests/fuzz/qos_fuzz.h
@@ -0,0 +1,29 @@
+#ifndef _QOS_FUZZ_H_
+#define _QOS_FUZZ_H_
+
+#include "tests/libqos/qgraph.h"
+
+int qos_fuzz(const unsigned char *Data, size_t Size);
+void qos_setup(void);
+
+extern char **fuzz_path_vec;
+extern int qos_argc;
+extern char **qos_argv;
+extern void* qos_obj;
+extern QGuestAllocator *qos_alloc;
+
+
+void fuzz_add_qos_target(const char* name,
+		const char* description,
+		const char* interface,
+		QOSGraphTestOptions* opts,
+		void(*init_pre_main)(void),
+		void(*init_pre_save)(void),
+		void(*save_state)(void),
+		void(*reset)(void),
+		void(*pre_fuzz)(void),
+		void(*fuzz)(const unsigned char*, size_t),
+		void(*post_fuzz)(void));
+
+void qos_init_path(void);
+#endif
diff --git a/tests/fuzz/qos_helpers.c b/tests/fuzz/qos_helpers.c
new file mode 100644
index 0000000000..79523c0552
--- /dev/null
+++ b/tests/fuzz/qos_helpers.c
@@ -0,0 +1,295 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qos_helpers.h"
+#include "fuzz.h"
+#include "qapi/qmp/qlist.h"
+#include "libqtest.h"
+#include "sysemu/qtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/qgraph_internal.h"
+#include "./qapi/qapi-commands-machine.h"
+#include "./qapi/qapi-commands-misc.h"
+#include "./qapi/qapi-commands-qom.h"
+#include <wordexp.h>
+#include "sysemu/sysemu.h"
+#include "sysemu/cpus.h"
+
+
+/* 
+ * This file is almost completely copied from tests/qos-test.c
+ * TODO: Find a way to re-use the code in tests/qos-test.c
+ */
+
+static void apply_to_node(const char *name, bool is_machine, bool is_abstract)
+{
+    char *machine_name = NULL;
+    if (is_machine) {
+        const char *arch = qtest_get_arch();
+        machine_name = g_strconcat(arch, "/", name, NULL);
+        name = machine_name;
+    }
+    qos_graph_node_set_availability(name, true);
+    if (is_abstract) {
+        qos_delete_cmd_line(name);
+    }
+    g_free(machine_name);
+}
+
+static void apply_to_qlist(QList *list, bool is_machine)
+{
+    const QListEntry *p;
+    const char *name;
+    bool abstract;
+    QDict *minfo;
+    QObject *qobj;
+    QString *qstr;
+    QBool *qbool;
+
+    for (p = qlist_first(list); p; p = qlist_next(p)) {
+        minfo = qobject_to(QDict, qlist_entry_obj(p));
+        qobj = qdict_get(minfo, "name");
+        qstr = qobject_to(QString, qobj);
+        name = qstring_get_str(qstr);
+
+        qobj = qdict_get(minfo, "abstract");
+        if (qobj) {
+            qbool = qobject_to(QBool, qobj);
+            abstract = qbool_get_bool(qbool);
+        } else {
+            abstract = false;
+        }
+
+        apply_to_node(name, is_machine, abstract);
+        qobj = qdict_get(minfo, "alias");
+        if (qobj) {
+            qstr = qobject_to(QString, qobj);
+            name = qstring_get_str(qstr);
+            apply_to_node(name, is_machine, abstract);
+        }
+    }
+}
+
+
+/*
+ * Replaced the qmp commands with direct qmp_marshal calls.
+ * Probably there is a better way to do this
+ */
+void qos_set_machines_devices_available(void)
+{
+    QDict *req = qdict_new();
+    QObject *response;
+    QDict *args = qdict_new();
+    QList *lst;
+    Error *err =NULL; 
+
+    qmp_marshal_query_machines(NULL,&response, &err);
+    assert(!err);
+    lst = qobject_to(QList, response);
+    apply_to_qlist(lst, true);
+
+    qobject_unref(response);
+
+
+    qdict_put_str(req, "execute", "qom-list-types" );
+    qdict_put_str(args, "implements", "device" );
+    qdict_put_bool(args, "abstract", true);
+    qdict_put_obj(req, "arguments", (QObject*) args);
+
+    qmp_marshal_qom_list_types(args, &response, &err);
+    assert(!err);
+    lst = qobject_to(QList, response);
+    apply_to_qlist(lst, false);
+    qobject_unref(response);
+    qobject_unref(req);
+}
+
+static char **current_path;
+
+static QGuestAllocator *get_machine_allocator(QOSGraphObject *obj)
+{
+    return obj->get_driver(obj, "memory");
+}
+
+void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc)
+{
+    return allocate_objects(qts, current_path + 1, p_alloc);
+}
+
+void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc)
+{
+    int current = 0;
+    QGuestAllocator *alloc;
+    QOSGraphObject *parent = NULL;
+    QOSGraphEdge *edge;
+    QOSGraphNode *node;
+    void *edge_arg;
+    void *obj;
+
+    node = qos_graph_get_node(path[current]);
+    g_assert(node->type == QNODE_MACHINE);
+
+    obj = qos_machine_new(node, qts);
+    qos_object_queue_destroy(obj);
+
+    alloc = get_machine_allocator(obj);
+    if (p_alloc) {
+        *p_alloc = alloc;
+    }
+
+    for (;;) {
+        if (node->type != QNODE_INTERFACE) {
+            qos_object_start_hw(obj);
+            parent = obj;
+        }
+
+        /* follow edge and get object for next node constructor */
+        current++;
+        edge = qos_graph_get_edge(path[current - 1], path[current]);
+        node = qos_graph_get_node(path[current]);
+
+        if (node->type == QNODE_TEST) {
+            g_assert(qos_graph_edge_get_type(edge) == QEDGE_CONSUMED_BY);
+            return obj;
+        }
+
+        switch (qos_graph_edge_get_type(edge)) {
+            case QEDGE_PRODUCES:
+                obj = parent->get_driver(parent, path[current]);
+                break;
+
+            case QEDGE_CONSUMED_BY:
+                edge_arg = qos_graph_edge_get_arg(edge);
+                obj = qos_driver_new(node, obj, alloc, edge_arg);
+                qos_object_queue_destroy(obj);
+                break;
+
+            case QEDGE_CONTAINS:
+                obj = parent->get_device(parent, path[current]);
+                break;
+        }
+    }
+}
+
+char **fuzz_path_vec;
+void* qos_obj;
+QGuestAllocator *qos_alloc;
+
+int qos_argc;
+char **qos_argv;
+
+void qos_build_main_args()
+{
+    char **path = fuzz_path_vec;
+    QOSGraphNode *test_node;
+    GString *cmd_line = g_string_new(path[0]);
+    void *test_arg;
+
+    /* Before test */
+    current_path = path;
+    test_node = qos_graph_get_node(path[(g_strv_length(path) - 1)]);
+    test_arg = test_node->u.test.arg;
+    if (test_node->u.test.before) {
+        test_arg = test_node->u.test.before(cmd_line, test_arg);
+    }
+
+    /* Prepend the arguments that we need */
+    g_string_prepend(cmd_line, "qemu-system-i386 -display none -machine accel=fuzz -m 3 ");
+    wordexp_t result;
+    wordexp (cmd_line->str, &result, 0);
+    qos_argc = result.we_wordc;
+    qos_argv = result.we_wordv;
+
+    g_string_free(cmd_line, true);
+}
+
+
+void walk_path(QOSGraphNode *orig_path, int len)
+{
+    QOSGraphNode *path;
+    QOSGraphEdge *edge;
+
+    /* etype set to QEDGE_CONSUMED_BY so that machine can add to the command line */
+    QOSEdgeType etype = QEDGE_CONSUMED_BY;
+
+    /* twice QOS_PATH_MAX_ELEMENT_SIZE since each edge can have its arg */
+    char **path_vec = g_new0(char *, (QOS_PATH_MAX_ELEMENT_SIZE * 2));
+    int path_vec_size = 0;
+
+    char *after_cmd, *before_cmd, *after_device;
+    GString *after_device_str = g_string_new("");
+    char *node_name = orig_path->name, *path_str;
+
+    GString *cmd_line = g_string_new("");
+    GString *cmd_line2 = g_string_new("");
+
+    path = qos_graph_get_node(node_name); /* root */
+    node_name = qos_graph_edge_get_dest(path->path_edge); /* machine name */
+
+    path_vec[path_vec_size++] = node_name;
+    path_vec[path_vec_size++] = qos_get_machine_type(node_name);
+
+    for (;;) {
+        path = qos_graph_get_node(node_name);
+        if (!path->path_edge) {
+            break;
+        }
+
+        node_name = qos_graph_edge_get_dest(path->path_edge);
+
+        /* append node command line + previous edge command line */
+        if (path->command_line && etype == QEDGE_CONSUMED_BY) {
+            g_string_append(cmd_line, path->command_line);
+            g_string_append(cmd_line, after_device_str->str);
+            g_string_truncate(after_device_str, 0);
+        }
+
+        path_vec[path_vec_size++] = qos_graph_edge_get_name(path->path_edge);
+        /* detect if edge has command line args */
+        after_cmd = qos_graph_edge_get_after_cmd_line(path->path_edge);
+        after_device = qos_graph_edge_get_extra_device_opts(path->path_edge);
+        before_cmd = qos_graph_edge_get_before_cmd_line(path->path_edge);
+        edge = qos_graph_get_edge(path->name, node_name);
+        etype = qos_graph_edge_get_type(edge);
+
+        if (before_cmd) {
+            g_string_append(cmd_line, before_cmd);
+        }
+        if (after_cmd) {
+            g_string_append(cmd_line2, after_cmd);
+        }
+        if (after_device) {
+            g_string_append(after_device_str, after_device);
+        }
+    }
+
+    path_vec[path_vec_size++] = NULL;
+    g_string_append(cmd_line, after_device_str->str);
+    g_string_free(after_device_str, true);
+
+    g_string_append(cmd_line, cmd_line2->str);
+    g_string_free(cmd_line2, true);
+
+    /* here position 0 has <arch>/<machine>, position 1 has <machine>.
+     * The path must not have the <arch>, qtest_add_data_func adds it.
+     */
+    path_str = g_strjoinv("/", path_vec + 1);
+
+    // Check that this is the test we care about:
+    char *test_name = strrchr(path_str, '/')+1;
+    if(strcmp(test_name, fuzz_target->name->str) == 0)
+    {
+        /* put arch/machine in position 1 so run_one_test can do its work
+         * and add the command line at position 0.
+         */
+        path_vec[1] = path_vec[0];
+        path_vec[0] = g_string_free(cmd_line, false);
+        printf("path_str: %s path_vec[0]: %s [1]: %s\n", path_str, path_vec[0], path_vec[1]);
+
+        fuzz_path_vec = path_vec;
+    } 
+    else {
+        g_free(path_vec);
+    }
+
+    g_free(path_str);
+}
diff --git a/tests/fuzz/qos_helpers.h b/tests/fuzz/qos_helpers.h
new file mode 100644
index 0000000000..baf9b49e9c
--- /dev/null
+++ b/tests/fuzz/qos_helpers.h
@@ -0,0 +1,17 @@
+#ifndef QOS_HELPERS_H
+#define QOS_HELPERS_H
+
+#include "qemu/osdep.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qstring.h"
+#include "libqtest.h"
+#include "qapi/qmp/qlist.h"
+#include "libqos/qgraph_internal.h"
+
+
+void qos_set_machines_devices_available(void);
+void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc);
+void walk_path(QOSGraphNode *orig_path, int len);
+void qos_build_main_args(void);
+#endif
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 05/19] fuzz: expose qemu_savevm_state & skip state header
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (3 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 04/19] fuzz: Add qos support to fuzz targets Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25 13:22   ` Dr. David Alan Gilbert
  2019-07-25  3:23 ` [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c Oleinik, Alexander
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Juan Quintela, Dr. David Alan Gilbert, Oleinik, Alexander, bsd,
	superirishdonkey, stefanha, pbonzini

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 migration/savevm.c | 8 ++++++--
 migration/savevm.h | 3 +++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 79ed44d475..80c00ea560 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1404,8 +1404,11 @@ void qemu_savevm_state_cleanup(void)
         }
     }
 }
-
+#ifdef CONFIG_FUZZ
+int qemu_savevm_state(QEMUFile *f, Error **errp)
+#else
 static int qemu_savevm_state(QEMUFile *f, Error **errp)
+#endif
 {
     int ret;
     MigrationState *ms = migrate_get_current();
@@ -1471,11 +1474,12 @@ void qemu_savevm_live_state(QEMUFile *f)
 int qemu_save_device_state(QEMUFile *f)
 {
     SaveStateEntry *se;
-
+#ifndef CONFIG_FUZZ
     if (!migration_in_colo_state()) {
         qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
         qemu_put_be32(f, QEMU_VM_FILE_VERSION);
     }
+#endif
     cpu_synchronize_all_states();
 
     QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
diff --git a/migration/savevm.h b/migration/savevm.h
index 51a4b9caa8..30315d0cfd 100644
--- a/migration/savevm.h
+++ b/migration/savevm.h
@@ -64,4 +64,7 @@ void qemu_loadvm_state_cleanup(void);
 int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis);
 int qemu_load_device_state(QEMUFile *f);
 
+#ifdef CONFIG_FUZZ
+int qemu_savevm_state(QEMUFile *f, Error **errp);
+#endif
 #endif
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (5 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-26 12:47   ` Stefan Hajnoczi
  2019-07-25  3:23 ` [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init Oleinik, Alexander
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

The ramfile allows vmstate to be saved and restored directly onto the
heap.

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/fuzz/ramfile.c | 127 +++++++++++++++++++++++++++++++++++++++++++
 tests/fuzz/ramfile.h |  20 +++++++
 2 files changed, 147 insertions(+)
 create mode 100644 tests/fuzz/ramfile.c
 create mode 100644 tests/fuzz/ramfile.h

diff --git a/tests/fuzz/ramfile.c b/tests/fuzz/ramfile.c
new file mode 100644
index 0000000000..8da242e9ee
--- /dev/null
+++ b/tests/fuzz/ramfile.c
@@ -0,0 +1,127 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ramfile.c
+ *
+ *    Description:  QEMUFile stored in dynamically allocated RAM for fast VMRestore
+ *
+ *         Author:  Alexander Oleinik (), alxndr@bu.edu
+ *   Organization:  
+ *
+ * =====================================================================================
+ */
+#include <stdlib.h>
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "exec/memory.h"
+#include "migration/qemu-file.h"
+#include "migration/migration.h"
+#include "migration/savevm.h"
+#include "ramfile.h"
+
+#define INCREMENT 10240
+#define IO_BUF_SIZE 32768
+#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
+
+struct QEMUFile {
+    const QEMUFileOps *ops;
+    const QEMUFileHooks *hooks;
+    void *opaque;
+
+    int64_t bytes_xfer;
+    int64_t xfer_limit;
+
+    int64_t pos; /* start of buffer when writing, end of buffer
+                    when reading */
+    int buf_index;
+    int buf_size; /* 0 when writing */
+    uint8_t buf[IO_BUF_SIZE];
+
+    DECLARE_BITMAP(may_free, MAX_IOV_SIZE);
+    struct iovec iov[MAX_IOV_SIZE];
+    unsigned int iovcnt;
+
+    int last_error;
+};
+
+static ssize_t ram_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+                                  int64_t pos)
+{
+	ram_disk *rd = (ram_disk*)opaque;
+	gsize newsize;
+	ssize_t total_size = 0;
+	int i;
+	if(!rd->base) {
+		rd->base = g_malloc(INCREMENT);
+		rd->len = INCREMENT;
+	}
+	for(i = 0; i< iovcnt; i++)
+	{
+		if(pos+iov[i].iov_len >= rd->len ){
+			newsize = ((pos + iov[i].iov_len)/INCREMENT + 1) * INCREMENT;
+			rd->base = g_realloc(rd->base, newsize);
+			rd->len = newsize;
+		}
+		/* for(int j =0; j<iov[i].iov_len; j++){ */
+		/* 	printf("%hhx",*((char*)iov[i].iov_base+j)); */
+		/* } */
+		memcpy(rd->base + pos, iov[i].iov_base, iov[i].iov_len);
+		pos += iov[i].iov_len;
+		total_size += iov[i].iov_len;
+	}
+	return total_size;
+}
+
+static ssize_t ram_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
+                                   size_t size)
+{
+	ram_disk *rd = (ram_disk*)opaque;
+	if(pos+size>rd->len){
+		if(rd->len-pos>=0){
+			memcpy(buf, rd->base + pos, rd->len-pos);
+			size = rd->len-pos;
+		}
+	}
+	else
+		memcpy(buf, rd->base + pos, size);
+	return size;
+}
+
+static int ram_fclose(void *opaque)
+{
+	return 0;
+}
+
+static const QEMUFileOps ram_read_ops = {
+    .get_buffer = ram_get_buffer,
+    .close =      ram_fclose
+};
+
+static const QEMUFileOps ram_write_ops = {
+    .writev_buffer = ram_writev_buffer,
+    .close =      ram_fclose
+};
+
+QEMUFile *qemu_fopen_ram(ram_disk **return_rd) {
+	ram_disk *rd = g_new0(ram_disk, 1);
+	*return_rd=rd;
+	return qemu_fopen_ops(rd, &ram_write_ops);
+}
+
+QEMUFile *qemu_fopen_ro_ram(ram_disk* rd) {
+    return qemu_fopen_ops(rd, &ram_read_ops);
+}
+
+void qemu_freopen_ro_ram(QEMUFile* f) {
+	void *rd = f->opaque;
+	f->bytes_xfer=0;
+	f->xfer_limit=0;
+	f->last_error=0;
+	f->iovcnt=0;
+	f->buf_index=0;
+	f->buf_size=0;
+	f->pos=0;
+	f->ops = &ram_read_ops;
+	f->opaque = rd;
+	return;
+}
diff --git a/tests/fuzz/ramfile.h b/tests/fuzz/ramfile.h
new file mode 100644
index 0000000000..b51cc72950
--- /dev/null
+++ b/tests/fuzz/ramfile.h
@@ -0,0 +1,20 @@
+#ifndef RAMFILE_H
+#define RAMFILE_H
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "migration/qemu-file.h"
+
+typedef struct ram_disk {
+	void *base;
+	gsize len;
+} ram_disk;
+
+QEMUFile *qemu_fopen_ram(ram_disk **rd);
+QEMUFile *qemu_fopen_ro_ram(ram_disk* rd);
+void qemu_freopen_ro_ram(QEMUFile* f);
+
+#endif
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (4 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 05/19] fuzz: expose qemu_savevm_state & skip state header Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  9:04   ` Thomas Huth
  2019-07-26 12:56   ` Stefan Hajnoczi
  2019-07-25  3:23 ` [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload Oleinik, Alexander
                   ` (15 subsequent siblings)
  21 siblings, 2 replies; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, Oleinik, Alexander, bsd,
	superirishdonkey, stefanha, pbonzini

libqtest directly invokes the qtest client and exposes a function to
accept responses.

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/libqtest.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++-
 tests/libqtest.h |  6 ++++++
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 3c5c3f49d8..a68a7287cb 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -30,12 +30,18 @@
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/qlist.h"
 #include "qapi/qmp/qstring.h"
+#ifdef CONFIG_FUZZ
+#include "sysemu/qtest.h"
+#endif
 
 #define MAX_IRQ 256
 #define SOCKET_TIMEOUT 50
 #define SOCKET_MAX_FDS 16
 
 QTestState *global_qtest;
+#ifdef CONFIG_FUZZ
+static GString *recv_str;
+#endif
 
 struct QTestState
 {
@@ -316,6 +322,20 @@ QTestState *qtest_initf(const char *fmt, ...)
     va_end(ap);
     return s;
 }
+#ifdef CONFIG_FUZZ
+QTestState *qtest_init_fuzz(const char *extra_args, int *sock_fd)
+{
+    QTestState *qts;
+    qts = g_new(QTestState, 1);
+    qts->wstatus = 0;
+    for (int i = 0; i < MAX_IRQ; i++) {
+        qts->irq_level[i] = false;
+    }
+    qts->big_endian = qtest_query_target_endianness(qts);
+
+    return qts;
+}
+#endif
 
 QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd)
 {
@@ -379,9 +399,18 @@ static void socket_sendf(int fd, const char *fmt, va_list ap)
 {
     gchar *str = g_strdup_vprintf(fmt, ap);
     size_t size = strlen(str);
+#ifdef CONFIG_FUZZ
+    // Directly call qtest_process_inbuf in the qtest server
+    GString *gstr = g_string_new_len(str, size);
+	/* printf(">>> %s",gstr->str); */
+    qtest_server_recv(gstr);
+    g_string_free(gstr, true);
+    g_free(str);
+#else
 
     socket_send(fd, str, size);
     g_free(str);
+#endif
 }
 
 static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...)
@@ -433,6 +462,12 @@ static GString *qtest_recv_line(QTestState *s)
     size_t offset;
     char *eol;
 
+#ifdef CONFIG_FUZZ
+    eol = strchr(recv_str->str, '\n');
+    offset = eol - recv_str->str;
+    line = g_string_new_len(recv_str->str, offset);
+    g_string_erase(recv_str, 0, offset + 1);
+#else
     while ((eol = strchr(s->rx->str, '\n')) == NULL) {
         ssize_t len;
         char buffer[1024];
@@ -453,7 +488,7 @@ static GString *qtest_recv_line(QTestState *s)
     offset = eol - s->rx->str;
     line = g_string_new_len(s->rx->str, offset);
     g_string_erase(s->rx, 0, offset + 1);
-
+#endif
     return line;
 }
 
@@ -797,6 +832,9 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
 
 const char *qtest_get_arch(void)
 {
+#ifdef CONFIG_FUZZ
+    return "i386";
+#endif
     const char *qemu = qtest_qemu_binary();
     const char *end = strrchr(qemu, '/');
 
@@ -1339,3 +1377,16 @@ void qmp_assert_error_class(QDict *rsp, const char *class)
 
     qobject_unref(rsp);
 }
+#ifdef CONFIG_FUZZ
+void qtest_clear_rxbuf(QTestState *s){
+    g_string_set_size(recv_str,0);
+}
+
+void qtest_client_recv(const char *str, size_t len)
+{
+    if(!recv_str)
+        recv_str = g_string_new(NULL);
+    g_string_append_len(recv_str, str, len);
+    return;
+}
+#endif
diff --git a/tests/libqtest.h b/tests/libqtest.h
index cadf1d4a03..dca8f2c2f2 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -1001,4 +1001,10 @@ void qmp_assert_error_class(QDict *rsp, const char *class);
  */
 bool qtest_probe_child(QTestState *s);
 
+#ifdef CONFIG_FUZZ
+QTestState *qtest_init_fuzz(const char *extra_args, int *sock_fd);
+void qtest_clear_rxbuf(QTestState *s);
+void qtest_client_recv(const char *str, size_t len);
+#endif
+
 #endif
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (6 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  8:21   ` Paolo Bonzini
  2019-07-25  3:23 ` [Qemu-devel] [RFC 09/19] fuzz: use mtree_info to find mapped addresses Oleinik, Alexander
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Intercept coverage buffer registration calls and use this information to
copy them to shared memory, if using fork() to avoid resetting device
state.

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/fuzz/fuzzer_hooks.c | 106 ++++++++++++++++++++++++++++++++++++++
 tests/fuzz/fuzzer_hooks.h |   9 ++++
 2 files changed, 115 insertions(+)
 create mode 100644 tests/fuzz/fuzzer_hooks.c
 create mode 100644 tests/fuzz/fuzzer_hooks.h

diff --git a/tests/fuzz/fuzzer_hooks.c b/tests/fuzz/fuzzer_hooks.c
new file mode 100644
index 0000000000..5a0bbec413
--- /dev/null
+++ b/tests/fuzz/fuzzer_hooks.c
@@ -0,0 +1,106 @@
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "fuzzer_hooks.h"
+
+#include <dlfcn.h>
+#include <elf.h>
+
+
+extern void* _ZN6fuzzer3TPCE;
+// The libfuzzer handlers
+void __real___sanitizer_cov_8bit_counters_init(uint8_t*, uint8_t*);
+void __real___sanitizer_cov_trace_pc_guard_init(uint8_t*, uint8_t*);
+
+void __wrap___sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop);
+void __wrap___sanitizer_cov_trace_pc_guard_init(uint8_t *Start, uint8_t *Stop);
+
+
+void* counter_shm;
+
+typedef struct CoverageRegion {
+    uint8_t* start;
+    size_t length;
+    bool store; /* Set this if it needs to be copied to the forked process */
+} CoverageRegion;
+
+CoverageRegion regions[10];
+int region_index = 0;
+
+void __wrap___sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop)
+{
+    regions[region_index].start = Start;
+    regions[region_index].length = Stop-Start;
+    regions[region_index].store = true;
+    region_index++;
+    __real___sanitizer_cov_8bit_counters_init(Start, Stop);
+}
+
+void __wrap___sanitizer_cov_trace_pc_guard_init(uint8_t *Start, uint8_t *Stop)
+{
+    regions[region_index].start = Start;
+    regions[region_index++].length = Stop-Start;
+    regions[region_index].store = true;
+    region_index++;
+    __real___sanitizer_cov_trace_pc_guard_init(Start, Stop);
+}
+
+static void add_tpc_region(void)
+{
+    /* Got symbol and length from readelf. Horrible way to do this! */
+    regions[region_index].start = (uint8_t*)(&_ZN6fuzzer3TPCE);
+    regions[region_index].length = 0x443c00; 
+    regions[region_index].store = true;
+    region_index++;
+}
+
+void counter_shm_init(void)
+{
+    /*
+     * Add the  internal libfuzzer object that gets modified by cmp, etc
+     * callbacks
+     */
+    add_tpc_region(); 
+
+    size_t length = 0;
+    for(int i=0; i<region_index; i++){
+        printf("%d %lx\n", i, length);
+        length += regions[i].length;
+    }
+
+    /* 
+     * Map some shared memory. When we use a fork-server we can copy the
+     * libfuzzer-related counters
+     * */
+    counter_shm = mmap(NULL, length, PROT_READ | PROT_WRITE, 
+            MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+    if(counter_shm == MAP_FAILED) {
+        printf("mmap() failed\n");
+        do { perror("error:"); exit(EXIT_FAILURE); } while (0);
+        exit(-1);
+    }
+}
+
+void counter_shm_store(void)
+{
+    size_t offset = 0;
+    for(int i=0; i<region_index; i++) {
+        if(regions[i].store) {
+            memcpy(counter_shm + offset, regions[i].start, regions[i].length);
+        }
+        offset+=regions[i].length;
+    }
+}
+
+void counter_shm_load(void)
+{
+    size_t offset = 0;
+    for(int i=0; i<region_index; i++) {
+        if(regions[i].store) {
+            memcpy(regions[i].start, counter_shm + offset, regions[i].length);
+        }
+        offset+=regions[i].length;
+    }
+}
+
diff --git a/tests/fuzz/fuzzer_hooks.h b/tests/fuzz/fuzzer_hooks.h
new file mode 100644
index 0000000000..90dca254d4
--- /dev/null
+++ b/tests/fuzz/fuzzer_hooks.h
@@ -0,0 +1,9 @@
+#ifndef FUZZER_HOOKS_H
+#define FUZZER_HOOKS_H
+
+void counter_shm_init(void);
+void counter_shm_store(void);
+void counter_shm_load(void);
+
+#endif
+
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 09/19] fuzz: use mtree_info to find mapped addresses
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (7 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-26 13:04   ` Stefan Hajnoczi
  2019-07-25  3:23 ` [Qemu-devel] [RFC 10/19] fuzz: expose real_main (aka regular vl.c:main) Oleinik, Alexander
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Locate mmio and port i/o addresses that are mapped to devices so we can
limit the fuzzer to only these addresses. This should be replaced with
a sane way of enumaring these memory regions.

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 memory.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/memory.c b/memory.c
index 5d8c9a9234..fa6cbe4f1d 100644
--- a/memory.c
+++ b/memory.c
@@ -34,6 +34,11 @@
 #include "hw/qdev-properties.h"
 #include "hw/boards.h"
 #include "migration/vmstate.h"
+#ifdef CONFIG_FUZZ
+#include "tests/fuzz/fuzz.h"
+#include "tests/fuzz/qos_fuzz.h"
+#endif
+
 
 //#define DEBUG_UNASSIGNED
 
@@ -3016,12 +3021,20 @@ static void mtree_print_flatview(gpointer key, gpointer value,
     int n = view->nr;
     int i;
     AddressSpace *as;
+#ifdef CONFIG_FUZZ
+    bool io=false;
+#endif
+
 
     qemu_printf("FlatView #%d\n", fvi->counter);
     ++fvi->counter;
 
     for (i = 0; i < fv_address_spaces->len; ++i) {
         as = g_array_index(fv_address_spaces, AddressSpace*, i);
+#ifdef CONFIG_FUZZ
+        if(strcmp("I/O",as->name) == 0)
+            io = true;
+#endif
         qemu_printf(" AS \"%s\", root: %s",
                     as->name, memory_region_name(as->root));
         if (as->root->alias) {
@@ -3062,6 +3075,27 @@ static void mtree_print_flatview(gpointer key, gpointer value,
                         range->readonly ? "rom" : memory_region_type(mr),
                         memory_region_name(mr));
         }
+#ifdef CONFIG_FUZZ
+        if(strcmp("i/o", memory_region_type(mr))==0 && strcmp("io", memory_region_name(mr))){
+            fuzz_memory_region *fmr = g_new0(fuzz_memory_region, 1);
+            if(!fuzz_memory_region_head)
+            {
+                fuzz_memory_region_head = fmr;
+                fuzz_memory_region_tail = fmr;
+            }
+            fmr->io = io;
+            fmr->start = int128_get64(range->addr.start);
+            fmr->length = MR_SIZE(range->addr.size);
+            fmr->next = fuzz_memory_region_head;
+            fuzz_memory_region_tail->next = fmr;
+            fuzz_memory_region_tail = fmr;
+            if(io == true){
+                total_io_mem += MR_SIZE(range->addr.size)+1;
+            } else {
+                total_ram_mem += MR_SIZE(range->addr.size)+1;
+            }
+        }
+#endif
         if (fvi->owner) {
             mtree_print_mr_owner(mr);
         }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 10/19] fuzz: expose real_main (aka regular vl.c:main)
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (8 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 09/19] fuzz: use mtree_info to find mapped addresses Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  9:38   ` Paolo Bonzini
  2019-07-25  3:23 ` [Qemu-devel] [RFC 11/19] fuzz: add direct send/receive in qtest client Oleinik, Alexander
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Export normal qemu-system main so it can be called from tests/fuzz/fuzz.c

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 include/sysemu/sysemu.h |  4 ++++
 vl.c                    | 21 ++++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 984c439ac9..1bb8cf184c 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -184,6 +184,10 @@ QemuOpts *qemu_get_machine_opts(void);
 
 bool defaults_enabled(void);
 
+#ifdef CONFIG_FUZZ
+int real_main(int argc, char **argv, char **envp);
+#endif
+
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
 extern QemuOptsList qemu_drive_opts;
diff --git a/vl.c b/vl.c
index b426b32134..b71b99b6f8 100644
--- a/vl.c
+++ b/vl.c
@@ -130,6 +130,10 @@ int main(int argc, char **argv)
 #include "sysemu/iothread.h"
 #include "qemu/guest-random.h"
 
+#ifdef CONFIG_FUZZ
+#include "tests/libqtest.h"
+#endif
+
 #define MAX_VIRTIO_CONSOLES 1
 
 static const char *data_dir[16];
@@ -2853,8 +2857,11 @@ static void user_register_global_props(void)
     qemu_opts_foreach(qemu_find_opts("global"),
                       global_init_func, NULL, NULL);
 }
-
+#ifdef CONFIG_FUZZ
+int real_main(int argc, char **argv, char **envp)
+#else
 int main(int argc, char **argv, char **envp)
+#endif
 {
     int i;
     int snapshot, linux_boot;
@@ -2903,7 +2910,9 @@ int main(int argc, char **argv, char **envp)
     atexit(qemu_run_exit_notifiers);
     qemu_init_exec_dir(argv[0]);
 
+#ifndef CONFIG_FUZZ // QOM is already set up by the fuzzer.
     module_call_init(MODULE_INIT_QOM);
+#endif
 
     qemu_add_opts(&qemu_drive_opts);
     qemu_add_drive_opts(&qemu_legacy_drive_opts);
@@ -4196,9 +4205,11 @@ int main(int argc, char **argv, char **envp)
      */
     migration_object_init();
 
+#ifndef CONFIG_FUZZ // Already set up by the fuzzer
     if (qtest_chrdev) {
         qtest_init(qtest_chrdev, qtest_log, &error_fatal);
     }
+#endif
 
     machine_opts = qemu_get_machine_opts();
     kernel_filename = qemu_opt_get(machine_opts, "kernel");
@@ -4470,6 +4481,14 @@ int main(int argc, char **argv, char **envp)
     accel_setup_post(current_machine);
     os_setup_post();
 
+/*
+ * Return to the fuzzer since it will run qtest programs and run the
+ * main_loop
+*/
+#ifdef CONFIG_FUZZ
+    return 0;
+#endif
+
     main_loop();
 
     gdbserver_cleanup();
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 11/19] fuzz: add direct send/receive in qtest client
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (9 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 10/19] fuzz: expose real_main (aka regular vl.c:main) Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  9:10   ` Thomas Huth
  2019-07-25  3:23 ` [Qemu-devel] [RFC 12/19] fuzz: hard-code all of the needed files for build Oleinik, Alexander
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, Oleinik, Alexander, bsd,
	superirishdonkey, stefanha, pbonzini

Directly interact with tests/libqtest.c functions

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 qtest.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/qtest.c b/qtest.c
index 15e27e911f..a6134d3ed0 100644
--- a/qtest.c
+++ b/qtest.c
@@ -31,6 +31,9 @@
 #ifdef TARGET_PPC64
 #include "hw/ppc/spapr_rtas.h"
 #endif
+#ifdef CONFIG_FUZZ
+#include "tests/libqtest.h"
+#endif
 
 #define MAX_IRQ 256
 
@@ -231,10 +234,14 @@ static void GCC_FMT_ATTR(1, 2) qtest_log_send(const char *fmt, ...)
 
 static void do_qtest_send(CharBackend *chr, const char *str, size_t len)
 {
+#ifdef CONFIG_FUZZ
+    qtest_client_recv(str, len);
+#else
     qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
     if (qtest_log_fp && qtest_opened) {
         fprintf(qtest_log_fp, "%s", str);
     }
+#endif
 }
 
 static void qtest_send(CharBackend *chr, const char *str)
@@ -748,8 +755,11 @@ static void qtest_event(void *opaque, int event)
         break;
     }
 }
-
+#ifdef CONFIG_FUZZ
+void qtest_init_server(const char *qtest_chrdev, const char *qtest_log, Error **errp)
+#else
 void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
+#endif
 {
     Chardev *chr;
 
@@ -781,3 +791,10 @@ bool qtest_driver(void)
 {
     return qtest_chr.chr != NULL;
 }
+#ifdef CONFIG_FUZZ
+void qtest_server_recv(GString *inbuf)
+{
+    qtest_process_inbuf(NULL, inbuf);
+}
+#endif
+
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 12/19] fuzz: hard-code all of the needed files for build
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (10 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 11/19] fuzz: add direct send/receive in qtest client Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  3:23 ` [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos Oleinik, Alexander
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, Oleinik, Alexander, bsd, superirishdonkey,
	stefanha, pbonzini, Richard Henderson

Once the fuzzer is better-integrated into the build-system, this should
go away

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 target/i386/Makefile.objs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index 3d646848ef..c8834f6ad1 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -23,7 +23,7 @@ endif
 # I find a better way to integrate into the build system
 ifeq ($(CONFIG_FUZZ),y)
 obj-$(CONFIG_FUZZ) += ../../tests/fuzz/ramfile.o ../../accel/fuzz.o
-obj-$(CONFIG_FUZZ) += ../../tests/fuzz/fuzz.o
+obj-$(CONFIG_FUZZ) += ../../tests/fuzz/fuzz.o ../../tests/fuzz/fuzzer_hooks.o
 obj-$(CONFIG_FUZZ) += ../../tests/fuzz/virtio-net-fuzz.o 
 obj-$(CONFIG_FUZZ) += ../../tests/fuzz/qtest_fuzz.o
 obj-$(CONFIG_FUZZ) += ../../tests/libqtest.o
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (11 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 12/19] fuzz: hard-code all of the needed files for build Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25 16:25   ` John Snow
  2019-07-25  3:23 ` [Qemu-devel] [RFC 14/19] fuzz: hard-code a main-loop timeout Oleinik, Alexander
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Thomas Huth, Oleinik, Alexander, bsd,
	superirishdonkey, stefanha, pbonzini

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/libqos/virtio-net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c
index 66405b646e..247a0a17a8 100644
--- a/tests/libqos/virtio-net.c
+++ b/tests/libqos/virtio-net.c
@@ -51,7 +51,7 @@ static void virtio_net_setup(QVirtioNet *interface)
     if (features & (1u << VIRTIO_NET_F_MQ)) {
         interface->n_queues = qvirtio_config_readw(vdev, 8) * 2;
     } else {
-        interface->n_queues = 2;
+        interface->n_queues = 3;
     }
 
     interface->queues = g_new(QVirtQueue *, interface->n_queues);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 14/19] fuzz: hard-code a main-loop timeout
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (12 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  9:40   ` Paolo Bonzini
  2019-07-25  3:23 ` [Qemu-devel] [RFC 15/19] fuzz: add fuzz accelerator type Oleinik, Alexander
                   ` (7 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 util/main-loop.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/util/main-loop.c b/util/main-loop.c
index e3eaa55866..708e6be5eb 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -513,6 +513,9 @@ void main_loop_wait(int nonblocking)
     timeout_ns = qemu_soonest_timeout(timeout_ns,
                                       timerlistgroup_deadline_ns(
                                           &main_loop_tlg));
+#ifdef CONFIG_FUZZ
+    timeout_ns = 50000;
+#endif
 
     ret = os_host_main_loop_wait(timeout_ns);
     mlpoll.state = ret < 0 ? MAIN_LOOP_POLL_ERR : MAIN_LOOP_POLL_OK;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 15/19] fuzz: add fuzz accelerator type
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (13 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 14/19] fuzz: hard-code a main-loop timeout Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  3:23 ` [Qemu-devel] [RFC 16/19] fuzz: add general fuzzer entrypoints Oleinik, Alexander
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 accel/fuzz.c          | 47 +++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/fuzz.h | 15 ++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 accel/fuzz.c
 create mode 100644 include/sysemu/fuzz.h

diff --git a/accel/fuzz.c b/accel/fuzz.c
new file mode 100644
index 0000000000..1694cf46e8
--- /dev/null
+++ b/accel/fuzz.c
@@ -0,0 +1,47 @@
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "sysemu/accel.h"
+#include "sysemu/fuzz.h"
+#include "sysemu/cpus.h"
+
+
+static void fuzz_setup_post(MachineState *ms, AccelState *accel) {
+}
+
+static int fuzz_init_accel(MachineState *ms)
+{
+    QemuOpts *opts = qemu_opts_create(qemu_find_opts("icount"), NULL, 0,
+                                      &error_abort);
+    qemu_opt_set(opts, "shift", "0", &error_abort);
+    configure_icount(opts, &error_abort);
+    qemu_opts_del(opts);
+    return 0;
+}
+
+static void fuzz_accel_class_init(ObjectClass *oc, void *data)
+{
+    AccelClass *ac = ACCEL_CLASS(oc);
+    ac->name = "fuzz";
+    ac->init_machine = fuzz_init_accel;
+	ac->setup_post = fuzz_setup_post;
+    ac->allowed = &fuzz_allowed;
+}
+
+#define TYPE_FUZZ_ACCEL ACCEL_CLASS_NAME("fuzz")
+
+static const TypeInfo fuzz_accel_type = {
+    .name = TYPE_FUZZ_ACCEL,
+    .parent = TYPE_ACCEL,
+    .class_init = fuzz_accel_class_init,
+};
+
+static void fuzz_type_init(void)
+{
+    type_register_static(&fuzz_accel_type);
+}
+
+type_init(fuzz_type_init);
+
diff --git a/include/sysemu/fuzz.h b/include/sysemu/fuzz.h
new file mode 100644
index 0000000000..09a2a9ffdf
--- /dev/null
+++ b/include/sysemu/fuzz.h
@@ -0,0 +1,15 @@
+#ifndef FUZZ_H
+#define FUZZ_H
+
+bool fuzz_allowed;
+
+static inline bool fuzz_enabled(void)
+{
+    return fuzz_allowed;
+}
+
+bool fuzz_driver(void);
+
+void fuzz_init(const char *fuzz_chrdev, const char *fuzz_log, Error **errp);
+
+#endif
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 16/19] fuzz: add general fuzzer entrypoints
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (14 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 15/19] fuzz: add fuzz accelerator type Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25 17:53   ` Philippe Mathieu-Daudé
  2019-07-25  3:23 ` [Qemu-devel] [RFC 17/19] fuzz: add general qtest fuzz target Oleinik, Alexander
                   ` (5 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Defines LLVMFuzzerInitialize and LLVMFuzzerTestOneInput

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/fuzz/fuzz.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/fuzz/fuzz.h |  96 +++++++++++++++++
 2 files changed, 358 insertions(+)
 create mode 100644 tests/fuzz/fuzz.c
 create mode 100644 tests/fuzz/fuzz.h

diff --git a/tests/fuzz/fuzz.c b/tests/fuzz/fuzz.c
new file mode 100644
index 0000000000..0421b9402c
--- /dev/null
+++ b/tests/fuzz/fuzz.c
@@ -0,0 +1,262 @@
+#include "tests/fuzz/ramfile.h"
+#include "migration/qemu-file.h"
+#include "migration/global_state.h"
+#include "migration/savevm.h"
+#include "tests/libqtest.h"
+#include "exec/memory.h"
+#include "migration/migration.h"
+#include "fuzz.h"
+#include "tests/libqos/qgraph.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/userfaultfd.h>
+#include <poll.h>
+#include <pthread.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+QTestState *s;
+
+QEMUFile *ramfile;
+QEMUFile *writefile;
+ram_disk *rd; 
+typedef QSLIST_HEAD(, FuzzTarget) FuzzTargetList;
+
+FuzzTargetList* fuzz_target_list;
+
+uint64_t total_mr_size = 0;
+uint64_t mr_index = 0;
+
+const MemoryRegion* mrs[1000];
+
+
+// Save just the VMStateDescriptors
+void save_device_state(void)
+{
+    writefile = qemu_fopen_ram(&rd);
+    global_state_store();
+    qemu_save_device_state(writefile);
+    qemu_fflush(writefile);
+    ramfile = qemu_fopen_ro_ram(rd);
+}
+
+// Save the entire vm state including RAM
+void save_vm_state(void) 
+{
+    writefile = qemu_fopen_ram(&rd);
+    vm_stop(RUN_STATE_SAVE_VM);
+    global_state_store();
+    qemu_savevm_state(writefile, NULL);
+    qemu_fflush(writefile);
+    ramfile = qemu_fopen_ro_ram(rd);
+}
+
+/* Reset state by rebooting */
+void reboot()
+{
+    qemu_system_reset(SHUTDOWN_CAUSE_NONE);
+}
+
+/* Restore device state */
+void load_device_state()
+{
+    qemu_freopen_ro_ram(ramfile);
+
+    int ret = qemu_load_device_state(ramfile);
+    if (ret < 0){
+        printf("reset error\n");
+        exit(-1);
+    }
+}
+
+/* Restore full vm state */
+void load_vm_state()
+{
+    qemu_freopen_ro_ram(ramfile);
+
+    vm_stop(RUN_STATE_RESTORE_VM);
+    /* qemu_system_reset(SHUTDOWN_CAUSE_NONE); */
+
+    int ret = qemu_loadvm_state(ramfile);
+    if (ret < 0){
+        printf("reset error\n");
+        exit(-1);
+    }
+    migration_incoming_state_destroy();
+    vm_start();
+}
+
+void qtest_setup()
+{
+    s = qtest_init_fuzz(NULL, NULL);
+    global_qtest = s;
+}
+
+void fuzz_add_target(const char* name,
+        const char* description,
+        void(*init_pre_main)(void),
+        void(*init_pre_save)(void),
+        void(*save_state)(void),
+        void(*reset)(void),
+        void(*pre_fuzz)(void),
+        void(*fuzz)(const unsigned char*, size_t),
+        void(*post_fuzz)(void),
+        int* main_argc,
+        char*** main_argv)
+{
+
+    FuzzTarget *target;
+    FuzzTarget *tmp;
+    if(!fuzz_target_list)
+        fuzz_target_list = g_new0(FuzzTargetList, 1);
+
+    QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
+        if (g_strcmp0(tmp->name->str, name) == 0) {
+            fprintf(stderr, "Error: Fuzz target name %s already in use\n", name);
+            abort();
+        }
+    }
+    target = g_new0(FuzzTarget, 1);
+    target->name = g_string_new(name);
+    target->description = g_string_new(description);
+    target->init_pre_main = init_pre_main;
+    target->init_pre_save = init_pre_save;
+    target->save_state = save_state;
+    target->reset = reset;
+    target->pre_fuzz = pre_fuzz;
+    target->fuzz = fuzz;
+    target->post_fuzz = post_fuzz;
+    target->main_argc = main_argc;
+    target->main_argv = main_argv;
+    QSLIST_INSERT_HEAD(fuzz_target_list, target, target_list);
+}
+
+
+FuzzTarget* fuzz_get_target(char* name)
+{
+    FuzzTarget* tmp;
+    if(!fuzz_target_list){
+        fprintf(stderr, "Fuzz target list not initialized");
+        abort();
+    }
+
+    QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
+        if (g_strcmp0(tmp->name->str, name) == 0) {
+            break;
+        }
+    }
+    return tmp;
+}
+
+FuzzTarget* fuzz_target;
+
+
+
+static void usage(void)
+{
+    printf("Usage: ./fuzz --FUZZ_TARGET [LIBFUZZER ARGUMENTS]\n");
+    printf("where --FUZZ_TARGET is one of:\n");
+    FuzzTarget* tmp;
+    if(!fuzz_target_list){
+        fprintf(stderr, "Fuzz target list not initialized");
+        abort();
+    }
+    QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
+        QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
+            printf(" --%s  : %s\n", tmp->name->str, tmp->description->str);
+        }
+        exit(0);
+    }
+}
+
+// TODO: Replace this with QEMU's built-in linked list
+static void enum_memory(void)
+{
+    mtree_info(true, true, true);
+    fuzz_memory_region *fmr = g_new0(fuzz_memory_region, 1);
+
+    fmr->io = false;
+    fmr->start = 0x100000;
+    fmr->length = 0x10000;
+    fmr->next = fuzz_memory_region_head;
+    fuzz_memory_region_tail->next = fmr;
+    fuzz_memory_region_tail = fmr;
+    fmr = fuzz_memory_region_head;
+
+    while(true){
+        fmr = fmr->next;
+        if(fmr == fuzz_memory_region_head)
+            break;
+    }
+}
+
+/* Executed for each fuzzing-input */
+int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size)
+{
+    /* e.g. Device bootstrapping */
+    if(fuzz_target->pre_fuzz)
+        fuzz_target->pre_fuzz();
+
+    if(fuzz_target->fuzz)
+        fuzz_target->fuzz(Data, Size);
+
+    /* e.g. Copy counter bitmap to shm*/
+    if(fuzz_target->post_fuzz)
+        fuzz_target->post_fuzz();
+
+    /* e.g. Reboot the machine or vmload */
+    if(fuzz_target->reset)
+        fuzz_target->reset();
+
+    return 0;
+}
+
+/* Executed once, prior to fuzzing */
+int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
+{
+
+    char *target_name;
+
+    // Initialize qgraph and modules
+    qos_graph_init();
+    module_call_init(MODULE_INIT_FUZZ_TARGET);
+    module_call_init(MODULE_INIT_QOM);
+    module_call_init(MODULE_INIT_LIBQOS);
+
+    if(*argc <= 1)
+        usage();
+
+
+    /* Identify the fuzz target */
+    target_name = (*argv)[1];
+    target_name+=2;
+    fuzz_target = fuzz_get_target(target_name);
+
+    if(!fuzz_target)
+    {
+        fprintf(stderr, "Error: Fuzz fuzz_target name %s not found\n", target_name);
+        usage();
+    }
+
+    if(fuzz_target->init_pre_main)
+        fuzz_target->init_pre_main();
+
+    /* Run QEMU's regular vl.c:main */
+    real_main(*(fuzz_target->main_argc), *(fuzz_target->main_argv), NULL);
+
+
+    /* Enumerate memory to identify mapped MMIO and I/O regions */
+    enum_memory();
+
+    /* Good place to do any one-time device initialization (such as QOS init) */
+    if(fuzz_target->init_pre_save)
+        fuzz_target->init_pre_save();
+
+    /* If configured, this is where we save vm or device state to ramdisk */
+    if(fuzz_target->save_state)
+        fuzz_target->save_state();
+
+    return 0;
+}
diff --git a/tests/fuzz/fuzz.h b/tests/fuzz/fuzz.h
new file mode 100644
index 0000000000..02f26752eb
--- /dev/null
+++ b/tests/fuzz/fuzz.h
@@ -0,0 +1,96 @@
+#ifndef FUZZER_H_
+#define FUZZER_H_
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "exec/memory.h"
+#include "tests/libqtest.h"
+#include "migration/qemu-file.h"
+#include "ramfile.h"
+
+#include <linux/userfaultfd.h>
+
+
+extern QTestState *s;
+extern QEMUFile *writefile;
+extern QEMUFile *ramfile;
+extern ram_disk *rd;
+
+typedef struct FuzzTarget {
+	GString* name;
+	GString* description;
+	void(*init_pre_main)(void);
+	void(*init_pre_save)(void);
+	void(*save_state)(void);
+	void(*reset)(void);
+	void(*pre_fuzz)(void);
+	void(*fuzz)(const unsigned char*, size_t);
+	void(*post_fuzz)(void);
+	int* main_argc;
+	char*** main_argv;
+	QSLIST_ENTRY(FuzzTarget) target_list;
+
+} FuzzTarget;
+
+extern void* _ZN6fuzzer3TPCE;
+/* extern uint8_t __sancov_trace_pc_guard_8bit_counters; */
+/* extern uint8_t __sancov_trace_pc_pcs; */
+extern void* __prof_nms_sect_data;
+extern void* __prof_vnodes_sect_data;
+
+#define TPC_SIZE 0x0443c00
+#define PROFILE_SIZE ( &__prof_vnodes_sect_data - &__prof_nms_sect_data)
+
+#define NUMPCS (1 << 21)
+/* #define TPC_SIZE 0x33c00 */
+
+extern uint8_t *TPCCopy;
+extern uint8_t *ARGCopy;
+
+void save_device_state(void);
+void save_vm_state(void);
+void reboot(void);
+
+void load_device_state(void);
+void load_vm_state(void);
+
+
+void save_device_state(void);
+void qtest_setup(void);
+void fuzz_register_mr(const MemoryRegion *mr);
+
+FuzzTarget* fuzz_get_target(char* name);
+
+extern FuzzTarget* fuzz_target;
+
+typedef struct fuzz_memory_region {
+	bool io;
+	uint64_t start;
+	uint64_t length;
+	struct fuzz_memory_region* next;
+} fuzz_memory_region;
+
+extern fuzz_memory_region *fuzz_memory_region_head;
+extern fuzz_memory_region *fuzz_memory_region_tail;
+
+extern uint64_t total_io_mem;
+extern uint64_t total_ram_mem;
+
+void fuzz_add_target(const char* name,
+	const char* description,
+	void(*init_pre_main)(void),
+	void(*init_pre_save)(void),
+	void(*save_state)(void),
+	void(*reset)(void),
+	void(*pre_fuzz)(void),
+	void(*fuzz)(const unsigned char*, size_t),
+	void(*post_fuzz)(void),
+	int* main_argc,
+	char*** main_argv);
+
+int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
+int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp);
+
+#endif
+
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 17/19] fuzz: add general qtest fuzz target
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (15 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 16/19] fuzz: add general fuzzer entrypoints Oleinik, Alexander
@ 2019-07-25  3:23 ` Oleinik, Alexander
  2019-07-25  3:24 ` [Qemu-devel] [RFC 18/19] fuzz: Add virtio-net tx and ctrl fuzz targets Oleinik, Alexander
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

These fuzz targets perform a range of qtest operations over mmio and
port i/o addresses mapped to devices.

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/fuzz/qtest_fuzz.c | 261 ++++++++++++++++++++++++++++++++++++++++
 tests/fuzz/qtest_fuzz.h |  38 ++++++
 2 files changed, 299 insertions(+)
 create mode 100644 tests/fuzz/qtest_fuzz.c
 create mode 100644 tests/fuzz/qtest_fuzz.h

diff --git a/tests/fuzz/qtest_fuzz.c b/tests/fuzz/qtest_fuzz.c
new file mode 100644
index 0000000000..6d6670838d
--- /dev/null
+++ b/tests/fuzz/qtest_fuzz.c
@@ -0,0 +1,261 @@
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+#include <wordexp.h>
+#include "qemu-common.h"
+#include "fuzzer_hooks.h"
+
+
+#include "fuzz.h"
+#include "qtest_fuzz.h"
+#include "tests/libqtest.h"
+#include "fuzz/qos_fuzz.h"
+
+
+/* Make sure that the io_port is mapped to some device */
+static uint16_t normalize_io_port(uint64_t addr) {
+    addr = addr%total_io_mem;
+    fuzz_memory_region *fmr = fuzz_memory_region_head;
+    while(addr!=0) {
+        if(!fmr->io){
+            fmr = fmr->next;
+            continue;
+        }
+        if(addr <= fmr->length)
+        {
+            addr= fmr->start + addr;
+            break;
+        }
+        addr -= fmr->length +1;
+        fmr = fmr->next;
+    }
+    /* Stuff that times out or hotplugs.. */
+    if(addr>=0x5655 && addr<=0x565b)
+        return 0;
+    if(addr>=0x510 && addr<=0x518)
+        return 0;
+    if(addr>=0xae00 && addr<=0xae13) // PCI Hotplug
+        return 0;
+    if(addr>=0xaf00 && addr<=0xaf1f) // CPU Hotplug
+        return 0;
+    return addr;
+}
+
+/* Make sure that the memory address is mapped to some interesting device */
+static uint16_t normalize_mem_addr(uint64_t addr) {
+    addr = addr%total_ram_mem;
+    fuzz_memory_region *fmr = fuzz_memory_region_head;
+    while(addr!=0) {
+        if(fmr->io){
+            fmr = fmr->next;
+            continue;
+        }
+        if(addr <= fmr->length)
+        {
+            return fmr->start + addr;
+        }
+        addr -= fmr->length +1;
+        fmr = fmr->next;
+    }
+    return addr;
+}
+
+static void qtest_fuzz(const unsigned char *Data, size_t Size){
+    const unsigned char *pos = Data;
+    const unsigned char *End = Data + Size;
+
+    qtest_cmd *cmd;
+
+    while(pos < Data+Size)
+    {
+        /* Translate the fuzz input to a qtest command */
+        cmd = &commands[(*pos)%(sizeof(commands)/sizeof(qtest_cmd))];
+        pos++;
+
+        if(strcmp(cmd->name, "clock_step") == 0){
+            // TODO: This times out
+            /* qtest_clock_step_next(s); */
+        } 
+        else if(strcmp(cmd->name, "outb") == 0) {
+            if(pos + sizeof(uint16_t) + sizeof(uint8_t) < End) {
+                uint16_t addr = *(int16_t*)(pos);
+                pos += sizeof(uint16_t);
+                uint8_t val = *(uint16_t*)(pos);
+                pos += sizeof(uint8_t);
+                addr = normalize_io_port(addr);
+                qtest_outb(s, addr, val);
+            }
+        }
+        else if(strcmp(cmd->name, "outw") == 0) {
+            if(pos + sizeof(uint16_t) + sizeof(uint16_t) < End) {
+                uint16_t addr = *(int16_t*)(pos);
+                pos += sizeof(uint16_t);
+                uint16_t val = *(uint16_t*)(pos);
+                pos += sizeof(uint16_t);
+                addr = normalize_io_port(addr);
+                qtest_outw(s, addr, val);
+            }
+        }
+        else if(strcmp(cmd->name, "outl") == 0) {
+            if(pos + sizeof(uint16_t) + sizeof(uint32_t) < End) {
+                uint16_t addr = *(int16_t*)(pos);
+                pos += sizeof(uint16_t);
+                uint32_t val = *(uint32_t*)(pos);
+                pos += sizeof(uint32_t);
+                addr = normalize_io_port(addr);
+                qtest_outl(s, addr, val);
+            }
+        }
+        else if(strcmp(cmd->name, "inb") == 0) {
+            if(pos + sizeof(uint16_t) < End) {
+                uint16_t addr = *(int16_t*)(pos);
+                pos += sizeof(uint16_t);
+                addr = normalize_io_port(addr);
+                qtest_inb(s, addr);
+            }
+        }
+        else if(strcmp(cmd->name, "inw") == 0) {
+            if(pos + sizeof(uint16_t) < End) {
+                uint16_t addr = *(int16_t*)(pos);
+                pos += sizeof(uint16_t);
+                addr = normalize_io_port(addr);
+                qtest_inw(s, addr);
+            }
+        }
+        else if(strcmp(cmd->name, "inl") == 0) {
+            if(pos + sizeof(uint16_t) < End) {
+                uint16_t addr = *(int16_t*)(pos);
+                pos += sizeof(uint16_t);
+                addr = normalize_io_port(addr);
+                qtest_inl(s, addr);
+            }
+        }
+        else if(strcmp(cmd->name, "writeb") == 0) {
+            if(pos + sizeof(uint32_t) + sizeof(uint8_t) < End) {
+                uint32_t addr = *(int32_t*)(pos);
+                pos += sizeof(uint32_t);
+                uint8_t val = *(uint8_t*)(pos);
+                pos += sizeof(uint8_t);
+                addr = normalize_mem_addr(addr);
+                qtest_writeb(s, addr, val);
+            }
+        }
+        else if(strcmp(cmd->name, "writew") == 0) {
+            if(pos + sizeof(uint32_t) + sizeof(uint16_t) < End) {
+                uint32_t addr = *(int32_t*)(pos);
+                pos += sizeof(uint32_t);
+                uint16_t val = *(uint16_t*)(pos);
+                pos += sizeof(uint16_t);
+                addr = normalize_mem_addr(addr);
+                qtest_writew(s, addr, val);
+            }
+        }
+        else if(strcmp(cmd->name, "writel") == 0) {
+            if(pos + sizeof(uint32_t) + sizeof(uint32_t) < End) {
+                uint32_t addr = *(int32_t*)(pos);
+                pos += sizeof(uint32_t);
+                uint32_t val = *(uint32_t*)(pos);
+                pos += sizeof(uint32_t);
+                addr = normalize_mem_addr(addr);
+                qtest_writel(s, addr, val);
+            }
+        }
+        else if(strcmp(cmd->name, "readb") == 0) {
+            if(pos + sizeof(uint32_t) < End) {
+                uint32_t addr = *(int32_t*)(pos);
+                pos += sizeof(uint32_t);
+                addr = normalize_mem_addr(addr);
+                qtest_readb(s, addr);
+            }
+        }
+        else if(strcmp(cmd->name, "readw") == 0) {
+            if(pos + sizeof(uint32_t) < End) {
+                uint32_t addr = *(int32_t*)(pos);
+                pos += sizeof(uint32_t);
+                addr = normalize_mem_addr(addr);
+                qtest_readw(s, addr); } }
+        else if(strcmp(cmd->name, "readl") == 0) {
+            if(pos + sizeof(uint32_t) < End) {
+                uint32_t addr = *(int32_t*)(pos);
+                pos += sizeof(uint32_t);
+                addr = normalize_mem_addr(addr);
+                qtest_readl(s, addr);
+            }
+        }
+        else if(strcmp(cmd->name, "write_dma") == 0) {
+            if(pos + sizeof(uint32_t) + sizeof(uint16_t) < End) {
+                uint32_t addr = *(int32_t*)(pos);
+                pos += sizeof(uint32_t);
+                uint32_t val = 0x100000;
+                addr = normalize_mem_addr(addr);
+                qtest_writel(s, addr, val);
+            }
+        }
+        else if(strcmp(cmd->name, "out_dma") == 0) {
+            if(pos + sizeof(uint16_t) + sizeof(uint16_t) < End) {
+                uint16_t addr = *(int16_t*)(pos);
+                pos += sizeof(uint16_t);
+                uint32_t val = 0x100000;
+                addr = normalize_io_port(addr);
+                qtest_outl(s, addr, val);
+            }
+        }
+        main_loop_wait(false);
+    }
+}
+
+static void *net_test_setup_nosocket(GString *cmd_line, void *arg)
+{
+    g_string_append(cmd_line, " -netdev hubport,hubid=0,id=hs0 ");
+    return arg;
+}
+
+static void fuzz_fork(const unsigned char *Data, size_t Size)
+{
+    if (fork() == 0) {
+        qtest_fuzz(Data, Size);
+        counter_shm_store();
+        _Exit(0);
+    }
+    else {
+        wait(NULL);
+        counter_shm_load();
+    }
+}
+
+static void init_fork(void) {
+    qos_init_path();
+}
+static void fork_pre_main(void) {
+    qos_setup();
+    counter_shm_init();
+}
+
+int qtest_argc;
+char **qtest_argv;
+static void register_qtest_fuzz_targets(void)
+{
+    QOSGraphTestOptions opts = {
+        .before = net_test_setup_nosocket,
+    };
+    fuzz_add_qos_target("qtest-fuzz", "fuzz qtest commands and a dma buffer. Reset device state for each run",
+            "e1000e", &opts, &qos_setup, &qos_init_path, &save_vm_state, &load_vm_state,
+            NULL, &qtest_fuzz, NULL);
+    fuzz_add_qos_target("qtest-fork-fuzz", "fuzz qtest commands and a dma buffer. Use COW/forking to reset state",
+            "e1000e", &opts, &fork_pre_main, NULL, &init_fork, NULL,
+            NULL, &fuzz_fork, NULL);
+
+    GString *cmd_line = g_string_new("qemu-system-i386 -display none -machine accel=fuzz -m 3"); 
+    wordexp_t result;
+    wordexp (cmd_line->str, &result, 0);
+    qtest_argc = result.we_wordc;
+    qtest_argv = result.we_wordv;
+    g_string_free(cmd_line, true);
+}
+
+fuzz_target_init(register_qtest_fuzz_targets);
diff --git a/tests/fuzz/qtest_fuzz.h b/tests/fuzz/qtest_fuzz.h
new file mode 100644
index 0000000000..bf472954e7
--- /dev/null
+++ b/tests/fuzz/qtest_fuzz.h
@@ -0,0 +1,38 @@
+#ifndef _QTEST_FUZZ_H_
+#define _QTEST_FUZZ_H_
+
+typedef struct qtest_cmd {
+	char name[32];
+	uint8_t size;
+} qtest_cmd;
+
+typedef uint32_t addr_type;
+
+static qtest_cmd commands[] = 
+{
+	{"clock_step", 0},
+	{"clock_step", 0},
+	{"clock_set", 1},
+	{"outb", 2},
+	{"outw", 2},
+	{"outl", 2},
+	{"inb", 1},
+	{"inw", 1},
+	{"inl", 1},
+	{"writeb", 2},
+	{"writew", 2},
+	{"writel", 2},
+	{"writeq", 2},
+	{"readb", 1},
+	{"readw", 1},
+	{"readl", 1},
+	{"readq", 1},
+	{"read", 2},
+	{"write", 3},
+	{"b64read", 2},
+	{"b64write", 10},
+	{"memset", 3},
+	{"write_dma", 2},
+	{"out_dma", 2},
+};
+#endif
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 18/19] fuzz: Add virtio-net tx and ctrl fuzz targets
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (16 preceding siblings ...)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 17/19] fuzz: add general qtest fuzz target Oleinik, Alexander
@ 2019-07-25  3:24 ` Oleinik, Alexander
  2019-07-25  3:24 ` [Qemu-devel] [RFC 19/19] fuzz: Add documentation about the fuzzer to docs/ Oleinik, Alexander
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

These virtio-net fuzz targets use libqos abstractions to virtio-net
virtqueues.

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 tests/fuzz/virtio-net-fuzz.c | 226 +++++++++++++++++++++++++++++++++++
 1 file changed, 226 insertions(+)
 create mode 100644 tests/fuzz/virtio-net-fuzz.c

diff --git a/tests/fuzz/virtio-net-fuzz.c b/tests/fuzz/virtio-net-fuzz.c
new file mode 100644
index 0000000000..4b6c788498
--- /dev/null
+++ b/tests/fuzz/virtio-net-fuzz.c
@@ -0,0 +1,226 @@
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "exec/memory.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+
+#include "hw/virtio/virtio-net.h"
+#include "hw/virtio/virtio.h"
+#include "tests/libqos/virtio-net.h"
+#include "fuzzer_hooks.h"
+
+#include "fuzz.h"
+#include "qos_fuzz.h"
+
+typedef struct vq_action {
+    uint8_t queue;
+    uint8_t length;
+    uint8_t write;
+    uint8_t next;
+    bool kick;
+} vq_action;
+
+static void virtio_net_ctrl_fuzz(const unsigned char *Data, size_t Size)
+{
+    uint64_t req_addr[10];
+    int reqi =0;
+    uint32_t free_head;
+
+    QGuestAllocator *t_alloc = qos_alloc;
+
+    QVirtioNet *net_if = qos_obj;
+    QVirtioDevice *dev = net_if->vdev;
+    QVirtQueue *q;
+    vq_action vqa;
+    int iters=0;
+    while(true) {
+        if(Size < sizeof(vqa)) {
+            break;
+        }
+        vqa = *((vq_action*)Data);
+        Data += sizeof(vqa);
+        Size -= sizeof(vqa);
+
+        q = net_if->queues[2];
+
+        vqa.length = vqa.length >= Size ? Size :  vqa.length;
+
+        req_addr[reqi] = guest_alloc(t_alloc, vqa.length);
+        memwrite(req_addr[reqi], Data, vqa.length);
+        if(iters == 0)
+            free_head = qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;
+        else
+            qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;
+        iters++;
+        reqi++;
+        if(iters==10)
+            break;
+        Data += vqa.length;
+        Size -= vqa.length;
+    }
+    if(iters){
+        qvirtqueue_kick(dev, q, free_head);
+        qtest_clock_step_next(s);
+        main_loop_wait(false);
+        for(int i =0; i<reqi; i++)
+            guest_free(t_alloc, req_addr[i]);
+    }
+    qtest_clear_rxbuf(s);
+    qos_object_queue_destroy(qos_obj);
+}
+
+static void virtio_net_ctrl_fuzz_multi(const unsigned char *Data, size_t Size)
+{
+    uint64_t req_addr[10];
+    int reqi =0;
+    uint32_t free_head;
+
+    QGuestAllocator *t_alloc = qos_alloc;
+
+    QVirtioNet *net_if = qos_obj;
+    QVirtioDevice *dev = net_if->vdev;
+    QVirtQueue *q;
+    vq_action vqa;
+    int iters=0;
+    while(Size >= sizeof(vqa)) {
+        vqa = *((vq_action*)Data);
+        Data += sizeof(vqa);
+        Size -= sizeof(vqa);
+        if(vqa.kick && free_head)
+        {
+            qvirtqueue_kick(dev, q, free_head);
+            qtest_clock_step_next(s);
+            main_loop_wait(false);
+            for(int i =0; i<reqi; i++)
+                guest_free(t_alloc, req_addr[i]);
+            reqi = 0;
+        }
+        else {
+            q = net_if->queues[2];
+
+            vqa.length = vqa.length >= Size ? Size :  vqa.length;
+
+            req_addr[reqi] = guest_alloc(t_alloc, vqa.length);
+            memwrite(req_addr[reqi], Data, vqa.length);
+            if(iters == 0)
+                free_head = qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;
+            else
+                qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;
+            iters++;
+            reqi++;
+            if(iters==10)
+                break;
+            Data += vqa.length;
+            Size -= vqa.length;
+        }
+    }
+    qtest_clear_rxbuf(s);
+    qos_object_queue_destroy(qos_obj);
+}
+
+int *sv;
+static void virtio_net_tx_fuzz(const unsigned char *Data, size_t Size)
+{
+    uint64_t req_addr[10];
+    int reqi =0;
+    uint32_t free_head;
+
+    QGuestAllocator *t_alloc = qos_alloc;
+
+    QVirtioNet *net_if = qos_obj;
+    QVirtioDevice *dev = net_if->vdev;
+    QVirtQueue *q;
+    vq_action vqa;
+    int iters=0;
+    while(true) {
+        if(Size < sizeof(vqa)) {
+            break;
+        }
+        vqa = *((vq_action*)Data);
+        Data += sizeof(vqa);
+        Size -= sizeof(vqa);
+
+        q = net_if->queues[1];
+
+        vqa.length = vqa.length >= Size ? Size :  vqa.length;
+
+        req_addr[reqi] = guest_alloc(t_alloc, vqa.length);
+        memwrite(req_addr[reqi], Data, vqa.length);
+        if(iters == 0)
+            free_head = qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;
+        else
+            qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;
+        iters++;
+        reqi++;
+        if(iters==10)
+            break;
+        Data += vqa.length;
+        Size -= vqa.length;
+    }
+    if(iters){
+        qvirtqueue_kick(dev, q, free_head);
+        qtest_clock_step_next(s);
+        main_loop_wait(false);
+        for(int i =0; i<reqi; i++)
+            guest_free(t_alloc, req_addr[i]);
+    }
+    qtest_clear_rxbuf(s);
+    qos_object_queue_destroy(qos_obj);
+}
+
+static void *virtio_net_test_setup_socket(GString *cmd_line, void *arg)
+{
+    if(!sv){
+        sv = g_new(int, 2);
+        int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
+        fcntl(sv[0], F_SETFL, O_NONBLOCK);
+        g_assert_cmpint(ret, !=, -1);
+    }
+    g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ", sv[1]);
+    return arg;
+}
+
+static void fuzz_fork(const unsigned char *Data, size_t Size){
+    if (fork() == 0) {
+        virtio_net_ctrl_fuzz(Data, Size);
+        counter_shm_store();
+        _Exit(0);
+    } 
+    else {
+        wait(NULL);
+        counter_shm_load();
+    }
+}
+
+static void fork_pre_main(void) {
+    qos_setup();
+    counter_shm_init();
+}
+
+static void register_virtio_net_fuzz_targets(void)
+{
+    QOSGraphTestOptions opts = {
+        .before = virtio_net_test_setup_socket,
+    };
+    fuzz_add_qos_target("virtio-net-ctrl-fuzz", "virtio-net ctrl virtqueue fuzzer",
+            "virtio-net", &opts, &qos_setup, NULL, NULL, &reboot,
+            &qos_init_path, &virtio_net_ctrl_fuzz, NULL);
+
+    fuzz_add_qos_target("virtio-net-ctrl-multi-fuzz", "virtio-net ctrl virtqueue \
+            fuzzer with multiple kicks",
+            "virtio-net", &opts, &qos_setup, NULL, NULL, &reboot,
+            &qos_init_path, &virtio_net_ctrl_fuzz_multi, NULL);
+
+    fuzz_add_qos_target("virtio-net-tx-fuzz", "virtio-net tx virtqueue fuzzer",
+            "virtio-net", &opts, &qos_setup, NULL, NULL, &reboot,
+            &qos_init_path, &virtio_net_tx_fuzz, NULL);
+
+    // TODO: This doesn't work. Possibly due to threading..
+    fuzz_add_qos_target("virtio-net-fork", "virtio-net tx virtqueue",
+            "virtio-net", &opts, &fork_pre_main, &qos_init_path, NULL, NULL,
+            NULL, &fuzz_fork, NULL);
+}
+
+fuzz_target_init(register_virtio_net_fuzz_targets);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [Qemu-devel] [RFC 19/19] fuzz: Add documentation about the fuzzer to docs/
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (17 preceding siblings ...)
  2019-07-25  3:24 ` [Qemu-devel] [RFC 18/19] fuzz: Add virtio-net tx and ctrl fuzz targets Oleinik, Alexander
@ 2019-07-25  3:24 ` Oleinik, Alexander
  2019-07-26 13:19   ` Stefan Hajnoczi
  2019-07-25  3:41 ` [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support no-reply
                   ` (2 subsequent siblings)
  21 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25  3:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha, Oleinik,  Alexander

Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
---
 docs/devel/fuzzing.txt | 145 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 145 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..321e005e8c
--- /dev/null
+++ b/docs/devel/fuzzing.txt
@@ -0,0 +1,145 @@
+= Fuzzing =
+
+== Introduction ==
+
+This document describes the fuzzing infrastructure in QEMU and how to use it
+to add additional fuzzing targets.
+
+== 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.
+
+libfuzzer provides its own main() and expects the developer to implement the
+entrypoint "LLVMFuzzerTestOneInput".
+
+Currently, Fuzz targets are built out to fuzz virtual-devices from guests. The
+fuzz targets can use qtest and qos functions to pass inputs to virtual devices.
+
+== Main Modifications required for Fuzzing ==
+
+Fuzzing is enabled with the -enable-fuzzing flag, which adds the needed cflags
+to enable Libfuzzer and AddressSanitizer. In the code, most of the changes to
+existing qemu source are surrounded by #ifdef CONFIG_FUZZ statements. Here are
+the key areas that are changed:
+
+=== General Changes ===
+
+vl.c:main renamed to real_main to avoid conflicts when libfuzzer is linked in.
+Also, real_main returns where it would normally call main_loop. 
+
+The fuzzer adds an accelerator. The accelerator does not do anything, much
+like the qtest accelerator.
+
+=== Changes to SaveVM ===
+
+There aren't any particular changes to SaveVM, but the fuzzer adds a type
+of file "ramfile" implemented in test/fuzz/ramfile.c which allocates a buffer
+on the heap to which it saves the vmstate.
+
+=== Changes to QTest ===
+
+QEMU-fuzz modifies the qtest server(qtest.c) and qtest client
+(tests/libqtest.c) so that they communicate within the same QEMU process. In
+the qtest server, there is a qtest_init_fuzz function to initialize the
+QTestState. Normally, qtest commands are passed to socket_send which
+communicates the command to the server/QEMU process over a socket. The fuzzer,
+instead, directly calls the qtest server recieve function with the the command
+string as an argument. The server usually responds to commands with an "OK"
+command. To support this, there is an added qtest_client_recv function in
+libqtest.c, which the server calls directly.
+
+At the moment, qtest's qmp wrapper functions are not supported.
+
+=== Chages to QOS ===
+
+QOS tests are usually linked against the compiled tests/qos-test.c. The main
+function in this file initializes the QOS graph and uses some QMP commands to
+query the qtest server for the available devices. It also registers the tests
+implemented in all of the linked qos test-case files. Then it uses a DFS walker
+to iterate over QOS graph and determine the required QEMU devices/arguments and
+device initialization functions to perform each test.
+
+The fuzzer doesn't link against qos-test, but re-uses most of the functionality
+in test/fuzz/qos_helpers.c The major changes are that the walker simply saves
+the last QGraph path for later use in the fuzzer. The
+qos_set_machines_devices_available function is changed to directly used qmp_*
+commands. Note that to populate the QGraph, the fuzzer still needs to be linked
+against the devices described in test/libqos/*.o
+
+== 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.
+
+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.
+
+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 three 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. vmsave the state to RAM, once, and restore it after each run.
+   Alternatively only save the device state(savevm.c:qemu_save_device_state)
+   Pros: Do not need to initialize devices prior to each run.
+   VMStateDescriptions often specify more state the device resetting
+   functions called during reboots.
+   Cons: Restoring state is often slower than rebooting. There is
+   currently no way to save the QOS object state, so the objects usually
+   needs to be re-allocated, defeating the purpose of one-time device
+   initialization.
+   Example target: --qtest-fuzz
+3. 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
+
+== Adding new Targets ==
+1. Create a file : tests/fuzz/[file].c
+2. Add target registration function and fuzz_target_init(FUNC) at the bottom of
+the file.
+3. In the registration function, register targets using fuzz_add_qos_target or
+fuzz_add_target. The arguments to thes function specify the resetting method
+and QOS path.
+4. These functions refererence a fuzz function which should be a:
+static void func(const unsigned char* Data, size_t Size)
+Inside the fuzz function, translate the "Data" into qtest actions.
+5. Add [file].o to target/i386/Makefile.objs
+
+tests/fuzz/qtest_fuzz.c and tests/fuzz/virtio-net-fuzz.c both contain examples
+of fuzz targets that follow this structure.
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (18 preceding siblings ...)
  2019-07-25  3:24 ` [Qemu-devel] [RFC 19/19] fuzz: Add documentation about the fuzzer to docs/ Oleinik, Alexander
@ 2019-07-25  3:41 ` no-reply
  2019-07-26 13:24 ` Stefan Hajnoczi
  2019-08-06  9:59 ` jiade zhang
  21 siblings, 0 replies; 49+ messages in thread
From: no-reply @ 2019-07-25  3:41 UTC (permalink / raw)
  To: alxndr; +Cc: qemu-devel, alxndr, bsd, superirishdonkey, stefanha, pbonzini

Patchew URL: https://patchew.org/QEMU/20190725032321.12721-1-alxndr@bu.edu/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support
Message-id: 20190725032321.12721-1-alxndr@bu.edu

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/20190725032321.12721-1-alxndr@bu.edu -> patchew/20190725032321.12721-1-alxndr@bu.edu
 * [new tag]         patchew/20190725032722.32271-1-richardw.yang@linux.intel.com -> patchew/20190725032722.32271-1-richardw.yang@linux.intel.com
Submodule 'capstone' (https://git.qemu.org/git/capstone.git) registered for path 'capstone'
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (https://git.qemu.org/git/QemuMacDrivers.git) registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (https://git.qemu.org/git/SLOF.git) registered for path 'roms/SLOF'
Submodule 'roms/edk2' (https://git.qemu.org/git/edk2.git) registered for path 'roms/edk2'
Submodule 'roms/ipxe' (https://git.qemu.org/git/ipxe.git) registered for path 'roms/ipxe'
Submodule 'roms/openbios' (https://git.qemu.org/git/openbios.git) registered for path 'roms/openbios'
Submodule 'roms/openhackware' (https://git.qemu.org/git/openhackware.git) registered for path 'roms/openhackware'
Submodule 'roms/opensbi' (https://git.qemu.org/git/opensbi.git) registered for path 'roms/opensbi'
Submodule 'roms/qemu-palcode' (https://git.qemu.org/git/qemu-palcode.git) registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (https://git.qemu.org/git/seabios.git/) registered for path 'roms/seabios'
Submodule 'roms/seabios-hppa' (https://git.qemu.org/git/seabios-hppa.git) registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (https://git.qemu.org/git/sgabios.git) registered for path 'roms/sgabios'
Submodule 'roms/skiboot' (https://git.qemu.org/git/skiboot.git) registered for path 'roms/skiboot'
Submodule 'roms/u-boot' (https://git.qemu.org/git/u-boot.git) registered for path 'roms/u-boot'
Submodule 'roms/u-boot-sam460ex' (https://git.qemu.org/git/u-boot-sam460ex.git) registered for path 'roms/u-boot-sam460ex'
Submodule 'slirp' (https://git.qemu.org/git/libslirp.git) registered for path 'slirp'
Submodule 'tests/fp/berkeley-softfloat-3' (https://git.qemu.org/git/berkeley-softfloat-3.git) registered for path 'tests/fp/berkeley-softfloat-3'
Submodule 'tests/fp/berkeley-testfloat-3' (https://git.qemu.org/git/berkeley-testfloat-3.git) registered for path 'tests/fp/berkeley-testfloat-3'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out '22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out '90c488d5f4a407342247b9ea869df1c2d9c8e266'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 'ba1ab360eebe6338bb8d7d83a9220ccf7e213af3'
Cloning into 'roms/edk2'...
Submodule path 'roms/edk2': checked out '20d2e5a125e34fc8501026613a71549b2a1a3e54'
Submodule 'SoftFloat' (https://github.com/ucb-bar/berkeley-softfloat-3.git) registered for path 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'
Submodule 'CryptoPkg/Library/OpensslLib/openssl' (https://github.com/openssl/openssl) registered for path 'CryptoPkg/Library/OpensslLib/openssl'
Cloning into 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'...
Submodule path 'roms/edk2/ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3': checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'CryptoPkg/Library/OpensslLib/openssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl': checked out '50eaac9f3337667259de725451f201e784599687'
Submodule 'boringssl' (https://boringssl.googlesource.com/boringssl) registered for path 'boringssl'
Submodule 'krb5' (https://github.com/krb5/krb5) registered for path 'krb5'
Submodule 'pyca.cryptography' (https://github.com/pyca/cryptography.git) registered for path 'pyca-cryptography'
Cloning into 'boringssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/boringssl': checked out '2070f8ad9151dc8f3a73bffaa146b5e6937a583f'
Cloning into 'krb5'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/krb5': checked out 'b9ad6c49505c96a088326b62a52568e3484f2168'
Cloning into 'pyca-cryptography'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography': checked out '09403100de2f6f1cdd0d484dcb8e620f1c335c8f'
Cloning into 'roms/ipxe'...
Submodule path 'roms/ipxe': checked out 'de4565cbe76ea9f7913a01f331be3ee901bb6e17'
Cloning into 'roms/openbios'...
Submodule path 'roms/openbios': checked out 'c79e0ecb84f4f1ee3f73f521622e264edd1bf174'
Cloning into 'roms/openhackware'...
Submodule path 'roms/openhackware': checked out 'c559da7c8eec5e45ef1f67978827af6f0b9546f5'
Cloning into 'roms/opensbi'...
Submodule path 'roms/opensbi': checked out 'ce228ee0919deb9957192d723eecc8aaae2697c6'
Cloning into 'roms/qemu-palcode'...
Submodule path 'roms/qemu-palcode': checked out 'bf0e13698872450164fa7040da36a95d2d4b326f'
Cloning into 'roms/seabios'...
Submodule path 'roms/seabios': checked out 'a5cab58e9a3fb6e168aba919c5669bea406573b4'
Cloning into 'roms/seabios-hppa'...
Submodule path 'roms/seabios-hppa': checked out '0f4fe84658165e96ce35870fd19fc634e182e77b'
Cloning into 'roms/sgabios'...
Submodule path 'roms/sgabios': checked out 'cbaee52287e5f32373181cff50a00b6c4ac9015a'
Cloning into 'roms/skiboot'...
Submodule path 'roms/skiboot': checked out '261ca8e779e5138869a45f174caa49be6a274501'
Cloning into 'roms/u-boot'...
Submodule path 'roms/u-boot': checked out 'd3689267f92c5956e09cc7d1baa4700141662bff'
Cloning into 'roms/u-boot-sam460ex'...
Submodule path 'roms/u-boot-sam460ex': checked out '60b3916f33e617a815973c5a6df77055b2e3a588'
Cloning into 'slirp'...
Submodule path 'slirp': checked out 'f0da6726207b740f6101028b2992f918477a4b08'
Cloning into 'tests/fp/berkeley-softfloat-3'...
Submodule path 'tests/fp/berkeley-softfloat-3': checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'tests/fp/berkeley-testfloat-3'...
Submodule path 'tests/fp/berkeley-testfloat-3': checked out '5a59dcec19327396a011a17fd924aed4fec416b3'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out '6b3d716e2b6472eb7189d3220552280ef3d832ce'
Switched to a new branch 'test'
4c6f68c fuzz: Add documentation about the fuzzer to docs/
0c31cb1 fuzz: Add virtio-net tx and ctrl fuzz targets
01a57b5 fuzz: add general qtest fuzz target
213ed5a fuzz: add general fuzzer entrypoints
7022925 fuzz: add fuzz accelerator type
2ce2166 fuzz: hard-code a main-loop timeout
6c53625 fuzz: add ctrl vq support to virtio-net in libqos
7022ef2 fuzz: hard-code all of the needed files for build
4963c01 fuzz: add direct send/receive in qtest client
ee10a51 fuzz: expose real_main (aka regular vl.c:main)
e1ccf13 fuzz: use mtree_info to find mapped addresses
7bb630b fuzz: add shims to intercept libfuzzer init
a6a24b4 fuzz: Modify libqtest to directly invoke qtest.c
8ffe410 fuzz: Add ramfile for fast vmstate/vmload
abdb33d fuzz: expose qemu_savevm_state & skip state header
5dedcc7 fuzz: Add qos support to fuzz targets
b2fb746 fuzz: add fuzz accelerator
04e48ac fuzz: add FUZZ_TARGET type to qemu module system
c7cb281 fuzz: add configure option and linker objects

=== OUTPUT BEGIN ===
1/19 Checking commit c7cb2811d47f (fuzz: add configure option and linker objects)
ERROR: trailing whitespace
#69: FILE: target/i386/Makefile.objs:27:
+obj-$(CONFIG_FUZZ) += ../../tests/fuzz/virtio-net-fuzz.o $

ERROR: trailing whitespace
#72: FILE: target/i386/Makefile.objs:30:
+obj-$(CONFIG_FUZZ) += ../../tests/libqos/qgraph.o ../../tests/libqos/libqos.o $

total: 2 errors, 0 warnings, 59 lines checked

Patch 1/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

2/19 Checking commit 04e48acd61bb (fuzz: add FUZZ_TARGET type to qemu module system)
WARNING: line over 80 characters
#30: FILE: include/qemu/module.h:63:
+#define fuzz_target_init(function) module_init(function, MODULE_INIT_FUZZ_TARGET)

total: 0 errors, 1 warnings, 19 lines checked

Patch 2/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/19 Checking commit b2fb746fe6ca (fuzz: add fuzz accelerator)
WARNING: line over 80 characters
#24: FILE: include/sysemu/qtest.h:28:
+void qtest_init_server(const char *qtest_chrdev, const char *qtest_log, Error **errp);

total: 0 errors, 1 warnings, 13 lines checked

Patch 3/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
4/19 Checking commit 5dedcc715012 (fuzz: Add qos support to fuzz targets)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#13: 
new file mode 100644

ERROR: do not initialise globals to 0 or NULL
#46: FILE: tests/fuzz/qos_fuzz.c:29:
+uint64_t total_io_mem = 0;

ERROR: do not initialise globals to 0 or NULL
#47: FILE: tests/fuzz/qos_fuzz.c:30:
+uint64_t total_ram_mem = 0;

ERROR: do not use C99 // comments
#50: FILE: tests/fuzz/qos_fuzz.c:33:
+//TODO: Put arguments in a neater struct

ERROR: "foo* bar" should be "foo *bar"
#51: FILE: tests/fuzz/qos_fuzz.c:34:
+void fuzz_add_qos_target(const char* name,

ERROR: code indent should never use tabs
#52: FILE: tests/fuzz/qos_fuzz.c:35:
+^I^Iconst char* description,$

ERROR: "foo* bar" should be "foo *bar"
#52: FILE: tests/fuzz/qos_fuzz.c:35:
+               const char* description,

ERROR: code indent should never use tabs
#53: FILE: tests/fuzz/qos_fuzz.c:36:
+^I^Iconst char* interface,$

ERROR: "foo* bar" should be "foo *bar"
#53: FILE: tests/fuzz/qos_fuzz.c:36:
+               const char* interface,

ERROR: code indent should never use tabs
#54: FILE: tests/fuzz/qos_fuzz.c:37:
+^I^IQOSGraphTestOptions* opts,$

ERROR: "foo* bar" should be "foo *bar"
#54: FILE: tests/fuzz/qos_fuzz.c:37:
+               QOSGraphTestOptions* opts,

ERROR: code indent should never use tabs
#55: FILE: tests/fuzz/qos_fuzz.c:38:
+^I^Ivoid(*init_pre_main)(void),$

ERROR: code indent should never use tabs
#56: FILE: tests/fuzz/qos_fuzz.c:39:
+^I^Ivoid(*init_pre_save)(void),$

ERROR: code indent should never use tabs
#57: FILE: tests/fuzz/qos_fuzz.c:40:
+^I^Ivoid(*save_state)(void),$

ERROR: code indent should never use tabs
#58: FILE: tests/fuzz/qos_fuzz.c:41:
+^I^Ivoid(*reset)(void),$

ERROR: code indent should never use tabs
#59: FILE: tests/fuzz/qos_fuzz.c:42:
+^I^Ivoid(*pre_fuzz)(void),$

ERROR: code indent should never use tabs
#60: FILE: tests/fuzz/qos_fuzz.c:43:
+^I^Ivoid(*fuzz)(const unsigned char*, size_t),$

ERROR: code indent should never use tabs
#61: FILE: tests/fuzz/qos_fuzz.c:44:
+^I^Ivoid(*post_fuzz)(void))$

ERROR: code indent should never use tabs
#63: FILE: tests/fuzz/qos_fuzz.c:46:
+^Iqos_add_test(name, interface, NULL, opts);$

ERROR: code indent should never use tabs
#64: FILE: tests/fuzz/qos_fuzz.c:47:
+^Ifuzz_add_target(name, description, init_pre_main, init_pre_save,$

ERROR: line over 90 characters
#65: FILE: tests/fuzz/qos_fuzz.c:48:
+                       save_state, reset, pre_fuzz, fuzz, post_fuzz, &qos_argc, &qos_argv);

ERROR: code indent should never use tabs
#65: FILE: tests/fuzz/qos_fuzz.c:48:
+^I^I^Isave_state, reset, pre_fuzz, fuzz, post_fuzz, &qos_argc, &qos_argv);$

ERROR: do not use C99 // comments
#69: FILE: tests/fuzz/qos_fuzz.c:52:
+// Do what is normally done in qos_test.c:main

ERROR: code indent should never use tabs
#71: FILE: tests/fuzz/qos_fuzz.c:54:
+^Iqtest_setup();$

ERROR: code indent should never use tabs
#72: FILE: tests/fuzz/qos_fuzz.c:55:
+^Iqos_set_machines_devices_available();$

ERROR: code indent should never use tabs
#73: FILE: tests/fuzz/qos_fuzz.c:56:
+^Iqos_graph_foreach_test_path(walk_path);$

ERROR: code indent should never use tabs
#74: FILE: tests/fuzz/qos_fuzz.c:57:
+^Iqos_build_main_args();$

ERROR: code indent should never use tabs
#79: FILE: tests/fuzz/qos_fuzz.c:62:
+^Iqos_obj = qos_allocate_objects(global_qtest, &qos_alloc);$

ERROR: "foo* bar" should be "foo *bar"
#98: FILE: tests/fuzz/qos_fuzz.h:12:
+extern void* qos_obj;

ERROR: "foo* bar" should be "foo *bar"
#102: FILE: tests/fuzz/qos_fuzz.h:16:
+void fuzz_add_qos_target(const char* name,

ERROR: code indent should never use tabs
#103: FILE: tests/fuzz/qos_fuzz.h:17:
+^I^Iconst char* description,$

ERROR: "foo* bar" should be "foo *bar"
#103: FILE: tests/fuzz/qos_fuzz.h:17:
+               const char* description,

ERROR: code indent should never use tabs
#104: FILE: tests/fuzz/qos_fuzz.h:18:
+^I^Iconst char* interface,$

ERROR: "foo* bar" should be "foo *bar"
#104: FILE: tests/fuzz/qos_fuzz.h:18:
+               const char* interface,

ERROR: code indent should never use tabs
#105: FILE: tests/fuzz/qos_fuzz.h:19:
+^I^IQOSGraphTestOptions* opts,$

ERROR: "foo* bar" should be "foo *bar"
#105: FILE: tests/fuzz/qos_fuzz.h:19:
+               QOSGraphTestOptions* opts,

ERROR: code indent should never use tabs
#106: FILE: tests/fuzz/qos_fuzz.h:20:
+^I^Ivoid(*init_pre_main)(void),$

ERROR: code indent should never use tabs
#107: FILE: tests/fuzz/qos_fuzz.h:21:
+^I^Ivoid(*init_pre_save)(void),$

ERROR: code indent should never use tabs
#108: FILE: tests/fuzz/qos_fuzz.h:22:
+^I^Ivoid(*save_state)(void),$

ERROR: code indent should never use tabs
#109: FILE: tests/fuzz/qos_fuzz.h:23:
+^I^Ivoid(*reset)(void),$

ERROR: code indent should never use tabs
#110: FILE: tests/fuzz/qos_fuzz.h:24:
+^I^Ivoid(*pre_fuzz)(void),$

ERROR: code indent should never use tabs
#111: FILE: tests/fuzz/qos_fuzz.h:25:
+^I^Ivoid(*fuzz)(const unsigned char*, size_t),$

ERROR: code indent should never use tabs
#112: FILE: tests/fuzz/qos_fuzz.h:26:
+^I^Ivoid(*post_fuzz)(void));$

ERROR: trailing whitespace
#139: FILE: tests/fuzz/qos_helpers.c:18:
+/* $

ERROR: trailing whitespace
#204: FILE: tests/fuzz/qos_helpers.c:83:
+    Error *err =NULL; $

ERROR: spaces required around that '=' (ctx:WxV)
#204: FILE: tests/fuzz/qos_helpers.c:83:
+    Error *err =NULL; 
                ^

ERROR: space required after that ',' (ctx:VxO)
#206: FILE: tests/fuzz/qos_helpers.c:85:
+    qmp_marshal_query_machines(NULL,&response, &err);
                                    ^

ERROR: space required before that '&' (ctx:OxV)
#206: FILE: tests/fuzz/qos_helpers.c:85:
+    qmp_marshal_query_machines(NULL,&response, &err);
                                     ^

ERROR: space prohibited before that close parenthesis ')'
#214: FILE: tests/fuzz/qos_helpers.c:93:
+    qdict_put_str(req, "execute", "qom-list-types" );

ERROR: space prohibited before that close parenthesis ')'
#215: FILE: tests/fuzz/qos_helpers.c:94:
+    qdict_put_str(args, "implements", "device" );

ERROR: "(foo*)" should be "(foo *)"
#217: FILE: tests/fuzz/qos_helpers.c:96:
+    qdict_put_obj(req, "arguments", (QObject*) args);

ERROR: switch and case should be at the same indent
#276: FILE: tests/fuzz/qos_helpers.c:155:
+        switch (qos_graph_edge_get_type(edge)) {
+            case QEDGE_PRODUCES:
[...]
+            case QEDGE_CONSUMED_BY:
[...]
+            case QEDGE_CONTAINS:

ERROR: "foo* bar" should be "foo *bar"
#295: FILE: tests/fuzz/qos_helpers.c:174:
+void* qos_obj;

ERROR: line over 90 characters
#317: FILE: tests/fuzz/qos_helpers.c:196:
+    g_string_prepend(cmd_line, "qemu-system-i386 -display none -machine accel=fuzz -m 3 ");

ERROR: space prohibited between function name and open parenthesis '('
#319: FILE: tests/fuzz/qos_helpers.c:198:
+    wordexp (cmd_line->str, &result, 0);

WARNING: line over 80 characters
#332: FILE: tests/fuzz/qos_helpers.c:211:
+    /* etype set to QEDGE_CONSUMED_BY so that machine can add to the command line */

WARNING: Block comments use a leading /* on a separate line
#393: FILE: tests/fuzz/qos_helpers.c:272:
+    /* here position 0 has <arch>/<machine>, position 1 has <machine>.

ERROR: do not use C99 // comments
#398: FILE: tests/fuzz/qos_helpers.c:277:
+    // Check that this is the test we care about:

ERROR: spaces required around that '+' (ctx:VxV)
#399: FILE: tests/fuzz/qos_helpers.c:278:
+    char *test_name = strrchr(path_str, '/')+1;
                                             ^

ERROR: that open brace { should be on the previous line
#400: FILE: tests/fuzz/qos_helpers.c:279:
+    if(strcmp(test_name, fuzz_target->name->str) == 0)
+    {

ERROR: space required before the open parenthesis '('
#400: FILE: tests/fuzz/qos_helpers.c:279:
+    if(strcmp(test_name, fuzz_target->name->str) == 0)

WARNING: Block comments use a leading /* on a separate line
#402: FILE: tests/fuzz/qos_helpers.c:281:
+        /* put arch/machine in position 1 so run_one_test can do its work

ERROR: line over 90 characters
#407: FILE: tests/fuzz/qos_helpers.c:286:
+        printf("path_str: %s path_vec[0]: %s [1]: %s\n", path_str, path_vec[0], path_vec[1]);

ERROR: trailing whitespace
#410: FILE: tests/fuzz/qos_helpers.c:289:
+    } $

ERROR: else should follow close brace '}'
#411: FILE: tests/fuzz/qos_helpers.c:290:
+    } 
+    else {

total: 61 errors, 4 warnings, 404 lines checked

Patch 4/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

5/19 Checking commit abdb33d4e984 (fuzz: expose qemu_savevm_state & skip state header)
6/19 Checking commit 8ffe41081f28 (fuzz: Add ramfile for fast vmstate/vmload)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14: 
new file mode 100644

WARNING: line over 80 characters
#20: FILE: tests/fuzz/ramfile.c:2:
+ * =====================================================================================

WARNING: line over 80 characters
#24: FILE: tests/fuzz/ramfile.c:6:
+ *    Description:  QEMUFile stored in dynamically allocated RAM for fast VMRestore

ERROR: trailing whitespace
#27: FILE: tests/fuzz/ramfile.c:9:
+ *   Organization:  $

WARNING: line over 80 characters
#29: FILE: tests/fuzz/ramfile.c:11:
+ * =====================================================================================

WARNING: Block comments use a leading /* on a separate line
#52: FILE: tests/fuzz/ramfile.c:34:
+    int64_t pos; /* start of buffer when writing, end of buffer

WARNING: Block comments use * on subsequent lines
#53: FILE: tests/fuzz/ramfile.c:35:
+    int64_t pos; /* start of buffer when writing, end of buffer
+                    when reading */

WARNING: Block comments use a trailing */ on a separate line
#53: FILE: tests/fuzz/ramfile.c:35:
+                    when reading */

ERROR: code indent should never use tabs
#68: FILE: tests/fuzz/ramfile.c:50:
+^Iram_disk *rd = (ram_disk*)opaque;$

ERROR: "(foo*)" should be "(foo *)"
#68: FILE: tests/fuzz/ramfile.c:50:
+       ram_disk *rd = (ram_disk*)opaque;

ERROR: code indent should never use tabs
#69: FILE: tests/fuzz/ramfile.c:51:
+^Igsize newsize;$

ERROR: code indent should never use tabs
#70: FILE: tests/fuzz/ramfile.c:52:
+^Issize_t total_size = 0;$

ERROR: code indent should never use tabs
#71: FILE: tests/fuzz/ramfile.c:53:
+^Iint i;$

ERROR: code indent should never use tabs
#72: FILE: tests/fuzz/ramfile.c:54:
+^Iif(!rd->base) {$

ERROR: space required before the open parenthesis '('
#72: FILE: tests/fuzz/ramfile.c:54:
+       if(!rd->base) {

ERROR: code indent should never use tabs
#73: FILE: tests/fuzz/ramfile.c:55:
+^I^Ird->base = g_malloc(INCREMENT);$

ERROR: code indent should never use tabs
#74: FILE: tests/fuzz/ramfile.c:56:
+^I^Ird->len = INCREMENT;$

ERROR: code indent should never use tabs
#75: FILE: tests/fuzz/ramfile.c:57:
+^I}$

ERROR: code indent should never use tabs
#76: FILE: tests/fuzz/ramfile.c:58:
+^Ifor(i = 0; i< iovcnt; i++)$

ERROR: that open brace { should be on the previous line
#76: FILE: tests/fuzz/ramfile.c:58:
+       for(i = 0; i< iovcnt; i++)
+       {

ERROR: spaces required around that '<' (ctx:VxW)
#76: FILE: tests/fuzz/ramfile.c:58:
+       for(i = 0; i< iovcnt; i++)
                    ^

ERROR: space required before the open parenthesis '('
#76: FILE: tests/fuzz/ramfile.c:58:
+       for(i = 0; i< iovcnt; i++)

ERROR: code indent should never use tabs
#77: FILE: tests/fuzz/ramfile.c:59:
+^I{$

ERROR: code indent should never use tabs
#78: FILE: tests/fuzz/ramfile.c:60:
+^I^Iif(pos+iov[i].iov_len >= rd->len ){$

ERROR: spaces required around that '+' (ctx:VxV)
#78: FILE: tests/fuzz/ramfile.c:60:
+               if(pos+iov[i].iov_len >= rd->len ){
                      ^

ERROR: space required before the open brace '{'
#78: FILE: tests/fuzz/ramfile.c:60:
+               if(pos+iov[i].iov_len >= rd->len ){

ERROR: space prohibited before that close parenthesis ')'
#78: FILE: tests/fuzz/ramfile.c:60:
+               if(pos+iov[i].iov_len >= rd->len ){

ERROR: space required before the open parenthesis '('
#78: FILE: tests/fuzz/ramfile.c:60:
+               if(pos+iov[i].iov_len >= rd->len ){

WARNING: line over 80 characters
#79: FILE: tests/fuzz/ramfile.c:61:
+                       newsize = ((pos + iov[i].iov_len)/INCREMENT + 1) * INCREMENT;

ERROR: code indent should never use tabs
#79: FILE: tests/fuzz/ramfile.c:61:
+^I^I^Inewsize = ((pos + iov[i].iov_len)/INCREMENT + 1) * INCREMENT;$

ERROR: spaces required around that '/' (ctx:VxV)
#79: FILE: tests/fuzz/ramfile.c:61:
+                       newsize = ((pos + iov[i].iov_len)/INCREMENT + 1) * INCREMENT;
                                                         ^

ERROR: code indent should never use tabs
#80: FILE: tests/fuzz/ramfile.c:62:
+^I^I^Ird->base = g_realloc(rd->base, newsize);$

ERROR: code indent should never use tabs
#81: FILE: tests/fuzz/ramfile.c:63:
+^I^I^Ird->len = newsize;$

ERROR: code indent should never use tabs
#82: FILE: tests/fuzz/ramfile.c:64:
+^I^I}$

ERROR: code indent should never use tabs
#83: FILE: tests/fuzz/ramfile.c:65:
+^I^I/* for(int j =0; j<iov[i].iov_len; j++){ */$

ERROR: code indent should never use tabs
#84: FILE: tests/fuzz/ramfile.c:66:
+^I^I/* ^Iprintf("%hhx",*((char*)iov[i].iov_base+j)); */$

ERROR: code indent should never use tabs
#85: FILE: tests/fuzz/ramfile.c:67:
+^I^I/* } */$

ERROR: code indent should never use tabs
#86: FILE: tests/fuzz/ramfile.c:68:
+^I^Imemcpy(rd->base + pos, iov[i].iov_base, iov[i].iov_len);$

ERROR: code indent should never use tabs
#87: FILE: tests/fuzz/ramfile.c:69:
+^I^Ipos += iov[i].iov_len;$

ERROR: code indent should never use tabs
#88: FILE: tests/fuzz/ramfile.c:70:
+^I^Itotal_size += iov[i].iov_len;$

ERROR: code indent should never use tabs
#89: FILE: tests/fuzz/ramfile.c:71:
+^I}$

ERROR: code indent should never use tabs
#90: FILE: tests/fuzz/ramfile.c:72:
+^Ireturn total_size;$

ERROR: code indent should never use tabs
#96: FILE: tests/fuzz/ramfile.c:78:
+^Iram_disk *rd = (ram_disk*)opaque;$

ERROR: "(foo*)" should be "(foo *)"
#96: FILE: tests/fuzz/ramfile.c:78:
+       ram_disk *rd = (ram_disk*)opaque;

ERROR: code indent should never use tabs
#97: FILE: tests/fuzz/ramfile.c:79:
+^Iif(pos+size>rd->len){$

ERROR: spaces required around that '+' (ctx:VxV)
#97: FILE: tests/fuzz/ramfile.c:79:
+       if(pos+size>rd->len){
              ^

ERROR: spaces required around that '>' (ctx:VxV)
#97: FILE: tests/fuzz/ramfile.c:79:
+       if(pos+size>rd->len){
                   ^

ERROR: space required before the open brace '{'
#97: FILE: tests/fuzz/ramfile.c:79:
+       if(pos+size>rd->len){

ERROR: space required before the open parenthesis '('
#97: FILE: tests/fuzz/ramfile.c:79:
+       if(pos+size>rd->len){

ERROR: code indent should never use tabs
#98: FILE: tests/fuzz/ramfile.c:80:
+^I^Iif(rd->len-pos>=0){$

ERROR: spaces required around that '-' (ctx:VxV)
#98: FILE: tests/fuzz/ramfile.c:80:
+               if(rd->len-pos>=0){
                          ^

ERROR: spaces required around that '>=' (ctx:VxV)
#98: FILE: tests/fuzz/ramfile.c:80:
+               if(rd->len-pos>=0){
                              ^

ERROR: space required before the open brace '{'
#98: FILE: tests/fuzz/ramfile.c:80:
+               if(rd->len-pos>=0){

ERROR: space required before the open parenthesis '('
#98: FILE: tests/fuzz/ramfile.c:80:
+               if(rd->len-pos>=0){

ERROR: code indent should never use tabs
#99: FILE: tests/fuzz/ramfile.c:81:
+^I^I^Imemcpy(buf, rd->base + pos, rd->len-pos);$

ERROR: spaces required around that '-' (ctx:VxV)
#99: FILE: tests/fuzz/ramfile.c:81:
+                       memcpy(buf, rd->base + pos, rd->len-pos);
                                                           ^

ERROR: code indent should never use tabs
#100: FILE: tests/fuzz/ramfile.c:82:
+^I^I^Isize = rd->len-pos;$

ERROR: spaces required around that '-' (ctx:VxV)
#100: FILE: tests/fuzz/ramfile.c:82:
+                       size = rd->len-pos;
                                      ^

ERROR: code indent should never use tabs
#101: FILE: tests/fuzz/ramfile.c:83:
+^I^I}$

ERROR: code indent should never use tabs
#102: FILE: tests/fuzz/ramfile.c:84:
+^I}$

ERROR: code indent should never use tabs
#103: FILE: tests/fuzz/ramfile.c:85:
+^Ielse$

ERROR: else should follow close brace '}'
#103: FILE: tests/fuzz/ramfile.c:85:
+       }
+       else

ERROR: code indent should never use tabs
#104: FILE: tests/fuzz/ramfile.c:86:
+^I^Imemcpy(buf, rd->base + pos, size);$

ERROR: code indent should never use tabs
#105: FILE: tests/fuzz/ramfile.c:87:
+^Ireturn size;$

ERROR: code indent should never use tabs
#110: FILE: tests/fuzz/ramfile.c:92:
+^Ireturn 0;$

ERROR: open brace '{' following function declarations go on the next line
#123: FILE: tests/fuzz/ramfile.c:105:
+QEMUFile *qemu_fopen_ram(ram_disk **return_rd) {

ERROR: code indent should never use tabs
#124: FILE: tests/fuzz/ramfile.c:106:
+^Iram_disk *rd = g_new0(ram_disk, 1);$

ERROR: code indent should never use tabs
#125: FILE: tests/fuzz/ramfile.c:107:
+^I*return_rd=rd;$

ERROR: spaces required around that '=' (ctx:VxV)
#125: FILE: tests/fuzz/ramfile.c:107:
+       *return_rd=rd;
                  ^

ERROR: code indent should never use tabs
#126: FILE: tests/fuzz/ramfile.c:108:
+^Ireturn qemu_fopen_ops(rd, &ram_write_ops);$

ERROR: open brace '{' following function declarations go on the next line
#129: FILE: tests/fuzz/ramfile.c:111:
+QEMUFile *qemu_fopen_ro_ram(ram_disk* rd) {

ERROR: "foo* bar" should be "foo *bar"
#133: FILE: tests/fuzz/ramfile.c:115:
+void qemu_freopen_ro_ram(QEMUFile* f) {

ERROR: open brace '{' following function declarations go on the next line
#133: FILE: tests/fuzz/ramfile.c:115:
+void qemu_freopen_ro_ram(QEMUFile* f) {

ERROR: code indent should never use tabs
#134: FILE: tests/fuzz/ramfile.c:116:
+^Ivoid *rd = f->opaque;$

ERROR: code indent should never use tabs
#135: FILE: tests/fuzz/ramfile.c:117:
+^If->bytes_xfer=0;$

ERROR: spaces required around that '=' (ctx:VxV)
#135: FILE: tests/fuzz/ramfile.c:117:
+       f->bytes_xfer=0;
                     ^

ERROR: code indent should never use tabs
#136: FILE: tests/fuzz/ramfile.c:118:
+^If->xfer_limit=0;$

ERROR: spaces required around that '=' (ctx:VxV)
#136: FILE: tests/fuzz/ramfile.c:118:
+       f->xfer_limit=0;
                     ^

ERROR: code indent should never use tabs
#137: FILE: tests/fuzz/ramfile.c:119:
+^If->last_error=0;$

ERROR: spaces required around that '=' (ctx:VxV)
#137: FILE: tests/fuzz/ramfile.c:119:
+       f->last_error=0;
                     ^

ERROR: code indent should never use tabs
#138: FILE: tests/fuzz/ramfile.c:120:
+^If->iovcnt=0;$

ERROR: spaces required around that '=' (ctx:VxV)
#138: FILE: tests/fuzz/ramfile.c:120:
+       f->iovcnt=0;
                 ^

ERROR: code indent should never use tabs
#139: FILE: tests/fuzz/ramfile.c:121:
+^If->buf_index=0;$

ERROR: spaces required around that '=' (ctx:VxV)
#139: FILE: tests/fuzz/ramfile.c:121:
+       f->buf_index=0;
                    ^

ERROR: code indent should never use tabs
#140: FILE: tests/fuzz/ramfile.c:122:
+^If->buf_size=0;$

ERROR: spaces required around that '=' (ctx:VxV)
#140: FILE: tests/fuzz/ramfile.c:122:
+       f->buf_size=0;
                   ^

ERROR: code indent should never use tabs
#141: FILE: tests/fuzz/ramfile.c:123:
+^If->pos=0;$

ERROR: spaces required around that '=' (ctx:VxV)
#141: FILE: tests/fuzz/ramfile.c:123:
+       f->pos=0;
              ^

ERROR: code indent should never use tabs
#142: FILE: tests/fuzz/ramfile.c:124:
+^If->ops = &ram_read_ops;$

ERROR: code indent should never use tabs
#143: FILE: tests/fuzz/ramfile.c:125:
+^If->opaque = rd;$

ERROR: code indent should never use tabs
#144: FILE: tests/fuzz/ramfile.c:126:
+^Ireturn;$

ERROR: code indent should never use tabs
#163: FILE: tests/fuzz/ramfile.h:12:
+^Ivoid *base;$

ERROR: code indent should never use tabs
#164: FILE: tests/fuzz/ramfile.h:13:
+^Igsize len;$

ERROR: "foo* bar" should be "foo *bar"
#169: FILE: tests/fuzz/ramfile.h:18:
+void qemu_freopen_ro_ram(QEMUFile* f);

total: 86 errors, 8 warnings, 147 lines checked

Patch 6/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

7/19 Checking commit a6a24b4ea5d9 (fuzz: Modify libqtest to directly invoke qtest.c)
ERROR: do not use C99 // comments
#62: FILE: tests/libqtest.c:403:
+    // Directly call qtest_process_inbuf in the qtest server

ERROR: code indent should never use tabs
#64: FILE: tests/libqtest.c:405:
+^I/* printf(">>> %s",gstr->str); */$

ERROR: space required before the open brace '{'
#113: FILE: tests/libqtest.c:1381:
+void qtest_clear_rxbuf(QTestState *s){

ERROR: space required after that ',' (ctx:VxV)
#114: FILE: tests/libqtest.c:1382:
+    g_string_set_size(recv_str,0);
                               ^

ERROR: space required before the open parenthesis '('
#119: FILE: tests/libqtest.c:1387:
+    if(!recv_str)

ERROR: braces {} are necessary for all arms of this statement
#119: FILE: tests/libqtest.c:1387:
+    if(!recv_str)
[...]

total: 6 errors, 0 warnings, 111 lines checked

Patch 7/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

8/19 Checking commit 7bb630b8ab1d (fuzz: add shims to intercept libfuzzer init)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#15: 
new file mode 100644

ERROR: "foo* bar" should be "foo *bar"
#30: FILE: tests/fuzz/fuzzer_hooks.c:11:
+extern void* _ZN6fuzzer3TPCE;

ERROR: externs should be avoided in .c files
#30: FILE: tests/fuzz/fuzzer_hooks.c:11:
+extern void* _ZN6fuzzer3TPCE;

ERROR: do not use C99 // comments
#31: FILE: tests/fuzz/fuzzer_hooks.c:12:
+// The libfuzzer handlers

ERROR: externs should be avoided in .c files
#32: FILE: tests/fuzz/fuzzer_hooks.c:13:
+void __real___sanitizer_cov_8bit_counters_init(uint8_t*, uint8_t*);

ERROR: externs should be avoided in .c files
#33: FILE: tests/fuzz/fuzzer_hooks.c:14:
+void __real___sanitizer_cov_trace_pc_guard_init(uint8_t*, uint8_t*);

ERROR: externs should be avoided in .c files
#35: FILE: tests/fuzz/fuzzer_hooks.c:16:
+void __wrap___sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop);

ERROR: externs should be avoided in .c files
#36: FILE: tests/fuzz/fuzzer_hooks.c:17:
+void __wrap___sanitizer_cov_trace_pc_guard_init(uint8_t *Start, uint8_t *Stop);

ERROR: "foo* bar" should be "foo *bar"
#39: FILE: tests/fuzz/fuzzer_hooks.c:20:
+void* counter_shm;

ERROR: "foo* bar" should be "foo *bar"
#42: FILE: tests/fuzz/fuzzer_hooks.c:23:
+    uint8_t* start;

ERROR: do not initialise globals to 0 or NULL
#48: FILE: tests/fuzz/fuzzer_hooks.c:29:
+int region_index = 0;

ERROR: spaces required around that '-' (ctx:VxV)
#53: FILE: tests/fuzz/fuzzer_hooks.c:34:
+    regions[region_index].length = Stop-Start;
                                        ^

ERROR: spaces required around that '-' (ctx:VxV)
#62: FILE: tests/fuzz/fuzzer_hooks.c:43:
+    regions[region_index++].length = Stop-Start;
                                          ^

ERROR: "(foo*)" should be "(foo *)"
#71: FILE: tests/fuzz/fuzzer_hooks.c:52:
+    regions[region_index].start = (uint8_t*)(&_ZN6fuzzer3TPCE);

ERROR: trailing whitespace
#72: FILE: tests/fuzz/fuzzer_hooks.c:53:
+    regions[region_index].length = 0x443c00; $

ERROR: trailing whitespace
#83: FILE: tests/fuzz/fuzzer_hooks.c:64:
+    add_tpc_region(); $

ERROR: spaces required around that '=' (ctx:VxV)
#86: FILE: tests/fuzz/fuzzer_hooks.c:67:
+    for(int i=0; i<region_index; i++){
              ^

ERROR: spaces required around that '<' (ctx:VxV)
#86: FILE: tests/fuzz/fuzzer_hooks.c:67:
+    for(int i=0; i<region_index; i++){
                   ^

ERROR: space required before the open brace '{'
#86: FILE: tests/fuzz/fuzzer_hooks.c:67:
+    for(int i=0; i<region_index; i++){

ERROR: space required before the open parenthesis '('
#86: FILE: tests/fuzz/fuzzer_hooks.c:67:
+    for(int i=0; i<region_index; i++){

ERROR: trailing whitespace
#91: FILE: tests/fuzz/fuzzer_hooks.c:72:
+    /* $

WARNING: Block comments use a trailing */ on a separate line
#94: FILE: tests/fuzz/fuzzer_hooks.c:75:
+     * */

ERROR: trailing whitespace
#95: FILE: tests/fuzz/fuzzer_hooks.c:76:
+    counter_shm = mmap(NULL, length, PROT_READ | PROT_WRITE, $

ERROR: space required before the open parenthesis '('
#97: FILE: tests/fuzz/fuzzer_hooks.c:78:
+    if(counter_shm == MAP_FAILED) {

ERROR: suspicious ; after while (0)
#99: FILE: tests/fuzz/fuzzer_hooks.c:80:
+        do { perror("error:"); exit(EXIT_FAILURE); } while (0);

ERROR: spaces required around that '=' (ctx:VxV)
#107: FILE: tests/fuzz/fuzzer_hooks.c:88:
+    for(int i=0; i<region_index; i++) {
              ^

ERROR: spaces required around that '<' (ctx:VxV)
#107: FILE: tests/fuzz/fuzzer_hooks.c:88:
+    for(int i=0; i<region_index; i++) {
                   ^

ERROR: space required before the open parenthesis '('
#107: FILE: tests/fuzz/fuzzer_hooks.c:88:
+    for(int i=0; i<region_index; i++) {

ERROR: space required before the open parenthesis '('
#108: FILE: tests/fuzz/fuzzer_hooks.c:89:
+        if(regions[i].store) {

ERROR: spaces required around that '+=' (ctx:VxV)
#111: FILE: tests/fuzz/fuzzer_hooks.c:92:
+        offset+=regions[i].length;
               ^

ERROR: spaces required around that '=' (ctx:VxV)
#118: FILE: tests/fuzz/fuzzer_hooks.c:99:
+    for(int i=0; i<region_index; i++) {
              ^

ERROR: spaces required around that '<' (ctx:VxV)
#118: FILE: tests/fuzz/fuzzer_hooks.c:99:
+    for(int i=0; i<region_index; i++) {
                   ^

ERROR: space required before the open parenthesis '('
#118: FILE: tests/fuzz/fuzzer_hooks.c:99:
+    for(int i=0; i<region_index; i++) {

ERROR: space required before the open parenthesis '('
#119: FILE: tests/fuzz/fuzzer_hooks.c:100:
+        if(regions[i].store) {

ERROR: spaces required around that '+=' (ctx:VxV)
#122: FILE: tests/fuzz/fuzzer_hooks.c:103:
+        offset+=regions[i].length;
               ^

total: 33 errors, 2 warnings, 115 lines checked

Patch 8/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

9/19 Checking commit e1ccf1346499 (fuzz: use mtree_info to find mapped addresses)
ERROR: spaces required around that '=' (ctx:VxV)
#35: FILE: memory.c:3025:
+    bool io=false;
            ^

ERROR: space required after that ',' (ctx:VxV)
#45: FILE: memory.c:3035:
+        if(strcmp("I/O",as->name) == 0)
                        ^

ERROR: space required before the open parenthesis '('
#45: FILE: memory.c:3035:
+        if(strcmp("I/O",as->name) == 0)

ERROR: braces {} are necessary for all arms of this statement
#45: FILE: memory.c:3035:
+        if(strcmp("I/O",as->name) == 0)
[...]

ERROR: line over 90 characters
#56: FILE: memory.c:3079:
+        if(strcmp("i/o", memory_region_type(mr))==0 && strcmp("io", memory_region_name(mr))){

ERROR: spaces required around that '==' (ctx:VxV)
#56: FILE: memory.c:3079:
+        if(strcmp("i/o", memory_region_type(mr))==0 && strcmp("io", memory_region_name(mr))){
                                                 ^

ERROR: space required before the open brace '{'
#56: FILE: memory.c:3079:
+        if(strcmp("i/o", memory_region_type(mr))==0 && strcmp("io", memory_region_name(mr))){

ERROR: space required before the open parenthesis '('
#56: FILE: memory.c:3079:
+        if(strcmp("i/o", memory_region_type(mr))==0 && strcmp("io", memory_region_name(mr))){

ERROR: that open brace { should be on the previous line
#58: FILE: memory.c:3081:
+            if(!fuzz_memory_region_head)
+            {

ERROR: space required before the open parenthesis '('
#58: FILE: memory.c:3081:
+            if(!fuzz_memory_region_head)

ERROR: space required before the open brace '{'
#69: FILE: memory.c:3092:
+            if(io == true){

ERROR: space required before the open parenthesis '('
#69: FILE: memory.c:3092:
+            if(io == true){

ERROR: spaces required around that '+' (ctx:VxV)
#70: FILE: memory.c:3093:
+                total_io_mem += MR_SIZE(range->addr.size)+1;
                                                          ^

ERROR: spaces required around that '+' (ctx:VxV)
#72: FILE: memory.c:3095:
+                total_ram_mem += MR_SIZE(range->addr.size)+1;
                                                           ^

total: 14 errors, 0 warnings, 58 lines checked

Patch 9/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

10/19 Checking commit ee10a51fdc62 (fuzz: expose real_main (aka regular vl.c:main))
ERROR: do not use C99 // comments
#59: FILE: vl.c:2913:
+#ifndef CONFIG_FUZZ // QOM is already set up by the fuzzer.

ERROR: do not use C99 // comments
#69: FILE: vl.c:4208:
+#ifndef CONFIG_FUZZ // Already set up by the fuzzer

WARNING: Block comments should align the * on each line
#84: FILE: vl.c:4487:
+ * main_loop
+*/

total: 2 errors, 1 warnings, 66 lines checked

Patch 10/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

11/19 Checking commit 4963c0131266 (fuzz: add direct send/receive in qtest client)
WARNING: line over 80 characters
#47: FILE: qtest.c:759:
+void qtest_init_server(const char *qtest_chrdev, const char *qtest_log, Error **errp)

total: 0 errors, 1 warnings, 45 lines checked

Patch 11/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
12/19 Checking commit 7022ef279174 (fuzz: hard-code all of the needed files for build)
13/19 Checking commit 6c53625dd9b9 (fuzz: add ctrl vq support to virtio-net in libqos)
14/19 Checking commit 2ce2166577b7 (fuzz: hard-code a main-loop timeout)
15/19 Checking commit 70229253c8a4 (fuzz: add fuzz accelerator type)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file mode 100644

ERROR: open brace '{' following function declarations go on the next line
#26: FILE: accel/fuzz.c:11:
+static void fuzz_setup_post(MachineState *ms, AccelState *accel) {

ERROR: code indent should never use tabs
#44: FILE: accel/fuzz.c:29:
+^Iac->setup_post = fuzz_setup_post;$

total: 2 errors, 1 warnings, 62 lines checked

Patch 15/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

16/19 Checking commit 213ed5ab99a4 (fuzz: add general fuzzer entrypoints)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#13: 
new file mode 100644

ERROR: trailing whitespace
#41: FILE: tests/fuzz/fuzz.c:24:
+ram_disk *rd; $

ERROR: "foo* bar" should be "foo *bar"
#44: FILE: tests/fuzz/fuzz.c:27:
+FuzzTargetList* fuzz_target_list;

ERROR: do not initialise globals to 0 or NULL
#46: FILE: tests/fuzz/fuzz.c:29:
+uint64_t total_mr_size = 0;

ERROR: do not initialise globals to 0 or NULL
#47: FILE: tests/fuzz/fuzz.c:30:
+uint64_t mr_index = 0;

ERROR: "foo* bar" should be "foo *bar"
#49: FILE: tests/fuzz/fuzz.c:32:
+const MemoryRegion* mrs[1000];

ERROR: do not use C99 // comments
#52: FILE: tests/fuzz/fuzz.c:35:
+// Save just the VMStateDescriptors

ERROR: do not use C99 // comments
#62: FILE: tests/fuzz/fuzz.c:45:
+// Save the entire vm state including RAM

ERROR: trailing whitespace
#63: FILE: tests/fuzz/fuzz.c:46:
+void save_vm_state(void) $

ERROR: space required before the open brace '{'
#85: FILE: tests/fuzz/fuzz.c:68:
+    if (ret < 0){

ERROR: space required before the open brace '{'
#100: FILE: tests/fuzz/fuzz.c:83:
+    if (ret < 0){

ERROR: "foo* bar" should be "foo *bar"
#114: FILE: tests/fuzz/fuzz.c:97:
+void fuzz_add_target(const char* name,

ERROR: "foo* bar" should be "foo *bar"
#115: FILE: tests/fuzz/fuzz.c:98:
+        const char* description,

ERROR: "foo* bar" should be "foo *bar"
#123: FILE: tests/fuzz/fuzz.c:106:
+        int* main_argc,

ERROR: "foo*** bar" should be "foo ***bar"
#124: FILE: tests/fuzz/fuzz.c:107:
+        char*** main_argv)

ERROR: space required before the open parenthesis '('
#129: FILE: tests/fuzz/fuzz.c:112:
+    if(!fuzz_target_list)

ERROR: braces {} are necessary for all arms of this statement
#129: FILE: tests/fuzz/fuzz.c:112:
+    if(!fuzz_target_list)
[...]

WARNING: line over 80 characters
#134: FILE: tests/fuzz/fuzz.c:117:
+            fprintf(stderr, "Error: Fuzz target name %s already in use\n", name);

ERROR: "foo* bar" should be "foo *bar"
#154: FILE: tests/fuzz/fuzz.c:137:
+FuzzTarget* fuzz_get_target(char* name)

ERROR: "foo* bar" should be "foo *bar"
#156: FILE: tests/fuzz/fuzz.c:139:
+    FuzzTarget* tmp;

ERROR: space required before the open brace '{'
#157: FILE: tests/fuzz/fuzz.c:140:
+    if(!fuzz_target_list){

ERROR: space required before the open parenthesis '('
#157: FILE: tests/fuzz/fuzz.c:140:
+    if(!fuzz_target_list){

ERROR: "foo* bar" should be "foo *bar"
#170: FILE: tests/fuzz/fuzz.c:153:
+FuzzTarget* fuzz_target;

ERROR: "foo* bar" should be "foo *bar"
#178: FILE: tests/fuzz/fuzz.c:161:
+    FuzzTarget* tmp;

ERROR: space required before the open brace '{'
#179: FILE: tests/fuzz/fuzz.c:162:
+    if(!fuzz_target_list){

ERROR: space required before the open parenthesis '('
#179: FILE: tests/fuzz/fuzz.c:162:
+    if(!fuzz_target_list){

ERROR: do not use C99 // comments
#191: FILE: tests/fuzz/fuzz.c:174:
+// TODO: Replace this with QEMU's built-in linked list

ERROR: space required before the open brace '{'
#205: FILE: tests/fuzz/fuzz.c:188:
+    while(true){

ERROR: space required before the open parenthesis '('
#205: FILE: tests/fuzz/fuzz.c:188:
+    while(true){

ERROR: space required before the open parenthesis '('
#207: FILE: tests/fuzz/fuzz.c:190:
+        if(fmr == fuzz_memory_region_head)

ERROR: braces {} are necessary for all arms of this statement
#207: FILE: tests/fuzz/fuzz.c:190:
+        if(fmr == fuzz_memory_region_head)
[...]

ERROR: space required before the open parenthesis '('
#216: FILE: tests/fuzz/fuzz.c:199:
+    if(fuzz_target->pre_fuzz)

ERROR: braces {} are necessary for all arms of this statement
#216: FILE: tests/fuzz/fuzz.c:199:
+    if(fuzz_target->pre_fuzz)
[...]

ERROR: space required before the open parenthesis '('
#219: FILE: tests/fuzz/fuzz.c:202:
+    if(fuzz_target->fuzz)

ERROR: braces {} are necessary for all arms of this statement
#219: FILE: tests/fuzz/fuzz.c:202:
+    if(fuzz_target->fuzz)
[...]

ERROR: space required before the open parenthesis '('
#223: FILE: tests/fuzz/fuzz.c:206:
+    if(fuzz_target->post_fuzz)

ERROR: braces {} are necessary for all arms of this statement
#223: FILE: tests/fuzz/fuzz.c:206:
+    if(fuzz_target->post_fuzz)
[...]

ERROR: space required before the open parenthesis '('
#227: FILE: tests/fuzz/fuzz.c:210:
+    if(fuzz_target->reset)

ERROR: braces {} are necessary for all arms of this statement
#227: FILE: tests/fuzz/fuzz.c:210:
+    if(fuzz_target->reset)
[...]

ERROR: do not use C99 // comments
#239: FILE: tests/fuzz/fuzz.c:222:
+    // Initialize qgraph and modules

ERROR: space required before the open parenthesis '('
#245: FILE: tests/fuzz/fuzz.c:228:
+    if(*argc <= 1)

ERROR: braces {} are necessary for all arms of this statement
#245: FILE: tests/fuzz/fuzz.c:228:
+    if(*argc <= 1)
[...]

ERROR: spaces required around that '+=' (ctx:VxV)
#251: FILE: tests/fuzz/fuzz.c:234:
+    target_name+=2;
                ^

ERROR: that open brace { should be on the previous line
#254: FILE: tests/fuzz/fuzz.c:237:
+    if(!fuzz_target)
+    {

ERROR: space required before the open parenthesis '('
#254: FILE: tests/fuzz/fuzz.c:237:
+    if(!fuzz_target)

WARNING: line over 80 characters
#256: FILE: tests/fuzz/fuzz.c:239:
+        fprintf(stderr, "Error: Fuzz fuzz_target name %s not found\n", target_name);

ERROR: space required before the open parenthesis '('
#260: FILE: tests/fuzz/fuzz.c:243:
+    if(fuzz_target->init_pre_main)

ERROR: braces {} are necessary for all arms of this statement
#260: FILE: tests/fuzz/fuzz.c:243:
+    if(fuzz_target->init_pre_main)
[...]

ERROR: space required before the open parenthesis '('
#271: FILE: tests/fuzz/fuzz.c:254:
+    if(fuzz_target->init_pre_save)

ERROR: braces {} are necessary for all arms of this statement
#271: FILE: tests/fuzz/fuzz.c:254:
+    if(fuzz_target->init_pre_save)
[...]

ERROR: space required before the open parenthesis '('
#275: FILE: tests/fuzz/fuzz.c:258:
+    if(fuzz_target->save_state)

ERROR: braces {} are necessary for all arms of this statement
#275: FILE: tests/fuzz/fuzz.c:258:
+    if(fuzz_target->save_state)
[...]

ERROR: code indent should never use tabs
#306: FILE: tests/fuzz/fuzz.h:21:
+^IGString* name;$

ERROR: "foo* bar" should be "foo *bar"
#306: FILE: tests/fuzz/fuzz.h:21:
+       GString* name;

ERROR: code indent should never use tabs
#307: FILE: tests/fuzz/fuzz.h:22:
+^IGString* description;$

ERROR: "foo* bar" should be "foo *bar"
#307: FILE: tests/fuzz/fuzz.h:22:
+       GString* description;

ERROR: code indent should never use tabs
#308: FILE: tests/fuzz/fuzz.h:23:
+^Ivoid(*init_pre_main)(void);$

ERROR: code indent should never use tabs
#309: FILE: tests/fuzz/fuzz.h:24:
+^Ivoid(*init_pre_save)(void);$

ERROR: code indent should never use tabs
#310: FILE: tests/fuzz/fuzz.h:25:
+^Ivoid(*save_state)(void);$

ERROR: code indent should never use tabs
#311: FILE: tests/fuzz/fuzz.h:26:
+^Ivoid(*reset)(void);$

ERROR: code indent should never use tabs
#312: FILE: tests/fuzz/fuzz.h:27:
+^Ivoid(*pre_fuzz)(void);$

ERROR: code indent should never use tabs
#313: FILE: tests/fuzz/fuzz.h:28:
+^Ivoid(*fuzz)(const unsigned char*, size_t);$

ERROR: code indent should never use tabs
#314: FILE: tests/fuzz/fuzz.h:29:
+^Ivoid(*post_fuzz)(void);$

ERROR: code indent should never use tabs
#315: FILE: tests/fuzz/fuzz.h:30:
+^Iint* main_argc;$

ERROR: "foo* bar" should be "foo *bar"
#315: FILE: tests/fuzz/fuzz.h:30:
+       int* main_argc;

ERROR: code indent should never use tabs
#316: FILE: tests/fuzz/fuzz.h:31:
+^Ichar*** main_argv;$

ERROR: "foo*** bar" should be "foo ***bar"
#316: FILE: tests/fuzz/fuzz.h:31:
+       char*** main_argv;

ERROR: code indent should never use tabs
#317: FILE: tests/fuzz/fuzz.h:32:
+^IQSLIST_ENTRY(FuzzTarget) target_list;$

ERROR: "foo* bar" should be "foo *bar"
#321: FILE: tests/fuzz/fuzz.h:36:
+extern void* _ZN6fuzzer3TPCE;

ERROR: "foo* bar" should be "foo *bar"
#324: FILE: tests/fuzz/fuzz.h:39:
+extern void* __prof_nms_sect_data;

ERROR: "foo* bar" should be "foo *bar"
#325: FILE: tests/fuzz/fuzz.h:40:
+extern void* __prof_vnodes_sect_data;

ERROR: space prohibited after that open parenthesis '('
#328: FILE: tests/fuzz/fuzz.h:43:
+#define PROFILE_SIZE ( &__prof_vnodes_sect_data - &__prof_nms_sect_data)

ERROR: "foo* bar" should be "foo *bar"
#348: FILE: tests/fuzz/fuzz.h:63:
+FuzzTarget* fuzz_get_target(char* name);

ERROR: "foo* bar" should be "foo *bar"
#350: FILE: tests/fuzz/fuzz.h:65:
+extern FuzzTarget* fuzz_target;

ERROR: code indent should never use tabs
#353: FILE: tests/fuzz/fuzz.h:68:
+^Ibool io;$

ERROR: code indent should never use tabs
#354: FILE: tests/fuzz/fuzz.h:69:
+^Iuint64_t start;$

ERROR: code indent should never use tabs
#355: FILE: tests/fuzz/fuzz.h:70:
+^Iuint64_t length;$

ERROR: code indent should never use tabs
#356: FILE: tests/fuzz/fuzz.h:71:
+^Istruct fuzz_memory_region* next;$

ERROR: "foo* bar" should be "foo *bar"
#356: FILE: tests/fuzz/fuzz.h:71:
+       struct fuzz_memory_region* next;

ERROR: "foo* bar" should be "foo *bar"
#365: FILE: tests/fuzz/fuzz.h:80:
+void fuzz_add_target(const char* name,

ERROR: code indent should never use tabs
#366: FILE: tests/fuzz/fuzz.h:81:
+^Iconst char* description,$

ERROR: "foo* bar" should be "foo *bar"
#366: FILE: tests/fuzz/fuzz.h:81:
+       const char* description,

ERROR: code indent should never use tabs
#367: FILE: tests/fuzz/fuzz.h:82:
+^Ivoid(*init_pre_main)(void),$

ERROR: code indent should never use tabs
#368: FILE: tests/fuzz/fuzz.h:83:
+^Ivoid(*init_pre_save)(void),$

ERROR: code indent should never use tabs
#369: FILE: tests/fuzz/fuzz.h:84:
+^Ivoid(*save_state)(void),$

ERROR: code indent should never use tabs
#370: FILE: tests/fuzz/fuzz.h:85:
+^Ivoid(*reset)(void),$

ERROR: code indent should never use tabs
#371: FILE: tests/fuzz/fuzz.h:86:
+^Ivoid(*pre_fuzz)(void),$

ERROR: code indent should never use tabs
#372: FILE: tests/fuzz/fuzz.h:87:
+^Ivoid(*fuzz)(const unsigned char*, size_t),$

ERROR: code indent should never use tabs
#373: FILE: tests/fuzz/fuzz.h:88:
+^Ivoid(*post_fuzz)(void),$

ERROR: code indent should never use tabs
#374: FILE: tests/fuzz/fuzz.h:89:
+^Iint* main_argc,$

ERROR: "foo* bar" should be "foo *bar"
#374: FILE: tests/fuzz/fuzz.h:89:
+       int* main_argc,

ERROR: code indent should never use tabs
#375: FILE: tests/fuzz/fuzz.h:90:
+^Ichar*** main_argv);$

ERROR: "foo*** bar" should be "foo ***bar"
#375: FILE: tests/fuzz/fuzz.h:90:
+       char*** main_argv);

total: 90 errors, 3 warnings, 358 lines checked

Patch 16/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

17/19 Checking commit 01a57b549156 (fuzz: add general qtest fuzz target)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14: 
new file mode 100644

ERROR: open brace '{' following function declarations go on the next line
#39: FILE: tests/fuzz/qtest_fuzz.c:21:
+static uint16_t normalize_io_port(uint64_t addr) {

ERROR: spaces required around that '%' (ctx:VxV)
#40: FILE: tests/fuzz/qtest_fuzz.c:22:
+    addr = addr%total_io_mem;
                ^

ERROR: spaces required around that '!=' (ctx:VxV)
#42: FILE: tests/fuzz/qtest_fuzz.c:24:
+    while(addr!=0) {
               ^

ERROR: space required before the open parenthesis '('
#42: FILE: tests/fuzz/qtest_fuzz.c:24:
+    while(addr!=0) {

ERROR: space required before the open brace '{'
#43: FILE: tests/fuzz/qtest_fuzz.c:25:
+        if(!fmr->io){

ERROR: space required before the open parenthesis '('
#43: FILE: tests/fuzz/qtest_fuzz.c:25:
+        if(!fmr->io){

ERROR: that open brace { should be on the previous line
#47: FILE: tests/fuzz/qtest_fuzz.c:29:
+        if(addr <= fmr->length)
+        {

ERROR: space required before the open parenthesis '('
#47: FILE: tests/fuzz/qtest_fuzz.c:29:
+        if(addr <= fmr->length)

ERROR: spaces required around that '=' (ctx:VxW)
#49: FILE: tests/fuzz/qtest_fuzz.c:31:
+            addr= fmr->start + addr;
                 ^

ERROR: spaces required around that '+' (ctx:WxV)
#52: FILE: tests/fuzz/qtest_fuzz.c:34:
+        addr -= fmr->length +1;
                             ^

ERROR: spaces required around that '>=' (ctx:VxV)
#56: FILE: tests/fuzz/qtest_fuzz.c:38:
+    if(addr>=0x5655 && addr<=0x565b)
            ^

ERROR: spaces required around that '<=' (ctx:VxV)
#56: FILE: tests/fuzz/qtest_fuzz.c:38:
+    if(addr>=0x5655 && addr<=0x565b)
                            ^

ERROR: space required before the open parenthesis '('
#56: FILE: tests/fuzz/qtest_fuzz.c:38:
+    if(addr>=0x5655 && addr<=0x565b)

ERROR: braces {} are necessary for all arms of this statement
#56: FILE: tests/fuzz/qtest_fuzz.c:38:
+    if(addr>=0x5655 && addr<=0x565b)
[...]

ERROR: spaces required around that '>=' (ctx:VxV)
#58: FILE: tests/fuzz/qtest_fuzz.c:40:
+    if(addr>=0x510 && addr<=0x518)
            ^

ERROR: spaces required around that '<=' (ctx:VxV)
#58: FILE: tests/fuzz/qtest_fuzz.c:40:
+    if(addr>=0x510 && addr<=0x518)
                           ^

ERROR: space required before the open parenthesis '('
#58: FILE: tests/fuzz/qtest_fuzz.c:40:
+    if(addr>=0x510 && addr<=0x518)

ERROR: braces {} are necessary for all arms of this statement
#58: FILE: tests/fuzz/qtest_fuzz.c:40:
+    if(addr>=0x510 && addr<=0x518)
[...]

ERROR: do not use C99 // comments
#60: FILE: tests/fuzz/qtest_fuzz.c:42:
+    if(addr>=0xae00 && addr<=0xae13) // PCI Hotplug

ERROR: spaces required around that '>=' (ctx:VxV)
#60: FILE: tests/fuzz/qtest_fuzz.c:42:
+    if(addr>=0xae00 && addr<=0xae13) // PCI Hotplug
            ^

ERROR: spaces required around that '<=' (ctx:VxV)
#60: FILE: tests/fuzz/qtest_fuzz.c:42:
+    if(addr>=0xae00 && addr<=0xae13) // PCI Hotplug
                            ^

ERROR: space required before the open parenthesis '('
#60: FILE: tests/fuzz/qtest_fuzz.c:42:
+    if(addr>=0xae00 && addr<=0xae13) // PCI Hotplug

ERROR: trailing statements should be on next line
#60: FILE: tests/fuzz/qtest_fuzz.c:42:
+    if(addr>=0xae00 && addr<=0xae13) // PCI Hotplug

ERROR: braces {} are necessary for all arms of this statement
#60: FILE: tests/fuzz/qtest_fuzz.c:42:
+    if(addr>=0xae00 && addr<=0xae13) // PCI Hotplug
[...]

ERROR: do not use C99 // comments
#62: FILE: tests/fuzz/qtest_fuzz.c:44:
+    if(addr>=0xaf00 && addr<=0xaf1f) // CPU Hotplug

ERROR: spaces required around that '>=' (ctx:VxV)
#62: FILE: tests/fuzz/qtest_fuzz.c:44:
+    if(addr>=0xaf00 && addr<=0xaf1f) // CPU Hotplug
            ^

ERROR: spaces required around that '<=' (ctx:VxV)
#62: FILE: tests/fuzz/qtest_fuzz.c:44:
+    if(addr>=0xaf00 && addr<=0xaf1f) // CPU Hotplug
                            ^

ERROR: space required before the open parenthesis '('
#62: FILE: tests/fuzz/qtest_fuzz.c:44:
+    if(addr>=0xaf00 && addr<=0xaf1f) // CPU Hotplug

ERROR: trailing statements should be on next line
#62: FILE: tests/fuzz/qtest_fuzz.c:44:
+    if(addr>=0xaf00 && addr<=0xaf1f) // CPU Hotplug

ERROR: braces {} are necessary for all arms of this statement
#62: FILE: tests/fuzz/qtest_fuzz.c:44:
+    if(addr>=0xaf00 && addr<=0xaf1f) // CPU Hotplug
[...]

ERROR: open brace '{' following function declarations go on the next line
#68: FILE: tests/fuzz/qtest_fuzz.c:50:
+static uint16_t normalize_mem_addr(uint64_t addr) {

ERROR: spaces required around that '%' (ctx:VxV)
#69: FILE: tests/fuzz/qtest_fuzz.c:51:
+    addr = addr%total_ram_mem;
                ^

ERROR: spaces required around that '!=' (ctx:VxV)
#71: FILE: tests/fuzz/qtest_fuzz.c:53:
+    while(addr!=0) {
               ^

ERROR: space required before the open parenthesis '('
#71: FILE: tests/fuzz/qtest_fuzz.c:53:
+    while(addr!=0) {

ERROR: space required before the open brace '{'
#72: FILE: tests/fuzz/qtest_fuzz.c:54:
+        if(fmr->io){

ERROR: space required before the open parenthesis '('
#72: FILE: tests/fuzz/qtest_fuzz.c:54:
+        if(fmr->io){

ERROR: that open brace { should be on the previous line
#76: FILE: tests/fuzz/qtest_fuzz.c:58:
+        if(addr <= fmr->length)
+        {

ERROR: space required before the open parenthesis '('
#76: FILE: tests/fuzz/qtest_fuzz.c:58:
+        if(addr <= fmr->length)

ERROR: spaces required around that '+' (ctx:WxV)
#80: FILE: tests/fuzz/qtest_fuzz.c:62:
+        addr -= fmr->length +1;
                             ^

ERROR: space required before the open brace '{'
#86: FILE: tests/fuzz/qtest_fuzz.c:68:
+static void qtest_fuzz(const unsigned char *Data, size_t Size){

ERROR: that open brace { should be on the previous line
#92: FILE: tests/fuzz/qtest_fuzz.c:74:
+    while(pos < Data+Size)
+    {

ERROR: spaces required around that '+' (ctx:VxV)
#92: FILE: tests/fuzz/qtest_fuzz.c:74:
+    while(pos < Data+Size)
                     ^

ERROR: space required before the open parenthesis '('
#92: FILE: tests/fuzz/qtest_fuzz.c:74:
+    while(pos < Data+Size)

ERROR: spaces required around that '%' (ctx:VxV)
#95: FILE: tests/fuzz/qtest_fuzz.c:77:
+        cmd = &commands[(*pos)%(sizeof(commands)/sizeof(qtest_cmd))];
                               ^

ERROR: spaces required around that '/' (ctx:VxV)
#95: FILE: tests/fuzz/qtest_fuzz.c:77:
+        cmd = &commands[(*pos)%(sizeof(commands)/sizeof(qtest_cmd))];
                                                 ^

ERROR: space required before the open brace '{'
#98: FILE: tests/fuzz/qtest_fuzz.c:80:
+        if(strcmp(cmd->name, "clock_step") == 0){

ERROR: space required before the open parenthesis '('
#98: FILE: tests/fuzz/qtest_fuzz.c:80:
+        if(strcmp(cmd->name, "clock_step") == 0){

ERROR: do not use C99 // comments
#99: FILE: tests/fuzz/qtest_fuzz.c:81:
+            // TODO: This times out

ERROR: trailing whitespace
#101: FILE: tests/fuzz/qtest_fuzz.c:83:
+        } $

ERROR: space required before the open parenthesis '('
#102: FILE: tests/fuzz/qtest_fuzz.c:84:
+        else if(strcmp(cmd->name, "outb") == 0) {

ERROR: else should follow close brace '}'
#102: FILE: tests/fuzz/qtest_fuzz.c:84:
+        } 
+        else if(strcmp(cmd->name, "outb") == 0) {

ERROR: space required before the open parenthesis '('
#103: FILE: tests/fuzz/qtest_fuzz.c:85:
+            if(pos + sizeof(uint16_t) + sizeof(uint8_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#104: FILE: tests/fuzz/qtest_fuzz.c:86:
+                uint16_t addr = *(int16_t*)(pos);

ERROR: "(foo*)" should be "(foo *)"
#106: FILE: tests/fuzz/qtest_fuzz.c:88:
+                uint8_t val = *(uint16_t*)(pos);

ERROR: space required before the open parenthesis '('
#112: FILE: tests/fuzz/qtest_fuzz.c:94:
+        else if(strcmp(cmd->name, "outw") == 0) {

ERROR: else should follow close brace '}'
#112: FILE: tests/fuzz/qtest_fuzz.c:94:
+        }
+        else if(strcmp(cmd->name, "outw") == 0) {

ERROR: space required before the open parenthesis '('
#113: FILE: tests/fuzz/qtest_fuzz.c:95:
+            if(pos + sizeof(uint16_t) + sizeof(uint16_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#114: FILE: tests/fuzz/qtest_fuzz.c:96:
+                uint16_t addr = *(int16_t*)(pos);

ERROR: "(foo*)" should be "(foo *)"
#116: FILE: tests/fuzz/qtest_fuzz.c:98:
+                uint16_t val = *(uint16_t*)(pos);

ERROR: space required before the open parenthesis '('
#122: FILE: tests/fuzz/qtest_fuzz.c:104:
+        else if(strcmp(cmd->name, "outl") == 0) {

ERROR: else should follow close brace '}'
#122: FILE: tests/fuzz/qtest_fuzz.c:104:
+        }
+        else if(strcmp(cmd->name, "outl") == 0) {

ERROR: space required before the open parenthesis '('
#123: FILE: tests/fuzz/qtest_fuzz.c:105:
+            if(pos + sizeof(uint16_t) + sizeof(uint32_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#124: FILE: tests/fuzz/qtest_fuzz.c:106:
+                uint16_t addr = *(int16_t*)(pos);

ERROR: "(foo*)" should be "(foo *)"
#126: FILE: tests/fuzz/qtest_fuzz.c:108:
+                uint32_t val = *(uint32_t*)(pos);

ERROR: space required before the open parenthesis '('
#132: FILE: tests/fuzz/qtest_fuzz.c:114:
+        else if(strcmp(cmd->name, "inb") == 0) {

ERROR: else should follow close brace '}'
#132: FILE: tests/fuzz/qtest_fuzz.c:114:
+        }
+        else if(strcmp(cmd->name, "inb") == 0) {

ERROR: space required before the open parenthesis '('
#133: FILE: tests/fuzz/qtest_fuzz.c:115:
+            if(pos + sizeof(uint16_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#134: FILE: tests/fuzz/qtest_fuzz.c:116:
+                uint16_t addr = *(int16_t*)(pos);

ERROR: space required before the open parenthesis '('
#140: FILE: tests/fuzz/qtest_fuzz.c:122:
+        else if(strcmp(cmd->name, "inw") == 0) {

ERROR: else should follow close brace '}'
#140: FILE: tests/fuzz/qtest_fuzz.c:122:
+        }
+        else if(strcmp(cmd->name, "inw") == 0) {

ERROR: space required before the open parenthesis '('
#141: FILE: tests/fuzz/qtest_fuzz.c:123:
+            if(pos + sizeof(uint16_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#142: FILE: tests/fuzz/qtest_fuzz.c:124:
+                uint16_t addr = *(int16_t*)(pos);

ERROR: space required before the open parenthesis '('
#148: FILE: tests/fuzz/qtest_fuzz.c:130:
+        else if(strcmp(cmd->name, "inl") == 0) {

ERROR: else should follow close brace '}'
#148: FILE: tests/fuzz/qtest_fuzz.c:130:
+        }
+        else if(strcmp(cmd->name, "inl") == 0) {

ERROR: space required before the open parenthesis '('
#149: FILE: tests/fuzz/qtest_fuzz.c:131:
+            if(pos + sizeof(uint16_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#150: FILE: tests/fuzz/qtest_fuzz.c:132:
+                uint16_t addr = *(int16_t*)(pos);

ERROR: space required before the open parenthesis '('
#156: FILE: tests/fuzz/qtest_fuzz.c:138:
+        else if(strcmp(cmd->name, "writeb") == 0) {

ERROR: else should follow close brace '}'
#156: FILE: tests/fuzz/qtest_fuzz.c:138:
+        }
+        else if(strcmp(cmd->name, "writeb") == 0) {

ERROR: space required before the open parenthesis '('
#157: FILE: tests/fuzz/qtest_fuzz.c:139:
+            if(pos + sizeof(uint32_t) + sizeof(uint8_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#158: FILE: tests/fuzz/qtest_fuzz.c:140:
+                uint32_t addr = *(int32_t*)(pos);

ERROR: "(foo*)" should be "(foo *)"
#160: FILE: tests/fuzz/qtest_fuzz.c:142:
+                uint8_t val = *(uint8_t*)(pos);

ERROR: space required before the open parenthesis '('
#166: FILE: tests/fuzz/qtest_fuzz.c:148:
+        else if(strcmp(cmd->name, "writew") == 0) {

ERROR: else should follow close brace '}'
#166: FILE: tests/fuzz/qtest_fuzz.c:148:
+        }
+        else if(strcmp(cmd->name, "writew") == 0) {

ERROR: space required before the open parenthesis '('
#167: FILE: tests/fuzz/qtest_fuzz.c:149:
+            if(pos + sizeof(uint32_t) + sizeof(uint16_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#168: FILE: tests/fuzz/qtest_fuzz.c:150:
+                uint32_t addr = *(int32_t*)(pos);

ERROR: "(foo*)" should be "(foo *)"
#170: FILE: tests/fuzz/qtest_fuzz.c:152:
+                uint16_t val = *(uint16_t*)(pos);

ERROR: space required before the open parenthesis '('
#176: FILE: tests/fuzz/qtest_fuzz.c:158:
+        else if(strcmp(cmd->name, "writel") == 0) {

ERROR: else should follow close brace '}'
#176: FILE: tests/fuzz/qtest_fuzz.c:158:
+        }
+        else if(strcmp(cmd->name, "writel") == 0) {

ERROR: space required before the open parenthesis '('
#177: FILE: tests/fuzz/qtest_fuzz.c:159:
+            if(pos + sizeof(uint32_t) + sizeof(uint32_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#178: FILE: tests/fuzz/qtest_fuzz.c:160:
+                uint32_t addr = *(int32_t*)(pos);

ERROR: "(foo*)" should be "(foo *)"
#180: FILE: tests/fuzz/qtest_fuzz.c:162:
+                uint32_t val = *(uint32_t*)(pos);

ERROR: space required before the open parenthesis '('
#186: FILE: tests/fuzz/qtest_fuzz.c:168:
+        else if(strcmp(cmd->name, "readb") == 0) {

ERROR: else should follow close brace '}'
#186: FILE: tests/fuzz/qtest_fuzz.c:168:
+        }
+        else if(strcmp(cmd->name, "readb") == 0) {

ERROR: space required before the open parenthesis '('
#187: FILE: tests/fuzz/qtest_fuzz.c:169:
+            if(pos + sizeof(uint32_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#188: FILE: tests/fuzz/qtest_fuzz.c:170:
+                uint32_t addr = *(int32_t*)(pos);

ERROR: space required before the open parenthesis '('
#194: FILE: tests/fuzz/qtest_fuzz.c:176:
+        else if(strcmp(cmd->name, "readw") == 0) {

ERROR: else should follow close brace '}'
#194: FILE: tests/fuzz/qtest_fuzz.c:176:
+        }
+        else if(strcmp(cmd->name, "readw") == 0) {

ERROR: space required before the open parenthesis '('
#195: FILE: tests/fuzz/qtest_fuzz.c:177:
+            if(pos + sizeof(uint32_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#196: FILE: tests/fuzz/qtest_fuzz.c:178:
+                uint32_t addr = *(int32_t*)(pos);

ERROR: space required before the open parenthesis '('
#200: FILE: tests/fuzz/qtest_fuzz.c:182:
+        else if(strcmp(cmd->name, "readl") == 0) {

ERROR: space required before the open parenthesis '('
#201: FILE: tests/fuzz/qtest_fuzz.c:183:
+            if(pos + sizeof(uint32_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#202: FILE: tests/fuzz/qtest_fuzz.c:184:
+                uint32_t addr = *(int32_t*)(pos);

ERROR: space required before the open parenthesis '('
#208: FILE: tests/fuzz/qtest_fuzz.c:190:
+        else if(strcmp(cmd->name, "write_dma") == 0) {

ERROR: else should follow close brace '}'
#208: FILE: tests/fuzz/qtest_fuzz.c:190:
+        }
+        else if(strcmp(cmd->name, "write_dma") == 0) {

ERROR: space required before the open parenthesis '('
#209: FILE: tests/fuzz/qtest_fuzz.c:191:
+            if(pos + sizeof(uint32_t) + sizeof(uint16_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#210: FILE: tests/fuzz/qtest_fuzz.c:192:
+                uint32_t addr = *(int32_t*)(pos);

ERROR: space required before the open parenthesis '('
#217: FILE: tests/fuzz/qtest_fuzz.c:199:
+        else if(strcmp(cmd->name, "out_dma") == 0) {

ERROR: else should follow close brace '}'
#217: FILE: tests/fuzz/qtest_fuzz.c:199:
+        }
+        else if(strcmp(cmd->name, "out_dma") == 0) {

ERROR: space required before the open parenthesis '('
#218: FILE: tests/fuzz/qtest_fuzz.c:200:
+            if(pos + sizeof(uint16_t) + sizeof(uint16_t) < End) {

ERROR: "(foo*)" should be "(foo *)"
#219: FILE: tests/fuzz/qtest_fuzz.c:201:
+                uint16_t addr = *(int16_t*)(pos);

ERROR: else should follow close brace '}'
#243: FILE: tests/fuzz/qtest_fuzz.c:225:
+    }
+    else {

ERROR: open brace '{' following function declarations go on the next line
#249: FILE: tests/fuzz/qtest_fuzz.c:231:
+static void init_fork(void) {

ERROR: open brace '{' following function declarations go on the next line
#252: FILE: tests/fuzz/qtest_fuzz.c:234:
+static void fork_pre_main(void) {

ERROR: line over 90 characters
#264: FILE: tests/fuzz/qtest_fuzz.c:246:
+    fuzz_add_qos_target("qtest-fuzz", "fuzz qtest commands and a dma buffer. Reset device state for each run",

WARNING: line over 80 characters
#265: FILE: tests/fuzz/qtest_fuzz.c:247:
+            "e1000e", &opts, &qos_setup, &qos_init_path, &save_vm_state, &load_vm_state,

ERROR: line over 90 characters
#267: FILE: tests/fuzz/qtest_fuzz.c:249:
+    fuzz_add_qos_target("qtest-fork-fuzz", "fuzz qtest commands and a dma buffer. Use COW/forking to reset state",

ERROR: trailing whitespace
#271: FILE: tests/fuzz/qtest_fuzz.c:253:
+    GString *cmd_line = g_string_new("qemu-system-i386 -display none -machine accel=fuzz -m 3"); $

ERROR: line over 90 characters
#271: FILE: tests/fuzz/qtest_fuzz.c:253:
+    GString *cmd_line = g_string_new("qemu-system-i386 -display none -machine accel=fuzz -m 3"); 

ERROR: space prohibited between function name and open parenthesis '('
#273: FILE: tests/fuzz/qtest_fuzz.c:255:
+    wordexp (cmd_line->str, &result, 0);

ERROR: code indent should never use tabs
#290: FILE: tests/fuzz/qtest_fuzz.h:5:
+^Ichar name[32];$

ERROR: code indent should never use tabs
#291: FILE: tests/fuzz/qtest_fuzz.h:6:
+^Iuint8_t size;$

ERROR: trailing whitespace
#296: FILE: tests/fuzz/qtest_fuzz.h:11:
+static qtest_cmd commands[] = $

ERROR: that open brace { should be on the previous line
#297: FILE: tests/fuzz/qtest_fuzz.h:12:
+static qtest_cmd commands[] = 
+{

ERROR: code indent should never use tabs
#298: FILE: tests/fuzz/qtest_fuzz.h:13:
+^I{"clock_step", 0},$

ERROR: code indent should never use tabs
#299: FILE: tests/fuzz/qtest_fuzz.h:14:
+^I{"clock_step", 0},$

ERROR: code indent should never use tabs
#300: FILE: tests/fuzz/qtest_fuzz.h:15:
+^I{"clock_set", 1},$

ERROR: code indent should never use tabs
#301: FILE: tests/fuzz/qtest_fuzz.h:16:
+^I{"outb", 2},$

ERROR: code indent should never use tabs
#302: FILE: tests/fuzz/qtest_fuzz.h:17:
+^I{"outw", 2},$

ERROR: code indent should never use tabs
#303: FILE: tests/fuzz/qtest_fuzz.h:18:
+^I{"outl", 2},$

ERROR: code indent should never use tabs
#304: FILE: tests/fuzz/qtest_fuzz.h:19:
+^I{"inb", 1},$

ERROR: code indent should never use tabs
#305: FILE: tests/fuzz/qtest_fuzz.h:20:
+^I{"inw", 1},$

ERROR: code indent should never use tabs
#306: FILE: tests/fuzz/qtest_fuzz.h:21:
+^I{"inl", 1},$

ERROR: code indent should never use tabs
#307: FILE: tests/fuzz/qtest_fuzz.h:22:
+^I{"writeb", 2},$

ERROR: code indent should never use tabs
#308: FILE: tests/fuzz/qtest_fuzz.h:23:
+^I{"writew", 2},$

ERROR: code indent should never use tabs
#309: FILE: tests/fuzz/qtest_fuzz.h:24:
+^I{"writel", 2},$

ERROR: code indent should never use tabs
#310: FILE: tests/fuzz/qtest_fuzz.h:25:
+^I{"writeq", 2},$

ERROR: code indent should never use tabs
#311: FILE: tests/fuzz/qtest_fuzz.h:26:
+^I{"readb", 1},$

ERROR: code indent should never use tabs
#312: FILE: tests/fuzz/qtest_fuzz.h:27:
+^I{"readw", 1},$

ERROR: code indent should never use tabs
#313: FILE: tests/fuzz/qtest_fuzz.h:28:
+^I{"readl", 1},$

ERROR: code indent should never use tabs
#314: FILE: tests/fuzz/qtest_fuzz.h:29:
+^I{"readq", 1},$

ERROR: code indent should never use tabs
#315: FILE: tests/fuzz/qtest_fuzz.h:30:
+^I{"read", 2},$

ERROR: code indent should never use tabs
#316: FILE: tests/fuzz/qtest_fuzz.h:31:
+^I{"write", 3},$

ERROR: code indent should never use tabs
#317: FILE: tests/fuzz/qtest_fuzz.h:32:
+^I{"b64read", 2},$

ERROR: code indent should never use tabs
#318: FILE: tests/fuzz/qtest_fuzz.h:33:
+^I{"b64write", 10},$

ERROR: code indent should never use tabs
#319: FILE: tests/fuzz/qtest_fuzz.h:34:
+^I{"memset", 3},$

ERROR: code indent should never use tabs
#320: FILE: tests/fuzz/qtest_fuzz.h:35:
+^I{"write_dma", 2},$

ERROR: code indent should never use tabs
#321: FILE: tests/fuzz/qtest_fuzz.h:36:
+^I{"out_dma", 2},$

total: 146 errors, 2 warnings, 299 lines checked

Patch 17/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

18/19 Checking commit 0c31cb1dde8d (fuzz: Add virtio-net tx and ctrl fuzz targets)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14: 
new file mode 100644

ERROR: spaces required around that '=' (ctx:WxV)
#46: FILE: tests/fuzz/virtio-net-fuzz.c:28:
+    int reqi =0;
              ^

ERROR: spaces required around that '=' (ctx:VxV)
#55: FILE: tests/fuzz/virtio-net-fuzz.c:37:
+    int iters=0;
              ^

ERROR: space required before the open parenthesis '('
#56: FILE: tests/fuzz/virtio-net-fuzz.c:38:
+    while(true) {

ERROR: space required before the open parenthesis '('
#57: FILE: tests/fuzz/virtio-net-fuzz.c:39:
+        if(Size < sizeof(vqa)) {

ERROR: "(foo*)" should be "(foo *)"
#60: FILE: tests/fuzz/virtio-net-fuzz.c:42:
+        vqa = *((vq_action*)Data);

ERROR: space required before the open parenthesis '('
#70: FILE: tests/fuzz/virtio-net-fuzz.c:52:
+        if(iters == 0)

ERROR: braces {} are necessary for all arms of this statement
#70: FILE: tests/fuzz/virtio-net-fuzz.c:52:
+        if(iters == 0)
[...]
+        else
[...]

ERROR: line over 90 characters
#71: FILE: tests/fuzz/virtio-net-fuzz.c:53:
+            free_head = qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;

WARNING: line over 80 characters
#73: FILE: tests/fuzz/virtio-net-fuzz.c:55:
+            qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;

ERROR: spaces required around that '==' (ctx:VxV)
#76: FILE: tests/fuzz/virtio-net-fuzz.c:58:
+        if(iters==10)
                 ^

ERROR: space required before the open parenthesis '('
#76: FILE: tests/fuzz/virtio-net-fuzz.c:58:
+        if(iters==10)

ERROR: braces {} are necessary for all arms of this statement
#76: FILE: tests/fuzz/virtio-net-fuzz.c:58:
+        if(iters==10)
[...]

ERROR: space required before the open brace '{'
#81: FILE: tests/fuzz/virtio-net-fuzz.c:63:
+    if(iters){

ERROR: space required before the open parenthesis '('
#81: FILE: tests/fuzz/virtio-net-fuzz.c:63:
+    if(iters){

ERROR: spaces required around that '=' (ctx:WxV)
#85: FILE: tests/fuzz/virtio-net-fuzz.c:67:
+        for(int i =0; i<reqi; i++)
                   ^

ERROR: spaces required around that '<' (ctx:VxV)
#85: FILE: tests/fuzz/virtio-net-fuzz.c:67:
+        for(int i =0; i<reqi; i++)
                        ^

ERROR: space required before the open parenthesis '('
#85: FILE: tests/fuzz/virtio-net-fuzz.c:67:
+        for(int i =0; i<reqi; i++)

ERROR: braces {} are necessary for all arms of this statement
#85: FILE: tests/fuzz/virtio-net-fuzz.c:67:
+        for(int i =0; i<reqi; i++)
[...]

ERROR: spaces required around that '=' (ctx:WxV)
#95: FILE: tests/fuzz/virtio-net-fuzz.c:77:
+    int reqi =0;
              ^

ERROR: spaces required around that '=' (ctx:VxV)
#104: FILE: tests/fuzz/virtio-net-fuzz.c:86:
+    int iters=0;
              ^

ERROR: space required before the open parenthesis '('
#105: FILE: tests/fuzz/virtio-net-fuzz.c:87:
+    while(Size >= sizeof(vqa)) {

ERROR: "(foo*)" should be "(foo *)"
#106: FILE: tests/fuzz/virtio-net-fuzz.c:88:
+        vqa = *((vq_action*)Data);

ERROR: that open brace { should be on the previous line
#109: FILE: tests/fuzz/virtio-net-fuzz.c:91:
+        if(vqa.kick && free_head)
+        {

ERROR: space required before the open parenthesis '('
#109: FILE: tests/fuzz/virtio-net-fuzz.c:91:
+        if(vqa.kick && free_head)

ERROR: spaces required around that '=' (ctx:WxV)
#114: FILE: tests/fuzz/virtio-net-fuzz.c:96:
+            for(int i =0; i<reqi; i++)
                       ^

ERROR: spaces required around that '<' (ctx:VxV)
#114: FILE: tests/fuzz/virtio-net-fuzz.c:96:
+            for(int i =0; i<reqi; i++)
                            ^

ERROR: space required before the open parenthesis '('
#114: FILE: tests/fuzz/virtio-net-fuzz.c:96:
+            for(int i =0; i<reqi; i++)

ERROR: braces {} are necessary for all arms of this statement
#114: FILE: tests/fuzz/virtio-net-fuzz.c:96:
+            for(int i =0; i<reqi; i++)
[...]

ERROR: else should follow close brace '}'
#118: FILE: tests/fuzz/virtio-net-fuzz.c:100:
+        }
+        else {

ERROR: space required before the open parenthesis '('
#125: FILE: tests/fuzz/virtio-net-fuzz.c:107:
+            if(iters == 0)

ERROR: braces {} are necessary for all arms of this statement
#125: FILE: tests/fuzz/virtio-net-fuzz.c:107:
+            if(iters == 0)
[...]
+            else
[...]

ERROR: line over 90 characters
#126: FILE: tests/fuzz/virtio-net-fuzz.c:108:
+                free_head = qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;

WARNING: line over 80 characters
#128: FILE: tests/fuzz/virtio-net-fuzz.c:110:
+                qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;

ERROR: spaces required around that '==' (ctx:VxV)
#131: FILE: tests/fuzz/virtio-net-fuzz.c:113:
+            if(iters==10)
                     ^

ERROR: space required before the open parenthesis '('
#131: FILE: tests/fuzz/virtio-net-fuzz.c:113:
+            if(iters==10)

ERROR: braces {} are necessary for all arms of this statement
#131: FILE: tests/fuzz/virtio-net-fuzz.c:113:
+            if(iters==10)
[...]

ERROR: spaces required around that '=' (ctx:WxV)
#145: FILE: tests/fuzz/virtio-net-fuzz.c:127:
+    int reqi =0;
              ^

ERROR: spaces required around that '=' (ctx:VxV)
#154: FILE: tests/fuzz/virtio-net-fuzz.c:136:
+    int iters=0;
              ^

ERROR: space required before the open parenthesis '('
#155: FILE: tests/fuzz/virtio-net-fuzz.c:137:
+    while(true) {

ERROR: space required before the open parenthesis '('
#156: FILE: tests/fuzz/virtio-net-fuzz.c:138:
+        if(Size < sizeof(vqa)) {

ERROR: "(foo*)" should be "(foo *)"
#159: FILE: tests/fuzz/virtio-net-fuzz.c:141:
+        vqa = *((vq_action*)Data);

ERROR: space required before the open parenthesis '('
#169: FILE: tests/fuzz/virtio-net-fuzz.c:151:
+        if(iters == 0)

ERROR: braces {} are necessary for all arms of this statement
#169: FILE: tests/fuzz/virtio-net-fuzz.c:151:
+        if(iters == 0)
[...]
+        else
[...]

ERROR: line over 90 characters
#170: FILE: tests/fuzz/virtio-net-fuzz.c:152:
+            free_head = qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;

WARNING: line over 80 characters
#172: FILE: tests/fuzz/virtio-net-fuzz.c:154:
+            qvirtqueue_add(q, req_addr[reqi], vqa.length, vqa.write , vqa.next) ;

ERROR: spaces required around that '==' (ctx:VxV)
#175: FILE: tests/fuzz/virtio-net-fuzz.c:157:
+        if(iters==10)
                 ^

ERROR: space required before the open parenthesis '('
#175: FILE: tests/fuzz/virtio-net-fuzz.c:157:
+        if(iters==10)

ERROR: braces {} are necessary for all arms of this statement
#175: FILE: tests/fuzz/virtio-net-fuzz.c:157:
+        if(iters==10)
[...]

ERROR: space required before the open brace '{'
#180: FILE: tests/fuzz/virtio-net-fuzz.c:162:
+    if(iters){

ERROR: space required before the open parenthesis '('
#180: FILE: tests/fuzz/virtio-net-fuzz.c:162:
+    if(iters){

ERROR: spaces required around that '=' (ctx:WxV)
#184: FILE: tests/fuzz/virtio-net-fuzz.c:166:
+        for(int i =0; i<reqi; i++)
                   ^

ERROR: spaces required around that '<' (ctx:VxV)
#184: FILE: tests/fuzz/virtio-net-fuzz.c:166:
+        for(int i =0; i<reqi; i++)
                        ^

ERROR: space required before the open parenthesis '('
#184: FILE: tests/fuzz/virtio-net-fuzz.c:166:
+        for(int i =0; i<reqi; i++)

ERROR: braces {} are necessary for all arms of this statement
#184: FILE: tests/fuzz/virtio-net-fuzz.c:166:
+        for(int i =0; i<reqi; i++)
[...]

ERROR: space required before the open brace '{'
#193: FILE: tests/fuzz/virtio-net-fuzz.c:175:
+    if(!sv){

ERROR: space required before the open parenthesis '('
#193: FILE: tests/fuzz/virtio-net-fuzz.c:175:
+    if(!sv){

ERROR: space required before the open brace '{'
#203: FILE: tests/fuzz/virtio-net-fuzz.c:185:
+static void fuzz_fork(const unsigned char *Data, size_t Size){

ERROR: trailing whitespace
#208: FILE: tests/fuzz/virtio-net-fuzz.c:190:
+    } $

ERROR: else should follow close brace '}'
#209: FILE: tests/fuzz/virtio-net-fuzz.c:191:
+    } 
+    else {

ERROR: open brace '{' following function declarations go on the next line
#215: FILE: tests/fuzz/virtio-net-fuzz.c:197:
+static void fork_pre_main(void) {

WARNING: line over 80 characters
#225: FILE: tests/fuzz/virtio-net-fuzz.c:207:
+    fuzz_add_qos_target("virtio-net-ctrl-fuzz", "virtio-net ctrl virtqueue fuzzer",

WARNING: line over 80 characters
#229: FILE: tests/fuzz/virtio-net-fuzz.c:211:
+    fuzz_add_qos_target("virtio-net-ctrl-multi-fuzz", "virtio-net ctrl virtqueue \

ERROR: do not use C99 // comments
#238: FILE: tests/fuzz/virtio-net-fuzz.c:220:
+    // TODO: This doesn't work. Possibly due to threading..

total: 58 errors, 6 warnings, 226 lines checked

Patch 18/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

19/19 Checking commit 4c6f68c48090 (fuzz: Add documentation about the fuzzer to docs/)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file mode 100644

total: 0 errors, 1 warnings, 145 lines checked

Patch 19/19 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190725032321.12721-1-alxndr@bu.edu/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init
  2019-07-25  3:23 ` [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init Oleinik, Alexander
@ 2019-07-25  8:21   ` Paolo Bonzini
  2019-07-26 12:59     ` Stefan Hajnoczi
  0 siblings, 1 reply; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-25  8:21 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel; +Cc: bsd, superirishdonkey, stefanha

On 25/07/19 05:23, Oleinik, Alexander wrote:
> Intercept coverage buffer registration calls and use this information to
> copy them to shared memory, if using fork() to avoid resetting device
> state.
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  tests/fuzz/fuzzer_hooks.c | 106 ++++++++++++++++++++++++++++++++++++++
>  tests/fuzz/fuzzer_hooks.h |   9 ++++
>  2 files changed, 115 insertions(+)
>  create mode 100644 tests/fuzz/fuzzer_hooks.c
>  create mode 100644 tests/fuzz/fuzzer_hooks.h
> 
> diff --git a/tests/fuzz/fuzzer_hooks.c b/tests/fuzz/fuzzer_hooks.c
> new file mode 100644
> index 0000000000..5a0bbec413
> --- /dev/null
> +++ b/tests/fuzz/fuzzer_hooks.c
> @@ -0,0 +1,106 @@
> +#include "qemu/osdep.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "qemu-common.h"
> +#include "fuzzer_hooks.h"
> +
> +#include <dlfcn.h>
> +#include <elf.h>
> +
> +
> +extern void* _ZN6fuzzer3TPCE;

Would it make sense to make this a C++ source, so that you can avoid
using the mangled names (in this case, "namespace fuzzer { extern void
*TPC; }" and then using fuzzer::TPC)?  Even if it's just a single symbol.

> +// The libfuzzer handlers
> +void __real___sanitizer_cov_8bit_counters_init(uint8_t*, uint8_t*);
> +void __real___sanitizer_cov_trace_pc_guard_init(uint8_t*, uint8_t*);
> +
> +void __wrap___sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop);
> +void __wrap___sanitizer_cov_trace_pc_guard_init(uint8_t *Start, uint8_t *Stop);
> +
> +
> +void* counter_shm;
> +
> +typedef struct CoverageRegion {
> +    uint8_t* start;
> +    size_t length;
> +    bool store; /* Set this if it needs to be copied to the forked process */
> +} CoverageRegion;
> +
> +CoverageRegion regions[10];
> +int region_index = 0;
> +
> +void __wrap___sanitizer_cov_8bit_counters_init(uint8_t *Start, uint8_t *Stop)
> +{
> +    regions[region_index].start = Start;
> +    regions[region_index].length = Stop-Start;
> +    regions[region_index].store = true;
> +    region_index++;
> +    __real___sanitizer_cov_8bit_counters_init(Start, Stop);
> +}
> +
> +void __wrap___sanitizer_cov_trace_pc_guard_init(uint8_t *Start, uint8_t *Stop)
> +{
> +    regions[region_index].start = Start;
> +    regions[region_index++].length = Stop-Start;
> +    regions[region_index].store = true;
> +    region_index++;
> +    __real___sanitizer_cov_trace_pc_guard_init(Start, Stop);
> +}
> +
> +static void add_tpc_region(void)
> +{
> +    /* Got symbol and length from readelf. Horrible way to do this! */
> +    regions[region_index].start = (uint8_t*)(&_ZN6fuzzer3TPCE);
> +    regions[region_index].length = 0x443c00; 
> +    regions[region_index].store = true;
> +    region_index++;
> +}
> +
> +void counter_shm_init(void)
> +{
> +    /*
> +     * Add the  internal libfuzzer object that gets modified by cmp, etc
> +     * callbacks
> +     */
> +    add_tpc_region(); 
> +
> +    size_t length = 0;
> +    for(int i=0; i<region_index; i++){
> +        printf("%d %lx\n", i, length);
> +        length += regions[i].length;
> +    }
> +
> +    /* 
> +     * Map some shared memory. When we use a fork-server we can copy the
> +     * libfuzzer-related counters
> +     * */
> +    counter_shm = mmap(NULL, length, PROT_READ | PROT_WRITE, 
> +            MAP_SHARED | MAP_ANONYMOUS, -1, 0);
> +    if(counter_shm == MAP_FAILED) {
> +        printf("mmap() failed\n");
> +        do { perror("error:"); exit(EXIT_FAILURE); } while (0);
> +        exit(-1);
> +    }
> +}
> +
> +void counter_shm_store(void)
> +{
> +    size_t offset = 0;
> +    for(int i=0; i<region_index; i++) {
> +        if(regions[i].store) {
> +            memcpy(counter_shm + offset, regions[i].start, regions[i].length);
> +        }
> +        offset+=regions[i].length;
> +    }
> +}
> +
> +void counter_shm_load(void)
> +{
> +    size_t offset = 0;
> +    for(int i=0; i<region_index; i++) {
> +        if(regions[i].store) {
> +            memcpy(regions[i].start, counter_shm + offset, regions[i].length);
> +        }
> +        offset+=regions[i].length;
> +    }
> +}
> +
> diff --git a/tests/fuzz/fuzzer_hooks.h b/tests/fuzz/fuzzer_hooks.h
> new file mode 100644
> index 0000000000..90dca254d4
> --- /dev/null
> +++ b/tests/fuzz/fuzzer_hooks.h
> @@ -0,0 +1,9 @@
> +#ifndef FUZZER_HOOKS_H
> +#define FUZZER_HOOKS_H
> +
> +void counter_shm_init(void);
> +void counter_shm_store(void);
> +void counter_shm_load(void);
> +
> +#endif
> +
> 



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c
  2019-07-25  3:23 ` [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c Oleinik, Alexander
@ 2019-07-25  9:04   ` Thomas Huth
  2019-07-25  9:33     ` Paolo Bonzini
  2019-07-26 12:49     ` Stefan Hajnoczi
  2019-07-26 12:56   ` Stefan Hajnoczi
  1 sibling, 2 replies; 49+ messages in thread
From: Thomas Huth @ 2019-07-25  9:04 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel
  Cc: Laurent Vivier, pbonzini, bsd, superirishdonkey, stefanha

On 25/07/2019 05.23, Oleinik, Alexander wrote:
> libqtest directly invokes the qtest client and exposes a function to
> accept responses.
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  tests/libqtest.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++-
>  tests/libqtest.h |  6 ++++++
>  2 files changed, 58 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 3c5c3f49d8..a68a7287cb 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -30,12 +30,18 @@
>  #include "qapi/qmp/qjson.h"
>  #include "qapi/qmp/qlist.h"
>  #include "qapi/qmp/qstring.h"
> +#ifdef CONFIG_FUZZ
> +#include "sysemu/qtest.h"
> +#endif
>  
>  #define MAX_IRQ 256
>  #define SOCKET_TIMEOUT 50
>  #define SOCKET_MAX_FDS 16
>  
>  QTestState *global_qtest;
> +#ifdef CONFIG_FUZZ
> +static GString *recv_str;
> +#endif
>  
>  struct QTestState
>  {
> @@ -316,6 +322,20 @@ QTestState *qtest_initf(const char *fmt, ...)
>      va_end(ap);
>      return s;
>  }
> +#ifdef CONFIG_FUZZ
> +QTestState *qtest_init_fuzz(const char *extra_args, int *sock_fd)
> +{
> +    QTestState *qts;
> +    qts = g_new(QTestState, 1);
> +    qts->wstatus = 0;
> +    for (int i = 0; i < MAX_IRQ; i++) {
> +        qts->irq_level[i] = false;
> +    }
> +    qts->big_endian = qtest_query_target_endianness(qts);
> +
> +    return qts;
> +}
> +#endif
>  
>  QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd)
>  {
> @@ -379,9 +399,18 @@ static void socket_sendf(int fd, const char *fmt, va_list ap)
>  {
>      gchar *str = g_strdup_vprintf(fmt, ap);
>      size_t size = strlen(str);
> +#ifdef CONFIG_FUZZ
> +    // Directly call qtest_process_inbuf in the qtest server
> +    GString *gstr = g_string_new_len(str, size);
> +	/* printf(">>> %s",gstr->str); */

Please check your patches with scripts/checkpatch.pl - e.g. don't use
TABs for indentation like in the above line, don't use //-comments, etc.

> +    qtest_server_recv(gstr);
> +    g_string_free(gstr, true);
> +    g_free(str);
> +#else
>  
>      socket_send(fd, str, size);
>      g_free(str);
> +#endif
>  }
>  
>  static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...)
> @@ -433,6 +462,12 @@ static GString *qtest_recv_line(QTestState *s)
>      size_t offset;
>      char *eol;
>  
> +#ifdef CONFIG_FUZZ
> +    eol = strchr(recv_str->str, '\n');
> +    offset = eol - recv_str->str;
> +    line = g_string_new_len(recv_str->str, offset);
> +    g_string_erase(recv_str, 0, offset + 1);
> +#else
>      while ((eol = strchr(s->rx->str, '\n')) == NULL) {
>          ssize_t len;
>          char buffer[1024];
> @@ -453,7 +488,7 @@ static GString *qtest_recv_line(QTestState *s)
>      offset = eol - s->rx->str;
>      line = g_string_new_len(s->rx->str, offset);
>      g_string_erase(s->rx, 0, offset + 1);
> -
> +#endif
>      return line;
>  }
>  
> @@ -797,6 +832,9 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
>  
>  const char *qtest_get_arch(void)
>  {
> +#ifdef CONFIG_FUZZ
> +    return "i386";
> +#endif

Hard-coding "i386" is quite ugly ... it's ok for an RFC patch, but I
think this should be fixed in the final version of the patches. Maybe
you could use TARGET_NAME instead?

>      const char *qemu = qtest_qemu_binary();
>      const char *end = strrchr(qemu, '/');
>  
> @@ -1339,3 +1377,16 @@ void qmp_assert_error_class(QDict *rsp, const char *class)
>  
>      qobject_unref(rsp);
>  }
> +#ifdef CONFIG_FUZZ
> +void qtest_clear_rxbuf(QTestState *s){

For functions, the curly brace should start on a new line.

> +    g_string_set_size(recv_str,0);
> +}

 Thomas


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 11/19] fuzz: add direct send/receive in qtest client
  2019-07-25  3:23 ` [Qemu-devel] [RFC 11/19] fuzz: add direct send/receive in qtest client Oleinik, Alexander
@ 2019-07-25  9:10   ` Thomas Huth
  0 siblings, 0 replies; 49+ messages in thread
From: Thomas Huth @ 2019-07-25  9:10 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel
  Cc: Laurent Vivier, bsd, superirishdonkey, stefanha, pbonzini

On 25/07/2019 05.23, Oleinik, Alexander wrote:
> Directly interact with tests/libqtest.c functions
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  qtest.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
[...]
> @@ -748,8 +755,11 @@ static void qtest_event(void *opaque, int event)
>          break;
>      }
>  }
> -
> +#ifdef CONFIG_FUZZ
> +void qtest_init_server(const char *qtest_chrdev, const char *qtest_log, Error **errp)
> +#else
>  void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
> +#endif
>  {
>      Chardev *chr;

Even without your fuzzer series, it's somewhat confusing that we have a
qtest_init() function here that is completely different from the
qtest_init() function in tests/libqtest.c ...
Maybe you could send a separate patch that renames the qtest_init() here
always to qtest_init_server() and change the calling of the function in
vl.c, too?

 Thomas


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c
  2019-07-25  9:04   ` Thomas Huth
@ 2019-07-25  9:33     ` Paolo Bonzini
  2019-07-26 12:49     ` Stefan Hajnoczi
  1 sibling, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-25  9:33 UTC (permalink / raw)
  To: Thomas Huth, Oleinik, Alexander, qemu-devel
  Cc: Laurent Vivier, bsd, superirishdonkey, stefanha

On 25/07/19 11:04, Thomas Huth wrote:
>> @@ -797,6 +832,9 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
>>  
>>  const char *qtest_get_arch(void)
>>  {
>> +#ifdef CONFIG_FUZZ
>> +    return "i386";
>> +#endif
> 
> Hard-coding "i386" is quite ugly ... it's ok for an RFC patch, but I
> think this should be fixed in the final version of the patches. Maybe
> you could use TARGET_NAME instead?

Yes, TARGET_NAME is the one.  Also I would just split the file in two:
the common bits that are used for both libqtest and fuzz in one file, so
the libqtest and fuzz "drivers" can be in completely separate file
without #ifdefs.

Paolo

> 
>>      const char *qemu = qtest_qemu_binary();
>>      const char *end = strrchr(qemu, '/');
>>  
>> @@ -1339,3 +1377,16 @@ void qmp_assert_error_class(QDict *rsp, const char *class)
>>  
>>      qobject_unref(rsp);
>>  }
>> +#ifdef CONFIG_FUZZ
>> +void qtest_clear_rxbuf(QTestState *s){
> 
> For functions, the curly brace should start on a new line.
> 
>> +    g_string_set_size(recv_str,0);
>> +}
> 
>  Thomas
> 



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 10/19] fuzz: expose real_main (aka regular vl.c:main)
  2019-07-25  3:23 ` [Qemu-devel] [RFC 10/19] fuzz: expose real_main (aka regular vl.c:main) Oleinik, Alexander
@ 2019-07-25  9:38   ` Paolo Bonzini
  0 siblings, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-25  9:38 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel; +Cc: bsd, superirishdonkey, stefanha

On 25/07/19 05:23, Oleinik, Alexander wrote:
> Export normal qemu-system main so it can be called from tests/fuzz/fuzz.c
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  include/sysemu/sysemu.h |  4 ++++
>  vl.c                    | 21 ++++++++++++++++++++-
>  2 files changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 984c439ac9..1bb8cf184c 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -184,6 +184,10 @@ QemuOpts *qemu_get_machine_opts(void);
>  
>  bool defaults_enabled(void);
>  
> +#ifdef CONFIG_FUZZ
> +int real_main(int argc, char **argv, char **envp);
> +#endif
> +
>  extern QemuOptsList qemu_legacy_drive_opts;
>  extern QemuOptsList qemu_common_drive_opts;
>  extern QemuOptsList qemu_drive_opts;
> diff --git a/vl.c b/vl.c
> index b426b32134..b71b99b6f8 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -130,6 +130,10 @@ int main(int argc, char **argv)
>  #include "sysemu/iothread.h"
>  #include "qemu/guest-random.h"
>  
> +#ifdef CONFIG_FUZZ
> +#include "tests/libqtest.h"
> +#endif
> +
>  #define MAX_VIRTIO_CONSOLES 1
>  
>  static const char *data_dir[16];
> @@ -2853,8 +2857,11 @@ static void user_register_global_props(void)
>      qemu_opts_foreach(qemu_find_opts("global"),
>                        global_init_func, NULL, NULL);
>  }
> -
> +#ifdef CONFIG_FUZZ
> +int real_main(int argc, char **argv, char **envp)
> +#else
>  int main(int argc, char **argv, char **envp)
> +#endif
>  {
>      int i;
>      int snapshot, linux_boot;
> @@ -2903,7 +2910,9 @@ int main(int argc, char **argv, char **envp)
>      atexit(qemu_run_exit_notifiers);
>      qemu_init_exec_dir(argv[0]);
>  
> +#ifndef CONFIG_FUZZ // QOM is already set up by the fuzzer.
>      module_call_init(MODULE_INIT_QOM);
> +#endif

You can modify module_call_init to record the modules that have been
initialized, and skip the call (i.e. make it idempotent).

>      qemu_add_opts(&qemu_drive_opts);
>      qemu_add_drive_opts(&qemu_legacy_drive_opts);
> @@ -4196,9 +4205,11 @@ int main(int argc, char **argv, char **envp)
>       */
>      migration_object_init();
>  
> +#ifndef CONFIG_FUZZ // Already set up by the fuzzer
>      if (qtest_chrdev) {
>          qtest_init(qtest_chrdev, qtest_log, &error_fatal);
>      }
> +#endif

Here, I suspect the fuzzing target would have qtest_chrdev == NULL,
therefore you can assert that qtest_init is only called once.  For
example, add an

    assert(!test_log_fp)

in the function.

>      machine_opts = qemu_get_machine_opts();
>      kernel_filename = qemu_opt_get(machine_opts, "kernel");
> @@ -4470,6 +4481,14 @@ int main(int argc, char **argv, char **envp)
>      accel_setup_post(current_machine);
>      os_setup_post();
>  
> +/*
> + * Return to the fuzzer since it will run qtest programs and run the
> + * main_loop
> +*/
> +#ifdef CONFIG_FUZZ
> +    return 0;
> +#endif

Just place everything up to this point into a new function qemu_init();
for CONFIG_FUZZ that's what you call from LLVMFuzzerInitialize, while
for !CONFIG_FUZZ you can call it from main().  All the functions below
have no arguments, so the patch is trivial.

Paolo

>      main_loop();
>  
>      gdbserver_cleanup();
> 



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects
  2019-07-25  3:23 ` [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects Oleinik, Alexander
@ 2019-07-25  9:39   ` Paolo Bonzini
  0 siblings, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-25  9:39 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel
  Cc: Eduardo Habkost, bsd, superirishdonkey, stefanha, Richard Henderson

On 25/07/19 05:23, Oleinik, Alexander wrote:
> +  QEMU_INCLUDES="-iquote \$(SRC_PATH)/tests $QEMU_INCLUDES"

Instead of this, please include files with the full path.

Paolo


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 14/19] fuzz: hard-code a main-loop timeout
  2019-07-25  3:23 ` [Qemu-devel] [RFC 14/19] fuzz: hard-code a main-loop timeout Oleinik, Alexander
@ 2019-07-25  9:40   ` Paolo Bonzini
  0 siblings, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-25  9:40 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel; +Cc: bsd, superirishdonkey, stefanha

On 25/07/19 05:23, Oleinik, Alexander wrote:
>      timeout_ns = qemu_soonest_timeout(timeout_ns,
>                                        timerlistgroup_deadline_ns(
>                                            &main_loop_tlg));
> +#ifdef CONFIG_FUZZ
> +    timeout_ns = 50000;
> +#endif
>  

What is the purpose of this, and should it be instead a MIN(50000,
timeout_ns)?

Paolo


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 05/19] fuzz: expose qemu_savevm_state & skip state header
  2019-07-25  3:23 ` [Qemu-devel] [RFC 05/19] fuzz: expose qemu_savevm_state & skip state header Oleinik, Alexander
@ 2019-07-25 13:22   ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 49+ messages in thread
From: Dr. David Alan Gilbert @ 2019-07-25 13:22 UTC (permalink / raw)
  To: Oleinik, Alexander
  Cc: Juan Quintela, qemu-devel, bsd, superirishdonkey, stefanha, pbonzini

* Oleinik, Alexander (alxndr@bu.edu) wrote:
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  migration/savevm.c | 8 ++++++--
>  migration/savevm.h | 3 +++
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/migration/savevm.c b/migration/savevm.c
> index 79ed44d475..80c00ea560 100644
> --- a/migration/savevm.c
> +++ b/migration/savevm.c
> @@ -1404,8 +1404,11 @@ void qemu_savevm_state_cleanup(void)
>          }
>      }
>  }
> -
> +#ifdef CONFIG_FUZZ
> +int qemu_savevm_state(QEMUFile *f, Error **errp)
> +#else
>  static int qemu_savevm_state(QEMUFile *f, Error **errp)
> +#endif

If it's useful to you, I'd rather you just dropped the 'static'
rather than add the ifdef.

>  {
>      int ret;
>      MigrationState *ms = migrate_get_current();
> @@ -1471,11 +1474,12 @@ void qemu_savevm_live_state(QEMUFile *f)
>  int qemu_save_device_state(QEMUFile *f)
>  {
>      SaveStateEntry *se;
> -
> +#ifndef CONFIG_FUZZ
>      if (!migration_in_colo_state()) {
>          qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
>          qemu_put_be32(f, QEMU_VM_FILE_VERSION);
>      }
> +#endif

Can you explain why you want to skip the header?

Dave

>      cpu_synchronize_all_states();
>  
>      QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
> diff --git a/migration/savevm.h b/migration/savevm.h
> index 51a4b9caa8..30315d0cfd 100644
> --- a/migration/savevm.h
> +++ b/migration/savevm.h
> @@ -64,4 +64,7 @@ void qemu_loadvm_state_cleanup(void);
>  int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis);
>  int qemu_load_device_state(QEMUFile *f);
>  
> +#ifdef CONFIG_FUZZ
> +int qemu_savevm_state(QEMUFile *f, Error **errp);
> +#endif
>  #endif
> -- 
> 2.20.1
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos
  2019-07-25  3:23 ` [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos Oleinik, Alexander
@ 2019-07-25 16:25   ` John Snow
  2019-07-25 17:05     ` Oleinik, Alexander
  0 siblings, 1 reply; 49+ messages in thread
From: John Snow @ 2019-07-25 16:25 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel
  Cc: Laurent Vivier, Thomas Huth, bsd, superirishdonkey, stefanha, pbonzini



On 7/24/19 11:23 PM, Oleinik, Alexander wrote:
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>

Is there some explanation for why the below patch does what the subject
line claims for the uninitiated?

I don't know why increasing the number of queues from 2 to 3 here is
correct in the general case, OR why it would "add ctrl vq support".
(Or what it has to do with fuzzing, in general.)

[Only responding because this landed in tests/libqos, which I do try to
keep an eye on, but this patch is opaque to me. --js]

> ---
>  tests/libqos/virtio-net.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c
> index 66405b646e..247a0a17a8 100644
> --- a/tests/libqos/virtio-net.c
> +++ b/tests/libqos/virtio-net.c
> @@ -51,7 +51,7 @@ static void virtio_net_setup(QVirtioNet *interface)
>      if (features & (1u << VIRTIO_NET_F_MQ)) {
>          interface->n_queues = qvirtio_config_readw(vdev, 8) * 2;
>      } else {
> -        interface->n_queues = 2;
> +        interface->n_queues = 3;
>      }
>  
>      interface->queues = g_new(QVirtQueue *, interface->n_queues);
> 



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos
  2019-07-25 16:25   ` John Snow
@ 2019-07-25 17:05     ` Oleinik, Alexander
  2019-07-26 13:09       ` Stefan Hajnoczi
  0 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-25 17:05 UTC (permalink / raw)
  To: qemu-devel, jsnow
  Cc: lvivier, thuth, bsd, superirishdonkey, stefanha, pbonzini

On Thu, 2019-07-25 at 12:25 -0400, John Snow wrote:
> 
> On 7/24/19 11:23 PM, Oleinik, Alexander wrote:
> > Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> 
> Is there some explanation for why the below patch does what the
> subject
> line claims for the uninitiated?
When multiqueue mode (VIRTIO_NET_F_MQ) is disabled, virtio-net sets up
three queues. 0:receiveq, 1:transmitq and 2:controlq. 
> I don't know why increasing the number of queues from 2 to 3 here is
> correct in the general case, OR why it would "add ctrl vq support".
> (Or what it has to do with fuzzing, in general.)

Prior to the change, accessing the ctrl vq through QOS, would trigger a
segfault, since only two queues were allocated to QVirtioDevice*
interface->queues.

Also, when VIRTIO_NET_F_MQ is enabled, the number of queues is 2*N + 1,
so I think in that case n->n_queues is also short by one in the code
below.

> [Only responding because this landed in tests/libqos, which I do try
> to
> keep an eye on, but this patch is opaque to me. --js]
> 
> > ---
> >  tests/libqos/virtio-net.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c
> > index 66405b646e..247a0a17a8 100644
> > --- a/tests/libqos/virtio-net.c
> > +++ b/tests/libqos/virtio-net.c
> > @@ -51,7 +51,7 @@ static void virtio_net_setup(QVirtioNet
> > *interface)
> >      if (features & (1u << VIRTIO_NET_F_MQ)) {
> >          interface->n_queues = qvirtio_config_readw(vdev, 8) * 2;
> >      } else {
> > -        interface->n_queues = 2;
> > +        interface->n_queues = 3;
> >      }
> >  
> >      interface->queues = g_new(QVirtQueue *, interface->n_queues);
> > 


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 16/19] fuzz: add general fuzzer entrypoints
  2019-07-25  3:23 ` [Qemu-devel] [RFC 16/19] fuzz: add general fuzzer entrypoints Oleinik, Alexander
@ 2019-07-25 17:53   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 49+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-07-25 17:53 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel; +Cc: pbonzini, bsd, superirishdonkey, stefanha

Hi Aleksander,

On 7/25/19 5:23 AM, Oleinik, Alexander wrote:
> Defines LLVMFuzzerInitialize and LLVMFuzzerTestOneInput
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  tests/fuzz/fuzz.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++
>  tests/fuzz/fuzz.h |  96 +++++++++++++++++
>  2 files changed, 358 insertions(+)
>  create mode 100644 tests/fuzz/fuzz.c
>  create mode 100644 tests/fuzz/fuzz.h
> 
> diff --git a/tests/fuzz/fuzz.c b/tests/fuzz/fuzz.c
> new file mode 100644
> index 0000000000..0421b9402c
> --- /dev/null
> +++ b/tests/fuzz/fuzz.c
> @@ -0,0 +1,262 @@
> +#include "tests/fuzz/ramfile.h"
> +#include "migration/qemu-file.h"
> +#include "migration/global_state.h"
> +#include "migration/savevm.h"
> +#include "tests/libqtest.h"
> +#include "exec/memory.h"
> +#include "migration/migration.h"
> +#include "fuzz.h"
> +#include "tests/libqos/qgraph.h"
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <linux/userfaultfd.h>
> +#include <poll.h>
> +#include <pthread.h>
> +#include <sys/syscall.h>
> +#include <sys/types.h>
> +#include <sys/ioctl.h>
> +
> +QTestState *s;
> +
> +QEMUFile *ramfile;
> +QEMUFile *writefile;
> +ram_disk *rd; 
> +typedef QSLIST_HEAD(, FuzzTarget) FuzzTargetList;
> +
> +FuzzTargetList* fuzz_target_list;
> +
> +uint64_t total_mr_size = 0;
> +uint64_t mr_index = 0;
> +
> +const MemoryRegion* mrs[1000];
> +
> +
> +// Save just the VMStateDescriptors
> +void save_device_state(void)
> +{
> +    writefile = qemu_fopen_ram(&rd);
> +    global_state_store();
> +    qemu_save_device_state(writefile);
> +    qemu_fflush(writefile);
> +    ramfile = qemu_fopen_ro_ram(rd);
> +}
> +
> +// Save the entire vm state including RAM
> +void save_vm_state(void) 
> +{
> +    writefile = qemu_fopen_ram(&rd);
> +    vm_stop(RUN_STATE_SAVE_VM);
> +    global_state_store();
> +    qemu_savevm_state(writefile, NULL);
> +    qemu_fflush(writefile);
> +    ramfile = qemu_fopen_ro_ram(rd);
> +}
> +
> +/* Reset state by rebooting */
> +void reboot()
> +{
> +    qemu_system_reset(SHUTDOWN_CAUSE_NONE);
> +}
> +
> +/* Restore device state */
> +void load_device_state()
> +{
> +    qemu_freopen_ro_ram(ramfile);
> +
> +    int ret = qemu_load_device_state(ramfile);
> +    if (ret < 0){
> +        printf("reset error\n");
> +        exit(-1);
> +    }
> +}
> +
> +/* Restore full vm state */
> +void load_vm_state()
> +{
> +    qemu_freopen_ro_ram(ramfile);
> +
> +    vm_stop(RUN_STATE_RESTORE_VM);
> +    /* qemu_system_reset(SHUTDOWN_CAUSE_NONE); */
> +
> +    int ret = qemu_loadvm_state(ramfile);
> +    if (ret < 0){
> +        printf("reset error\n");
> +        exit(-1);
> +    }
> +    migration_incoming_state_destroy();
> +    vm_start();
> +}
> +
> +void qtest_setup()
> +{
> +    s = qtest_init_fuzz(NULL, NULL);
> +    global_qtest = s;
> +}
> +
> +void fuzz_add_target(const char* name,
> +        const char* description,
> +        void(*init_pre_main)(void),
> +        void(*init_pre_save)(void),
> +        void(*save_state)(void),
> +        void(*reset)(void),
> +        void(*pre_fuzz)(void),
> +        void(*fuzz)(const unsigned char*, size_t),
> +        void(*post_fuzz)(void),
> +        int* main_argc,
> +        char*** main_argv)
> +{
> +
> +    FuzzTarget *target;
> +    FuzzTarget *tmp;
> +    if(!fuzz_target_list)
> +        fuzz_target_list = g_new0(FuzzTargetList, 1);
> +
> +    QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
> +        if (g_strcmp0(tmp->name->str, name) == 0) {
> +            fprintf(stderr, "Error: Fuzz target name %s already in use\n", name);
> +            abort();
> +        }
> +    }
> +    target = g_new0(FuzzTarget, 1);
> +    target->name = g_string_new(name);
> +    target->description = g_string_new(description);
> +    target->init_pre_main = init_pre_main;
> +    target->init_pre_save = init_pre_save;
> +    target->save_state = save_state;
> +    target->reset = reset;
> +    target->pre_fuzz = pre_fuzz;
> +    target->fuzz = fuzz;
> +    target->post_fuzz = post_fuzz;
> +    target->main_argc = main_argc;
> +    target->main_argv = main_argv;
> +    QSLIST_INSERT_HEAD(fuzz_target_list, target, target_list);
> +}
> +
> +
> +FuzzTarget* fuzz_get_target(char* name)
> +{
> +    FuzzTarget* tmp;
> +    if(!fuzz_target_list){
> +        fprintf(stderr, "Fuzz target list not initialized");
> +        abort();
> +    }
> +
> +    QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
> +        if (g_strcmp0(tmp->name->str, name) == 0) {
> +            break;
> +        }
> +    }
> +    return tmp;
> +}
> +
> +FuzzTarget* fuzz_target;
> +
> +
> +
> +static void usage(void)
> +{
> +    printf("Usage: ./fuzz --FUZZ_TARGET [LIBFUZZER ARGUMENTS]\n");
> +    printf("where --FUZZ_TARGET is one of:\n");
> +    FuzzTarget* tmp;
> +    if(!fuzz_target_list){
> +        fprintf(stderr, "Fuzz target list not initialized");
> +        abort();
> +    }
> +    QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
> +        QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
> +            printf(" --%s  : %s\n", tmp->name->str, tmp->description->str);
> +        }
> +        exit(0);
> +    }
> +}
> +
> +// TODO: Replace this with QEMU's built-in linked list
> +static void enum_memory(void)
> +{
> +    mtree_info(true, true, true);
> +    fuzz_memory_region *fmr = g_new0(fuzz_memory_region, 1);
> +
> +    fmr->io = false;
> +    fmr->start = 0x100000;
> +    fmr->length = 0x10000;
> +    fmr->next = fuzz_memory_region_head;
> +    fuzz_memory_region_tail->next = fmr;
> +    fuzz_memory_region_tail = fmr;
> +    fmr = fuzz_memory_region_head;
> +
> +    while(true){
> +        fmr = fmr->next;
> +        if(fmr == fuzz_memory_region_head)
> +            break;
> +    }
> +}
> +
> +/* Executed for each fuzzing-input */
> +int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size)
> +{
> +    /* e.g. Device bootstrapping */
> +    if(fuzz_target->pre_fuzz)
> +        fuzz_target->pre_fuzz();
> +
> +    if(fuzz_target->fuzz)
> +        fuzz_target->fuzz(Data, Size);
> +
> +    /* e.g. Copy counter bitmap to shm*/
> +    if(fuzz_target->post_fuzz)
> +        fuzz_target->post_fuzz();
> +
> +    /* e.g. Reboot the machine or vmload */
> +    if(fuzz_target->reset)
> +        fuzz_target->reset();
> +
> +    return 0;
> +}
> +
> +/* Executed once, prior to fuzzing */
> +int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
> +{
> +
> +    char *target_name;
> +
> +    // Initialize qgraph and modules
> +    qos_graph_init();
> +    module_call_init(MODULE_INIT_FUZZ_TARGET);
> +    module_call_init(MODULE_INIT_QOM);
> +    module_call_init(MODULE_INIT_LIBQOS);
> +
> +    if(*argc <= 1)
> +        usage();
> +
> +
> +    /* Identify the fuzz target */
> +    target_name = (*argv)[1];
> +    target_name+=2;
> +    fuzz_target = fuzz_get_target(target_name);
> +
> +    if(!fuzz_target)
> +    {
> +        fprintf(stderr, "Error: Fuzz fuzz_target name %s not found\n", target_name);
> +        usage();
> +    }
> +
> +    if(fuzz_target->init_pre_main)
> +        fuzz_target->init_pre_main();
> +
> +    /* Run QEMU's regular vl.c:main */
> +    real_main(*(fuzz_target->main_argc), *(fuzz_target->main_argv), NULL);
> +
> +
> +    /* Enumerate memory to identify mapped MMIO and I/O regions */
> +    enum_memory();
> +
> +    /* Good place to do any one-time device initialization (such as QOS init) */
> +    if(fuzz_target->init_pre_save)
> +        fuzz_target->init_pre_save();
> +
> +    /* If configured, this is where we save vm or device state to ramdisk */
> +    if(fuzz_target->save_state)
> +        fuzz_target->save_state();
> +
> +    return 0;
> +}
> diff --git a/tests/fuzz/fuzz.h b/tests/fuzz/fuzz.h
> new file mode 100644
> index 0000000000..02f26752eb
> --- /dev/null
> +++ b/tests/fuzz/fuzz.h
> @@ -0,0 +1,96 @@
> +#ifndef FUZZER_H_
> +#define FUZZER_H_
> +
> +#include "qemu/osdep.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "exec/memory.h"
> +#include "tests/libqtest.h"
> +#include "migration/qemu-file.h"
> +#include "ramfile.h"
> +
> +#include <linux/userfaultfd.h>
> +
> +
> +extern QTestState *s;
> +extern QEMUFile *writefile;
> +extern QEMUFile *ramfile;
> +extern ram_disk *rd;
> +
> +typedef struct FuzzTarget {
> +	GString* name;
> +	GString* description;
> +	void(*init_pre_main)(void);
> +	void(*init_pre_save)(void);
> +	void(*save_state)(void);
> +	void(*reset)(void);
> +	void(*pre_fuzz)(void);
> +	void(*fuzz)(const unsigned char*, size_t);
> +	void(*post_fuzz)(void);
> +	int* main_argc;
> +	char*** main_argv;
> +	QSLIST_ENTRY(FuzzTarget) target_list;
> +
> +} FuzzTarget;
> +
> +extern void* _ZN6fuzzer3TPCE;
> +/* extern uint8_t __sancov_trace_pc_guard_8bit_counters; */
> +/* extern uint8_t __sancov_trace_pc_pcs; */
> +extern void* __prof_nms_sect_data;
> +extern void* __prof_vnodes_sect_data;
> +
> +#define TPC_SIZE 0x0443c00
> +#define PROFILE_SIZE ( &__prof_vnodes_sect_data - &__prof_nms_sect_data)
> +
> +#define NUMPCS (1 << 21)
> +/* #define TPC_SIZE 0x33c00 */
> +
> +extern uint8_t *TPCCopy;
> +extern uint8_t *ARGCopy;
> +
> +void save_device_state(void);
> +void save_vm_state(void);
> +void reboot(void);
> +
> +void load_device_state(void);
> +void load_vm_state(void);
> +
> +
> +void save_device_state(void);
> +void qtest_setup(void);
> +void fuzz_register_mr(const MemoryRegion *mr);
> +
> +FuzzTarget* fuzz_get_target(char* name);
> +
> +extern FuzzTarget* fuzz_target;
> +
> +typedef struct fuzz_memory_region {
> +	bool io;
> +	uint64_t start;
> +	uint64_t length;
> +	struct fuzz_memory_region* next;
> +} fuzz_memory_region;
> +
> +extern fuzz_memory_region *fuzz_memory_region_head;
> +extern fuzz_memory_region *fuzz_memory_region_tail;
> +
> +extern uint64_t total_io_mem;
> +extern uint64_t total_ram_mem;
> +
> +void fuzz_add_target(const char* name,
> +	const char* description,
> +	void(*init_pre_main)(void),
> +	void(*init_pre_save)(void),
> +	void(*save_state)(void),
> +	void(*reset)(void),
> +	void(*pre_fuzz)(void),
> +	void(*fuzz)(const unsigned char*, size_t),
> +	void(*post_fuzz)(void),
> +	int* main_argc,
> +	char*** main_argv);

What about having in tests/fuzz/fuzz.h:

typedef struct FuzzTarget {
	GString* name;
	GString* description;
	void(*init_pre_main)(void);
	void(*init_pre_save)(void);
	void(*save_state)(void);
	void(*reset)(void);
	void(*pre_fuzz)(void);
	void(*fuzz)(const unsigned char*, size_t);
	void(*post_fuzz)(void);
	int* main_argc;
	char*** main_argv;
} FuzzTarget;

void fuzz_add_target(FuzzTarget *target);

And in tests/fuzz/fuzz.c:

typedef struct FuzzTargetState {
	FuzzTarget *target;
	QSLIST_ENTRY(FuzzTarget) target_list;
} FuzzTargetState;

> +
> +int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
> +int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp);
> +
> +#endif
> +
> 


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator
  2019-07-25  3:23 ` [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator Oleinik, Alexander
@ 2019-07-26 10:33   ` Paolo Bonzini
  2019-07-26 12:35   ` Stefan Hajnoczi
  1 sibling, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-26 10:33 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel; +Cc: bsd, superirishdonkey, stefanha

On 25/07/19 05:23, Oleinik, Alexander wrote:
> +#ifdef CONFIG_FUZZ
> +/* Both the client and the server have qtest_init's, Rename on of them... */
> +void qtest_init_server(const char *qtest_chrdev, const char *qtest_log, Error **errp);

Just rename it in qtest.c and vl.c.

> +void qtest_server_recv(GString *inbuf); /* Client sends commands using this */

Please define this in this patch already.

> +#else
>  void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
> +#endif
>  



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 04/19] fuzz: Add qos support to fuzz targets
  2019-07-25  3:23 ` [Qemu-devel] [RFC 04/19] fuzz: Add qos support to fuzz targets Oleinik, Alexander
@ 2019-07-26 10:39   ` Paolo Bonzini
  0 siblings, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-26 10:39 UTC (permalink / raw)
  To: Oleinik, Alexander, qemu-devel; +Cc: bsd, superirishdonkey, stefanha

On 25/07/19 05:23, Oleinik, Alexander wrote:
> qos_helpers.c is largely a copy of tests/qos-test.c
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  tests/fuzz/qos_fuzz.c    |  63 +++++++++
>  tests/fuzz/qos_fuzz.h    |  29 ++++
>  tests/fuzz/qos_helpers.c | 295 +++++++++++++++++++++++++++++++++++++++
>  tests/fuzz/qos_helpers.h |  17 +++
>  4 files changed, 404 insertions(+)
>  create mode 100644 tests/fuzz/qos_fuzz.c
>  create mode 100644 tests/fuzz/qos_fuzz.h
>  create mode 100644 tests/fuzz/qos_helpers.c
>  create mode 100644 tests/fuzz/qos_helpers.h

If there are functions that are exactly the same, please move them to a
new file that is shared by qos-test.c and the fuzzing driver.  Other
functions can stay in qos_fuzz.c.

Paolo


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 02/19] fuzz: add FUZZ_TARGET type to qemu module system
  2019-07-25  3:23 ` [Qemu-devel] [RFC 02/19] fuzz: add FUZZ_TARGET type to qemu module system Oleinik, Alexander
@ 2019-07-26 12:32   ` Stefan Hajnoczi
  0 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 12:32 UTC (permalink / raw)
  To: Oleinik, Alexander; +Cc: pbonzini, bsd, qemu-devel, stefanha, superirishdonkey

[-- Attachment #1: Type: text/plain, Size: 481 bytes --]

On Thu, Jul 25, 2019 at 03:23:45AM +0000, Oleinik, Alexander wrote:
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  include/qemu/module.h | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)

I wouldn't worry about #ifdefs since none of this generates code.  The
only bloat will be the debuginfo, but I think avoiding ifdef is worth it
(to prevent bitrot and to make the code easier to understand).

Anyway:

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator
  2019-07-25  3:23 ` [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator Oleinik, Alexander
  2019-07-26 10:33   ` Paolo Bonzini
@ 2019-07-26 12:35   ` Stefan Hajnoczi
  1 sibling, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 12:35 UTC (permalink / raw)
  To: Oleinik, Alexander; +Cc: pbonzini, bsd, qemu-devel, stefanha, superirishdonkey

[-- Attachment #1: Type: text/plain, Size: 975 bytes --]

On Thu, Jul 25, 2019 at 03:23:46AM +0000, Oleinik, Alexander wrote:
> Much like the qtest accelerator, the fuzz accelerator skips the CPU
> emulation
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  include/sysemu/qtest.h | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
> index cd114b8d80..adfbd10d20 100644
> --- a/include/sysemu/qtest.h
> +++ b/include/sysemu/qtest.h
> @@ -23,7 +23,12 @@ static inline bool qtest_enabled(void)
>  }
>  
>  bool qtest_driver(void);
> -
> +#ifdef CONFIG_FUZZ
> +/* Both the client and the server have qtest_init's, Rename on of them... */

s/on/one/

> +void qtest_init_server(const char *qtest_chrdev, const char *qtest_log, Error **errp);
> +void qtest_server_recv(GString *inbuf); /* Client sends commands using this */

qtest_server_init() is more consistent since the other function is
called qtest_server_recv().

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload
  2019-07-25  3:23 ` [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload Oleinik, Alexander
@ 2019-07-26 12:47   ` Stefan Hajnoczi
  2019-07-26 19:36     ` Oleinik, Alexander
  0 siblings, 1 reply; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 12:47 UTC (permalink / raw)
  To: Oleinik, Alexander; +Cc: pbonzini, bsd, qemu-devel, stefanha, superirishdonkey

[-- Attachment #1: Type: text/plain, Size: 2458 bytes --]

On Thu, Jul 25, 2019 at 03:23:49AM +0000, Oleinik, Alexander wrote:
> The ramfile allows vmstate to be saved and restored directly onto the
> heap.
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  tests/fuzz/ramfile.c | 127 +++++++++++++++++++++++++++++++++++++++++++
>  tests/fuzz/ramfile.h |  20 +++++++
>  2 files changed, 147 insertions(+)
>  create mode 100644 tests/fuzz/ramfile.c
>  create mode 100644 tests/fuzz/ramfile.h
> 
> diff --git a/tests/fuzz/ramfile.c b/tests/fuzz/ramfile.c
> new file mode 100644
> index 0000000000..8da242e9ee
> --- /dev/null
> +++ b/tests/fuzz/ramfile.c

Please put this in migration/.  This code doesn't do fuzzing and is
general-purpose enough to be used by other parts of QEMU dealing with
live migration.

> @@ -0,0 +1,127 @@
> +/*
> + * =====================================================================================
> + *
> + *       Filename:  ramfile.c
> + *
> + *    Description:  QEMUFile stored in dynamically allocated RAM for fast VMRestore
> + *
> + *         Author:  Alexander Oleinik (), alxndr@bu.edu
> + *   Organization:  
> + *
> + * =====================================================================================
> + */

Please use license headers with all new files that are created.
Fine-grained filename and authorship information is already kept by git
so it's not necessary to duplicate it here.

> +#include <stdlib.h>
> +#include "qemu/osdep.h"

osdep.h already includes stdlib.h.

> +#include "qemu-common.h"
> +#include "exec/memory.h"
> +#include "migration/qemu-file.h"
> +#include "migration/migration.h"
> +#include "migration/savevm.h"
> +#include "ramfile.h"
> +
> +#define INCREMENT 10240
> +#define IO_BUF_SIZE 32768
> +#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
> +
> +struct QEMUFile {
> +    const QEMUFileOps *ops;
> +    const QEMUFileHooks *hooks;
> +    void *opaque;
> +
> +    int64_t bytes_xfer;
> +    int64_t xfer_limit;
> +
> +    int64_t pos; /* start of buffer when writing, end of buffer
> +                    when reading */
> +    int buf_index;
> +    int buf_size; /* 0 when writing */
> +    uint8_t buf[IO_BUF_SIZE];
> +
> +    DECLARE_BITMAP(may_free, MAX_IOV_SIZE);
> +    struct iovec iov[MAX_IOV_SIZE];
> +    unsigned int iovcnt;
> +
> +    int last_error;
> +};

Wait, what?! :)

Please add the ram file to qemu-file.c instead of duplicating QEMUFile.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c
  2019-07-25  9:04   ` Thomas Huth
  2019-07-25  9:33     ` Paolo Bonzini
@ 2019-07-26 12:49     ` Stefan Hajnoczi
  1 sibling, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 12:49 UTC (permalink / raw)
  To: Oleinik, Alexander
  Cc: Laurent Vivier, Thomas Huth, qemu-devel, bsd, superirishdonkey,
	stefanha, pbonzini

[-- Attachment #1: Type: text/plain, Size: 819 bytes --]

On Thu, Jul 25, 2019 at 11:04:11AM +0200, Thomas Huth wrote:
> On 25/07/2019 05.23, Oleinik, Alexander wrote:
> > @@ -379,9 +399,18 @@ static void socket_sendf(int fd, const char *fmt, va_list ap)
> >  {
> >      gchar *str = g_strdup_vprintf(fmt, ap);
> >      size_t size = strlen(str);
> > +#ifdef CONFIG_FUZZ
> > +    // Directly call qtest_process_inbuf in the qtest server
> > +    GString *gstr = g_string_new_len(str, size);
> > +	/* printf(">>> %s",gstr->str); */
> 
> Please check your patches with scripts/checkpatch.pl - e.g. don't use
> TABs for indentation like in the above line, don't use //-comments, etc.

You can set up a git-hook with checkpatch.pl to scan code automatically
before each commit:
http://blog.vmsplice.net/2011/03/how-to-automatically-run-checkpatchpl.html

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c
  2019-07-25  3:23 ` [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c Oleinik, Alexander
  2019-07-25  9:04   ` Thomas Huth
@ 2019-07-26 12:56   ` Stefan Hajnoczi
  2019-07-26 21:50     ` Paolo Bonzini
  1 sibling, 1 reply; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 12:56 UTC (permalink / raw)
  To: Oleinik, Alexander
  Cc: Laurent Vivier, Thomas Huth, qemu-devel, bsd, superirishdonkey,
	stefanha, pbonzini

[-- Attachment #1: Type: text/plain, Size: 872 bytes --]

On Thu, Jul 25, 2019 at 03:23:49AM +0000, Oleinik, Alexander wrote:
> @@ -379,9 +399,18 @@ static void socket_sendf(int fd, const char *fmt, va_list ap)
>  {
>      gchar *str = g_strdup_vprintf(fmt, ap);
>      size_t size = strlen(str);
> +#ifdef CONFIG_FUZZ
> +    // Directly call qtest_process_inbuf in the qtest server
> +    GString *gstr = g_string_new_len(str, size);
> +	/* printf(">>> %s",gstr->str); */
> +    qtest_server_recv(gstr);
> +    g_string_free(gstr, true);
> +    g_free(str);
> +#else
>  
>      socket_send(fd, str, size);
>      g_free(str);
> +#endif
>  }

This should use indirection: a function pointer to dispatch to either
the socket or the internal qtest_process_inbuf() call.

With a bit of refactoring you can eliminate the #ifdefs and treat the
socket fd as one backend and direct invocation as another backend.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init
  2019-07-25  8:21   ` Paolo Bonzini
@ 2019-07-26 12:59     ` Stefan Hajnoczi
  0 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 12:59 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Oleinik, Alexander, bsd, qemu-devel, stefanha, superirishdonkey

[-- Attachment #1: Type: text/plain, Size: 1484 bytes --]

On Thu, Jul 25, 2019 at 10:21:18AM +0200, Paolo Bonzini wrote:
> On 25/07/19 05:23, Oleinik, Alexander wrote:
> > Intercept coverage buffer registration calls and use this information to
> > copy them to shared memory, if using fork() to avoid resetting device
> > state.
> > 
> > Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> > ---
> >  tests/fuzz/fuzzer_hooks.c | 106 ++++++++++++++++++++++++++++++++++++++
> >  tests/fuzz/fuzzer_hooks.h |   9 ++++
> >  2 files changed, 115 insertions(+)
> >  create mode 100644 tests/fuzz/fuzzer_hooks.c
> >  create mode 100644 tests/fuzz/fuzzer_hooks.h
> > 
> > diff --git a/tests/fuzz/fuzzer_hooks.c b/tests/fuzz/fuzzer_hooks.c
> > new file mode 100644
> > index 0000000000..5a0bbec413
> > --- /dev/null
> > +++ b/tests/fuzz/fuzzer_hooks.c
> > @@ -0,0 +1,106 @@
> > +#include "qemu/osdep.h"
> > +#include "qemu/units.h"
> > +#include "qapi/error.h"
> > +#include "qemu-common.h"
> > +#include "fuzzer_hooks.h"
> > +
> > +#include <dlfcn.h>
> > +#include <elf.h>
> > +
> > +
> > +extern void* _ZN6fuzzer3TPCE;
> 
> Would it make sense to make this a C++ source, so that you can avoid
> using the mangled names (in this case, "namespace fuzzer { extern void
> *TPC; }" and then using fuzzer::TPC)?  Even if it's just a single symbol.

A proper libfuzzer API is nicest in the long term.

Alexander: Could you send a patch to libfuzzer to see if they are
willing to support this via their API?

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 09/19] fuzz: use mtree_info to find mapped addresses
  2019-07-25  3:23 ` [Qemu-devel] [RFC 09/19] fuzz: use mtree_info to find mapped addresses Oleinik, Alexander
@ 2019-07-26 13:04   ` Stefan Hajnoczi
  2019-07-26 21:51     ` Paolo Bonzini
  0 siblings, 1 reply; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 13:04 UTC (permalink / raw)
  To: Oleinik, Alexander; +Cc: pbonzini, bsd, qemu-devel, stefanha, superirishdonkey

[-- Attachment #1: Type: text/plain, Size: 2908 bytes --]

On Thu, Jul 25, 2019 at 03:23:51AM +0000, Oleinik, Alexander wrote:
> Locate mmio and port i/o addresses that are mapped to devices so we can
> limit the fuzzer to only these addresses. This should be replaced with
> a sane way of enumaring these memory regions.
> 
> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> ---
>  memory.c | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/memory.c b/memory.c
> index 5d8c9a9234..fa6cbe4f1d 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -34,6 +34,11 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/boards.h"
>  #include "migration/vmstate.h"
> +#ifdef CONFIG_FUZZ
> +#include "tests/fuzz/fuzz.h"
> +#include "tests/fuzz/qos_fuzz.h"
> +#endif
> +
>  
>  //#define DEBUG_UNASSIGNED
>  
> @@ -3016,12 +3021,20 @@ static void mtree_print_flatview(gpointer key, gpointer value,
>      int n = view->nr;
>      int i;
>      AddressSpace *as;
> +#ifdef CONFIG_FUZZ
> +    bool io=false;
> +#endif
> +
>  
>      qemu_printf("FlatView #%d\n", fvi->counter);
>      ++fvi->counter;
>  
>      for (i = 0; i < fv_address_spaces->len; ++i) {
>          as = g_array_index(fv_address_spaces, AddressSpace*, i);
> +#ifdef CONFIG_FUZZ
> +        if(strcmp("I/O",as->name) == 0)
> +            io = true;
> +#endif
>          qemu_printf(" AS \"%s\", root: %s",
>                      as->name, memory_region_name(as->root));
>          if (as->root->alias) {
> @@ -3062,6 +3075,27 @@ static void mtree_print_flatview(gpointer key, gpointer value,
>                          range->readonly ? "rom" : memory_region_type(mr),
>                          memory_region_name(mr));
>          }
> +#ifdef CONFIG_FUZZ
> +        if(strcmp("i/o", memory_region_type(mr))==0 && strcmp("io", memory_region_name(mr))){
> +            fuzz_memory_region *fmr = g_new0(fuzz_memory_region, 1);
> +            if(!fuzz_memory_region_head)
> +            {
> +                fuzz_memory_region_head = fmr;
> +                fuzz_memory_region_tail = fmr;
> +            }
> +            fmr->io = io;
> +            fmr->start = int128_get64(range->addr.start);
> +            fmr->length = MR_SIZE(range->addr.size);
> +            fmr->next = fuzz_memory_region_head;
> +            fuzz_memory_region_tail->next = fmr;
> +            fuzz_memory_region_tail = fmr;
> +            if(io == true){
> +                total_io_mem += MR_SIZE(range->addr.size)+1;
> +            } else {
> +                total_ram_mem += MR_SIZE(range->addr.size)+1;
> +            }
> +        }
> +#endif

Why is this patch modifying a print function?  I think the goal is to
build the fuzz_memory_region list and calculate
total_io_mem/total_ram_mem.  This should be done by a separate function.

Can you use memory_region_is_ram() instead of the string compares?

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos
  2019-07-25 17:05     ` Oleinik, Alexander
@ 2019-07-26 13:09       ` Stefan Hajnoczi
  0 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 13:09 UTC (permalink / raw)
  To: Oleinik, Alexander
  Cc: lvivier, thuth, qemu-devel, bsd, superirishdonkey, stefanha,
	pbonzini, jsnow

[-- Attachment #1: Type: text/plain, Size: 2097 bytes --]

On Thu, Jul 25, 2019 at 05:05:25PM +0000, Oleinik, Alexander wrote:
> On Thu, 2019-07-25 at 12:25 -0400, John Snow wrote:
> > 
> > On 7/24/19 11:23 PM, Oleinik, Alexander wrote:
> > > Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
> > 
> > Is there some explanation for why the below patch does what the
> > subject
> > line claims for the uninitiated?
> When multiqueue mode (VIRTIO_NET_F_MQ) is disabled, virtio-net sets up
> three queues. 0:receiveq, 1:transmitq and 2:controlq. 
> > I don't know why increasing the number of queues from 2 to 3 here is
> > correct in the general case, OR why it would "add ctrl vq support".
> > (Or what it has to do with fuzzing, in general.)
> 
> Prior to the change, accessing the ctrl vq through QOS, would trigger a
> segfault, since only two queues were allocated to QVirtioDevice*
> interface->queues.
> 
> Also, when VIRTIO_NET_F_MQ is enabled, the number of queues is 2*N + 1,
> so I think in that case n->n_queues is also short by one in the code
> below.

I think the patch could be changed to:

> > [Only responding because this landed in tests/libqos, which I do try
> > to
> > keep an eye on, but this patch is opaque to me. --js]
> > 
> > > ---
> > >  tests/libqos/virtio-net.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c
> > > index 66405b646e..247a0a17a8 100644
> > > --- a/tests/libqos/virtio-net.c
> > > +++ b/tests/libqos/virtio-net.c
> > > @@ -51,7 +51,7 @@ static void virtio_net_setup(QVirtioNet
> > > *interface)
> > >      if (features & (1u << VIRTIO_NET_F_MQ)) {
> > >          interface->n_queues = qvirtio_config_readw(vdev, 8) * 2;
> > >      } else {
> > > -        interface->n_queues = 2;
> > > +        interface->n_queues = 3;
> > >      }

interface->n_queues++; /* ctrl vq */

And a comment added to the QVirtQueue::n_queues field definition:

  /* total number of virtqueues (rx, tx, ctrl) */

This will prevent confusion about whether the ctrl queue is counted or
not.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 19/19] fuzz: Add documentation about the fuzzer to docs/
  2019-07-25  3:24 ` [Qemu-devel] [RFC 19/19] fuzz: Add documentation about the fuzzer to docs/ Oleinik, Alexander
@ 2019-07-26 13:19   ` Stefan Hajnoczi
  0 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 13:19 UTC (permalink / raw)
  To: Oleinik, Alexander; +Cc: pbonzini, bsd, qemu-devel, stefanha, superirishdonkey

[-- Attachment #1: Type: text/plain, Size: 937 bytes --]

On Thu, Jul 25, 2019 at 03:24:00AM +0000, Oleinik, Alexander wrote:
> +== Main Modifications required for Fuzzing ==
> +
> +Fuzzing is enabled with the -enable-fuzzing flag, which adds the needed cflags
> +to enable Libfuzzer and AddressSanitizer. In the code, most of the changes to
> +existing qemu source are surrounded by #ifdef CONFIG_FUZZ statements. Here are
> +the key areas that are changed:
> +
> +=== General Changes ===

The audience of this file are people wishing to run existing fuzz tests
and/or add new fuzz tests.  Changes are of limited use to someone who
wants to write fuzz tests but isn't familiar with QEMU internals.

Instead I suggest documenting fuzzing in terms of:

1. How to run existing fuzz tests.
2. How to add new fuzz tests.
3. Advice on achieving good code coverage and explanation of the fuzz
   test development cycle.

Focus less on the fuzz infrastructure internals and more on how to use
fuzzing.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (19 preceding siblings ...)
  2019-07-25  3:41 ` [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support no-reply
@ 2019-07-26 13:24 ` Stefan Hajnoczi
  2019-08-06  9:59 ` jiade zhang
  21 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2019-07-26 13:24 UTC (permalink / raw)
  To: Oleinik, Alexander; +Cc: pbonzini, bsd, qemu-devel, stefanha, superirishdonkey

[-- Attachment #1: Type: text/plain, Size: 814 bytes --]

On Thu, Jul 25, 2019 at 03:23:43AM +0000, Oleinik, Alexander wrote:
> As part of Google Summer of Code 2019, I'm working on integrating
> fuzzing of virtual devices into QEMU [1]. This is a highly WIP patchset
> adding this functionality.
> 
> Fuzzers provide random data to a program and monitor its execution for
> errors. Coverage-guided fuzzers also observe the parts of the program
> that are exercised by each input, and use this information to
> mutate/guide the inputs to reach additional parts of the program. They
> are quite effective for finding bugs in a wide range of software. 

Good start!  The overall approach is maintainable and not too invasive.
Some iteration on the current patch series will be necessary to clean
things up, but the fundamentals look promising to me.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload
  2019-07-26 12:47   ` Stefan Hajnoczi
@ 2019-07-26 19:36     ` Oleinik, Alexander
  2019-07-26 19:54       ` Paolo Bonzini
  0 siblings, 1 reply; 49+ messages in thread
From: Oleinik, Alexander @ 2019-07-26 19:36 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: pbonzini, bsd, qemu-devel, stefanha, superirishdonkey

On 7/26/19 8:47 AM, Stefan Hajnoczi wrote:
> On Thu, Jul 25, 2019 at 03:23:49AM +0000, Oleinik, Alexander wrote:
>> The ramfile allows vmstate to be saved and restored directly onto the
>> heap.
>>
>> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
>> ---
>>   tests/fuzz/ramfile.c | 127 +++++++++++++++++++++++++++++++++++++++++++
>>   tests/fuzz/ramfile.h |  20 +++++++
>>   2 files changed, 147 insertions(+)
>>   create mode 100644 tests/fuzz/ramfile.c
>>   create mode 100644 tests/fuzz/ramfile.h
>>
>> diff --git a/tests/fuzz/ramfile.c b/tests/fuzz/ramfile.c
>> new file mode 100644
>> index 0000000000..8da242e9ee
>> --- /dev/null
>> +++ b/tests/fuzz/ramfile.c
> 
> Please put this in migration/.  This code doesn't do fuzzing and is
> general-purpose enough to be used by other parts of QEMU dealing with
> live migration.
> 
>> @@ -0,0 +1,127 @@
>> +/*
>> + * =====================================================================================
>> + *
>> + *       Filename:  ramfile.c
>> + *
>> + *    Description:  QEMUFile stored in dynamically allocated RAM for fast VMRestore
>> + *
>> + *         Author:  Alexander Oleinik (), alxndr@bu.edu
>> + *   Organization:
>> + *
>> + * =====================================================================================
>> + */
> 
> Please use license headers with all new files that are created.
> Fine-grained filename and authorship information is already kept by git
> so it's not necessary to duplicate it here.
> 
>> +#include <stdlib.h>
>> +#include "qemu/osdep.h"
> 
> osdep.h already includes stdlib.h.
> 
>> +#include "qemu-common.h"
>> +#include "exec/memory.h"
>> +#include "migration/qemu-file.h"
>> +#include "migration/migration.h"
>> +#include "migration/savevm.h"
>> +#include "ramfile.h"
>> +
>> +#define INCREMENT 10240
>> +#define IO_BUF_SIZE 32768
>> +#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
>> +
>> +struct QEMUFile {
>> +    const QEMUFileOps *ops;
>> +    const QEMUFileHooks *hooks;
>> +    void *opaque;
>> +
>> +    int64_t bytes_xfer;
>> +    int64_t xfer_limit;
>> +
>> +    int64_t pos; /* start of buffer when writing, end of buffer
>> +                    when reading */
>> +    int buf_index;
>> +    int buf_size; /* 0 when writing */
>> +    uint8_t buf[IO_BUF_SIZE];
>> +
>> +    DECLARE_BITMAP(may_free, MAX_IOV_SIZE);
>> +    struct iovec iov[MAX_IOV_SIZE];
>> +    unsigned int iovcnt;
>> +
>> +    int last_error;
>> +};
> 
> Wait, what?! :)
> 
> Please add the ram file to qemu-file.c instead of duplicating QEMUFile.
> 
I think we should be able to replace all of this simply by using 
memfd_create. Since it acts as a regular file, it will work with the 
existing code (likely with performance gains).


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload
  2019-07-26 19:36     ` Oleinik, Alexander
@ 2019-07-26 19:54       ` Paolo Bonzini
  0 siblings, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-26 19:54 UTC (permalink / raw)
  To: Oleinik, Alexander, Stefan Hajnoczi
  Cc: bsd, qemu-devel, stefanha, superirishdonkey

On 26/07/19 21:36, Oleinik, Alexander wrote:
>>
>> Please add the ram file to qemu-file.c instead of duplicating QEMUFile.
>>
> I think we should be able to replace all of this simply by using 
> memfd_create. Since it acts as a regular file, it will work with the 
> existing code (likely with performance gains).

That wouldn't be portable to non-Linux, so having RAMFile is better.

Paolo


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c
  2019-07-26 12:56   ` Stefan Hajnoczi
@ 2019-07-26 21:50     ` Paolo Bonzini
  0 siblings, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-26 21:50 UTC (permalink / raw)
  To: Stefan Hajnoczi, Oleinik, Alexander
  Cc: Laurent Vivier, Thomas Huth, qemu-devel, bsd, superirishdonkey, stefanha

On 26/07/19 14:56, Stefan Hajnoczi wrote:
> This should use indirection: a function pointer to dispatch to either
> the socket or the internal qtest_process_inbuf() call.
> 
> With a bit of refactoring you can eliminate the #ifdefs and treat the
> socket fd as one backend and direct invocation as another backend.

My suggestion was a bit different (two files), but this also works.  In
fact it can also be combined to have three files:

- one defining libqtest's qtest_init and associated struct of function
pointers

- one defining the fuzzer's qtest_init and associated struct of function
pointers

- one with the remaining libqtest code, modified to use the struct of
function pointers for everything that you're #ifdef-ing here, and a
function qtest_client_init that receives the struct of function pointers
and stores them in QTestState.  The two qtest_init implementations in
the other files just call qtest_client_init.

Paolo


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 09/19] fuzz: use mtree_info to find mapped addresses
  2019-07-26 13:04   ` Stefan Hajnoczi
@ 2019-07-26 21:51     ` Paolo Bonzini
  0 siblings, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2019-07-26 21:51 UTC (permalink / raw)
  To: Stefan Hajnoczi, Oleinik, Alexander
  Cc: bsd, qemu-devel, stefanha, superirishdonkey

On 26/07/19 15:04, Stefan Hajnoczi wrote:
> On Thu, Jul 25, 2019 at 03:23:51AM +0000, Oleinik, Alexander wrote:
>> Locate mmio and port i/o addresses that are mapped to devices so we can
>> limit the fuzzer to only these addresses. This should be replaced with
>> a sane way of enumaring these memory regions.
>>
>> Signed-off-by: Alexander Oleinik <alxndr@bu.edu>
>> ---
>>  memory.c | 34 ++++++++++++++++++++++++++++++++++
>>  1 file changed, 34 insertions(+)
>>
>> diff --git a/memory.c b/memory.c
>> index 5d8c9a9234..fa6cbe4f1d 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -34,6 +34,11 @@
>>  #include "hw/qdev-properties.h"
>>  #include "hw/boards.h"
>>  #include "migration/vmstate.h"
>> +#ifdef CONFIG_FUZZ
>> +#include "tests/fuzz/fuzz.h"
>> +#include "tests/fuzz/qos_fuzz.h"
>> +#endif
>> +
>>  
>>  //#define DEBUG_UNASSIGNED
>>  
>> @@ -3016,12 +3021,20 @@ static void mtree_print_flatview(gpointer key, gpointer value,
>>      int n = view->nr;
>>      int i;
>>      AddressSpace *as;
>> +#ifdef CONFIG_FUZZ
>> +    bool io=false;
>> +#endif
>> +
>>  
>>      qemu_printf("FlatView #%d\n", fvi->counter);
>>      ++fvi->counter;
>>  
>>      for (i = 0; i < fv_address_spaces->len; ++i) {
>>          as = g_array_index(fv_address_spaces, AddressSpace*, i);
>> +#ifdef CONFIG_FUZZ
>> +        if(strcmp("I/O",as->name) == 0)
>> +            io = true;
>> +#endif
>>          qemu_printf(" AS \"%s\", root: %s",
>>                      as->name, memory_region_name(as->root));
>>          if (as->root->alias) {
>> @@ -3062,6 +3075,27 @@ static void mtree_print_flatview(gpointer key, gpointer value,
>>                          range->readonly ? "rom" : memory_region_type(mr),
>>                          memory_region_name(mr));
>>          }
>> +#ifdef CONFIG_FUZZ
>> +        if(strcmp("i/o", memory_region_type(mr))==0 && strcmp("io", memory_region_name(mr))){
>> +            fuzz_memory_region *fmr = g_new0(fuzz_memory_region, 1);
>> +            if(!fuzz_memory_region_head)
>> +            {
>> +                fuzz_memory_region_head = fmr;
>> +                fuzz_memory_region_tail = fmr;
>> +            }
>> +            fmr->io = io;
>> +            fmr->start = int128_get64(range->addr.start);
>> +            fmr->length = MR_SIZE(range->addr.size);
>> +            fmr->next = fuzz_memory_region_head;
>> +            fuzz_memory_region_tail->next = fmr;
>> +            fuzz_memory_region_tail = fmr;
>> +            if(io == true){
>> +                total_io_mem += MR_SIZE(range->addr.size)+1;
>> +            } else {
>> +                total_ram_mem += MR_SIZE(range->addr.size)+1;
>> +            }
>> +        }
>> +#endif
> 
> Why is this patch modifying a print function?  I think the goal is to
> build the fuzz_memory_region list and calculate
> total_io_mem/total_ram_mem.  This should be done by a separate function.

Yeah, this should just cut-and-paste code from mtree_print_flatview,
then you can remove the printing stuff completely from your copy.

Paolo



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support
  2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
                   ` (20 preceding siblings ...)
  2019-07-26 13:24 ` Stefan Hajnoczi
@ 2019-08-06  9:59 ` jiade zhang
  21 siblings, 0 replies; 49+ messages in thread
From: jiade zhang @ 2019-08-06  9:59 UTC (permalink / raw)
  To: Oleinik, Alexander; +Cc: pbonzini, bsd, qemu-devel, stefanha

it seems the code in blue in tests/fuzz/fuzz.c does not do anything, what
it supposed to be?

// TODO: Replace this with QEMU's built-in linked list
static void enum_memory(void)
{
    mtree_info(true, true, true);
    fuzz_memory_region *fmr = g_new0(fuzz_memory_region, 1);

    fmr->io = false;
    fmr->start = 0x100000;
    fmr->length = 0x10000;
    fmr->next = fuzz_memory_region_head;
    fuzz_memory_region_tail->next = fmr;
    fuzz_memory_region_tail = fmr;
    fmr = fuzz_memory_region_head;




*    while(true){        fmr = fmr->next;        if(fmr ==
fuzz_memory_region_head)            break;*
    }
}

Oleinik, Alexander <alxndr@bu.edu> 于2019年7月25日周四 上午11:23写道:

> As part of Google Summer of Code 2019, I'm working on integrating
> fuzzing of virtual devices into QEMU [1]. This is a highly WIP patchset
> adding this functionality.
>
> Fuzzers provide random data to a program and monitor its execution for
> errors. Coverage-guided fuzzers also observe the parts of the program
> that are exercised by each input, and use this information to
> mutate/guide the inputs to reach additional parts of the program. They
> are quite effective for finding bugs in a wide range of software.
>
> Summary:
>  - The virtual-device fuzzers use libfuzzer [2] for coverage-guided
>    in-process fuzzing.
>  - To fuzz a device, create a new fuzz "target" - i.e. a function that
>    exercises QEMU based on inputs provided by the fuzzer.
>  - Fuzz targets rely on qtest and libqos to turn inputs into actions.
>  - Since libfuzzer does in-process fuzzing, the QEMU state needs to be
>    reset after each fuzz run. These patches provide three methods for
>    resetting state.
>  - There are currently few targets, but they have already helped
>    discover bugs in the console, and virtio-net, and have reproduced
>    previously-reported vulnerabilities.
>
> Here are some main implementation details:
>  - The fuzzing occurs within a single process. QTest and QOS are
>    modified so the QTest client and server coexist within the same
>    process. They communicate with each other through direct function
>    calls. Similar to qtest, the fuzzer uses a lightweight accelerator to
>    skip CPU emulation. The fuzzing target is responsible for manually
>    executing the main loop.
>  - 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 three
>    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. vmsave the state to RAM, once, and restore it after each run.
>       Alternatively, only save the device state
>       (savevm.c:qemu_save_device_state)
>       Pros: Do not need to initialize devices prior to each run.
>       VMStateDescriptions often specify more state than the device
>       resetting functions called during reboots.
>       Cons: Restoring state is often slower than rebooting. There is
>       currently no way to save the QOS object state, so the objects
>       usually needs to be re-allocated, defeating the purpose of
>       one-time device initialization.
>       Example target: --qtest-fuzz
>    3. 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
>  - Fuzz targets are registered using QEMU's module system, similar to
>    QOS test cases. Base qtest targets are registed with fuzz_add_target
>    and QOS-based targets with fuzz_add_qos_target.
>  - There are two entry points for the fuzzer:
>     LLVMFuzzerInitialize: Run once, prior to fuzzing. Here, we set up
>    qtest/qos, register the fuzz targets and partially execute vl.c:main.
>    This is also where we would take a snapshot, if using the vmsave
>    approach to resetting.
>     LLVMFuzzerTestOneInput: Run for each fuzzing input. This function is
>    responsible for taking care of device initialization, calling the
>    actual fuzz target, and resetting state at the end of each run.
>    Both of these functions are defined in tests/fuzz/fuzz.c
>  - There are many libfuzzer flags which should be used to configure the
>    coverage metrics and storage of interesting fuzz inputs. [2] These
>    flags can also be helpful in evaluating fuzzing performance through
>    metrics such as inputs/seconds and line-coverage.
>
> Here are some key issues with the current state of the code:
>  - The patches change vl.c, main-loop.c, qtest.c, tests/libqtest.c,
>    savevm.c, memory.c. I wrapped the changes with #ifdef CONFIG_FUZZ,
>    but many of these changes can and should be avoided.
>  - tests/fuzz/qos_helpers.c is largely a copy of tests/qos-test.c.
>  - The fuzzer is not properly integrated into the build system.
>    Currently I simply added all of the necessary objects to
>    target/i386/Makefile.objs, but there should be a simple way to build
>    for other arches. The binary needs to be linked against libqemuutil,
>    libqtest, qos and the qos objects, and the requirements for softmmu
>    targets.
>  - Some of the fuzz targets leak memory during state-resetting that need
>    to be tracked down and fixed.
>  - As mentioned already, running each test in a separate process does
>    not seem to be supported by libfuzzer, and the implementation
>    reflects this (tests/fuzz/fuzzer_hooks.c)
>  - The existing fuzz targets should be cleaned up as they have issues
>    with memory alignment and contain redundant checks. The should also
>    use qtest's clock_step. The fork fuzz targets are dependant on
>    a hard-coded section size.
>
> Building and running:
> Libfuzzer requires clang.
>   $ CC=clang-7 CXX=clang++-7 ./configure --enable-fuzzing
>   $ make i386-softmmu/all
>   $ i386-softmmu/qemu-system-i386 --qtest-dma-fuzz -detect_leaks=0
>
> Here "qtest-dma-fuzz" is the fuzz target name. Running qemu-system-i386
> without any arguments should print all of the available fuzz targets.
> The -help=1 command prints out the available libfuzzer options.
>
> There are more details, including instructions for adding new fuzz
> targets in docs/devel/fuzzing.txt
>
> In the coming weeks I would like to fix the issues listed above, more
> fuzzing targets, and ideally work on getting QEMU into oss-fuzz[4],
> where it can be fuzzed continuously.
>
> I appreciate any feedback. Thanks
> -Alex
>
> [1] https://wiki.qemu.org/Internships/ProjectIdeas/QtestOssFuzz
> [2] Trophy Case section: http://lcamtuf.coredump.cx/afl/
> [3] https://llvm.org/docs/LibFuzzer.html
> [4] https://github.com/mirrorer/afl/blob/master/llvm_mode/README.llvm#L82
> [5] https://github.com/google/oss-fuzz
>
>
> Alexander Oleinik (19):
>   fuzz: add configure option and linker objects
>   fuzz: add FUZZ_TARGET type to qemu module system
>   fuzz: add fuzz accelerator
>   fuzz: Add qos support to fuzz targets
>   fuzz: expose qemu_savevm_state & skip state header
>   fuzz: Add ramfile for fast vmstate/vmload
>   fuzz: Modify libqtest to directly invoke qtest.c
>   fuzz: add shims to intercept libfuzzer init
>   fuzz: use mtree_info to find mapped addresses
>   fuzz: expose real_main (aka regular vl.c:main)
>   fuzz: add direct send/receive in qtest client
>   fuzz: hard-code all of the needed files for build
>   fuzz: add ctrl vq support to virtio-net in libqos
>   fuzz: hard-code a main-loop timeout
>   fuzz: add fuzz accelerator type
>   fuzz: add general fuzzer entrypoints
>   fuzz: add general qtest fuzz target
>   fuzz: Add virtio-net tx and ctrl fuzz targets
>   fuzz: Add documentation about the fuzzer to docs/
>
>  accel/fuzz.c                 |  47 ++++++
>  configure                    |  11 ++
>  docs/devel/fuzzing.txt       | 145 +++++++++++++++++
>  include/qemu/module.h        |   7 +-
>  include/sysemu/fuzz.h        |  15 ++
>  include/sysemu/qtest.h       |   7 +-
>  include/sysemu/sysemu.h      |   4 +
>  memory.c                     |  34 ++++
>  migration/savevm.c           |   8 +-
>  migration/savevm.h           |   3 +
>  qtest.c                      |  19 ++-
>  target/i386/Makefile.objs    |  19 +++
>  tests/fuzz/fuzz.c            | 262 +++++++++++++++++++++++++++++++
>  tests/fuzz/fuzz.h            |  96 ++++++++++++
>  tests/fuzz/fuzzer_hooks.c    | 106 +++++++++++++
>  tests/fuzz/fuzzer_hooks.h    |   9 ++
>  tests/fuzz/qos_fuzz.c        |  63 ++++++++
>  tests/fuzz/qos_fuzz.h        |  29 ++++
>  tests/fuzz/qos_helpers.c     | 295 +++++++++++++++++++++++++++++++++++
>  tests/fuzz/qos_helpers.h     |  17 ++
>  tests/fuzz/qtest_fuzz.c      | 261 +++++++++++++++++++++++++++++++
>  tests/fuzz/qtest_fuzz.h      |  38 +++++
>  tests/fuzz/ramfile.c         | 127 +++++++++++++++
>  tests/fuzz/ramfile.h         |  20 +++
>  tests/fuzz/virtio-net-fuzz.c | 226 +++++++++++++++++++++++++++
>  tests/libqos/virtio-net.c    |   2 +-
>  tests/libqtest.c             |  53 ++++++-
>  tests/libqtest.h             |   6 +
>  util/main-loop.c             |   3 +
>  vl.c                         |  21 ++-
>  30 files changed, 1945 insertions(+), 8 deletions(-)
>  create mode 100644 accel/fuzz.c
>  create mode 100644 docs/devel/fuzzing.txt
>  create mode 100644 include/sysemu/fuzz.h
>  create mode 100644 tests/fuzz/fuzz.c
>  create mode 100644 tests/fuzz/fuzz.h
>  create mode 100644 tests/fuzz/fuzzer_hooks.c
>  create mode 100644 tests/fuzz/fuzzer_hooks.h
>  create mode 100644 tests/fuzz/qos_fuzz.c
>  create mode 100644 tests/fuzz/qos_fuzz.h
>  create mode 100644 tests/fuzz/qos_helpers.c
>  create mode 100644 tests/fuzz/qos_helpers.h
>  create mode 100644 tests/fuzz/qtest_fuzz.c
>  create mode 100644 tests/fuzz/qtest_fuzz.h
>  create mode 100644 tests/fuzz/ramfile.c
>  create mode 100644 tests/fuzz/ramfile.h
>  create mode 100644 tests/fuzz/virtio-net-fuzz.c
>
> --
> 2.20.1
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2019-08-06 10:01 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-25  3:23 [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support Oleinik, Alexander
2019-07-25  3:23 ` [Qemu-devel] [RFC 01/19] fuzz: add configure option and linker objects Oleinik, Alexander
2019-07-25  9:39   ` Paolo Bonzini
2019-07-25  3:23 ` [Qemu-devel] [RFC 02/19] fuzz: add FUZZ_TARGET type to qemu module system Oleinik, Alexander
2019-07-26 12:32   ` Stefan Hajnoczi
2019-07-25  3:23 ` [Qemu-devel] [RFC 03/19] fuzz: add fuzz accelerator Oleinik, Alexander
2019-07-26 10:33   ` Paolo Bonzini
2019-07-26 12:35   ` Stefan Hajnoczi
2019-07-25  3:23 ` [Qemu-devel] [RFC 04/19] fuzz: Add qos support to fuzz targets Oleinik, Alexander
2019-07-26 10:39   ` Paolo Bonzini
2019-07-25  3:23 ` [Qemu-devel] [RFC 05/19] fuzz: expose qemu_savevm_state & skip state header Oleinik, Alexander
2019-07-25 13:22   ` Dr. David Alan Gilbert
2019-07-25  3:23 ` [Qemu-devel] [RFC 07/19] fuzz: Modify libqtest to directly invoke qtest.c Oleinik, Alexander
2019-07-25  9:04   ` Thomas Huth
2019-07-25  9:33     ` Paolo Bonzini
2019-07-26 12:49     ` Stefan Hajnoczi
2019-07-26 12:56   ` Stefan Hajnoczi
2019-07-26 21:50     ` Paolo Bonzini
2019-07-25  3:23 ` [Qemu-devel] [RFC 06/19] fuzz: Add ramfile for fast vmstate/vmload Oleinik, Alexander
2019-07-26 12:47   ` Stefan Hajnoczi
2019-07-26 19:36     ` Oleinik, Alexander
2019-07-26 19:54       ` Paolo Bonzini
2019-07-25  3:23 ` [Qemu-devel] [RFC 08/19] fuzz: add shims to intercept libfuzzer init Oleinik, Alexander
2019-07-25  8:21   ` Paolo Bonzini
2019-07-26 12:59     ` Stefan Hajnoczi
2019-07-25  3:23 ` [Qemu-devel] [RFC 09/19] fuzz: use mtree_info to find mapped addresses Oleinik, Alexander
2019-07-26 13:04   ` Stefan Hajnoczi
2019-07-26 21:51     ` Paolo Bonzini
2019-07-25  3:23 ` [Qemu-devel] [RFC 10/19] fuzz: expose real_main (aka regular vl.c:main) Oleinik, Alexander
2019-07-25  9:38   ` Paolo Bonzini
2019-07-25  3:23 ` [Qemu-devel] [RFC 11/19] fuzz: add direct send/receive in qtest client Oleinik, Alexander
2019-07-25  9:10   ` Thomas Huth
2019-07-25  3:23 ` [Qemu-devel] [RFC 12/19] fuzz: hard-code all of the needed files for build Oleinik, Alexander
2019-07-25  3:23 ` [Qemu-devel] [RFC 13/19] fuzz: add ctrl vq support to virtio-net in libqos Oleinik, Alexander
2019-07-25 16:25   ` John Snow
2019-07-25 17:05     ` Oleinik, Alexander
2019-07-26 13:09       ` Stefan Hajnoczi
2019-07-25  3:23 ` [Qemu-devel] [RFC 14/19] fuzz: hard-code a main-loop timeout Oleinik, Alexander
2019-07-25  9:40   ` Paolo Bonzini
2019-07-25  3:23 ` [Qemu-devel] [RFC 15/19] fuzz: add fuzz accelerator type Oleinik, Alexander
2019-07-25  3:23 ` [Qemu-devel] [RFC 16/19] fuzz: add general fuzzer entrypoints Oleinik, Alexander
2019-07-25 17:53   ` Philippe Mathieu-Daudé
2019-07-25  3:23 ` [Qemu-devel] [RFC 17/19] fuzz: add general qtest fuzz target Oleinik, Alexander
2019-07-25  3:24 ` [Qemu-devel] [RFC 18/19] fuzz: Add virtio-net tx and ctrl fuzz targets Oleinik, Alexander
2019-07-25  3:24 ` [Qemu-devel] [RFC 19/19] fuzz: Add documentation about the fuzzer to docs/ Oleinik, Alexander
2019-07-26 13:19   ` Stefan Hajnoczi
2019-07-25  3:41 ` [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support no-reply
2019-07-26 13:24 ` Stefan Hajnoczi
2019-08-06  9:59 ` jiade zhang

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).