cargo-fuzz
Contract
| Field | Bound contract |
|---|---|
| Trigger | User needs to initialize, run, measure, or triage a cargo-fuzz target in a Rust crate. |
| Authority | Reversible local: writes only the fuzz/ workspace, corpus, artifact, and coverage output directories under the target crate, plus src/ edits needed to expose a library target (e.g., moving code from src/main.rs to src/lib.rs) and nightly toolchain and cargo-fuzz installation via rustup and cargo install; rollback is removing fuzz/, reverting src/ edits, and uninstalling the added toolchain or tool. No remote mutation. |
| Side effect | Creates and mutates Rust fuzz targets, corpus files, crash artifacts, coverage reports, and src/ layout on the local filesystem. Installs nightly Rust and cargo-fuzz if absent. No remote, credential, or VCS mutation. |
| Done | The named cargo-fuzz target runs under the intended sanitizer and reproduces any selected artifact. |
Inputs
- Target crate path (required): the Cargo crate to fuzz, containing a library target.
- Fuzz target name (required for run/coverage/triage; generated by
init): the name underfuzz/fuzz_targets/. - Sanitizer choice (optional, default
address): one ofaddress,thread,memory,none. Usenoneonly for pure safe Rust with no unsafe in the dependency tree. - Crash artifact path (optional, for triage): a file under
fuzz/artifacts/<target>/. - Source filter (optional, for coverage): one or more
src/*.rspaths to scope the HTML report, loaded into theSRC_FILTERarray.
Procedure
- Install the nightly toolchain and cargo-fuzz with
rustup install nightlyandcargo install cargo-fuzz. Confirm both are installed withcargo +nightly --versionandcargo fuzz --version. cargo-fuzz requires nightly because it relies on unstable compiler features and libFuzzer integration. Done when: nightly and cargo-fuzz are installed and confirmed. - Ensure the target crate exposes a library target. If the project is binary-only, move reusable code from
src/main.rsintosrc/lib.rsso the fuzz harness can call it. Done when: the crate exposes a library target. - Initialize the fuzz workspace:
cargo fuzz init. This createsfuzz/Cargo.tomlandfuzz/fuzz_targets/fuzz_target_1.rs. Done when: the fuzz workspace is initialized. - Write the harness in the generated fuzz target file using the
fuzz_target!macro with#![no_main]:
Handle#![no_main] use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { your_project::target_function(data); });Result::Errgracefully inside the harness, and keep the harness deterministic with no RNG. For structure-aware fuzzing, deriveArbitraryon a type in the library crate (#[derive(Debug, Arbitrary)]) and addarbitrary = { version = "1", features = ["derive"] }to the libraryCargo.toml. Use that type as thefuzz_target!parameter instead of&[u8]. Done when: the harness is written with deterministic behavior and graceful error handling. - Run the campaign:
cargo +nightly fuzz run <target>. AddressSanitizer is enabled by default. To disable it for pure safe Rust, first verify no unsafe code withcargo install cargo-geiger && cargo geiger, then runcargo +nightly fuzz run --sanitizer none <target>for approximately 2x throughput. Done when: the campaign is running or completed under the chosen sanitizer. - Reproduce a crash artifact:
cargo +nightly fuzz run <target> fuzz/artifacts/<target>/crash-<hash>. To replay the full corpus without fuzzing:cargo +nightly fuzz run <target> fuzz/corpus/<target> -- -runs=0. Pass libFuzzer options after--(e.g.-timeout=10,-max_len=1024,-dict=dict.dict). Done when: the artifact is reproduced or the corpus is replayed. - Measure coverage: install
rustup toolchain install nightly --component llvm-tools-preview,cargo install cargo-binutils, andcargo install rustfilt. Runcargo +nightly fuzz coverage <target>. Generate the HTML report:
LeaveHOST=$(rustc -vV | sed -n 's|host: ||p') cargo +nightly cov -- show -Xdemangler=rustfilt \ "target/$HOST/coverage/$HOST/release/<target>" \ -instr-profile="fuzz/coverage/<target>/coverage.profdata" \ -show-line-counts-or-regions -show-instantiations \ -format=html -o fuzz_html/ ${SRC_FILTER[@]+"${SRC_FILTER[@]}"}SRC_FILTERunset when no source filter is supplied. Done when: the HTML coverage report is generated underfuzz_html/.
Failure and recovery
- "requires nightly" error: the stable toolchain was selected. Re-run with
cargo +nightly fuzz. - Sanitizer compilation failure: the installed nightly is incompatible. Pin a dated nightly with
rustup install nightly-<YYYY-MM-DD>and re-run. - "cannot find binary": the crate has no library target. Move code from
main.rsintolib.rsand re-runcargo fuzz init. - Low coverage: the seed corpus is empty or sparse. Add representative sample inputs to
fuzz/corpus/<target>/. - Magic value not reached: supply a dictionary file with
-dict=<file>. - Partial-result rule: a crash artifact must be reproduced by re-running the target against it before reporting it as a terminal finding. If reproduction fails, classify the artifact as nondeterministic rather than confirmed. Do not stop on an unreproduced artifact.
- Rollback: mutations cover
fuzz/,target/,fuzz_html/,src/edits to expose a library target, and toolchain installation. Removefuzz/to revert initialization; deletefuzz/corpus/<target>/,fuzz/artifacts/<target>/, orfuzz/coverage/to revert a single phase. Revertsrc/edits by restoring the original file layout. Uninstall the nightly toolchain or cargo-fuzz withrustup toolchain uninstall nightlyorcargo uninstall cargo-fuzzif they were installed by this skill.
Output
A running or completed fuzz campaign under the chosen sanitizer, a corpus under fuzz/corpus/<target>/, any crash artifacts under fuzz/artifacts/<target>/ (each reproducible by re-running the target against the artifact path), and optionally an HTML coverage report under fuzz_html/.