Index: testing/libfuzzer/getting_started.md |
diff --git a/testing/libfuzzer/getting_started.md b/testing/libfuzzer/getting_started.md |
new file mode 100644 |
index 0000000000000000000000000000000000000000..95bdf75cf6b66ea72a27ffa54f0369ab3f604a6b |
--- /dev/null |
+++ b/testing/libfuzzer/getting_started.md |
@@ -0,0 +1,119 @@ |
+# Getting Started with Libfuzzer in Chrome |
+ |
+*** note |
+**Prerequisites:** libfuzzer in chrome is supported with GN on Linux only. |
+*** |
+ |
+This document will walk you through: |
+ |
+* setting up your build enviroment. |
+* creating your first fuzzer. |
+* running the fuzzer and verifying its vitals. |
+ |
+## Check Out ToT Clang |
+ |
+Libfuzzer relies heavily on compile-time instrumentation. Because it is still |
+under heavy development you need to use tot clang with libfuzzer: |
+ |
+```bash |
+# In chrome/src |
+LLVM_FORCE_HEAD_REVISION=1 ./tools/clang/scripts/update.py --force-local-build --without-android |
+``` |
+ |
+To revert this run the same script without specifying `LLVM_FORCE_HEAD_REVISION`. |
+ |
+## Configure Build |
+ |
+Use `use_libfuzzer` GN argument together with sanitizer to generate build files: |
+ |
+```bash |
+# With address sanitizer |
+gn gen out/libfuzzer '--args=use_libfuzzer=true is_asan=true enable_nacl=false' --check |
+``` |
+ |
+Supported sanitizer configurations are: |
+ |
+| GN Argument | Description | |
+|--------------|----| |
+| is_asan=true | enables [Address Sanitizer] to catch problems like buffer overruns. | |
+| is_msan=true | enables [Memory Sanitizer] to catch problems like uninitialed reads. | |
+ |
+ |
+## Write Fuzzer Function |
+ |
+Create a new .cc file and define a `LLVMFuzzerTestOneInput` function: |
+ |
+```cpp |
+extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) { |
+ // put your fuzzing code here and use data+size as input. |
+ return 0; |
+} |
+``` |
+ |
+[url_parse_fuzzer.cc] is a simple example of real-world fuzzer. |
+ |
+## Define GN Target |
+ |
+Define `fuzzer_test` GN target: |
+ |
+``` |
+import("//testing/libfuzzer/fuzzer_test.gni") |
+fuzzer_test("my_fuzzer") { |
+ sources = [ "my_fuzzer.cc" ] |
+ deps = [ ... ] |
+} |
+``` |
+ |
+## Build and Run Fuzzer Locally |
+ |
+Build with ninja as usual and run: |
+ |
+```bash |
+ninja -C out/libfuzzer url_parse_fuzzer |
+./out/libfuzzer url_parse_fuzzer |
+``` |
+ |
+Your fuzzer should produce output like this: |
+ |
+``` |
+INFO: Seed: 1787335005 |
+INFO: -max_len is not provided, using 64 |
+INFO: PreferSmall: 1 |
+#0 READ units: 1 exec/s: 0 |
+#1 INITED cov: 2361 bits: 95 indir: 29 units: 1 exec/s: 0 |
+#2 NEW cov: 2710 bits: 359 indir: 36 units: 2 exec/s: 0 L: 64 MS: 0 |
+#3 NEW cov: 2715 bits: 371 indir: 37 units: 3 exec/s: 0 L: 64 MS: 1 ShuffleBytes- |
+#5 NEW cov: 2728 bits: 375 indir: 38 units: 4 exec/s: 0 L: 63 MS: 3 ShuffleBytes-ShuffleBytes-EraseByte- |
+#6 NEW cov: 2729 bits: 384 indir: 38 units: 5 exec/s: 0 L: 10 MS: 4 ShuffleBytes-ShuffleBytes-EraseByte-CrossOver- |
+#7 NEW cov: 2733 bits: 424 indir: 39 units: 6 exec/s: 0 L: 63 MS: 1 ShuffleBytes- |
+#8 NEW cov: 2733 bits: 426 indir: 39 units: 7 exec/s: 0 L: 63 MS: 2 ShuffleBytes-ChangeByte- |
+#11 NEW cov: 2733 bits: 447 indir: 39 units: 8 exec/s: 0 L: 33 MS: 5 ShuffleBytes-ChangeByte-ChangeASCIIInt-ChangeBit-CrossOver- |
+#12 NEW cov: 2733 bits: 451 indir: 39 units: 9 exec/s: 0 L: 62 MS: 1 CrossOver- |
+#16 NEW cov: 2733 bits: 454 indir: 39 units: 10 exec/s: 0 L: 61 MS: 5 CrossOver-ChangeBit-ChangeBit-EraseByte-ChangeBit- |
+#18 NEW cov: 2733 bits: 458 indir: 39 units: 11 exec/s: 0 L: 24 MS: 2 CrossOver-CrossOver- |
+``` |
+ |
+The `... NEW ...` line appears when libfuzzer finds new and interesting input. The |
+efficient fuzzer should be able to finds lots of them rather quickly. |
+ |
+The '... pulse ...' line will appear periodically to show the current status. |
+ |
+ |
+## Submitting Fuzzer to ClusterFuzz |
+ |
+ClusterFuzz builds and executes all `fuzzer_test` targets in the source tree. |
+The only thing you should do is to submit a fuzzer into Chrome. |
+ |
+## Next Steps |
+ |
+* After your fuzzer is submitted, you should check its [ClusterFuzz status] in |
+a day or two. |
+* Check the [Efficient Fuzzer Guide] to better understand your fuzzer |
+performance and for optimization hints. |
+ |
+ |
+[Address Sanitizer]: http://clang.llvm.org/docs/AddressSanitizer.html |
+[Memory Sanitizer]: http://clang.llvm.org/docs/MemorySanitizer.html |
+[url_parser_fuzzer.cc]: https://code.google.com/p/chromium/codesearch#chromium/src/testing/libfuzzer/fuzzers/url_parse_fuzzer.cc |
+[ClusterFuzz status]: ./clusterfuzz.md#Fuzzer-Status |
+[Efficient Fuzzer Guide]: ./efficient_fuzzer.md |