Initializing a Project
This section describes how to initialize a project for use with the CI Fuzz. It covers the cifuzz init
command and details needed to integrate cifuzz with a specific build system.
Table of contents
Overview
The first step to fuzz testing with cifuzz
is to initialize the project. Generally, there are two parts to this:
- Run
cifuzz init
in the root of your project directory. This will create thecifuzz.yaml
configuration file in the same directory. - Modify your build system configuration files to support
cifuzz
.
Details on how to modify your build system are provided below for each language and build system currently supported.
C/C++
CMake
After running cifuzz init
in the root directory of your CMake project, you need to add the following commands to your top level CMakeLists.txt
file:
find_package(cifuzz NO_SYSTEM_ENVIRONMENT_PATH)
enable_fuzz_testing()
These commands must be added before any add_library
or add_executable
directives, otherwise the targets will not be compiled with the correct instrumentation/build flags.
You can see an example CMakeLists.txt
in the cifuzz repo: example CMakeLists.txt file
Bazel
After running cifuzz init
in the root directory of your Bazel project, you need to add the following to your WORKSPACE
file:
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_fuzzing",
sha256 = "93353c864968596cfee046ea1ef587ff62eda90dd24d4360c70465376e507982",
strip_prefix = "rules_fuzzing-2492fd2f37163de8e19ce85061e90a464f3e9255",
urls = ["https://github.com/bazelbuild/rules_fuzzing/archive/2492fd2f37163de8e19ce85061e90a464f3e9255.tar.gz"],
)
load("@rules_fuzzing//fuzzing:repositories.bzl", "rules_fuzzing_dependencies")
rules_fuzzing_dependencies()
load("@rules_fuzzing//fuzzing:init.bzl", "rules_fuzzing_init")
rules_fuzzing_init()
git_repository(
name = "cifuzz",
branch = "bazel-support",
remote = "https://github.com/CodeIntelligenceTesting/cifuzz",
strip_prefix = "tools/cmake/cifuzz/include/cifuzz",
)
You can see an example WORKSPACE
in the cifuzz repo: example WORKSPACE file
Make
While cifuzz provides direct support for C/C++ CMake and Bazel projects, it can generally support several other build systems by allowing you to configure build-commands that enable your project to build the fuzz tests properly. Here is an example for Make.
Start by running cifuzz init
in the root directory of your project.
Set build-system
After running cifuzz init
, you will need to edit cifuzz.yaml
. The build-system
option should be other
:
build-system: other
Set build-command and clean-command
When the build-system
is set to other
, then cifuzz will use the clean-command
and build-command
in cifuzz.yaml
. The clean-command
is executed once before building the fuzz tests for a given build variant. This keeps shared dependencies from having to be rebuilt for each fuzz test.
Edit cifuzz.yaml
to include a clean-command
and a build-command
. For example:
clean-command: make clean
build-command: make $FUZZ_TEST
You can see an example cifuzz.yaml
for a Make project in the cifuzz repo: example cifuzz.yaml
Meson
While cifuzz provides direct support for C/C++ CMake and Bazel projects, it can generally support several other build systems by allowing you to configure build-commands that enable your project to build the fuzz tests properly. Here is an example for Meson.
Start by running cifuzz init
in the root directory of your project.
Set build-system
After running cifuzz init
, you will need to edit cifuzz.yaml
. The build-system
option should be other
:
build-system: other
Set build-command and clean-command
When the build-system
is set to other
, then cifuzz will use the clean-command
and build-command
in cifuzz.yaml
. The clean-command
is executed once before building the fuzz tests for a given build variant. This keeps shared dependencies from having to be rebuilt for each fuzz test.
Edit cifuzz.yaml
to include a clean-command
and a build-command
. For example:
clean-command: "rm -rf builddir"
build-command: "meson setup builddir; cd builddir; meson compile -v"
You can see an example cifuzz.yaml
for a Meson project in this repo: example cifuzz.yaml
Java
Maven
After running cifuzz init
in the root directory of your Maven project, you need to add the following dependencies to your top level pom.xml
file:
<dependency>
<groupId>com.code-intelligence</groupId>
<artifactId>jazzer-junit</artifactId>
<version>0.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
If you want to generate Jacoco coverage reports, you also need to include the jacoco plugin in pom.xml
:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
You can see an example pom.xml
in the cifuzz repo: example pom.xml file
Gradle
After running cifuzz init
in the root directory of your Gradle project, you need to add the following dependencies to your top level build.gradle
file:
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0'
testImplementation 'com.code-intelligence:jazzer-junit:0.13.0'
If you want to generate Jacoco coverage reports, you also need to include the jacoco plugin in build.gradle
:
id 'jacoco'
You can see an example build.gradle
in the cifuzz repo: example build.gradle file