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

2019-08-06 Thread jiade zhang
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 = 0x10;
fmr->length = 0x1;
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  于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 

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

2019-07-26 Thread Stefan Hajnoczi
On Thu, Jul 25, 2019 at 03:23:43AM +, 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


signature.asc
Description: PGP signature


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

2019-07-24 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20190725032321.12721-1-alx...@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-alx...@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-alx...@bu.edu -> 
patchew/20190725032321.12721-1-alx...@bu.edu
 * [new tag] 
patchew/20190725032722.32271-1-richardw.y...@linux.intel.com -> 
patchew/20190725032722.32271-1-richardw.y...@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/O

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

2019-07-24 Thread 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