2019-08-07 14:37:16 +00:00
|
|
|
---
|
|
|
|
layout: default
|
|
|
|
title: Ideal integration
|
|
|
|
parent: Advanced topics
|
|
|
|
nav_order: 1
|
2019-08-22 18:33:39 +00:00
|
|
|
permalink: /advanced-topics/ideal-integration/
|
2019-08-07 14:37:16 +00:00
|
|
|
---
|
|
|
|
|
2016-11-15 18:04:07 +00:00
|
|
|
# Ideal integration with OSS-Fuzz
|
2016-11-16 16:59:35 +00:00
|
|
|
OSS projects have different build and test systems. So, we can not expect them
|
2019-08-07 14:37:16 +00:00
|
|
|
to have a unified way of implementing and maintaining fuzz targets and
|
|
|
|
integrating them with OSS-Fuzz. However, we will still try to give
|
|
|
|
recommendations on the preferred ways.
|
|
|
|
|
|
|
|
Here are several features (starting from the easiest) that will make automated
|
|
|
|
fuzzing simple and efficient, and will allow to catch regressions early on in
|
|
|
|
the development cycle.
|
2016-11-15 18:04:07 +00:00
|
|
|
|
2019-08-07 14:37:16 +00:00
|
|
|
- TOC
|
|
|
|
{:toc}
|
|
|
|
---
|
2016-11-16 06:07:18 +00:00
|
|
|
|
2017-08-04 18:15:52 +00:00
|
|
|
## TL;DR
|
|
|
|
Every [fuzz target](http://libfuzzer.info/#fuzz-target):
|
|
|
|
* Is [maintained by code owners](#fuzz-target) in their RCS (Git, SVN, etc).
|
|
|
|
* Is [built with the rest of the tests](#build-support) - no bit rot!
|
2017-08-04 18:16:18 +00:00
|
|
|
* Has a [seed corpus](#seed-corpus) with good [code coverage](#coverage).
|
2019-08-15 22:07:23 +00:00
|
|
|
* Has a [dictionary](#dictionary), if applicable.
|
2019-08-07 14:37:16 +00:00
|
|
|
* Is [continuously tested on the seed corpus](#regression-testing) with
|
|
|
|
[ASan/UBSan/MSan](https://github.com/google/sanitizers).
|
|
|
|
* Is [fast and has no OOMs](#performance).
|
2017-08-04 18:15:52 +00:00
|
|
|
|
2016-11-18 23:04:06 +00:00
|
|
|
## Fuzz Target
|
2019-08-07 14:37:16 +00:00
|
|
|
The code of the [fuzz target(s)](http://libfuzzer.info/#fuzz-target) should be
|
|
|
|
part of the project's source code repository.
|
|
|
|
All fuzz targets should be easily discoverable (e.g. reside in the same
|
|
|
|
directory, or follow the same naming pattern, etc).
|
2016-11-15 18:04:07 +00:00
|
|
|
|
2019-08-07 14:37:16 +00:00
|
|
|
This makes it easy to maintain the fuzzers and minimizes breakages that can
|
|
|
|
arise as source code changes over time.
|
2016-11-18 23:25:28 +00:00
|
|
|
|
|
|
|
Make sure to fuzz the target locally for a small period of time to ensure that
|
2017-02-08 03:15:53 +00:00
|
|
|
it does not crash, hang, or run out of memory instantly.
|
2019-08-15 22:07:23 +00:00
|
|
|
You can read more about what makes a good fuzz target [here]
|
|
|
|
(https://github.com/google/fuzzing/blob/master/docs/good-fuzz-target.md)
|
2016-11-16 16:59:35 +00:00
|
|
|
|
2016-12-13 17:33:59 +00:00
|
|
|
The interface between the [fuzz target]((http://libfuzzer.info/#fuzz-target))
|
|
|
|
and the fuzzing engines is C, so you may use C or C++ to implement the fuzz target.
|
|
|
|
|
2016-11-15 18:04:07 +00:00
|
|
|
Examples:
|
|
|
|
[boringssl](https://github.com/google/boringssl/tree/master/fuzz),
|
|
|
|
[SQLite](https://www.sqlite.org/src/artifact/ad79e867fb504338),
|
|
|
|
[s2n](https://github.com/awslabs/s2n/tree/master/tests/fuzz),
|
|
|
|
[openssl](https://github.com/openssl/openssl/tree/master/fuzz),
|
|
|
|
[FreeType](http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/tools/ftfuzzer),
|
2016-11-15 19:56:11 +00:00
|
|
|
[re2](https://github.com/google/re2/tree/master/re2/fuzzing),
|
2016-11-15 18:04:07 +00:00
|
|
|
[harfbuzz](https://github.com/behdad/harfbuzz/tree/master/test/fuzzing),
|
2019-02-09 01:21:54 +00:00
|
|
|
[pcre2](https://vcs.pcre.org/pcre2/code/trunk/src/pcre2_fuzzsupport.c?view=markup),
|
2017-01-31 15:42:12 +00:00
|
|
|
[ffmpeg](https://github.com/FFmpeg/FFmpeg/blob/master/tools/target_dec_fuzzer.c).
|
2016-11-15 18:04:07 +00:00
|
|
|
|
2017-04-24 20:25:22 +00:00
|
|
|
## Build support
|
|
|
|
A plethora of different build systems exist in the open-source world.
|
|
|
|
And the less OSS-Fuzz knows about them, the better it can scale.
|
|
|
|
|
|
|
|
An ideal build integration for OSS-Fuzz would look like this:
|
2019-08-07 14:37:16 +00:00
|
|
|
* For every fuzz target `foo` in the project, there is a build rule that
|
|
|
|
builds `foo_fuzzer`, a binary that contains the fuzzing entry point
|
|
|
|
(`LLVMFuzzerTestOneInput`) and all the code it depends on, and that uses the
|
|
|
|
`main()` function from `$LIB_FUZZING_ENGINE`
|
|
|
|
(env var [provided]({{ site.baseurl }}/getting-started/new-project-guide/) by OSS-Fuzz environment).
|
2017-04-24 20:25:22 +00:00
|
|
|
* The build system supports changing the compiler and passing extra compiler
|
|
|
|
flags so that the build command for a `foo_fuzzer` looks similar to this:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
# Assume the following env vars are set:
|
|
|
|
# CC, CXX, CFLAGS, CXXFLAGS, LIB_FUZZING_ENGINE
|
|
|
|
$ make_or_whatever_other_command foo_fuzzer
|
|
|
|
```
|
|
|
|
|
2019-08-07 14:37:16 +00:00
|
|
|
This will allow to have minimal OSS-Fuzz-specific configuration and thus be
|
|
|
|
more robust.
|
2017-04-24 20:25:22 +00:00
|
|
|
|
2019-08-07 14:37:16 +00:00
|
|
|
There is no point in hardcoding the exact compiler flags in the build system
|
|
|
|
because they a) may change and b) are different depending on the fuzzing engine
|
|
|
|
and the sanitizer being used.
|
2016-11-15 18:04:07 +00:00
|
|
|
|
2016-11-18 23:04:06 +00:00
|
|
|
## Seed Corpus
|
2016-11-17 04:20:49 +00:00
|
|
|
The *corpus* is a set of inputs for the fuzz target (stored as individual files).
|
|
|
|
When starting the fuzzing process, one should have a "seed corpus",
|
|
|
|
i.e. a set of inputs to "seed" the mutations.
|
2019-08-07 14:37:16 +00:00
|
|
|
The quality of the seed corpus has a huge impact on fuzzing efficiency as it
|
|
|
|
allows the fuzzer to discover new code paths more easily.
|
2016-11-15 18:04:07 +00:00
|
|
|
|
2016-12-11 06:22:01 +00:00
|
|
|
The ideal corpus is a minimal set of inputs that provides maximal code coverage.
|
2016-11-17 04:20:49 +00:00
|
|
|
|
2016-11-23 18:27:29 +00:00
|
|
|
For better OSS-Fuzz integration,
|
2019-08-07 14:37:16 +00:00
|
|
|
the seed corpus should be available in revision control (can be same or
|
|
|
|
different as the source code). It should be regularly extended with the inputs
|
|
|
|
that (used to) trigger bugs and/or touch new parts of the code.
|
2016-11-16 06:10:56 +00:00
|
|
|
|
2016-11-15 18:04:07 +00:00
|
|
|
Examples:
|
|
|
|
[boringssl](https://github.com/google/boringssl/tree/master/fuzz),
|
|
|
|
[openssl](https://github.com/openssl/openssl/tree/master/fuzz),
|
2016-11-29 19:19:32 +00:00
|
|
|
[nss](https://github.com/mozilla/nss-fuzzing-corpus) (corpus in a separate repo).
|
2016-11-15 18:04:07 +00:00
|
|
|
|
2019-08-15 22:07:23 +00:00
|
|
|
## Dictionary
|
2016-11-23 18:27:29 +00:00
|
|
|
For some input types, a simple dictionary of tokens used by the input language
|
|
|
|
can have a dramatic positive effect on fuzzing efficiency.
|
2016-11-18 23:04:06 +00:00
|
|
|
For example, when fuzzing an XML parser, a dictionary of XML tokens will help.
|
|
|
|
AFL has a [collection](https://github.com/rc0r/afl-fuzz/tree/master/dictionaries)
|
|
|
|
of such dictionaries for some of the popular data formats.
|
|
|
|
Ideally, a dictionary should be maintained alongside the fuzz target.
|
|
|
|
The syntax is described [here](http://libfuzzer.info/#dictionaries).
|
|
|
|
|
2017-04-25 02:20:38 +00:00
|
|
|
## Coverage
|
2019-08-07 14:37:16 +00:00
|
|
|
For a fuzz target to be useful, it must have good coverage in the code that it
|
|
|
|
is testing. You can view the coverage for your fuzz targets by looking at the
|
2019-08-21 22:10:15 +00:00
|
|
|
[fuzzer stats]({{ site.baseurl }}/further-reading/clusterfuzz#fuzzer-stats)
|
2019-08-07 14:37:16 +00:00
|
|
|
dashboard on ClusterFuzz, as well as
|
2019-08-21 22:10:15 +00:00
|
|
|
[coverage reports]({{ site.baseurl }}/further-reading/clusterfuzz#coverage-reports).
|
2017-04-25 02:20:38 +00:00
|
|
|
|
2018-07-17 19:34:25 +00:00
|
|
|
To generate an aggregated code coverage report for your project, please see
|
2019-08-07 14:37:16 +00:00
|
|
|
[code coverage]({{ site.baseurl }}/advanced-topics/code-coverage)
|
2018-07-17 19:34:25 +00:00
|
|
|
documentation page.
|
|
|
|
|
2019-08-07 14:37:16 +00:00
|
|
|
Coverage can often be improved by adding dictionaries, more inputs for seed
|
|
|
|
corpora, and fixing timeouts/out-of-memory bugs in your targets.
|
2017-04-25 02:20:38 +00:00
|
|
|
|
2019-08-15 22:07:23 +00:00
|
|
|
## Regression Testing
|
|
|
|
The fuzz targets should be regularly tested (not necessarily fuzzed!) as a part
|
|
|
|
of the project's regression testing process.
|
|
|
|
One way to do so is to link the fuzz target with a simple standalone driver
|
|
|
|
(e.g. [this one](https://github.com/llvm-mirror/compiler-rt/tree/master/lib/fuzzer/standalone))
|
|
|
|
that runs the provided inputs and use this driver with the seed corpus created
|
|
|
|
in previous step. It is recommended to use
|
|
|
|
[sanitizers](https://github.com/google/sanitizers) during regression testing.
|
|
|
|
|
|
|
|
Examples: [SQLite](https://www.sqlite.org/src/artifact/d9f1a6f43e7bab45),
|
|
|
|
[openssl](https://github.com/openssl/openssl/blob/master/fuzz/test-corpus.c)
|
|
|
|
|
2017-04-25 02:24:00 +00:00
|
|
|
## Performance
|
2019-08-07 14:37:16 +00:00
|
|
|
Fuzz targets should also be performant, as high memory usage and/or slow
|
|
|
|
execution speed can slow the down the growth of coverage and finding of new
|
|
|
|
bugs. ClusterFuzz provides a
|
2019-08-21 22:10:15 +00:00
|
|
|
[performance analyzer]({{ site.baseurl }}/further-reading/clusterfuzz/#performance-analyzer)
|
2019-08-07 14:37:16 +00:00
|
|
|
for each fuzz target that shows problems that are impacting the performance of
|
|
|
|
the fuzz target.
|
2016-11-17 04:26:11 +00:00
|
|
|
|
2017-05-15 22:17:40 +00:00
|
|
|
## Example
|
2019-08-07 14:37:16 +00:00
|
|
|
|
|
|
|
You may look at a simple
|
|
|
|
[example](https://github.com/google/oss-fuzz/tree/master/projects/example/my-api-repo)
|
|
|
|
that covers most of the items above.
|
2017-05-15 22:17:40 +00:00
|
|
|
|
2016-11-18 23:25:28 +00:00
|
|
|
## Not a project member?
|
|
|
|
|
2016-11-18 23:26:02 +00:00
|
|
|
If you are a member of the project you want to fuzz, most of the steps above are simple.
|
2016-11-23 18:27:29 +00:00
|
|
|
However in some cases, someone outside the project team may want to fuzz the code
|
2016-11-18 23:30:46 +00:00
|
|
|
and the project maintainers are not interested in helping.
|
|
|
|
|
2016-11-23 18:27:29 +00:00
|
|
|
In such cases, we can host the fuzz targets, dictionaries, etc in OSS-Fuzz's
|
2016-11-19 00:04:50 +00:00
|
|
|
repository and mention them in the Dockerfile.
|
2019-08-07 14:37:16 +00:00
|
|
|
Examples: [libxml2](https://github.com/google/oss-fuzz/tree/master/projects/libxml2),
|
|
|
|
[c-ares](https://github.com/google/oss-fuzz/tree/master/projects/c-ares), [expat](https://github.com/google/oss-fuzz/tree/master/projects/expat).
|
2016-11-19 02:54:10 +00:00
|
|
|
This is far from ideal because the fuzz targets will not be continuously tested
|
2016-11-18 23:33:16 +00:00
|
|
|
and hence may quickly bitrot.
|
2016-11-18 23:30:46 +00:00
|
|
|
|
2019-08-07 14:37:16 +00:00
|
|
|
If you are not a project maintainer, we may not be able to CC you to security
|
|
|
|
bugs found by OSS-Fuzz.
|