Fuzzing workflows really depends on the project and there isn't one workflow to rule them all. We will show you a few options, from which you can take inspiration and adapt them to your needs.
The first question that needs an answer is which version of the fuzz targets to fuzz. The answer depends on a number of factors, Some notable ones are:
- Number of targets and amount of resources the project can dedicate for fuzzing.
- Responsibilities of the project - is the project responsible for all versions or is it an open-source project which 3rd party vendors customize and commercialize?
- Git workflow.
One popular option is to fuzz the master on a daily basis. This is done with the following steps:
- For each fuzz target create a target on Fuzzit named <target_name>-master.
- Add a daily cron job in your CI that will compile the latest fuzz target from master and start fuzzing jobs on Fuzzit.
On the Fuzzit side, each time you create a new fuzzing job for a specific target the old one is stopped and a new fuzzing job is started with the new binary. The corpus is shared between runs s you can think of the fuzzing job as a long running job with version updates on a daily basis. Corpus is also merged on an hourly basis seamlessly. Here is an illustration:
Continuous fuzzing with version updates
Daily develop branch
This example refers to the master branch but it can be applicable to any develop branch.
If you are responsible for multiple releases, it might be a good idea to fuzz specific versions. For example, you may decide to fuzz the two latest stable releases. This is done similarly to the previous step but instead of creating a cron-job, you create a job that runs on new commits to the specific version-branch/tag. For each version-branch/tag you need to create a target on Fuzzit, e.g.: <TARGET_NAME>-latest-release or <TARGET_NAME>-previous-release.
LibFuzzer fuzzers can run in two modes: fuzzing - generating new test-cases and looking for new paths, or what we call sanity tests - executing specific test-cases.
After you setup continuous fuzzing, your fuzzers will generate valuable test cases for each target and crashes that you fix along the way. You can use them to catch bugs early on in your development cycle.
For every PR or push to master (or your develop branch) you can setup an additional step where you compile your targets and a sanity test against <TARGET_NAME>-master. This is usually a very quick run so you can be notified before a PR is merged if a new bug is introduced or an old one is reintroduced.
Updated 6 months ago