diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-07-21 10:24:38 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-07-21 10:24:38 +0100 |
| commit | 90218a9a393c7925f330e7dcc08658e2a01d3bd4 (patch) | |
| tree | 6f21ee31b7408198bc21391806e04010b076e5f2 /docs/devel/fuzzing.txt | |
| parent | af3d69058e09bede9900f266a618ed11f76f49f3 (diff) | |
| parent | 7ad36e2e241bd924f774a1f9fb208c102da58e50 (diff) | |
| download | focaccia-qemu-90218a9a393c7925f330e7dcc08658e2a01d3bd4.tar.gz focaccia-qemu-90218a9a393c7925f330e7dcc08658e2a01d3bd4.zip | |
Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2020-07-21' into staging
* Fix memory leak in fuzzer * Fuzzer documentation updates * Some other minor fuzzer updates * Fix "make check-qtest SPEED=slow" (bug in msf2 instance_init) # gpg: Signature made Tue 21 Jul 2020 07:48:10 BST # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "thuth@redhat.com" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * remotes/huth-gitlab/tags/pull-request-2020-07-21: hw: Mark nd_table[] misuse in realize methods FIXME msf2: Unbreak device-list-properties for "msf-soc" MAINTAINERS: Extend the device fuzzing section docs/fuzz: add instructions for generating a coverage report docs/fuzz: add information about useful libFuzzer flags docs/fuzz: describe building fuzzers with enable-sanitizers fuzz: build without AddressSanitizer, by default gitlab-ci.yml: Add oss-fuzz build tests fuzz: Fix leak when assembling datadir path string scripts/oss-fuzz: Limit target list to i386-softmmu Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'docs/devel/fuzzing.txt')
| -rw-r--r-- | docs/devel/fuzzing.txt | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/docs/devel/fuzzing.txt b/docs/devel/fuzzing.txt index db5641de74..96d71c94d7 100644 --- a/docs/devel/fuzzing.txt +++ b/docs/devel/fuzzing.txt @@ -23,9 +23,12 @@ AddressSanitizer mmaps ~20TB of memory, as part of its detection. This results in a large page-map, and a much slower fork(). To build the fuzzers, install a recent version of clang: -Configure with (substitute the clang binaries with the version you installed): +Configure with (substitute the clang binaries with the version you installed). +Here, enable-sanitizers, is optional but it allows us to reliably detect bugs +such as out-of-bounds accesses, use-after-frees, double-frees etc. - CC=clang-8 CXX=clang++-8 /path/to/configure --enable-fuzzing + CC=clang-8 CXX=clang++-8 /path/to/configure --enable-fuzzing \ + --enable-sanitizers Fuzz targets are built similarly to system/softmmu: @@ -45,6 +48,62 @@ Information about these is available by passing -help=1 Now the only thing left to do is wait for the fuzzer to trigger potential crashes. +== Useful libFuzzer flags == + +As mentioned above, libFuzzer accepts some arguments. Passing -help=1 will list +the available arguments. In particular, these arguments might be helpful: + +$CORPUS_DIR/ : Specify a directory as the last argument to libFuzzer. libFuzzer +stores each "interesting" input in this corpus directory. The next time you run +libFuzzer, it will read all of the inputs from the corpus, and continue fuzzing +from there. You can also specify multiple directories. libFuzzer loads existing +inputs from all specified directories, but will only write new ones to the +first one specified. + +-max_len=4096 : specify the maximum byte-length of the inputs libFuzzer will +generate. + +-close_fd_mask={1,2,3} : close, stderr, or both. Useful for targets that +trigger many debug/error messages, or create output on the serial console. + +-jobs=4 -workers=4 : These arguments configure libFuzzer to run 4 fuzzers in +parallel (4 fuzzing jobs in 4 worker processes). Alternatively, with only +-jobs=N, libFuzzer automatically spawns a number of workers less than or equal +to half the available CPU cores. Replace 4 with a number appropriate for your +machine. Make sure to specify a $CORPUS_DIR, which will allow the parallel +fuzzers to share information about the interesting inputs they find. + +-use_value_profile=1 : For each comparison operation, libFuzzer computes +(caller_pc&4095) | (popcnt(Arg1 ^ Arg2) << 12) and places this in the coverage +table. Useful for targets with "magic" constants. If Arg1 came from the fuzzer's +input and Arg2 is a magic constant, then each time the Hamming distance +between Arg1 and Arg2 decreases, libFuzzer adds the input to the corpus. + +-shrink=1 : Tries to make elements of the corpus "smaller". Might lead to +better coverage performance, depending on the target. + +Note that libFuzzer's exact behavior will depend on the version of +clang and libFuzzer used to build the device fuzzers. + +== Generating Coverage Reports == +Code coverage is a crucial metric for evaluating a fuzzer's performance. +libFuzzer's output provides a "cov: " column that provides a total number of +unique blocks/edges covered. To examine coverage on a line-by-line basis we +can use Clang coverage: + + 1. Configure libFuzzer to store a corpus of all interesting inputs (see + CORPUS_DIR above) + 2. ./configure the QEMU build with: + --enable-fuzzing \ + --extra-cflags="-fprofile-instr-generate -fcoverage-mapping" + 3. Re-run the fuzzer. Specify $CORPUS_DIR/* as an argument, telling libfuzzer + to execute all of the inputs in $CORPUS_DIR and exit. Once the process + exits, you should find a file, "default.profraw" in the working directory. + 4. Execute these commands to generate a detailed HTML coverage-report: + llvm-profdata merge -output=default.profdata default.profraw + llvm-cov show ./path/to/qemu-fuzz-i386 -instr-profile=default.profdata \ + --format html -output-dir=/path/to/output/report + == Adding a new fuzzer == Coverage over virtual devices can be improved by adding additional fuzzers. Fuzzers are kept in tests/qtest/fuzz/ and should be added to |