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. |
| 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 with ninja as usual and run: |
| 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. T
he |
| 97 efficient fuzzer should be able to finds lots of them rather quickly. |
| 98 |
| 99 The '... pulse ...' line will appear periodically to show the current status. |
| 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 |