Cargo Fuzz
Trail of BitsOfficialPublished by Trail of Bits
- Skill
- Tool integration
- Security
- CC-BY-SA-4.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
cargo-fuzz is the primary fuzzing tool for Rust projects managed with Cargo. It integrates with libFuzzer to provide automated testing for memory errors and edge cases. The tool simplifies the setup of fuzzing harnesses, supports AddressSanitizer for detecting memory corruption, and provides mechanisms for coverage analysis and structure-aware fuzzing using the arbitrary crate.
What it does
- Initializes fuzzing infrastructure within a Cargo project
- Provides a command-line interface for running fuzzing campaigns
- Integrates with AddressSanitizer to detect memory-related bugs
- Supports structure-aware fuzzing via the arbitrary crate
- Generates coverage reports to measure fuzzing effectiveness
- Manages crash artifacts for reproduction and debugging
When to use it
- When fuzzing Rust crates managed by Cargo
- When testing code that utilizes unsafe blocks or FFI
- When performing security-focused testing to find crashes or memory leaks
- When you need to improve test coverage for complex input parsers
Advantages
- Native integration with the Cargo ecosystem
- Simple setup process for new fuzzing targets
- Built-in support for sanitizers to catch memory errors
- Extensible with custom dictionaries and seed corpora
Usage examples
- “How do I initialize fuzzing for my Rust project?”
- Run the command cargo fuzz init in your project root to create the necessary directory structure and default fuzz target.
- “How can I run a fuzzing campaign?”
- Use the command cargo +nightly fuzz run fuzz_target_1 to start the fuzzer on your specified target.
- “How do I improve performance for safe Rust code?”
- You can disable sanitizers by running the fuzzer with the --sanitizer none flag.
- “How do I reproduce a crash found by the fuzzer?”
- Execute the command cargo +nightly fuzz run fuzz_target_1 followed by the path to the specific crash artifact file.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/trailofbits/cargo-fuzz/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip cargo-fuzz.zip -d .agents/skills
Documentation by Trail of Bits
cargo-fuzz
cargo-fuzz is the de facto choice for fuzzing Rust projects when using Cargo. It uses libFuzzer as the backend and provides a convenient Cargo subcommand that automatically enables relevant compilation flags for your Rust project, including support for sanitizers like AddressSanitizer.
When to Use
cargo-fuzz is currently the primary and most mature fuzzing solution for Rust projects using Cargo.
| Fuzzer | Best For | Complexity |
|---|---|---|
| cargo-fuzz | Cargo-based Rust projects, quick setup | Low |
| AFL++ | Multi-core fuzzing, non-Cargo projects | Medium |
| LibAFL | Custom fuzzers, research, advanced use cases | High |
Choose cargo-fuzz when:
Your project uses Cargo (required)
You want simple, quick setup with minimal configuration
You need integrated sanitizer support
You're fuzzing Rust code with or without unsafe blocks
Quick Start
#![no_main]
use libfuzzer_sys::fuzz_target;
fn harness(data: &[u8]) {
your_project::check_buf(data);
}
fuzz_target!(|data: &[u8]| {
harness(data);
});Initialize and run:
cargo fuzz init
# Edit fuzz/fuzz_targets/fuzz_target_1.rs with your harness
cargo +nightly fuzz run fuzz_target_1Installation
cargo-fuzz requires the nightly Rust toolchain because it uses features only available in nightly.
Prerequisites
Rust and Cargo installed via rustup
Nightly toolchain
Linux/macOS
# Install nightly toolchain
rustup install nightly
# Install cargo-fuzz
cargo install cargo-fuzzVerification
cargo +nightly --version
cargo fuzz --versionWriting a Harness
Project Structure
cargo-fuzz works best when your code is structured as a library crate. If you have a binary project, split your main.rs into:
src/main.rs # Entry point (main function)
src/lib.rs # Code to fuzz (public functions)
Cargo.tomlInitialize fuzzing:
cargo fuzz initThis creates:
fuzz/
├── Cargo.toml
└── fuzz_targets/
└── fuzz_target_1.rsHarness Structure
#![no_main]
use libfuzzer_sys::fuzz_target;
fn harness(data: &[u8]) {
// 1. Validate input size if needed
if data.is_empty() {
return;
}
// 2. Call target function with fuzz data
your_project::target_function(data);
}
fuzz_target!(|data: &[u8]| {
harness(data);
});Harness Rules
| Do | Don't |
|---|---|
| Structure code as library crate | Keep everything in main.rs |
Use fuzz_target! macro | Write custom main function |
Handle Result::Err gracefully | Panic on expected errors |
| Keep harness deterministic | Use random number generators |
See Also: For detailed harness writing techniques and structure-aware fuzzing with the
arbitrarycrate, see the fuzz-harness-writing technique skill.
Structure-Aware Fuzzing
cargo-fuzz integrates with the arbitrary crate for structure-aware fuzzing:
// In your library crate
use arbitrary::Arbitrary;
#[derive(Debug, Arbitrary)]
pub struct Name {
data: String
}// In your fuzz target
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: your_project::Name| {
data.check_buf();
});Add to your library's Cargo.toml:
[dependencies]
arbitrary = { version = "1", features = ["derive"] }Running Campaigns
Basic Run
cargo +nightly fuzz run fuzz_target_1Without Sanitizers (Safe Rust)
If your project doesn't use unsafe Rust, disable sanitizers for 2x performance boost:
cargo +nightly fuzz run --sanitizer none fuzz_target_1Check if your project uses unsafe code:
cargo install cargo-geiger
cargo geigerRe-executing Test Cases
# Run a specific test case (e.g., a crash)
cargo +nightly fuzz run fuzz_target_1 fuzz/artifacts/fuzz_target_1/crash-<hash>
# Run all corpus entries without fuzzing
cargo +nightly fuzz run fuzz_target_1 fuzz/corpus/fuzz_target_1 -- -runs=0Using Dictionaries
cargo +nightly fuzz run fuzz_target_1 -- -dict=./dict.dictInterpreting Output
| Output | Meaning |
|---|---|
NEW | New coverage-increasing input discovered |
pulse | Periodic status update |
INITED | Fuzzer initialized successfully |
| Crash with stack trace | Bug found, saved to fuzz/artifacts/ |
Corpus location: fuzz/corpus/fuzz_target_1/
Crashes location: fuzz/artifacts/fuzz_target_1/
Sanitizer Integration
AddressSanitizer (ASan)
ASan is enabled by default and detects memory errors:
cargo +nightly fuzz run fuzz_target_1Disabling Sanitizers
For pure safe Rust (no unsafe blocks in your code or dependencies):
cargo +nightly fuzz run --sanitizer none fuzz_target_1Performance impact: ASan adds ~2x overhead. Disable for safe Rust to improve fuzzing speed.
Checking for Unsafe Code
cargo install cargo-geiger
cargo geigerSee Also: For detailed sanitizer configuration, flags, and troubleshooting, see the address-sanitizer technique skill.
Coverage Analysis
cargo-fuzz integrates with Rust's coverage tools to analyze fuzzing effectiveness.
Prerequisites
rustup toolchain install nightly --component llvm-tools-preview
cargo install cargo-binutils
cargo install rustfiltGenerating Coverage Reports
# Generate coverage data from corpus
cargo +nightly fuzz coverage fuzz_target_1Create coverage generation script:
cat <<'EOF' > ./generate_html
#!/bin/sh
if [ $# -lt 1 ]; then
echo "Error: Name of fuzz target is required."
echo "Usage: $0 fuzz_target [sources...]"
exit 1
fi
FUZZ_TARGET="$1"
shift
SRC_FILTER="$@"
TARGET=$(rustc -vV | sed -n 's|host: ||p')
cargo +nightly cov -- show -Xdemangler=rustfilt \
"target/$TARGET/coverage/$TARGET/release/$FUZZ_TARGET" \
-instr-profile="fuzz/coverage/$FUZZ_TARGET/coverage.profdata" \
-show-line-counts-or-regions -show-instantiations \
-format=html -o fuzz_html/ $SRC_FILTER
EOF
chmod +x ./generate_htmlGenerate HTML report:
./generate_html fuzz_target_1 src/lib.rsHTML report saved to: fuzz_html/
See Also: For detailed coverage analysis techniques and systematic coverage improvement, see the coverage-analysis technique skill.
Advanced Usage
Tips and Tricks
| Tip | Why It Helps |
|---|---|
| Start with a seed corpus | Dramatically speeds up initial coverage discovery |
Use --sanitizer none for safe Rust | 2x performance improvement |
| Check coverage regularly | Identifies gaps in harness or seed corpus |
| Use dictionaries for parsers | Helps overcome magic value checks |
| Structure code as library | Required for cargo-fuzz integration |
libFuzzer Options
Pass options to libFuzzer after --:
# See all options
cargo +nightly fuzz run fuzz_target_1 -- -help=1
# Set timeout per run
cargo +nightly fuzz run fuzz_target_1 -- -timeout=10
# Use dictionary
cargo +nightly fuzz run fuzz_target_1 -- -dict=dict.dict
# Limit maximum input size
cargo +nightly fuzz run fuzz_target_1 -- -max_len=1024Multi-Core Fuzzing
# Experimental forking support (not recommended)
cargo +nightly fuzz run --jobs 1 fuzz_target_1Note: The multi-core fuzzing feature is experimental and not recommended. For parallel fuzzing, consider running multiple instances manually or using AFL++.
Real-World Examples
Example: ogg Crate
The ogg crate parses Ogg media container files. Parsers are excellent fuzzing targets because they handle untrusted data.
# Clone and initialize
git clone https://github.com/RustAudio/ogg.git
cd ogg/
cargo fuzz initHarness at fuzz/fuzz_targets/fuzz_target_1.rs:
#![no_main]
use ogg::{PacketReader, PacketWriter};
use ogg::writing::PacketWriteEndInfo;
use std::io::Cursor;
use libfuzzer_sys::fuzz_target;
fn harness(data: &[u8]) {
let mut pck_rdr = PacketReader::new(Cursor::new(data.to_vec()));
pck_rdr.delete_unread_packets();
let output = Vec::new();
let mut pck_wtr = PacketWriter::new(Cursor::new(output));
if let Ok(_) = pck_rdr.read_packet() {
if let Ok(r) = pck_rdr.read_packet() {
match r {
Some(pck) => {
let inf = if pck.last_in_stream() {
PacketWriteEndInfo::EndStream
} else if pck.last_in_page() {
PacketWriteEndInfo::EndPage
} else {
PacketWriteEndInfo::NormalPacket
};
let stream_serial = pck.stream_serial();
let absgp_page = pck.absgp_page();
let _ = pck_wtr.write_packet(
pck.data, stream_serial, inf, absgp_page
);
}
None => return,
}
}
}
}
fuzz_target!(|data: &[u8]| {
harness(data);
});Seed the corpus:
mkdir fuzz/corpus/fuzz_target_1/
curl -o fuzz/corpus/fuzz_target_1/320x240.ogg \
https://commons.wikimedia.org/wiki/File:320x240.oggRun:
cargo +nightly fuzz run fuzz_target_1Analyze coverage:
cargo +nightly fuzz coverage fuzz_target_1
./generate_html fuzz_target_1 src/lib.rsTroubleshooting
| Problem | Cause | Solution |
|---|---|---|
| "requires nightly" error | Using stable toolchain | Use cargo +nightly fuzz |
| Slow fuzzing performance | ASan enabled for safe Rust | Add --sanitizer none flag |
| "cannot find binary" | No library crate | Move code from main.rs to lib.rs |
| Sanitizer compilation issues | Wrong nightly version | Try different nightly: rustup install nightly-2024-01-01 |
| Low coverage | Missing seed corpus | Add sample inputs to fuzz/corpus/fuzz_target_1/ |
| Magic value not found | No dictionary | Create dictionary file with magic values |
Related Skills
Technique Skills
| Skill | Use Case |
|---|---|
| fuzz-harness-writing | Structure-aware fuzzing with arbitrary crate |
| address-sanitizer | Understanding ASan output and configuration |
| coverage-analysis | Measuring and improving fuzzing effectiveness |
| fuzzing-corpus | Building and managing seed corpora |
| fuzzing-dictionaries | Creating dictionaries for format-aware fuzzing |
Related Fuzzers
| Skill | When to Consider |
|---|---|
| libfuzzer | Fuzzing C/C++ code with similar workflow |
| aflpp | Multi-core fuzzing or non-Cargo Rust projects |
| libafl | Advanced fuzzing research or custom fuzzer development |
Resources
Rust Fuzz Book - cargo-fuzz Official documentation for cargo-fuzz covering installation, usage, and advanced features.
arbitrary crate documentation Guide to structure-aware fuzzing with automatic derivation for Rust types.
cargo-fuzz GitHub Repository Source code, issue tracker, and examples for cargo-fuzz.
Files
- ATTRIBUTION.mdAdded by AutoGineer937 B
- LICENSELicence file added by AutoGineer19.7 KiB
- SKILL.md11.5 KiB
- agents/openai.yaml223 B
- assets/trail-of-bits-mark.svg3.0 KiB
ATTRIBUTION.md
Attribution
This folder is an unmodified copy of the Agent Skill "cargo-fuzz", distributed by AutoGineer (https://autogineer.com/agent-skills).
Commit: e4dd0bb5b15535f7c5a0834187dffba6ac37e4ff
Published by: Trail of Bits (https://github.com/trailofbits)
Publisher: Trail of Bits (https://github.com/trailofbits)
Licence: Creative Commons Attribution-ShareAlike 4.0 International (https://github.com/trailofbits/skills/blob/e4dd0bb5b15535f7c5a0834187dffba6ac37e4ff/LICENSE)
Licence evidence: repository licence LICENSE
Retrieved: 2026-11-07
The skill's own files are unmodified copies. AutoGineer is not affiliated with or endorsed by the author or the publisher.
Files added by AutoGineer
ATTRIBUTION.md: this file, written by AutoGineer
LICENSE: copied from LICENSE
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs a command-line tool
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Trail of Bits
- Publisher
- Trail of Bits (Official)
- Source
- trailofbits/skills · plugins/testing-handbook-skills/skills/cargo-fuzz · commit e4dd0bb
- Licence
- Creative Commons Attribution-ShareAlike 4.0 International (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Trail of Bits or Trail of Bits.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download cargo-fuzz.zip