Commit 968d2f73 authored by Abhishek Arya's avatar Abhishek Arya Committed by Commit Bot

Improve libFuzzer documentation based on fuzzathon feedback.

R=ochang@chromium.org,mmoroz@chromium.org

Bug: 
Change-Id: Ie4a1446726e84b2cb3826515f06a9a9d74f3b0fb
Reviewed-on: https://chromium-review.googlesource.com/794593
Commit-Queue: Abhishek Arya <inferno@chromium.org>
Reviewed-by: default avatarOliver Chang <ochang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519889}
parent bc0ed76b
This diff is collapsed.
# Getting Started with libFuzzer in Chrome # Getting Started with libFuzzer in Chrome
*** note ***
**Prerequisites:** libFuzzer in Chrome is supported with GN on Linux only. **Prerequisites:** libFuzzer in Chrome is supported with GN on Linux and Mac only.
*** ***
This document will walk you through: This document will walk you through:
...@@ -15,9 +15,9 @@ This document will walk you through: ...@@ -15,9 +15,9 @@ This document will walk you through:
Use `use_libfuzzer` GN argument together with sanitizer to generate build files: Use `use_libfuzzer` GN argument together with sanitizer to generate build files:
*Notice*: current implementation also supports `use_afl` argument, but it is *Notice*: current implementation also supports `use_afl` argument, but it is
recommended to use libFuzzer for development. Running libFuzzer locally doesn't recommended to use libFuzzer for local development. Running libFuzzer locally
require any special configuration and quickly gives meaningful output for speed, doesn't require any special configuration and gives meaningful output quickly for
coverage and other parameters. speed, coverage and other parameters.
```bash ```bash
# With address sanitizer # With address sanitizer
...@@ -42,7 +42,7 @@ To get the exact GN configuration that are used on our builders, see ...@@ -42,7 +42,7 @@ To get the exact GN configuration that are used on our builders, see
## Write Fuzzer Function ## Write Fuzzer Function
Create a new .cc file and define a `LLVMFuzzerTestOneInput` function: Create a new `<my_fuzzer>.cc` file and define a `LLVMFuzzerTestOneInput` function:
```cpp ```cpp
#include <stddef.h> #include <stddef.h>
...@@ -54,11 +54,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -54,11 +54,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
} }
``` ```
[url_parse_fuzzer.cc] is a simple example of real-world fuzzer. *Note*: You should create the fuzzer file `<my_fuzzer>.cc next to the code that is being
tested and in the same directory as your other unit tests. Please do not use
`testing/libfuzzer/fuzzers` directory, this was a directory used for initial sample fuzzers and
is no longer recommended for any new fuzzers.
[quic_stream_factory_fuzzer.cc] is a simple example of real-world fuzzer.
## Define GN Target ## Define GN Target
Define `fuzzer_test` GN target: Define `fuzzer_test` GN target in BUILD.gn:
```python ```python
import("//testing/libfuzzer/fuzzer_test.gni") import("//testing/libfuzzer/fuzzer_test.gni")
...@@ -88,7 +93,7 @@ INFO: PreferSmall: 1 ...@@ -88,7 +93,7 @@ INFO: PreferSmall: 1
#2 NEW cov: 2710 bits: 359 indir: 36 units: 2 exec/s: 0 L: 64 MS: 0 #2 NEW cov: 2710 bits: 359 indir: 36 units: 2 exec/s: 0 L: 64 MS: 0
``` ```
The `... NEW ...` line appears when libFuzzer finds new and interesting input. The `... NEW ...` line appears when libFuzzer finds new and interesting inputs.
The efficient fuzzer should be able to finds lots of them rather quickly. The efficient fuzzer should be able to finds lots of them rather quickly.
The `... pulse ...` line will appear periodically to show the current status. The `... pulse ...` line will appear periodically to show the current status.
...@@ -99,15 +104,15 @@ stacktrace, make sure that you have directory containing `llvm-symbolizer` ...@@ -99,15 +104,15 @@ stacktrace, make sure that you have directory containing `llvm-symbolizer`
binary added in `$PATH`. The symbolizer binary is included in Chromium's Clang binary added in `$PATH`. The symbolizer binary is included in Chromium's Clang
package located at `third_party/llvm-build/Release+Asserts/bin/` directory. package located at `third_party/llvm-build/Release+Asserts/bin/` directory.
Alternatively, you can set `external_symbolizer_path` option via `ASAN_OPTIONS` Alternatively, you can set `external_symbolizer_path` option via
env variable: `ASAN_OPTIONS` env variable:
```bash ```bash
$ ASAN_OPTIONS=external_symbolizer_path=/my/local/llvm/build/llvm-symbolizer \ $ ASAN_OPTIONS=external_symbolizer_path=/my/local/llvm/build/llvm-symbolizer \
./fuzzer ./crash-input ./fuzzer ./crash-input
``` ```
The same approach works with other sanitizers (e.g. `MSAN_OPTIONS` and others). The same approach works with other sanitizers (e.g. `MSAN_OPTIONS`, `UBSAN_OPTIONS`, etc).
## Improving Your Fuzzer ## Improving Your Fuzzer
...@@ -120,18 +125,19 @@ in [Seed Corpus] section of efficient fuzzer guide. ...@@ -120,18 +125,19 @@ in [Seed Corpus] section of efficient fuzzer guide.
*Make sure corpus files are appropriately licensed.* *Make sure corpus files are appropriately licensed.*
* Create mutation dictionary. With a `dict = "protocol.dict"` attribute and * Create mutation dictionary. With a `dict = "protocol.dict"` attribute and
`key=value` dicitionary file format, mutations can be more effective. `key=value` dicitionary file format, mutations can be more effective.
See [Fuzzer Dictionary]. See [Fuzzer Dictionary] section of efficient fuzzer guide.
* Specify maximum testcase length. By default libFuzzer uses `-max_len=64` * Specify maximum testcase length. By default libFuzzer uses `-max_len=64`
(or takes the longest testcase in a corpus). ClusterFuzz takes (or takes the longest testcase in a corpus). ClusterFuzz takes
random value in range from `1` to `10000` for each fuzzing session and passes random value in range from `1` to `10000` for each fuzzing session and passes
that value to libFuzzers. If corpus contains testcases of size greater than that value to libFuzzers. If corpus contains testcases of size greater than
`max_len`, libFuzzer will use only first `max_len` bytes of such testcases. `max_len`, libFuzzer will use only first `max_len` bytes of such testcases.
See [Maximum Testcase Length]. See [Maximum Testcase Length] section of efficient fuzzer guide.
## Disable noisy error message logging ## Disable noisy error message logging
If the code that you are a fuzzing generates error messages when encountering If the code that you are a fuzzing generates lot of error messages when
incorrect or invalid data then you need to silence those errors in the fuzzer. encountering incorrect or invalid data, then you need to silence those errors
in the fuzzer. Otherwise, fuzzer will be slow and inefficient.
If the target uses the Chromium logging APIs, the best way to do that is to If the target uses the Chromium logging APIs, the best way to do that is to
override the environment used for logging in your fuzzer: override the environment used for logging in your fuzzer:
...@@ -148,12 +154,15 @@ Environment* env = new Environment(); ...@@ -148,12 +154,15 @@ Environment* env = new Environment();
## Submitting Fuzzer to ClusterFuzz ## Submitting Fuzzer to ClusterFuzz
ClusterFuzz builds and executes all `fuzzer_test` targets in the source tree. ClusterFuzz builds and executes all `fuzzer_test` targets in the Chromium
The only thing you should do is to submit a fuzzer into Chrome. repository. It is extremely important to submit a fuzzer into Chromium
repository so that ClusterFuzz can run it at scale. Do not rely on just
running fuzzing locally in your own environment, as it will catch far less
issues and needs to run it continuously forever to catch regressions.
## Next Steps ## Next Steps
* After your fuzzer is submitted, you should check its [ClusterFuzz status] in * After your fuzzer is submitted, you should check [ClusterFuzz status] page in
a day or two. a day or two.
* Check the [Efficient Fuzzer Guide] to better understand your fuzzer * Check the [Efficient Fuzzer Guide] to better understand your fuzzer
performance and for optimization hints. performance and for optimization hints.
...@@ -168,5 +177,5 @@ performance and for optimization hints. ...@@ -168,5 +177,5 @@ performance and for optimization hints.
[Seed Corpus]: efficient_fuzzer.md#Seed-Corpus [Seed Corpus]: efficient_fuzzer.md#Seed-Corpus
[Undefined Behavior Sanitizer]: http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html [Undefined Behavior Sanitizer]: http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
[crbug/598448]: https://bugs.chromium.org/p/chromium/issues/detail?id=598448 [crbug/598448]: https://bugs.chromium.org/p/chromium/issues/detail?id=598448
[url_parse_fuzzer.cc]: https://code.google.com/p/chromium/codesearch#chromium/src/testing/libfuzzer/fuzzers/url_parse_fuzzer.cc [quic_stream_factory_fuzzer.cc]: https://cs.chromium.org/chromium/src/net/quic/chromium/quic_stream_factory_fuzzer.cc
[Build Config]: reference.md#Builder-configurations [Build Config]: reference.md#Builder-configurations
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment