Integrating libFuzzer tests into Fuzzbuzz

Fuzzbuzz has first-class support for libFuzzer fuzz tests. This guide specifically tackles integrating C or C++ libFuzzer tests so that they are continuously tested on Fuzzbuzz. If you are interested in fuzzing your Rust tests, check out the cargo-fuzz getting started guide instead.

Introduction

This guide assumes that you have some experience with libFuzzer, so minimal attention will be given to the mechanics behind how you compile libFuzzer tests, since this can vary from project to project.

We will be using github.com/fuzzbuzz/fuzzgoat as an example of a C project with a single libFuzzer test. The principles behind this tutorial will work for all libFuzzer projects, since Fuzzbuzz automatically detects all libFuzzer tests in a repository.

There are two requirements to setting up libFuzzer fuzz tests on Fuzzbuzz:

1) Your repository already contains libFuzzer tests that you now how to compile

2) Your build system can use the CC, CXX, CFLAGS and CXXFLAGS environment variables

Fuzzbuzz will run your standard steps used to compile your project and its tests, and inject custom variables into CC, CXX, CFLAGS and CXXFLAGS. Once your build has finished, all binaries containing libFuzzer tests that are present in your repository will be automatically detected and added to the platform as fuzz tests.

Example

The Fuzzgoat repository contains a Makefile which defines the build options for this project. The most important requirement is that your build system respects external variables for compilers and flags, just like this Makefile does:

# Makefile
DEPS=fuzzgoat.c main.c
LIBS=-lm

all: $(DEPS)
    $(CC) -w -I. -o fuzzgoat $(CFLAGS) $^ $(LIBS)

fuzzer: $(DEPS)
    $(CC) -w -o parse-json-fuzzer -pthread -DFUZZING $(CFLAGS) -fsanitize=fuzzer $^ $(LIBS)

.PHONY: clean

clean:
    rm -f ./fuzzgoat ./parse-json-fuzzer

The fuzzbuzz.yaml at the root of the repository contains all the information Fuzzbuzz needs to build the test in this project:

# fuzzbuzz.yaml
# 'base' is just a placeholder. the top-level name in this file can be any valid yaml key
base:
  # 'engine' needs to be provided for C and C++ projects
  language: c
  engine: libFuzzer
  # place your fuzz test build steps here:
  steps:
    - run: make
    - run: make fuzzer
  # define the sanitizers that Fuzzbuzz should use. Each sanitizer enables detection of
  # a particular class of bug.
  sanitizers:
    address: {}
    undefined: {}

When this repository is integrated with Fuzzbuzz, the steps in the fuzzbuzz.yaml will be run with the flags necessary for code coverage instrumentation, as well as all the sanitizer flags necessary to satisfy the sanitizers block. You can learn more about how Fuzzbuzz handles sanitizers in the fuzzbuzz.yaml reference.

You can fork the Fuzzgoat repository and run it on Fuzzbuzz to get a feel for how libFuzzer tests run on the platform.

ON THIS PAGE