• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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