What it does
dev-fuzz wraps cargo-fuzz
(libFuzzer-based) and emits findings as a
dev-report::Report. Each finding
carries the reproducer path that triggered it as
Evidence::FileRef, so the input can be replayed and debugged.
What is fuzzing?
Fuzzing feeds random or guided-random inputs to your code looking for crashes, panics, or unexpected behavior. It's the standard tool for:
- Parsers
- Deserializers
- Network protocol handlers
- Anything that takes untrusted bytes
A typical fuzz session runs for minutes to hours and feeds billions of inputs through the target.
Quick start
[]
= "0.9"
One-time tool install:
Drive it from code:
use ;
use Duration;
let run = new
.budget;
let result = run.execute?;
let report = result.into_report;
println!;
# Ok::
Builder surface
| Method | What it does |
|---|---|
budget(FuzzBudget) |
Time- or executions-based budget. Default: 60s wall-clock. |
in_dir(path) |
Run cargo fuzz from a different directory. |
sanitizer(Sanitizer) |
Pick Address / Leak / Memory / Thread / None. Default Address. |
timeout_per_iter(Duration) |
libFuzzer's -timeout=<secs>. |
rss_limit_mb(u32) |
libFuzzer's -rss_limit_mb=<N>. |
allow(name) / allow_all(iter) |
Suppress findings whose reproducer basename matches. |
Budget types
FuzzBudget |
Maps to libFuzzer flag |
|---|---|
time(Duration) |
-max_total_time=<secs> |
executions(u64) |
-runs=<N> |
Severity policy
FuzzFindingKind |
dev-report::Severity |
CheckResult verdict |
|---|---|---|
Crash |
Critical |
Fail |
OutOfMemory |
Error |
Fail |
Timeout |
Warning |
Fail |
Each finding emits a CheckResult named
fuzz::<target>::<kind-label> (e.g. fuzz::parse_input::crash),
tagged fuzz plus the kind label (crash / timeout / oom).
The reproducer path rides along as Evidence::FileRef with the label
"reproducer".
Allow-listing known false positives
use ;
use Duration;
let run = new
.budget
.allow
.allow_all;
let _result = run.execute?;
# Ok::
Matches are on the basename of the reproducer path (the final
component, typically crash-<hex> or timeout-<hex>).
Producer integration
FuzzProducer plugs the fuzz target into a multi-producer pipeline
driven by dev-tools:
use ;
use Producer;
use Duration;
let producer = new;
let report = producer.produce;
println!;
Subprocess failures (missing tool, missing nightly, target not found,
libFuzzer harness error) map to a single failing CheckResult named
fuzz::<target> with Severity::Critical — the pipeline keeps
running.
Wire format
FuzzResult, FuzzFinding, FuzzFindingKind, FuzzBudget, and
Sanitizer are all serde-derived. JSON uses snake_case field
names and lowercase enum variants:
Examples
| File | What it shows |
|---|---|
examples/basic.rs |
Default 10s budget; graceful tool-missing handling. |
examples/executions_budget.rs |
FuzzBudget::executions(N) instead of time. |
examples/with_limits.rs |
Sanitizer choice, per-iter timeout, RSS limit, allow-list. |
examples/producer.rs |
FuzzProducer (gated by DEV_FUZZ_EXAMPLE_RUN). |
Requirements
Both prerequisites must be installed:
The crate detects absence of either and surfaces a typed FuzzError
variant rather than panicking.
Runtime dependency footprint: dev-report, serde, serde_json.
Migration from 0.1.0
0.1.0 was a name-claim publish with a stub execute() returning an
empty result. Existing builder calls (new, budget, execute,
into_report) keep their signatures and behavior. New builder
methods (in_dir, sanitizer, timeout_per_iter, rss_limit_mb,
allow, allow_all) are additive.
The dev-* suite
See dev-tools for the
umbrella crate covering the full suite.
Status
v0.9.x is the pre-1.0 stabilization line. The crate is
feature-complete for libFuzzer-based fuzzing (subprocess invocation,
stderr parsing, severity policy, allow-list, sanitizer choice,
producer integration). 1.0 will pin the public API and the wire
format.
Minimum supported Rust version
1.85 for this crate. The user's fuzz targets require nightly
Rust because libFuzzer instrumentation is nightly-only — that's a
property of cargo-fuzz, not dev-fuzz.
License
Apache-2.0. See LICENSE.