OLD | NEW |
---|---|
(Empty) | |
1 # Getting Started with Libfuzzer in Chrome | |
2 | |
3 *** note | |
4 **Prerequisites:** libfuzzer in chrome is supported with GN on Linux only. | |
5 *** | |
6 | |
7 This document will walk you through: | |
8 | |
9 * setting up your build enviroment | |
10 * creating your first fuzzer | |
inferno
2016/03/17 16:49:37
nit: end lines 9 and 10 with period like line 11.
aizatsky
2016/03/17 23:39:25
Done.
| |
11 * running the fuzzer and verifying its vitals. | |
12 | |
13 ## Check Out ToT Clang | |
14 | |
15 Libfuzzer relies heavily on compile-time instrumentation. Because it is still | |
16 under heavy development you need to use tot clang with libfuzzer: | |
17 | |
18 ```bash | |
19 # In chrome/src | |
20 LLVM_FORCE_HEAD_REVISION=1 ./tools/clang/scripts/update.py --force-local-build - -without-android | |
21 ``` | |
22 | |
23 To revert this run the same script without specifying `LLVM_FORCE_HEAD_REVISION` . | |
24 | |
25 ## Configure Build | |
26 | |
27 Use `use_libfuzzer` GN argument together with sanitizer to generate build files: | |
28 | |
29 ```bash | |
30 # With address sanitizer | |
31 gn gen out/libfuzzer '--args=use_libfuzzer=true is_asan=true enable_nacl=false' --check | |
32 ``` | |
33 | |
34 Supported sanitizer configurations are: | |
35 | |
36 | GN Argument | Description | | |
37 |--------------|----| | |
38 | is_asan=true | enables [Address Sanitizer] to catch problems like buffer overr uns. | | |
39 | is_msan=true | enables [Memory Sanitizer] to catch problems like uninitialed r eads. | | |
40 | |
41 | |
42 ## Write Fuzzer Function | |
43 | |
44 Create a new .cc file and define a `LLVMFuzzerTestOneInput` function: | |
45 | |
46 ```cpp | |
47 extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) { | |
48 // put your fuzzing code here and use data+size as input. | |
49 return 0; | |
50 } | |
51 ``` | |
52 | |
53 [url_parse_fuzzer.cc] is a simple example of real-world fuzzer. | |
54 | |
55 ## Define GN Target | |
56 | |
57 Define `fuzzer_test` GN target: | |
58 | |
59 ``` | |
60 import("//testing/libfuzzer/fuzzer_test.gni") | |
61 fuzzer_test("my_fuzzer") { | |
62 sources = [ "my_fuzzer.cc" ] | |
63 deps = [ ... ] | |
64 } | |
65 ``` | |
66 | |
67 ## Build and Run Fuzzer Locally | |
68 | |
69 Build and run with ninja as usual: | |
mmoroz
2016/03/17 11:58:13
May be "Build with ninja as usual and run"?
aizatsky
2016/03/17 23:39:25
Done.
| |
70 | |
71 ```bash | |
72 ninja -C out/libfuzzer url_parse_fuzzer | |
73 ./out/libfuzzer url_parse_fuzzer | |
74 ``` | |
75 | |
76 Your fuzzer should produce output like this: | |
77 | |
78 ``` | |
79 INFO: Seed: 1787335005 | |
80 INFO: -max_len is not provided, using 64 | |
81 INFO: PreferSmall: 1 | |
82 #0 READ units: 1 exec/s: 0 | |
83 #1 INITED cov: 2361 bits: 95 indir: 29 units: 1 exec/s: 0 | |
84 #2 NEW cov: 2710 bits: 359 indir: 36 units: 2 exec/s: 0 L: 64 MS: 0 | |
85 #3 NEW cov: 2715 bits: 371 indir: 37 units: 3 exec/s: 0 L: 64 MS: 1 Shuf fleBytes- | |
86 #5 NEW cov: 2728 bits: 375 indir: 38 units: 4 exec/s: 0 L: 63 MS: 3 Shuf fleBytes-ShuffleBytes-EraseByte- | |
87 #6 NEW cov: 2729 bits: 384 indir: 38 units: 5 exec/s: 0 L: 10 MS: 4 Shuf fleBytes-ShuffleBytes-EraseByte-CrossOver- | |
88 #7 NEW cov: 2733 bits: 424 indir: 39 units: 6 exec/s: 0 L: 63 MS: 1 Shuf fleBytes- | |
89 #8 NEW cov: 2733 bits: 426 indir: 39 units: 7 exec/s: 0 L: 63 MS: 2 Shuf fleBytes-ChangeByte- | |
90 #11 NEW cov: 2733 bits: 447 indir: 39 units: 8 exec/s: 0 L: 33 MS: 5 Shuf fleBytes-ChangeByte-ChangeASCIIInt-ChangeBit-CrossOver- | |
91 #12 NEW cov: 2733 bits: 451 indir: 39 units: 9 exec/s: 0 L: 62 MS: 1 Cros sOver- | |
92 #16 NEW cov: 2733 bits: 454 indir: 39 units: 10 exec/s: 0 L: 61 MS: 5 Cro ssOver-ChangeBit-ChangeBit-EraseByte-ChangeBit- | |
93 #18 NEW cov: 2733 bits: 458 indir: 39 units: 11 exec/s: 0 L: 24 MS: 2 Cro ssOver-CrossOver- | |
94 ``` | |
95 | |
96 The `NEW` line appears when libfuzzer finds new and interesting input. The | |
97 efficient fuzzer should be able to finds lots of them rather quickly. | |
98 | |
99 The 'pulse' line will appear periodicly to show the current status. | |
mmoroz
2016/03/17 11:58:13
May be "pulse" -> "pulse..."
aizatsky
2016/03/17 23:39:25
Done.
| |
100 | |
101 | |
102 ## Submitting Fuzzer to ClusterFuzz | |
103 | |
104 ClusterFuzz builds and executes all `fuzzer_test` targets in the source tree. | |
105 The only thing you should do is to submit a fuzzer into Chrome. | |
106 | |
107 ## Next Steps | |
108 | |
109 * After your fuzzer is submitted, you should check its [ClusterFuzz status] in | |
110 a day or two. | |
111 * Check the [Efficient Fuzzer Guide] to better understand your fuzzer | |
112 performance and for optimization hints. | |
113 | |
114 | |
115 [Address Sanitizer]: http://clang.llvm.org/docs/AddressSanitizer.html | |
116 [Memory Sanitizer]: http://clang.llvm.org/docs/MemorySanitizer.html | |
117 [url_parser_fuzzer.cc]: https://code.google.com/p/chromium/codesearch#chromium/s rc/testing/libfuzzer/fuzzers/url_parse_fuzzer.cc | |
118 [ClusterFuzz status]: ./clusterfuzz.md#Fuzzer-Status | |
119 [Efficient Fuzzer Guide]: ./efficient_fuzzer.md | |
OLD | NEW |