Rust bindings and utilities for LLVM’s libFuzzer
  • C++ 87.4%
  • Rust 8%
  • CMake 2.1%
  • C 1.8%
  • Python 0.5%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-04-13 10:54:29 +02:00
example chore: sync dependencies (monorepo) 2026-04-01 19:28:41 +02:00
example_arbitrary chore: sync dependencies (monorepo) 2026-04-01 19:28:41 +02:00
example_crossover chore: sync dependencies (monorepo) 2026-04-01 19:28:41 +02:00
example_init chore: sync dependencies (monorepo) 2026-04-01 19:28:41 +02:00
example_mutator chore: sync dependencies (monorepo) 2026-04-01 19:28:41 +02:00
libfuzzer Update vendored LibFuzzer to LLVM 22.x release 2026-02-08 18:56:13 -05:00
src chore: sync dependencies (monorepo) 2026-04-01 19:28:41 +02:00
.gitignore Migrate to using cargo fuzz in CI 2022-03-03 09:52:25 -08:00
build.rs fix cc invocations to use provided methods 2024-11-25 16:19:40 +02:00
Cargo.toml chore: sync dependencies (monorepo) 2026-04-13 10:54:29 +02:00
LICENSE-APACHE Add license files 2021-03-19 17:09:42 -07:00
LICENSE-MIT Add license files 2021-03-19 17:09:42 -07:00
README.md Update docs on libfuzzer vendoring 2024-11-07 12:56:44 -08:00
rust-toolchain CI: use nightly toolchain by default 2020-01-14 12:15:23 -08:00
update-libfuzzer.sh Update vendored LibFuzzer to LLVM 22.x release 2026-02-08 18:56:13 -05:00

The libfuzzer-sys Crate

Barebones wrapper around LLVM's libFuzzer runtime library.

The CPP parts are extracted from compiler-rt git repository with git filter-branch.

libFuzzer relies on LLVM sanitizer support. The Rust compiler has built-in support for LLVM sanitizer support, for now, it's limited to Linux. As a result, libfuzzer-sys only works on Linux.

Usage

Use cargo fuzz!

The recommended way to use this crate with cargo fuzz!.

Manual Usage

This crate can also be used manually as following:

First create a new cargo project:

$ cargo new --bin fuzzed
$ cd fuzzed

Then add a dependency on the fuzzer-sys crate and your own crate:

[dependencies]
libfuzzer-sys = "0.4.0"
your_crate = { path = "../path/to/your/crate" }

Change the fuzzed/src/main.rs to fuzz your code:

#![no_main]

use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {
    // code to fuzz goes here
});

Build by running the following command:

$ cargo rustc -- \
    -C passes='sancov-module' \
    -C llvm-args='-sanitizer-coverage-level=3' \
    -C llvm-args='-sanitizer-coverage-inline-8bit-counters' \
    -Z sanitizer=address

And finally, run the fuzzer:

$ ./target/debug/fuzzed

Linking to a local libfuzzer

When using libfuzzer-sys, you can provide your own libfuzzer runtime in two ways.

If you are developing a fuzzer, you can set the CUSTOM_LIBFUZZER_PATH environment variable to the path of your local libfuzzer runtime, which will then be linked instead of building libfuzzer as part of the build stage of libfuzzer-sys. For an example, to link to a prebuilt LLVM 16 libfuzzer, you could use:

$ export CUSTOM_LIBFUZZER_PATH=/usr/lib64/clang/16/lib/libclang_rt.fuzzer-x86_64.a
$ cargo fuzz run ...

Alternatively, you may also disable the default link_libfuzzer feature:

In Cargo.toml:

[dependencies]
libfuzzer-sys = { path = "../../libfuzzer", default-features = false }

Then link to your own runtime in your build.rs.

Updating libfuzzer from upstream

  • Update the COMMIT=... variable in ./update-libfuzzer.sh with the new commit hash from llvm-mirror/llvm-project that you are vendoring.

  • Re-run the script:

    $ ./update-libfuzzer.sh <github.com/llvm-mirror/llvm-project SHA1>
    

License

All files in the libfuzzer directory are licensed NCSA.

Everything else is dual-licensed Apache 2.0 and MIT.