qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support


From: jiade zhang
Subject: Re: [Qemu-devel] [RFC 00/19] Add virtual device fuzzing support
Date: Tue, 6 Aug 2019 17:59:49 +0800

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 <address@hidden> 于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
>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]