# Fuzze.rs

> Managed AFL++, libFuzzer, Centipede, and Honggfuzz infrastructure for security teams.

## What Fuzze.rs is

Fuzze.rs is a commercial managed fuzzing platform. Customers push a Dockerfile and a libFuzzer/AFL++ harness; we operate the fuzzer fleet, schedule jobs on dedicated compute, deduplicate crashes by stack trace, and surface coverage + executions-per-second trends in a private per-account dashboard. Three plans: Starter at $179/month (8 CPU cores, 32 GB RAM), Professional at $349/month (16 cores, 64 GB), Enterprise (custom, 240+ cores). First month 50% off on Starter and Professional. Plans are month-to-month with no usage limits on crash count or fuzzing-job count.

## Architecture

- Customers supply: a libFuzzer or AFL++ harness, a Dockerfile that builds it with appropriate sanitizer flags, an optional seed corpus.
- We run: jobs in isolated containers on cloud compute sized to your plan tier; coverage and crash data streamed to your dashboard.
- We do not see: customer source code beyond what the harness encodes; crash data is never published or shared.
- Crash deduplication uses stack-trace fingerprints; minimised reproducers are downloadable per crash.

## Supported fuzzers

AFL++, libFuzzer, Honggfuzz, Centipede are all first-class — same plan, any engine, switchable per job. Power Fuzzing runs multiple engines against the same target in parallel for broader coverage diversity.


## Use Cases

### Fuzzing Rust
URL: https://fuzze.rs/use-cases/fuzzing-rust

Rust's memory safety doesn't cover logic bugs, panics, or unsafe blocks. Fuzze.rs runs continuous libFuzzer and AFL++ campaigns against your crates with zero infrastructure work.

Rust catches a huge class of memory-safety bugs at compile time — but fuzzing remains the highest-yield way to find the bugs the borrow checker can't see. Panics on attacker-controlled input, logic bugs in parsers and state machines, and the genuine vulnerabilities hiding inside `unsafe` blocks are exactly what coverage-guided fuzzing surfaces fastest.

Fuzze.rs runs libFuzzer (via cargo-fuzz) and AFL++ (via afl.rs) as managed campaigns against your Rust targets. Push a Dockerfile, point us at your fuzz target, and crashes start landing in the dashboard within hours.

Why it matters:
- Catches panics on attacker-controlled input: Rust's `unwrap()` and array-index panics are denial-of-service primitives in any server handling user data. cargo-fuzz finds them fast.
- Audits every `unsafe` block: Memory-safety bugs in `unsafe` blocks fuzz exactly like C/C++. Coverage-guided campaigns reach paths your unit tests don't.
- Validates parsers, codecs, and protocols: The classic libFuzzer wheelhouse. Anything that takes a `&[u8]` and produces structured output is a natural target.
- Runs continuously, not just on PR: Real Rust bugs surface after millions of executions. Continuous campaigns find what one-shot CI runs miss.

Workflow:
1. Write a libFuzzer harness — Use cargo-fuzz init / cargo-fuzz add target_name to scaffold a #[fuzz_target] entry point that consumes &[u8].
2. Build the Docker image — Standard rust:slim base + cargo install cargo-fuzz. We supply a starter Dockerfile in the docs.
3. Push and start a job — Either via the Fuzze.rs dashboard or POST /api/jobs/start. Optional seed corpus uploaded alongside.
4. Watch coverage climb — Branch coverage and execs/sec stream live. Most crates plateau in 6-24 hours.
5. Triage crashes — Stack-trace-based deduplication. Minimised reproducers downloadable per crash.
6. Wire into CI — POST a short fuzz run from your CI pipeline on every PR; a failing crash blocks merge.

Recommended fuzzers:
- libFuzzer (via cargo-fuzz) — the default for Rust. Tight feedback loop, fast iteration, in-process.
- AFL++ (via afl.rs) — strong on stateful targets and where libFuzzer's persistent-mode constraints hurt.
- Power Fuzzing — run both engines against the same target in parallel for broader coverage.

### Fuzzing C/C++
URL: https://fuzze.rs/use-cases/fuzzing-c-cpp

C and C++ memory bugs are still the #1 source of exploitable CVEs. Fuzze.rs runs AFL++ and libFuzzer campaigns with ASan, UBSan, and MSan against your codebase — fully managed.

Memory-safety bugs in C and C++ are still the dominant source of exploitable vulnerabilities. CVEs in widely-deployed codebases are still being found at a steady rate — most by fuzzers, not by manual code review.

Fuzze.rs runs AFL++, libFuzzer, Honggfuzz, and Centipede campaigns against your C and C++ targets with sanitizer combinations (ASan, UBSan, MSan) configured per job. The same harness you'd run locally on a laptop runs continuously against persistent corpora on dedicated compute.

Why it matters:
- Finds use-after-free, OOB, double-free: ASan catches the entire memory-corruption class in seconds once the fuzzer hits the path. UBSan adds integer overflow and signed-shift bugs.
- Multi-sanitizer campaigns: One job per sanitizer combination (ASan, UBSan, MSan, TSan). Same harness, broader bug class.
- Power Fuzzing for stubborn targets: Run AFL++, libFuzzer, Honggfuzz, and Centipede against the same harness in parallel — corpus shared, coverage merged.
- Persistent corpora across runs: Coverage gains accumulate. A 24-hour run picks up where the last one left off, not from scratch.

Workflow:
1. Write a libFuzzer or AFL++ harness — Standard LLVMFuzzerTestOneInput(const uint8_t *data, size_t size). One harness per parsing entry-point usually wins.
2. Pick your sanitizers — ASan + UBSan is the default; add MSan for uninitialised-memory bugs.
3. Build the Docker image — clang or gcc with -fsanitize=fuzzer plus sanitizer flags. Docs ship a working starter Dockerfile.
4. Submit the job — Via dashboard or REST API. Optional seed corpus and dictionary alongside.
5. Triage crashes — Stack-trace-based deduplication, minimised reproducers, sanitizer report in each crash.
6. CI integration — Short fuzz runs on every PR via our REST API; long campaigns on a schedule.

Recommended fuzzers:
- AFL++ — the workhorse. Strong on stateful and binary-format targets.
- libFuzzer — fastest feedback loop for in-process harnesses.
- Honggfuzz — strong on signal-handler and persistent-mode targets.
- Centipede — handles large inputs and complex coverage signals better than the others.

### Fuzzing Embedded Firmware
URL: https://fuzze.rs/use-cases/fuzzing-embedded

Embedded firmware is where the worst-case bugs live and the worst tooling lives. Fuzze.rs runs AFL++ and libFuzzer campaigns against unicorn-/qemu-hosted firmware targets — managed.

Embedded firmware is one of the hardest targets to fuzz well: the code runs on hardware you don't have ten copies of, the build chain is bespoke, and the standard ASan + libFuzzer combination doesn't apply. The bugs that hide there are also the most consequential — bootloaders, secure-element interfaces, network stacks running with no exploit mitigations.

Fuzze.rs runs AFL++ and libFuzzer against firmware emulated under unicorn or qemu, in a containerised environment you control. The harness drives the firmware entry point you'd reach in real boot; the fuzzer mutates the data path you care about.

Why it matters:
- Bootloader and secure-boot fuzzing: The signature-parsing and metadata-parsing paths in bootloaders are the highest-stakes attack surface on the device. Fuzzing them finds the bugs static analysis misses.
- Protocol stacks under emulation: BLE, MQTT, CoAP, Zigbee — anything taking bytes off the wire is a natural fuzz target. Emulate the radio interface and fuzz the parser.
- No hardware-fleet needed: Emulated firmware runs fast and parallel. One job pinned to qemu-system-arm gives you dozens of parallel executions where one device gives you one.
- Reproducible across job runs: Persistent corpora mean coverage compounds. The 80% coverage from week one is the starting point of week two.

Workflow:
1. Pick the emulation target — unicorn for tight CPU emulation, qemu-system for a full SoC.
2. Write the harness — Boot the firmware to the entry point you care about; feed input from a known buffer the fuzzer mutates.
3. Containerise — Standard Docker image with your cross-toolchain + emulator. Docs ship a starter for cortex-m and aarch64.
4. Run the campaign — AFL++ with QEMU mode is the default; libFuzzer when you can compile to host with sanitizers.
5. Triage and minimise — Reproducers run under the same emulator config. Single-step the failure path under gdbserver if you need to.
6. Re-run on every firmware build — Wire the campaign into your firmware CI — a new build, a fresh fuzz run.

Recommended fuzzers:
- AFL++ + QEMU mode — the most popular setup for binary-only or limited-toolchain firmware.
- libFuzzer when you can build the firmware as a host shared library with sanitizers.
- Honggfuzz for protocol stacks where its persistent mode pays off.

### Fuzzing for CVE Research
URL: https://fuzze.rs/use-cases/cve-research

Bug bounty pays in CVEs. CVEs pay best when you find them faster than the next person. Fuzze.rs gives you serious compute without standing up your own cluster.

If your day job is finding CVEs in widely-deployed open-source software, your time is better spent writing harnesses than babysitting fuzzer hosts. Fuzze.rs gives you serious dedicated compute, persistent corpora across runs, and a private dashboard where your in-progress findings stay your own.

The platform is designed for the workflow CVE hunters actually run: write a harness against the latest commit, fire it at 16-240+ cores, come back when the dashboard shows a crash, minimise the reproducer, and disclose on your own schedule.

Why it matters:
- Private until you disclose: Your crashes are yours. We don't publish, sell, or expose them. Disclose when you're ready, not when a public tracker dictates.
- 240+ cores when you need them: Enterprise plans give you the same compute scale that public clusters use. Outpace the next researcher in the same target.
- Persistent corpora: Coverage compounds across runs. The corpus from your first target attempt is the starting point for the next version's release.
- Multi-engine Power Fuzzing: Diversify mutators in a single campaign. AFL++, libFuzzer, Honggfuzz, and Centipede running against the same target widen the surface fast.

Workflow:
1. Pick a target — Anything from `apt source` to a GitHub release tag. Bring the source, we bring the cores.
2. Write a harness — libFuzzer-style entry point is the default; AFL++ persistent mode for trickier targets.
3. Build in a Dockerfile — Pin your toolchain, sanitizers, and target version. Reproducibility matters when you're disclosing.
4. Fire a long campaign — 12, 24, 72 hours. Coverage and crashes stream live; pause and resume as needed.
5. Triage in private — Stack-trace dedup, minimised reproducers, sanitizer output. All private to your account.
6. Disclose on your schedule — Coordinate with the upstream maintainer or programme. Nothing leaks unless you publish it.

Recommended fuzzers:
- AFL++ — the default for binary-format and stateful targets.
- libFuzzer — fastest iteration for in-process API fuzzing.
- Honggfuzz — strong on signal-handler-based persistent fuzzing.
- Power Fuzzing — run all four in parallel on the same harness for maximum coverage diversity.


## Comparisons

### Fuzze.rs vs OSS-Fuzz
URL: https://fuzze.rs/compare/fuzze-rs-vs-oss-fuzz

When Google's open-source fuzzing service won't take your code, Fuzze.rs picks up where it leaves off.

OSS-Fuzz is excellent — for the open-source projects it accepts. Fuzze.rs is the answer when your code is proprietary, your project hasn't been accepted, or you need fuzzing on your own schedule and infrastructure. Both run AFL++, libFuzzer, Honggfuzz, and Centipede; the differences are in eligibility, control, and reporting.

Pick Fuzze.rs when:
- Your codebase is proprietary or commercial — OSS-Fuzz only accepts open-source.
- You want crash reports inside your own dashboard, not in a public ClusterFuzz issue tracker.
- You need predictable scheduling and dedicated compute, not best-effort cluster time.
- You want a managed REST API and webhooks for CI/CD wiring without standing up your own ClusterFuzz instance.
- You don't want every fuzzing-discovered bug becoming a public issue 90 days from disclosure.

Pick OSS-Fuzz when:
- You maintain a widely-used open-source project that meets OSS-Fuzz acceptance criteria — the free compute is genuinely valuable.
- You're happy with the public-disclosure timeline (issues go public after 90 days).
- You don't need crash deduplication or coverage trends in your own UI — Google's tooling is good enough for your workflow.

FAQ:
Q: Can I use OSS-Fuzz for a private codebase?
A: No. OSS-Fuzz only accepts open-source projects that meet Google's acceptance criteria. For private codebases, Fuzze.rs is a direct alternative with the same underlying fuzzers (AFL++, libFuzzer, Honggfuzz, Centipede).

Q: Why is OSS-Fuzz free and Fuzze.rs paid?
A: OSS-Fuzz is a Google-funded public-good service. Fuzze.rs is a commercial managed service — you pay for dedicated compute, private dashboards, and predictable scheduling instead of best-effort cluster time.

Q: Does Fuzze.rs publish my crashes the way OSS-Fuzz does after 90 days?
A: No. Your crashes are private to your team. We never publish, sell, or share crash data. You control disclosure.

Q: Can I run the same fuzz target on both?
A: Yes. Both OSS-Fuzz and Fuzze.rs use the same upstream fuzzers, so a libFuzzer or AFL++ harness ports between them with minimal changes.

### Fuzze.rs vs ClusterFuzz
URL: https://fuzze.rs/compare/fuzze-rs-vs-clusterfuzz

ClusterFuzz is powerful, but operating it is its own full-time job. Fuzze.rs gives you the same outcomes without the infrastructure burden.

ClusterFuzz is the open-source backbone behind OSS-Fuzz and Chrome's fuzzing programme. Running your own ClusterFuzz cluster means standing up GCP / AWS infra, App Engine, datastore, bot pools, and ongoing maintenance. Fuzze.rs delivers the same fuzzer set with a managed dashboard and REST API — no infrastructure to operate.

Pick Fuzze.rs when:
- You don't want to maintain App Engine apps, bot worker pools, datastores, and credentials yourself.
- You need fuzzing results in days, not the weeks a self-hosted deployment takes to stabilise.
- Your team's time is better spent on fuzz harnesses and triage than on cluster operations.
- You want a single REST API to drive jobs from CI/CD, without writing your own client tooling.

Pick ClusterFuzz when:
- You have dedicated SRE / infra capacity and want full source-level control of the fuzzing platform.
- Your security posture requires every byte of fuzzing infra to live inside your own cloud account.
- You're already a Google Cloud shop and the GCP-native deployment is genuinely cheaper than a managed plan at your scale.

FAQ:
Q: Is Fuzze.rs built on top of ClusterFuzz?
A: No. Fuzze.rs runs the same upstream fuzzers (AFL++, libFuzzer, Honggfuzz, Centipede) on its own purpose-built scheduling and reporting layer. We don't depend on the ClusterFuzz codebase.

Q: Can I migrate from a self-hosted ClusterFuzz cluster to Fuzze.rs?
A: Yes. Your fuzz harnesses are portable — they're standard libFuzzer or AFL++ targets. Most teams migrate by re-pointing their CI step from their ClusterFuzz API to the Fuzze.rs REST API.

Q: What about ClusterFuzzLite for CI-only fuzzing?
A: ClusterFuzzLite is a good fit for short fuzz runs inside a CI job. Fuzze.rs covers a broader use case — continuous long-running fuzzing, scheduled campaigns, and persistent crash tracking.

### Fuzze.rs vs Self-hosted AFL++
URL: https://fuzze.rs/compare/fuzze-rs-vs-self-hosted-afl-plus-plus

AFL++ is free and excellent. Operating it at scale, with crash dedup and triage, is the work.

AFL++ itself is free — the cost is everything around it. A serious AFL++ programme needs a fuzz-job scheduler, crash deduplication, coverage tracking, persistent corpora, and triage workflow. Fuzze.rs is the same AFL++ binaries with all of that operationalised for you.

Pick Fuzze.rs when:
- You're already running afl-fuzz on a screen session and the corpus is on someone's laptop — formalise it.
- You need crash deduplication and coverage trend graphs without writing them yourself.
- You want continuous fuzzing in CI without your team running a long-lived fuzzing host.
- You want Power Fuzzing (running multiple engines against the same target) without writing the orchestration.

Pick Self-hosted AFL++ when:
- You're a researcher running short, ad-hoc fuzzing experiments on a single laptop — overhead beats value.
- Your security posture requires every fuzzer instance to live inside your own infrastructure.
- You're tuning AFL++ at the source level and need direct access to the fuzzer binary.

FAQ:
Q: Will my AFL++ harness work on Fuzze.rs?
A: Yes. We run upstream AFL++. Your harness builds the same way — supply a Dockerfile, point it at your seed corpus, and the same instrumentation works.

Q: Can I switch between AFL++ and libFuzzer mid-campaign?
A: Yes — Power Fuzzing runs both (and Centipede / Honggfuzz) against the same target in parallel, sharing the corpus.

Q: Do I lose any AFL++ features by using the managed version?
A: No — we expose all of AFL++'s standard options. Specialised mutators and custom instrumentation work the same way.


## Glossary

### Fuzz Testing
URL: https://fuzze.rs/glossary/fuzz-testing

Fuzz testing (or fuzzing) is an automated testing technique that feeds a program a large volume of generated inputs in search of crashes, hangs, and incorrect outputs. Modern fuzzers — AFL++, libFuzzer, Honggfuzz, Centipede — combine input mutation with execution-time feedback (typically branch-coverage instrumentation) to evolve inputs that progressively exercise new code paths. The technique scales: a corpus of crashes that would take a human auditor months to find can surface in hours of fuzzing. Fuzzing is most effective against parsers, codecs, protocol implementations, and any code that processes attacker-controllable byte strings. It is complementary to, not a replacement for, unit testing and static analysis.

### Coverage-Guided Fuzzing
URL: https://fuzze.rs/glossary/coverage-guided-fuzzing

Coverage-guided fuzzing uses runtime instrumentation — typically compile-time branch or edge counters — to measure which parts of the target program an input exercised. The fuzzer maintains a corpus of inputs that collectively cover discovered edges. When a mutated input causes a previously unseen edge to be hit, it is added to the corpus; inputs that don't expand coverage are discarded. This feedback loop allows the fuzzer to climb through the program's control-flow graph systematically, reaching deep parsing logic and conditional branches that purely random inputs would almost never trigger. AFL++, libFuzzer, Honggfuzz, and Centipede all implement coverage-guided strategies, though they differ in how they measure coverage, schedule mutations, and share corpora across parallel instances.

### AFL++
URL: https://fuzze.rs/glossary/afl-plus-plus

AFL++ is a fork of Michal Zalewski's AFL that incorporates years of research improvements: LLVM-based instrumentation modes (LTO, PCGUARD, classic), custom mutators via a plugin API, CmpLog to solve comparison checks, MOpt mutation scheduling, and persistent-mode for dramatically higher execution throughput. It operates by instrumenting the target at compile time, tracking branch-pair (edge) coverage via a shared-memory bitmap, and evolving a corpus of test cases that collectively maximize coverage. AFL++ supports both source-instrumented and binary-only (QEMU, Unicorn, Frida) targets. It is the default choice for file-format and protocol parsers where you can supply a small seed corpus; its parallel mode (`-M`/`-S`) allows scaling across multiple CPU cores with a shared corpus directory.

### libFuzzer
URL: https://fuzze.rs/glossary/libfuzzer

libFuzzer is an in-process fuzzing engine distributed as part of the LLVM toolchain. Rather than running the target as a separate process, libFuzzer links into the target binary and calls a `LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)` entry point in a tight loop. This eliminates process-startup overhead and enables extremely high throughput — often hundreds of thousands of executions per second. Coverage is measured via SanitizerCoverage edge counters. libFuzzer uses a value-profile mode to detect comparisons and checksums that block deeper exploration, and supports structured input via custom mutators and `LLVMFuzzerCustomMutator`. Its main limitation is single-process: crashes in the target crash the fuzzer itself, requiring a wrapper for fragile targets.

### Honggfuzz
URL: https://fuzze.rs/glossary/honggfuzz

Honggfuzz is an open-source fuzzer developed at Google, designed for robustness and correctness of coverage measurement. Unlike AFL++ and libFuzzer's software instrumentation, Honggfuzz can use hardware performance counters (Intel PT, BTS, or Linux perf) to collect branch coverage with no compile-time changes to the target. It also supports software instrumentation via SanitizerCoverage. Honggfuzz runs each fuzz iteration in a separate process by default, making it tolerant of targets that fork or use threads internally — a significant practical advantage for network daemons and complex stateful programs. It shares corpus with AFL++ and libFuzzer through a common directory format, making it a natural addition to a multi-engine fuzzing setup.

### Centipede
URL: https://fuzze.rs/glossary/centipede

Centipede is a coverage-guided fuzzer from Google, introduced as the successor to libFuzzer for large-scale distributed fuzzing. Unlike libFuzzer or AFL++, which assume local corpus directories, Centipede is architected around a central corpus database — originally Google's internal infra, but adaptable to any blob store. It uses SanitizerCoverage counters and a custom feature-based corpus pruning strategy: inputs are retained only if they provide at least one unique coverage feature not covered by any other corpus entry. This produces compact, high-value corpora. Centipede is the best-fit fuzzer when you need to distribute fuzz work across hundreds of machines with a single shared corpus, avoiding the coordination overhead of AFL++'s distributed `-S` mode.

### Corpus
URL: https://fuzze.rs/glossary/corpus

A corpus is the set of test inputs that a coverage-guided fuzzer has selected for retention based on coverage contribution. Each input in the corpus covers at least one code path not covered by any other entry, so the corpus collectively represents the fuzzer's current coverage map. As the fuzzer runs, it mutates corpus entries, and any mutation that discovers a new edge is added to the corpus. Over time the corpus grows until the fuzzer can no longer find uncovered edges — at which point it has likely explored all paths reachable with its mutation strategy. Corpus quality is critical: a good seed corpus that exercises common code paths allows the fuzzer to start from a high-coverage baseline and immediately mutate toward uncovered edges rather than building from scratch.

### Seed Corpus
URL: https://fuzze.rs/glossary/seed-corpus

A seed corpus is the set of human-curated or programmatically collected inputs used to bootstrap a fuzzer. For a fuzzer targeting a PNG decoder, good seeds are valid PNG files representing a variety of color modes, compression levels, and chunk types. For a TLS implementation, seeds might be recorded handshake transcripts. A strong seed corpus dramatically reduces the time for a fuzzer to reach deep code paths because it starts from inputs the parser already accepts, rather than spending millions of iterations constructing a parseable prefix from random bytes. Seeds must be deduplicated before use — duplicate inputs waste corpus space and skew mutation probability. Tools like `afl-cmin` and libFuzzer's `-merge=1` mode prune redundant seeds while preserving unique coverage.

### Crash Deduplication
URL: https://fuzze.rs/glossary/crash-deduplication

A fuzzing campaign against a target with one real bug may produce thousands of inputs that all trigger the same crash. Without deduplication, engineers drown in duplicate reports rather than unique bugs. Crash deduplication groups crashes by their root cause, typically by comparing sanitized stack traces: two crashes are considered duplicates if their top N stack frames match. More sophisticated approaches compare the crash address, fault type (read vs. write, stack vs. heap), or use sanitizer output like AddressSanitizer's allocation and deallocation traces to distinguish overlapping bugs. Deduplication is not a solved problem — imperfect heuristics both merge distinct bugs (undercounting) and split variants of the same bug (overcounting). A practical system errs toward splitting (showing more unique groups) and lets humans merge obvious duplicates.

### AddressSanitizer (ASan)
URL: https://fuzze.rs/glossary/address-sanitizer

AddressSanitizer (ASan) is a compile-time instrumentation tool built into LLVM and GCC that detects memory-safety errors at runtime with roughly 2x overhead. It works by replacing malloc/free with poisoned shadow memory: every allocated object is surrounded by redzone bytes, and all memory accesses are checked against the shadow map. Detected errors include heap-buffer-overflow, stack-buffer-overflow, use-after-free, use-after-return, use-after-scope, and double-free. In fuzzing, ASan is the standard companion to a coverage-guided fuzzer: it converts silent memory corruption into loud, symbolized crash reports. Without ASan, a buffer overflow that doesn't crash immediately may go undetected; with AsAN, it terminates the process with a precise error report including the allocation stack, free stack, and access address.

### UndefinedBehaviorSanitizer (UBSan)
URL: https://fuzze.rs/glossary/undefined-behavior-sanitizer

UndefinedBehaviorSanitizer (UBSan) is a compile-time instrumentation tool from LLVM/GCC that inserts runtime checks for operations with undefined behavior in C and C++. Checked categories include signed integer overflow, shift-amount violations, null pointer dereferences, misaligned pointer access, invalid enum casts, and out-of-bounds array indexing. Unlike AddressSanitizer, UBSan has very low overhead (typically 5-20%) and can be enabled in production or near-production builds. In fuzzing, UBSan catches bugs that don't directly crash the target but are exploitable or indicate logic errors — a signed overflow that quietly wraps in debug builds may corrupt a length calculation and lead to a heap overflow. UBSan is routinely combined with ASan and a coverage-guided fuzzer in the same build.

### MemorySanitizer (MSan)
URL: https://fuzze.rs/glossary/memory-sanitizer

MemorySanitizer (MSan) is an LLVM instrumentation tool that tracks every bit of memory for initialization state and reports when uninitialized bytes flow into a conditional branch or are returned to the caller. Uninitialized reads are a common source of information-disclosure vulnerabilities — reading from uninitialized stack or heap bytes can leak cryptographic material or pointer values across security boundaries. MSan carries roughly 3x overhead and requires that all linked code (including system libraries) be compiled with MSan instrumentation; linking uninstrumented libraries produces false positives. For this reason, MSan is typically used in a dedicated fuzzing environment with a fully-instrumented libc. It should not be combined in the same build as AddressSanitizer — each sanitizer requires its own build.

### Greybox Fuzzing
URL: https://fuzze.rs/glossary/greybox-fuzzing

Greybox fuzzing sits between blackbox fuzzing (no program knowledge) and whitebox fuzzing (full symbolic analysis). A greybox fuzzer instruments the target to collect lightweight runtime information — most commonly branch or edge coverage — and uses that feedback to guide mutation without modeling the program's logic explicitly. The 'grey' refers to the partial, imprecise nature of the feedback: the fuzzer observes which code paths ran, but not why. AFL++, libFuzzer, and Honggfuzz are all greybox fuzzers. This approach scales to large, complex binaries because instrumentation is cheap and the feedback loop is tight — millions of executions per second are achievable. The tradeoff is that the fuzzer cannot reason about deep semantic constraints; it can find the comparison block but may struggle to satisfy multi-byte magic values without additional hints like CmpLog or a dictionary.

### Blackbox Fuzzing
URL: https://fuzze.rs/glossary/blackbox-fuzzing

Blackbox fuzzing treats the target program as an opaque function: inputs go in, outputs (or crashes) come out, and the fuzzer has no information about code coverage, control flow, or internal state. Classic blackbox fuzzers — Peach, Boofuzz, and early radamsa-based scripts — generate inputs using only format specifications or random perturbation of sample files. Without coverage feedback, blackbox fuzzers struggle to penetrate deep code paths because there is no signal distinguishing an input that reached a new parser state from one that was rejected at the first byte. Blackbox fuzzing remains useful when instrumentation is impractical: fuzzing closed-source binaries without binary rewriting support, network protocols where responses are the only observable signal, or hardware targets where execution tracing is unavailable or prohibitively expensive.

### Whitebox Fuzzing
URL: https://fuzze.rs/glossary/whitebox-fuzzing

Whitebox fuzzing (also called smart fuzzing or SAGE-style fuzzing) uses complete program analysis — symbolic execution, concolic execution, or model checking — to systematically generate inputs that satisfy branch constraints deep in the program. A concolic engine runs the program on a concrete input while simultaneously tracking symbolic path constraints; it then negates individual constraints to produce inputs that take alternative branches. This allows whitebox fuzzers to solve multi-byte magic values, checksums, and complex conditional logic that stop greybox fuzzers. The cost is scalability: symbolic execution suffers from state explosion and requires significant compute per input. In practice, whitebox techniques are often combined with greybox fuzzing — using symbolic execution to break through blocking constraints and then handing solved inputs back to a coverage-guided corpus.

### Mutation-Based Fuzzing
URL: https://fuzze.rs/glossary/mutation-based-fuzzing

Mutation-based fuzzing starts from a set of known-valid or interesting inputs (the corpus or seed corpus) and applies transformations — bit flips, byte substitutions, block splicing, arithmetic mutations — to produce new test cases. Most modern coverage-guided fuzzers are mutation-based: AFL++ and libFuzzer both evolve a corpus by mutating its members and retaining mutations that increase coverage. The quality of the mutation engine determines what territory the fuzzer can reach: a fuzzer with only bit-flip mutations will struggle with format magic numbers, while one with a dictionary of format-specific tokens can construct valid container structures faster. Mutation-based fuzzing assumes the starting corpus exercises at least some of the target's parsing logic; for targets with no available seed inputs, generation-based fuzzing or a hybrid approach may be preferable.

### Generation-Based Fuzzing
URL: https://fuzze.rs/glossary/generation-based-fuzzing

Generation-based fuzzing constructs inputs from a formal model of the target's expected input format — a grammar, a protocol specification, or a type schema. Rather than mutating existing samples, the fuzzer synthesizes structurally valid inputs according to the model and then introduces controlled deviations or random terminal values. Tools like Peach, Boofuzz, and grammar-aware AFL++ custom mutators implement this approach. Generation-based fuzzing excels where mutation-based fuzzers stall: protocol state machines, deeply nested data formats with length fields and checksums, and targets that reject malformed inputs at the outermost parsing layer without coverage gain. The main cost is the model itself — writing an accurate grammar is manual work and becomes outdated as the protocol evolves. Hybrid approaches combine a grammar-guided generator with a coverage-guided mutation engine.

### Instrumentation
URL: https://fuzze.rs/glossary/instrumentation

Instrumentation is the mechanism by which a fuzzer observes the target's behavior during execution. At compile time, LLVM's SanitizerCoverage or AFL++'s LLVM pass inserts callbacks or inline counter increments at every edge or basic block; these fire during execution and update a shared-memory coverage bitmap the fuzzer reads after each run. Binary-only instrumentation (QEMU mode, Frida, DynamoRIO) rewrites the target at runtime without source changes, at the cost of higher overhead. Instrumentation granularity matters: basic-block coverage misses which edge was taken in a multi-way branch; edge (branch) coverage is the standard because it distinguishes which direction a conditional went. Higher-precision instrumentation — context-sensitive coverage, call-stack hashing — can improve the fuzzer's ability to distinguish functionally different paths but increases bitmap size and reduces throughput.

### Coverage
URL: https://fuzze.rs/glossary/coverage

In the context of fuzzing, coverage measures how much of the target program's code has been exercised by the current corpus. Edge (branch) coverage is the standard metric for coverage-guided fuzzers: it counts the number of unique source-edge-destination-edge pairs (branch transitions) that have been observed across all executions. Line coverage and basic-block coverage are coarser and can miss control-flow distinctions. Coverage serves two purposes in fuzzing: as the feedback signal the fuzzer uses to select and retain corpus entries, and as the progress metric a human uses to evaluate when a fuzzing campaign has likely exhausted accessible code paths. Coverage plateauing — the number of new edges discovered per day flattening out — is the primary indicator that a campaign has reached diminishing returns and that structural improvements (better seeds, dictionaries, or additional fuzzers) are needed.

### Triage
URL: https://fuzze.rs/glossary/triage

Triage is the human-and-tool process that converts raw fuzzer crashes into actionable bug reports. A typical triage workflow proceeds in stages: first, crash deduplication to collapse thousands of crash inputs into unique bugs by stack-trace signature; second, automated reproduction to confirm each crash is deterministic and record the exact sanitizer output; third, severity classification — is this a heap overflow (critical) or a null dereference in error handling (low)?; fourth, root-cause analysis to identify the vulnerable code path. AddressSanitizer output — fault type, allocation trace, free trace — is the primary artifact. Tools like `afl-tmin` and libFuzzer's `-minimize_crash=1` mode shrink crash inputs to their minimal reproducer, which makes manual root-cause analysis significantly faster. Triage backlogs are the most common operational bottleneck in mature fuzzing programmes.

### Reproducer
URL: https://fuzze.rs/glossary/reproducer

A reproducer is the smallest input that reliably causes a target program to exhibit a specific bug — a crash, a hang, or an incorrect output. Fuzzers record the crash-triggering input, but the raw crash file is often hundreds of kilobytes of mutation history; minimization tools like `afl-tmin`, `afl-cmin`, and libFuzzer's `-minimize_crash` mode iteratively reduce the input while confirming the crash persists, often producing a file of tens of bytes. A good reproducer is valuable for three reasons: it enables developers to confirm and understand the bug without running a full fuzzer; it becomes a regression test to verify that a patch actually fixes the issue; and it is the artifact shared in a vulnerability disclosure or CVE report. Reproducer quality — minimal, well-commented, deterministic — is a proxy for the overall maturity of a fuzzing program.

### Dictionary
URL: https://fuzze.rs/glossary/dictionary

A dictionary is a list of byte strings — keywords, magic numbers, delimiters, protocol constants — that the fuzzer splices into mutations to help it construct inputs that pass structural validation in the target. Without a dictionary, a fuzzer mutating a PNG file may take millions of iterations before randomly producing the four-byte `\x89PNG` magic at offset zero; with a dictionary entry for that value, it can combine the magic with mutations from the corpus immediately. AFL++ and libFuzzer both support the same dictionary file format (one quoted token per line). Dictionaries are particularly high value for text-based formats (HTML, SQL, JavaScript), binary format magic bytes, and network protocol keywords. A dictionary does not replace a good seed corpus but complements it: seeds provide structural coverage, dictionaries provide the vocabulary the fuzzer needs to construct valid variants.


## Blog index

- [Fuzzing a Rust Crate End-to-End with cargo-fuzz](https://fuzze.rs/blog/fuzzing-rust-end-to-end) (2026-06-10, Tutorial, 11 min read): A complete walkthrough: install cargo-fuzz, write a fuzz target against a real Rust crate, run it, triage a crash, minimise the reproducer, ship a fix.
- [AFL++ vs Honggfuzz — When to Pick Each](https://fuzze.rs/blog/afl-plus-plus-vs-honggfuzz) (2026-06-09, Deep Dive, 10 min read): AFL++ and Honggfuzz are both production-grade fuzzers. They optimise for different things. Architecture, mutators, persistent mode, and how to choose.
- [Reading ASan, UBSan, and MSan Crash Reports — A Field Guide](https://fuzze.rs/blog/reading-sanitizer-output) (2026-06-08, Deep Dive, 12 min read): How to decode AddressSanitizer, UndefinedBehaviorSanitizer, and MemorySanitizer crash reports from a fuzzer. Stack traces, shadow memory, false positives.
- [Your First Fuzz Job on Fuzze.rs: From Zero to a Real Crash](https://fuzze.rs/blog/first-fuzz-job) (2026-05-17, Tutorial, 8 min read): Submit your first fuzzing job on Fuzze.rs: a tiny deliberately-buggy target, a six-line Dockerfile, and a short JSON config — explained line by line.
- [How to Add Continuous Fuzzing to Your CI/CD Pipeline](https://fuzze.rs/blog/continuous-fuzzing-cicd-pipeline) (2026-02-22, DevSecOps, 11 min read): How to wire AFL++ and libFuzzer into GitHub Actions, GitLab CI, and other CI/CD pipelines — with real configuration examples you can copy and run.
- [libFuzzer vs AFL++: Choosing the Right Fuzzer for Your Project](https://fuzze.rs/blog/libfuzzer-vs-afl-plus-plus) (2026-02-18, Deep Dive, 9 min read): libFuzzer vs AFL++: how the two leading coverage-guided fuzzers differ in architecture, speed, ease of use, and which to pick for your target.
- [AFL++ Tutorial: Getting Started with Coverage-Guided Fuzzing](https://fuzze.rs/blog/afl-plus-plus-getting-started) (2026-02-14, Tutorial, 10 min read): A hands-on AFL++ guide: instrument your target, build a starter corpus, tune for executions-per-second, and triage the first crashes that land.
- [What Is Fuzz Testing? A Developer's Guide to Finding Hidden Bugs](https://fuzze.rs/blog/what-is-fuzz-testing) (2026-02-10, Fundamentals, 8 min read): Fuzz testing generates millions of random inputs to find crashes and security bugs your unit tests miss. Here's how it works and when to use it.