cargo-fuzz

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

cargo-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.
FuzzerBest ForComplexity
cargo-fuzzCargo-based Rust projects, quick setupLow
AFL++Multi-core fuzzing, non-Cargo projectsMedium
LibAFLCustom fuzzers, research, advanced use casesHigh
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 init
rust
#![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 init

Edit fuzz/fuzz_targets/fuzz_target_1.rs with your harness

编辑 fuzz/fuzz_targets/fuzz_target_1.rs,添加你的测试逻辑

cargo +nightly fuzz run fuzz_target_1
undefined
cargo +nightly fuzz run fuzz_target_1
undefined

Installation

安装

cargo-fuzz requires the nightly Rust toolchain because it uses features only available in nightly.
cargo-fuzz 需要 nightly Rust 工具链,因为它使用仅在 nightly 版本中可用的特性。

Prerequisites

前置条件

  • Rust and Cargo installed via rustup
  • Nightly toolchain
  • 通过 rustup 安装 Rust 和 Cargo
  • Nightly 工具链

Linux/macOS

Linux/macOS

bash
undefined
bash
undefined

Install nightly toolchain

安装 nightly 工具链

rustup install nightly
rustup install nightly

Install cargo-fuzz

安装 cargo-fuzz

cargo install cargo-fuzz
undefined
cargo install cargo-fuzz
undefined

Verification

验证

bash
cargo +nightly --version
cargo fuzz --version
bash
cargo +nightly --version
cargo fuzz --version

Writing 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
main.rs
into:
text
src/main.rs  # Entry point (main function)
src/lib.rs   # Code to fuzz (public functions)
Cargo.toml
Initialize fuzzing:
bash
cargo fuzz init
This creates:
text
fuzz/
├── Cargo.toml
└── fuzz_targets/
    └── fuzz_target_1.rs
当你的代码以库 crate 的形式组织时,cargo-fuzz 的效果最佳。如果你的项目是二进制项目,请将
main.rs
拆分为:
text
src/main.rs  # 入口点(main 函数)
src/lib.rs   # 要进行模糊测试的代码(公开函数)
Cargo.toml
初始化模糊测试:
bash
cargo fuzz init
这会创建如下结构:
text
fuzz/
├── Cargo.toml
└── fuzz_targets/
    └── fuzz_target_1.rs

Harness 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

测试逻辑编写规则

DoDon't
Structure code as library crateKeep everything in main.rs
Use
fuzz_target!
macro
Write custom main function
Handle
Result::Err
gracefully
Panic on expected errors
Keep harness deterministicUse random number generators
See Also: For detailed harness writing techniques and structure-aware fuzzing with the
arbitrary
crate, see the fuzz-harness-writing technique skill.
建议做法不建议做法
将代码组织为库 crate所有代码都放在 main.rs 中
使用
fuzz_target!
编写自定义 main 函数
优雅处理
Result::Err
在预期错误时触发 panic
保持测试逻辑的确定性使用随机数生成器
另请参阅: 如需详细的测试逻辑编写技巧和使用
arbitrary
crate 的结构化模糊测试,请查看 fuzz-harness-writing 技术文档。

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.toml
:
toml
[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.toml
中添加依赖:
toml
[dependencies]
arbitrary = { version = "1", features = ["derive"] }

Running Campaigns

运行模糊测试任务

Basic Run

基础运行

bash
cargo +nightly fuzz run fuzz_target_1
bash
cargo +nightly fuzz run fuzz_target_1

Without 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_1
Check 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 geiger

Re-executing Test Cases

重新执行测试用例

bash
undefined
bash
undefined

Run 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
undefined
cargo +nightly fuzz run fuzz_target_1 fuzz/corpus/fuzz_target_1 -- -runs=0
undefined

Using Dictionaries

使用字典

bash
cargo +nightly fuzz run fuzz_target_1 -- -dict=./dict.dict
bash
cargo +nightly fuzz run fuzz_target_1 -- -dict=./dict.dict

Interpreting Output

输出解读

OutputMeaning
NEW
New coverage-increasing input discovered
pulse
Periodic status update
INITED
Fuzzer initialized successfully
Crash with stack traceBug found, saved to
fuzz/artifacts/
Corpus location:
fuzz/corpus/fuzz_target_1/
Crashes location:
fuzz/artifacts/fuzz_target_1/
输出内容含义
NEW
发现了能提升代码覆盖率的新输入
pulse
定期状态更新
INITED
模糊测试工具初始化成功
带有堆栈跟踪的崩溃信息发现 bug,已保存到
fuzz/artifacts/
语料库位置:
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_1
ASan 默认启用,用于检测内存错误:
bash
cargo +nightly fuzz run fuzz_target_1

Disabling Sanitizers

禁用 Sanitizer

For pure safe Rust (no unsafe blocks in your code or dependencies):
bash
cargo +nightly fuzz run --sanitizer none fuzz_target_1
Performance 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 geiger
See 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 rustfilt
bash
rustup toolchain install nightly --component llvm-tools-preview
cargo install cargo-binutils
cargo install rustfilt

Generating Coverage Reports

生成覆盖率报告

bash
undefined
bash
undefined

Generate 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_html
Generate HTML report:
bash
./generate_html fuzz_target_1 src/lib.rs
HTML 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.rs
HTML 报告保存位置:
fuzz_html/
另请参阅: 如需详细的覆盖率分析技巧和系统性提升覆盖率的方法,请查看 coverage-analysis 技术文档。

Advanced Usage

高级用法

Tips and Tricks

技巧与窍门

TipWhy It Helps
Start with a seed corpusDramatically speeds up initial coverage discovery
Use
--sanitizer none
for safe Rust
2x performance improvement
Check coverage regularlyIdentifies gaps in harness or seed corpus
Use dictionaries for parsersHelps overcome magic value checks
Structure code as libraryRequired for cargo-fuzz integration
技巧优势
从种子语料库开始大幅加快初始覆盖率的发现速度
对于安全 Rust 代码使用
--sanitizer none
性能提升 2 倍
定期检查覆盖率识别测试逻辑或种子语料库中的不足
为解析器使用字典帮助突破魔术值检查
将代码组织为库是 cargo-fuzz 集成的必要条件

libFuzzer Options

libFuzzer 选项

Pass options to libFuzzer after
--
:
bash
undefined
--
之后向 libFuzzer 传递选项:
bash
undefined

See 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
undefined
cargo +nightly fuzz run fuzz_target_1 -- -max_len=1024
undefined

Multi-Core Fuzzing

多核模糊测试

bash
undefined
bash
undefined

Experimental 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
undefined
ogg crate 用于解析 Ogg 媒体容器文件。解析器是极佳的模糊测试目标,因为它们要处理不受信任的数据。
bash
undefined

Clone 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.ogg
Run:
bash
cargo +nightly fuzz run fuzz_target_1
Analyze coverage:
bash
cargo +nightly fuzz coverage fuzz_target_1
./generate_html fuzz_target_1 src/lib.rs
git 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.rs

Troubleshooting

故障排除

ProblemCauseSolution
"requires nightly" errorUsing stable toolchainUse
cargo +nightly fuzz
Slow fuzzing performanceASan enabled for safe RustAdd
--sanitizer none
flag
"cannot find binary"No library crateMove code from
main.rs
to
lib.rs
Sanitizer compilation issuesWrong nightly versionTry different nightly:
rustup install nightly-2024-01-01
Low coverageMissing seed corpusAdd sample inputs to
fuzz/corpus/fuzz_target_1/
Magic value not foundNo dictionaryCreate dictionary file with magic values
问题原因解决方案
"requires nightly" 错误使用了稳定版工具链使用
cargo +nightly fuzz
模糊测试性能缓慢为安全 Rust 代码启用了 ASan添加
--sanitizer none
标志
"cannot find binary"没有库 crate将代码从
main.rs
移至
lib.rs
Sanitizer 编译问题Nightly 版本不兼容尝试其他 nightly 版本:
rustup install nightly-2024-01-01
覆盖率低缺少种子语料库
fuzz/corpus/fuzz_target_1/
添加示例输入
未找到魔术值没有使用字典创建包含魔术值的字典文件

Related Skills

相关技术

Technique Skills

技术技巧

SkillUse Case
fuzz-harness-writingStructure-aware fuzzing with
arbitrary
crate
address-sanitizerUnderstanding ASan output and configuration
coverage-analysisMeasuring and improving fuzzing effectiveness
fuzzing-corpusBuilding and managing seed corpora
fuzzing-dictionariesCreating dictionaries for format-aware fuzzing
技术适用场景
fuzz-harness-writing使用
arbitrary
crate 进行结构化模糊测试
address-sanitizer理解 ASan 输出和配置
coverage-analysis衡量并提升模糊测试的有效性
fuzzing-corpus构建和管理种子语料库
fuzzing-dictionaries创建用于格式感知模糊测试的字典

Related Fuzzers

相关模糊测试工具

SkillWhen to Consider
libfuzzerFuzzing C/C++ code with similar workflow
aflppMulti-core fuzzing or non-Cargo Rust projects
libaflAdvanced 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 的源代码、问题追踪器和示例。