blob: fbd9b4c099746d0897ccf672f3b42078c1d9a235 [file] [log] [blame] [view]
aizatsky9c8c5b02016-03-30 22:09:091# Getting Started with libFuzzer in Chrome
aizatskya6f86292016-03-18 00:22:242
3*** note
mmoroz27ea9c22016-04-07 21:17:484**Prerequisites:** libFuzzer in Chrome is supported with GN on Linux only.
aizatskya6f86292016-03-18 00:22:245***
6
7This document will walk you through:
8
9* setting up your build enviroment.
10* creating your first fuzzer.
11* running the fuzzer and verifying its vitals.
12
aizatskya6f86292016-03-18 00:22:2413## Configure Build
14
15Use `use_libfuzzer` GN argument together with sanitizer to generate build files:
16
17```bash
18# With address sanitizer
19gn gen out/libfuzzer '--args=use_libfuzzer=true is_asan=true enable_nacl=false' --check
20```
21
22Supported sanitizer configurations are:
23
24| GN Argument | Description |
25|--------------|----|
aizatsky8f19edd2016-09-01 20:54:5026| `is_asan=true` | enables [Address Sanitizer] to catch problems like buffer overruns. |
27| `is_msan=true` | enables [Memory Sanitizer] to catch problems like uninitialed reads. |
28| `is_ubsan_security=true` | enables [Undefined Behavior Sanitizer] to catch<sup>\[[1](#Notes)\]</sup> undefined behavior like integer overflow. |
29| | it is possible to run libfuzzer without any sanitizers; *probably not what you want*.|
aizatskya6f86292016-03-18 00:22:2430
31
32## Write Fuzzer Function
33
34Create a new .cc file and define a `LLVMFuzzerTestOneInput` function:
35
36```cpp
reillyg21fe44502016-05-20 22:28:5037#include <stddef.h>
38#include <stdint.h>
39
40extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
aizatskya6f86292016-03-18 00:22:2441 // put your fuzzing code here and use data+size as input.
42 return 0;
43}
44```
45
46[url_parse_fuzzer.cc] is a simple example of real-world fuzzer.
47
48## Define GN Target
49
50Define `fuzzer_test` GN target:
51
52```
53import("//testing/libfuzzer/fuzzer_test.gni")
54fuzzer_test("my_fuzzer") {
55 sources = [ "my_fuzzer.cc" ]
56 deps = [ ... ]
57}
58```
59
60## Build and Run Fuzzer Locally
61
62Build with ninja as usual and run:
63
64```bash
65ninja -C out/libfuzzer url_parse_fuzzer
mmoroz27ea9c22016-04-07 21:17:4866./out/libfuzzer/url_parse_fuzzer
aizatskya6f86292016-03-18 00:22:2467```
68
69Your fuzzer should produce output like this:
70
71```
72INFO: Seed: 1787335005
73INFO: -max_len is not provided, using 64
74INFO: PreferSmall: 1
75#0 READ units: 1 exec/s: 0
76#1 INITED cov: 2361 bits: 95 indir: 29 units: 1 exec/s: 0
77#2 NEW cov: 2710 bits: 359 indir: 36 units: 2 exec/s: 0 L: 64 MS: 0
78#3 NEW cov: 2715 bits: 371 indir: 37 units: 3 exec/s: 0 L: 64 MS: 1 ShuffleBytes-
79#5 NEW cov: 2728 bits: 375 indir: 38 units: 4 exec/s: 0 L: 63 MS: 3 ShuffleBytes-ShuffleBytes-EraseByte-
80#6 NEW cov: 2729 bits: 384 indir: 38 units: 5 exec/s: 0 L: 10 MS: 4 ShuffleBytes-ShuffleBytes-EraseByte-CrossOver-
81#7 NEW cov: 2733 bits: 424 indir: 39 units: 6 exec/s: 0 L: 63 MS: 1 ShuffleBytes-
82#8 NEW cov: 2733 bits: 426 indir: 39 units: 7 exec/s: 0 L: 63 MS: 2 ShuffleBytes-ChangeByte-
83#11 NEW cov: 2733 bits: 447 indir: 39 units: 8 exec/s: 0 L: 33 MS: 5 ShuffleBytes-ChangeByte-ChangeASCIIInt-ChangeBit-CrossOver-
84#12 NEW cov: 2733 bits: 451 indir: 39 units: 9 exec/s: 0 L: 62 MS: 1 CrossOver-
85#16 NEW cov: 2733 bits: 454 indir: 39 units: 10 exec/s: 0 L: 61 MS: 5 CrossOver-ChangeBit-ChangeBit-EraseByte-ChangeBit-
86#18 NEW cov: 2733 bits: 458 indir: 39 units: 11 exec/s: 0 L: 24 MS: 2 CrossOver-CrossOver-
87```
88
aizatsky9c8c5b02016-03-30 22:09:0989The `... NEW ...` line appears when libFuzzer finds new and interesting input. The
aizatskya6f86292016-03-18 00:22:2490efficient fuzzer should be able to finds lots of them rather quickly.
91
aizatsky9b70cf1b2016-03-18 19:33:5092The `... pulse ...` line will appear periodically to show the current status.
aizatskya6f86292016-03-18 00:22:2493
94
mmoroz9e075592016-05-06 08:37:5395### Default value for maximum testcase length
96
97By default, when run manually, libFuzzer uses `-max_len=64` or takes the length
98of the biggest testcase in corpus if corpus is not empty. ClusterFuzz takes
99random value in range from `1` to `10000` for each fuzzing session and passes
100that value to libFuzzers. If corpus contains testcases of size greater than
101`max_len`, libFuzzer will use only first `max_len` bytes of such testcases.
102
103
104You can specify custom `max_len` value to be used by ClusterFuzz. For more
105information check out [Maximum Testcase Length] section of the [Efficient Fuzzer
106Guide].
107
robert.bradford160c5982016-08-30 17:04:30108## Disable noisy error message logging
109
110If the code that you are a fuzzing generates error messages when encountering
111incorrect or invalid data then you need to silence those errors in the fuzzer.
112
113If the target uses the Chromium logging APIs, the best way to do that is to
114override the environment used for logging in your fuzzer:
115
116```cpp
117struct Environment {
118 Environment() {
119 logging::SetMinLogLevel(logging::LOG_FATAL);
120 }
121};
122
123Environment* env = new Environment();
124```
125
aizatskya6f86292016-03-18 00:22:24126## Submitting Fuzzer to ClusterFuzz
127
128ClusterFuzz builds and executes all `fuzzer_test` targets in the source tree.
129The only thing you should do is to submit a fuzzer into Chrome.
130
131## Next Steps
132
133* After your fuzzer is submitted, you should check its [ClusterFuzz status] in
134a day or two.
135* Check the [Efficient Fuzzer Guide] to better understand your fuzzer
136performance and for optimization hints.
137
138
mmoroz5a2604d42016-04-21 10:08:13139## Notes
140[1] By default UBSan doesn't crash once undefined behavior has been detected.
141To make it crash the following additional option should be provided:
142
143```bash
144UBSAN_OPTIONS=halt_on_error=1 ./fuzzer <corpus_directory_or_single_testcase_path>
145```
146
147Other useful options (used by ClusterFuzz) are:
148```bash
149UBSAN_OPTIONS=symbolize=1:halt_on_error=1:print_stacktrace=1 ./fuzzer <corpus_directory_or_single_testcase_path>
150```
151
152
aizatskya6f86292016-03-18 00:22:24153[Address Sanitizer]: http://clang.llvm.org/docs/AddressSanitizer.html
aizatsky62c7a842016-05-13 19:23:01154[Memory Sanitizer]: http://clang.llvm.org/docs/MemorySanitizer.html
155[Undefined Behavior Sanitizer]: http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
mmoroz9e075592016-05-06 08:37:53156[ClusterFuzz status]: clusterfuzz.md#Status-Links
157[crbug/598448]: https://bugs.chromium.org/p/chromium/issues/detail?id=598448
158[Efficient Fuzzer Guide]: efficient_fuzzer.md
159[Maximum Testcase Length]: efficient_fuzzer.md#Maximum-Testcase-Length
aizatsky9c8c5b02016-03-30 22:09:09160[url_parse_fuzzer.cc]: https://code.google.com/p/chromium/codesearch#chromium/src/testing/libfuzzer/fuzzers/url_parse_fuzzer.cc