cargo-fuzz
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesecargo-fuzz
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.
cargo-fuzz 是使用 Cargo 的 Rust 项目进行模糊测试时的事实标准选择。它采用 libFuzzer 作为后端,提供便捷的 Cargo 子命令,可自动为你的 Rust 项目启用相关编译标志,包括对 AddressSanitizer 等 sanitizer 的支持。
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
cargo-fuzz 目前是使用 Cargo 的 Rust 项目的主要且最成熟的模糊测试解决方案。
| 模糊测试工具 | 最佳适用场景 | 复杂度 |
|---|---|---|
| cargo-fuzz | 基于 Cargo 的 Rust 项目,快速搭建 | 低 |
| AFL++ | 多核模糊测试,非 Cargo 项目 | 中 |
| LibAFL | 自定义模糊测试工具,研究,高级使用场景 | 高 |
选择 cargo-fuzz 的场景:
- 你的项目使用 Cargo(必需)
- 你想要简单、快速的搭建流程,只需最少配置
- 你需要集成 sanitizer 支持
- 你要对包含或不包含 unsafe 块的 Rust 代码进行模糊测试
Quick Start
快速开始
rust
#![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:
bash
cargo fuzz initrust
#![no_main]
use libfuzzer_sys::fuzz_target;
fn harness(data: &[u8]) {
your_project::check_buf(data);
}
fuzz_target!(|data: &[u8]| {
harness(data);
});初始化并运行:
bash
cargo fuzz initEdit fuzz/fuzz_targets/fuzz_target_1.rs with your harness
编辑 fuzz/fuzz_targets/fuzz_target_1.rs,添加你的测试逻辑
cargo +nightly fuzz run fuzz_target_1
undefinedcargo +nightly fuzz run fuzz_target_1
undefinedInstallation
安装
cargo-fuzz requires the nightly Rust toolchain because it uses features only available in nightly.
cargo-fuzz 需要 nightly Rust 工具链,因为它使用仅在 nightly 版本中可用的特性。
Prerequisites
前置条件
Linux/macOS
Linux/macOS
bash
undefinedbash
undefinedInstall nightly toolchain
安装 nightly 工具链
rustup install nightly
rustup install nightly
Install cargo-fuzz
安装 cargo-fuzz
cargo install cargo-fuzz
undefinedcargo install cargo-fuzz
undefinedVerification
验证
bash
cargo +nightly --version
cargo fuzz --versionbash
cargo +nightly --version
cargo fuzz --versionWriting a Harness
编写测试逻辑(Harness)
Project Structure
项目结构
cargo-fuzz works best when your code is structured as a library crate. If you have a binary project, split your into:
main.rstext
src/main.rs # Entry point (main function)
src/lib.rs # Code to fuzz (public functions)
Cargo.tomlInitialize fuzzing:
bash
cargo fuzz initThis creates:
text
fuzz/
├── Cargo.toml
└── fuzz_targets/
└── fuzz_target_1.rs当你的代码以库 crate 的形式组织时,cargo-fuzz 的效果最佳。如果你的项目是二进制项目,请将 拆分为:
main.rstext
src/main.rs # 入口点(main 函数)
src/lib.rs # 要进行模糊测试的代码(公开函数)
Cargo.toml初始化模糊测试:
bash
cargo fuzz init这会创建如下结构:
text
fuzz/
├── Cargo.toml
└── fuzz_targets/
└── fuzz_target_1.rsHarness Structure
测试逻辑结构
rust
#![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);
});rust
#![no_main]
use libfuzzer_sys::fuzz_target;
fn harness(data: &[u8]) {
// 1. 如有需要,验证输入大小
if data.is_empty() {
return;
}
// 2. 使用模糊测试数据调用目标函数
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 | Write custom main function |
Handle | Panic on expected errors |
| Keep harness deterministic | Use random number generators |
See Also: For detailed harness writing techniques and structure-aware fuzzing with thecrate, see the fuzz-harness-writing technique skill.arbitrary
| 建议做法 | 不建议做法 |
|---|---|
| 将代码组织为库 crate | 所有代码都放在 main.rs 中 |
使用 | 编写自定义 main 函数 |
优雅处理 | 在预期错误时触发 panic |
| 保持测试逻辑的确定性 | 使用随机数生成器 |
另请参阅: 如需详细的测试逻辑编写技巧和使用crate 的结构化模糊测试,请查看 fuzz-harness-writing 技术文档。arbitrary
Structure-Aware Fuzzing
结构化模糊测试
cargo-fuzz integrates with the arbitrary crate for structure-aware fuzzing:
rust
// In your library crate
use arbitrary::Arbitrary;
#[derive(Debug, Arbitrary)]
pub struct Name {
data: String
}rust
// 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.tomltoml
[dependencies]
arbitrary = { version = "1", features = ["derive"] }cargo-fuzz 可与 arbitrary crate 集成,实现结构化模糊测试:
rust
// 在你的库 crate 中
use arbitrary::Arbitrary;
#[derive(Debug, Arbitrary)]
pub struct Name {
data: String
}rust
// 在你的模糊测试目标中
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: your_project::Name| {
data.check_buf();
});在你的库的 中添加依赖:
Cargo.tomltoml
[dependencies]
arbitrary = { version = "1", features = ["derive"] }Running Campaigns
运行模糊测试任务
Basic Run
基础运行
bash
cargo +nightly fuzz run fuzz_target_1bash
cargo +nightly fuzz run fuzz_target_1Without Sanitizers (Safe Rust)
禁用 Sanitizer(纯安全 Rust 代码)
If your project doesn't use unsafe Rust, disable sanitizers for 2x performance boost:
bash
cargo +nightly fuzz run --sanitizer none fuzz_target_1Check if your project uses unsafe code:
bash
cargo install cargo-geiger
cargo geiger如果你的项目不使用 unsafe Rust 代码,禁用 sanitizer 可使性能提升 2 倍:
bash
cargo +nightly fuzz run --sanitizer none fuzz_target_1检查你的项目是否使用 unsafe 代码:
bash
cargo install cargo-geiger
cargo geigerRe-executing Test Cases
重新执行测试用例
bash
undefinedbash
undefinedRun a specific test case (e.g., a crash)
运行特定测试用例(例如,崩溃案例)
cargo +nightly fuzz run fuzz_target_1 fuzz/artifacts/fuzz_target_1/crash-<hash>
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=0
undefinedcargo +nightly fuzz run fuzz_target_1 fuzz/corpus/fuzz_target_1 -- -runs=0
undefinedUsing Dictionaries
使用字典
bash
cargo +nightly fuzz run fuzz_target_1 -- -dict=./dict.dictbash
cargo +nightly fuzz run fuzz_target_1 -- -dict=./dict.dictInterpreting Output
输出解读
| Output | Meaning |
|---|---|
| New coverage-increasing input discovered |
| Periodic status update |
| Fuzzer initialized successfully |
| Crash with stack trace | Bug found, saved to |
Corpus location:
Crashes location:
fuzz/corpus/fuzz_target_1/fuzz/artifacts/fuzz_target_1/| 输出内容 | 含义 |
|---|---|
| 发现了能提升代码覆盖率的新输入 |
| 定期状态更新 |
| 模糊测试工具初始化成功 |
| 带有堆栈跟踪的崩溃信息 | 发现 bug,已保存到 |
语料库位置:
崩溃案例位置:
fuzz/corpus/fuzz_target_1/fuzz/artifacts/fuzz_target_1/Sanitizer Integration
Sanitizer 集成
AddressSanitizer (ASan)
AddressSanitizer (ASan)
ASan is enabled by default and detects memory errors:
bash
cargo +nightly fuzz run fuzz_target_1ASan 默认启用,用于检测内存错误:
bash
cargo +nightly fuzz run fuzz_target_1Disabling Sanitizers
禁用 Sanitizer
For pure safe Rust (no unsafe blocks in your code or dependencies):
bash
cargo +nightly fuzz run --sanitizer none fuzz_target_1Performance impact: ASan adds ~2x overhead. Disable for safe Rust to improve fuzzing speed.
对于纯安全 Rust 代码(你的代码或依赖中均无 unsafe 块):
bash
cargo +nightly fuzz run --sanitizer none fuzz_target_1性能影响: ASan 会增加约 2 倍的开销。对于安全 Rust 代码,禁用它可提升模糊测试速度。
Checking for Unsafe Code
检查 unsafe 代码
bash
cargo install cargo-geiger
cargo geigerSee Also: For detailed sanitizer configuration, flags, and troubleshooting, see the address-sanitizer technique skill.
bash
cargo install cargo-geiger
cargo geiger另请参阅: 如需详细的 sanitizer 配置、标志和故障排除方法,请查看 address-sanitizer 技术文档。
Coverage Analysis
覆盖率分析
cargo-fuzz integrates with Rust's coverage tools to analyze fuzzing effectiveness.
cargo-fuzz 与 Rust 的覆盖率工具集成,用于分析模糊测试的有效性。
Prerequisites
前置条件
bash
rustup toolchain install nightly --component llvm-tools-preview
cargo install cargo-binutils
cargo install rustfiltbash
rustup toolchain install nightly --component llvm-tools-preview
cargo install cargo-binutils
cargo install rustfiltGenerating Coverage Reports
生成覆盖率报告
bash
undefinedbash
undefinedGenerate coverage data from corpus
从语料库生成覆盖率数据
cargo +nightly fuzz coverage fuzz_target_1
Create coverage generation script:
```bash
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:
bash
./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.
cargo +nightly fuzz coverage fuzz_target_1
创建覆盖率生成脚本:
```bash
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_html生成 HTML 报告:
bash
./generate_html fuzz_target_1 src/lib.rsHTML 报告保存位置:
fuzz_html/另请参阅: 如需详细的覆盖率分析技巧和系统性提升覆盖率的方法,请查看 coverage-analysis 技术文档。
Advanced Usage
高级用法
Tips and Tricks
技巧与窍门
| Tip | Why It Helps |
|---|---|
| Start with a seed corpus | Dramatically speeds up initial coverage discovery |
Use | 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 |
| 技巧 | 优势 |
|---|---|
| 从种子语料库开始 | 大幅加快初始覆盖率的发现速度 |
对于安全 Rust 代码使用 | 性能提升 2 倍 |
| 定期检查覆盖率 | 识别测试逻辑或种子语料库中的不足 |
| 为解析器使用字典 | 帮助突破魔术值检查 |
| 将代码组织为库 | 是 cargo-fuzz 集成的必要条件 |
libFuzzer Options
libFuzzer 选项
Pass options to libFuzzer after :
--bash
undefined在 之后向 libFuzzer 传递选项:
--bash
undefinedSee all options
查看所有选项
cargo +nightly fuzz run fuzz_target_1 -- -help=1
cargo +nightly fuzz run fuzz_target_1 -- -help=1
Set timeout per run
设置每次运行的超时时间
cargo +nightly fuzz run fuzz_target_1 -- -timeout=10
cargo +nightly fuzz run fuzz_target_1 -- -timeout=10
Use dictionary
使用字典
cargo +nightly fuzz run fuzz_target_1 -- -dict=dict.dict
cargo +nightly fuzz run fuzz_target_1 -- -dict=dict.dict
Limit maximum input size
限制最大输入大小
cargo +nightly fuzz run fuzz_target_1 -- -max_len=1024
undefinedcargo +nightly fuzz run fuzz_target_1 -- -max_len=1024
undefinedMulti-Core Fuzzing
多核模糊测试
bash
undefinedbash
undefinedExperimental forking support (not recommended)
实验性的 fork 支持(不推荐)
cargo +nightly fuzz run --jobs 1 fuzz_target_1
Note: The multi-core fuzzing feature is experimental and not recommended. For parallel fuzzing, consider running multiple instances manually or using AFL++.cargo +nightly fuzz run --jobs 1 fuzz_target_1
注意:多核模糊测试功能处于实验阶段,不推荐使用。如需并行模糊测试,建议手动运行多个实例或使用 AFL++。Real-World Examples
实际案例
Example: ogg Crate
示例:ogg Crate
The ogg crate parses Ogg media container files. Parsers are excellent fuzzing targets because they handle untrusted data.
bash
undefinedogg crate 用于解析 Ogg 媒体容器文件。解析器是极佳的模糊测试目标,因为它们要处理不受信任的数据。
bash
undefinedClone and initialize
克隆并初始化
git clone https://github.com/RustAudio/ogg.git
cd ogg/
cargo fuzz init
Harness at `fuzz/fuzz_targets/fuzz_target_1.rs`:
```rust
#![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:
bash
mkdir fuzz/corpus/fuzz_target_1/
curl -o fuzz/corpus/fuzz_target_1/320x240.ogg \
https://commons.wikimedia.org/wiki/File:320x240.oggRun:
bash
cargo +nightly fuzz run fuzz_target_1Analyze coverage:
bash
cargo +nightly fuzz coverage fuzz_target_1
./generate_html fuzz_target_1 src/lib.rsgit clone https://github.com/RustAudio/ogg.git
cd ogg/
cargo fuzz init
测试逻辑位于 `fuzz/fuzz_targets/fuzz_target_1.rs`:
```rust
#![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);
});为语料库添加种子:
bash
mkdir fuzz/corpus/fuzz_target_1/
curl -o fuzz/corpus/fuzz_target_1/320x240.ogg \
https://commons.wikimedia.org/wiki/File:320x240.ogg运行:
bash
cargo +nightly fuzz run fuzz_target_1分析覆盖率:
bash
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 |
| Slow fuzzing performance | ASan enabled for safe Rust | Add |
| "cannot find binary" | No library crate | Move code from |
| Sanitizer compilation issues | Wrong nightly version | Try different nightly: |
| Low coverage | Missing seed corpus | Add sample inputs to |
| Magic value not found | No dictionary | Create dictionary file with magic values |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| "requires nightly" 错误 | 使用了稳定版工具链 | 使用 |
| 模糊测试性能缓慢 | 为安全 Rust 代码启用了 ASan | 添加 |
| "cannot find binary" | 没有库 crate | 将代码从 |
| Sanitizer 编译问题 | Nightly 版本不兼容 | 尝试其他 nightly 版本: |
| 覆盖率低 | 缺少种子语料库 | 向 |
| 未找到魔术值 | 没有使用字典 | 创建包含魔术值的字典文件 |
Related Skills
相关技术
Technique Skills
技术技巧
| Skill | Use Case |
|---|---|
| fuzz-harness-writing | Structure-aware fuzzing with |
| 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 |
| 技术 | 适用场景 |
|---|---|
| fuzz-harness-writing | 使用 |
| address-sanitizer | 理解 ASan 输出和配置 |
| coverage-analysis | 衡量并提升模糊测试的有效性 |
| fuzzing-corpus | 构建和管理种子语料库 |
| fuzzing-dictionaries | 创建用于格式感知模糊测试的字典 |
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 |
| 技术 | 适用场景 |
|---|---|
| libfuzzer | 使用类似流程对 C/C++ 代码进行模糊测试 |
| aflpp | 多核模糊测试或非 Cargo Rust 项目 |
| libafl | 高级模糊测试研究或自定义模糊测试工具开发 |
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.
Rust Fuzz 书籍 - cargo-fuzz
cargo-fuzz 的官方文档,涵盖安装、使用和高级特性。
arbitrary crate 文档
关于使用 Rust 类型自动推导实现结构化模糊测试的指南。
cargo-fuzz GitHub 仓库
cargo-fuzz 的源代码、问题追踪器和示例。