Skip to main content

Overview

Implementation

From an implementation perspective, several modules exist to make the fuzzer reusable.

Fuzzing loop

The main fuzzing loop is made of the following modules, each at a different layer (from high-level to low-level):

  1. puffin: Core fuzzing engine which is protocol- and target-agnostic. It deals at a high level with the terms algebra, the input traces and the fuzzing process (scheduling, logging, mutations, ...). This module is built on top of the libAFL crate.
  2. tlspuffin: TLS fuzzer which instantiates puffin to the TLS protocol and is PUTs-agnostic. It notably instantiates the traces to TLS traces with the TLS-specific terms and functions for the TLS terms algebra, based on the rustls crate (e.g., ECSDA signatures, ECDHE encryption, ClientHello, etc.).
  3. harness, for example for OpenSSL PUTs: harness/openssl - Harnesses for some PUTs.

Finally, other protocols and PUTs can be fuzzed as well, by extending the fuzzer at layer 2. (new protocols) and 3. (new PUTs harnesses).. We did a preliminary version of those for SSH and OpenSSH in the module sshpuffin (WIP).

The following diagram shows the dependencies between the modules:

The interfaces between the modules are defined by the following Rust traits which define what a protocol is and what a PUT harness is: ProtocolBehavior and Put<PB: ProtocolBehavior>.

Program Under Tests (PUTs)

The fuzzer then requires a target (that is a harness linked to some PUT) to fuzz. To build the PUTs (vendor libraries) and link them to the fuzzer, the following tooling is used:

  • puffin-build (generates the mk_vendor tool): contains a crate implements the build process, from creating PUTs (vendor libraries) to linking PUTs into the fuzzer (through some fuzzing harness).

Benchmarks

To benchmark the fuzzer and perform regression tests, the following tooling is used:

  • puffin-bench: performance testbench for the puffin fuzzer (external tooling; not part to the puffin crate), see benchmarks.

Setup

Ongoing Work

The rest of this page is currently under development. Information presented here might be incomplete or outdated.

Configure your environment for developement on the puffin project:

  • nix
  • editor setup
    • vscode (recommended extensions, change default features, ...)

Testing my changes

  • justfile: use just fmt for code formatting, just check for basic checks, and just check-workspace for more advanced checks. Under-the-hood, it uses:
    • rustfmt
    • clang-format
    • cargo clippy
    • cargo bench
  • github PRs/github CI: use the PR's labels ci:none, ci:fast, ci:full to fine-tune the CI checks. The full checks (ci-full) must be checked prior to merging PRs.
  • puffin-bench: run uv run benchmark for end-to-end, long, and comprehensive regressions and performance checks, see benchmarks.