1--- 2layout: default 3title: Ideal integration 4parent: Advanced topics 5nav_order: 1 6permalink: /advanced-topics/ideal-integration/ 7--- 8 9# Ideal integration with OSS-Fuzz 10{: .no_toc} 11 12OSS projects have different build and test systems. We can't expect them all to 13implement and maintain fuzz targets or integrate them with OSS-Fuzz in the same 14way. However, we do have recommendations. 15 16This page documents several features (starting from the easiest) that will make 17automated fuzzing simple and efficient, and will help you catch regressions 18early in the development cycle. This simple 19[example](https://github.com/google/oss-fuzz/tree/master/projects/example/my-api-repo) 20covers most of the items. 21 22- TOC 23{:toc} 24--- 25 26## Summary 27 28Every [fuzz target](http://libfuzzer.info/#fuzz-target): 29* Is [maintained by code owners](#fuzz-target) in their RCS (Git, SVN, etc). 30* Is [built with the rest of the tests](#build-support) - no bit rot! 31* Has a [seed corpus](#seed-corpus) with good [code coverage](#coverage). 32* Has a [dictionary](#dictionary), if applicable. 33* Is [continuously tested on the seed corpus](#regression-testing) with 34 [ASan/UBSan/MSan](https://github.com/google/sanitizers). 35* Is [fast and has no OOMs](#performance). 36 37## Fuzz Target 38 39The code of the [fuzz target(s)](http://libfuzzer.info/#fuzz-target) should be 40part of the project's source code repository. All fuzz targets should be easily 41discoverable (reside in the same directory, follow the same naming pattern, 42etc.). 43 44This makes it easy to maintain the fuzzers and minimizes breakages that can 45arise as source code changes over time. 46 47Make sure to fuzz the target locally for a small period of time to ensure that 48it does not crash, hang, or run out of memory instantly. If you're having 49trouble, read about [what makes a good fuzz 50target](https://github.com/google/fuzzing/blob/master/docs/good-fuzz-target.md). 51 52The interface between the [fuzz target]((http://libfuzzer.info/#fuzz-target)) 53and the fuzzing engines is C, so you can use either C or C++ to implement the 54fuzz target. 55 56Examples: 57[boringssl](https://github.com/google/boringssl/tree/master/fuzz), 58[SQLite](https://www.sqlite.org/src/artifact/ad79e867fb504338), 59[s2n](https://github.com/awslabs/s2n/tree/master/tests/fuzz), 60[openssl](https://github.com/openssl/openssl/tree/master/fuzz), 61[FreeType](http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/tools/ftfuzzer), 62[re2](https://github.com/google/re2/tree/master/re2/fuzzing), 63[harfbuzz](https://github.com/behdad/harfbuzz/tree/master/test/fuzzing), 64[pcre2](https://vcs.pcre.org/pcre2/code/trunk/src/pcre2_fuzzsupport.c?view=markup), 65[ffmpeg](https://github.com/FFmpeg/FFmpeg/blob/master/tools/target_dec_fuzzer.c). 66 67## Build support 68 69Many different build systems exist in the open-source world. The less OSS-Fuzz 70knows about them, the better it can scale. 71 72An ideal build integration for OSS-Fuzz looks like this: 73* For every fuzz target `foo` in the project, there is a build rule that 74builds `foo_fuzzer`, a binary that: 75 * Contains the fuzzing entry point. 76 * Contains (`LLVMFuzzerTestOneInput`) and all the code it depends on. 77 * Uses the `main()` function from `$LIB_FUZZING_ENGINE` (env var [provided]({{ site.baseurl }}/getting-started/new-project-guide/) by OSS-Fuzz environment). 78* Since the build system supports changing the compiler and passing extra compiler 79flags, the build command for `foo_fuzzer` looks similar to this: 80 81```bash 82# Assume the following env vars are set: 83# CC, CXX, CFLAGS, CXXFLAGS, LIB_FUZZING_ENGINE 84$ make_or_whatever_other_command foo_fuzzer 85``` 86 87This minimizes OSS-Fuzz-specific configuration, making your fuzzing more robust. 88 89There is no point in hardcoding the exact compiler flags in the build system 90because they a) may change and b) depend on the fuzzing engine and sanitizer 91being used. 92 93## Seed Corpus 94 95The *seed corpus* is a set of test inputs, stored as individual files, provided 96to the fuzz target as a starting point (to "seed" the mutations). The quality of 97the seed corpus has a huge impact on fuzzing efficiency; the higher the quality, 98the easier it is for the fuzzer to discover new code paths. The ideal corpus is 99a minimal set of inputs that provides maximal code coverage. 100 101For better OSS-Fuzz integration, the seed corpus should be available in 102revision control (it can be the same as or different from the source code). It 103should be regularly extended with the inputs that (used to) trigger bugs and/or 104touch new parts of the code. 105 106Examples: 107[boringssl](https://github.com/google/boringssl/tree/master/fuzz), 108[openssl](https://github.com/openssl/openssl/tree/master/fuzz), 109[nss](https://github.com/mozilla/nss-fuzzing-corpus) (corpus in a separate repo). 110 111## Dictionary 112 113For some input types, a simple dictionary of tokens used by the input language 114can have a dramatic impact on fuzzing efficiency. For example, when fuzzing an 115XML parser, a dictionary of XML tokens is helpful. AFL++ has a 116[collection](https://github.com/AFLplusplus/AFLplusplus/tree/master/dictionaries) 117of dictionaries for popular data formats. Ideally, a dictionary should be 118maintained alongside the fuzz target, and it must use [correct 119syntax](http://libfuzzer.info/#dictionaries). 120 121## Coverage 122 123For a fuzz target to be useful, it must have good coverage in the code that it 124is testing. You can view the coverage for your fuzz targets by looking at the 125[fuzzer stats]({{ site.baseurl }}/further-reading/clusterfuzz#fuzzer-stats) 126dashboard on ClusterFuzz, as well as [coverage reports]({{ site.baseurl 127}}/further-reading/clusterfuzz#coverage-reports). 128 129To generate an aggregated code coverage report for your project, please see the 130[code coverage]({{ site.baseurl }}/advanced-topics/code-coverage) page. 131 132Coverage can often be improved by adding dictionaries, more inputs for seed 133corpora, and fixing timeouts/out-of-memory bugs in your targets. 134 135## Regression Testing 136 137Fuzz targets should be regularly tested (not necessarily fuzzed!) as a part of 138the project's regression testing process. One way to do so is to link the fuzz 139target with a simple standalone driver 140([example](https://github.com/llvm-mirror/compiler-rt/tree/master/lib/fuzzer/standalone)) 141that runs the provided inputs, then use this driver with the seed corpus created 142in previous step. We recommend you use 143[sanitizers](https://github.com/google/sanitizers) during regression testing. 144 145Examples: [SQLite](https://www.sqlite.org/src/artifact/d9f1a6f43e7bab45), 146[openssl](https://github.com/openssl/openssl/blob/master/fuzz/test-corpus.c). 147 148## Performance 149 150Fuzz targets should perform well, because high memory usage and/or slow 151execution speed can slow the down the growth of coverage and finding of new 152bugs. ClusterFuzz provides a [performance analyzer]({{ site.baseurl 153}}/further-reading/clusterfuzz/#performance-analyzer) for each fuzz target that 154shows problems that are impacting performance. 155 156## Not a project member? 157 158If you are a member of the project you want to fuzz, most of the steps above are 159simple. However in some cases, someone outside the project team may want to fuzz 160the code, and the project maintainers are not interested in helping. 161 162In such cases, we can host the fuzz targets, dictionaries, etc. in OSS-Fuzz's 163repository and mention them in the Dockerfile. It's not ideal, because the fuzz 164targets will not be continuously tested, so may quickly bitrot. 165 166Examples: [libxml2](https://github.com/google/oss-fuzz/tree/master/projects/libxml2), 167[c-ares](https://github.com/google/oss-fuzz/tree/master/projects/c-ares), [expat](https://github.com/google/oss-fuzz/tree/master/projects/expat). 168 169If you are not a project maintainer, we may not be able to CC you to security 170bugs found by OSS-Fuzz. 171