fuzzing
Fuzzing skill for automated input-driven bug finding in C/C++. Use when setting up libFuzzer or AFL++ fuzz targets, defining fuzz entry points around parsing or I/O boundaries, integrating fuzzing into CI, managing corpora, or combining fuzzing with sanitizers. Activates on queries about libFuzzer, AFL, afl-fuzz, fuzz targets, corpus management, coverage-guided fuzzing, or OSS-Fuzz integration.
How do I install this agent skill?
npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill fuzzingIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill is a comprehensive educational resource for C/C++, Python, and Zig fuzzing. It provides legitimate instructions for setting up libFuzzer, AFL++, and Google's Atheris, referencing official documentation from trusted sources.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
- Runlayerwarn
2/2 files flagged
What does this agent skill do?
Fuzzing
Purpose
Guide agents through setting up and running coverage-guided fuzz testing: libFuzzer (in-process) and AFL++ (fork-based), with sanitizer integration and CI pipeline setup.
Triggers
- "How do I fuzz-test my parser/deserializer?"
- "What is a fuzz target / how do I write one?"
- "How do I set up libFuzzer?"
- "How do I use AFL++ on my program?"
- "How do I run fuzzing in CI?"
- "Fuzzer found a crash — how do I reproduce it?"
Workflow
1. Write a fuzz target (libFuzzer)
A fuzz target is a function that accepts arbitrary bytes and exercises the code under test.
// fuzz_parser.c
#include <stdint.h>
#include <stddef.h>
#include "myparser.h"
// Entry point called by libFuzzer with random data
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Must not abort/exit on invalid input (that's expected)
// Must not read outside [data, data+size)
MyParser *p = parser_create();
if (p) {
parser_feed(p, (const char *)data, size);
parser_destroy(p);
}
return 0; // Always return 0 (non-zero means discard input)
}
Key rules:
- Never call
abort(),exit(), or use global state that persists across calls - Handle all inputs gracefully (crash = bug found)
- Keep the target fast: the fuzzer calls it millions of times
2. Build with libFuzzer
# Clang (libFuzzer is built into Clang)
clang -fsanitize=fuzzer,address -g -O1 \
fuzz_parser.c myparser.c -o fuzz_parser
# With UBSan too
clang -fsanitize=fuzzer,address,undefined -g -O1 \
fuzz_parser.c myparser.c -o fuzz_parser
-fsanitize=fuzzer links libFuzzer and provides main(). Do not provide your own main() in the fuzz target.
3. Run libFuzzer
# Create corpus directory
mkdir -p corpus
# Seed with known-good inputs (greatly accelerates coverage)
cp tests/inputs/* corpus/
# Run the fuzzer
./fuzz_parser corpus/ -max_len=65536 -timeout=10
# Run for a time limit
./fuzz_parser corpus/ -max_total_time=3600
# Run with specific number of jobs (parallel)
./fuzz_parser corpus/ -jobs=4 -workers=4
# Minimise a corpus (remove redundant inputs)
./fuzz_parser -merge=1 corpus_min/ corpus/
Common flags:
| Flag | Default | Effect |
|---|---|---|
-max_len=N | 4096 | Max input size in bytes |
-timeout=N | 1200 | Kill if single run takes > N seconds |
-max_total_time=N | 0 (forever) | Total fuzzing time |
-runs=N | -1 (infinite) | Total number of runs |
-dict=file | none | Dictionary of interesting tokens |
-jobs=N | 1 | Parallel jobs (each writes its own log) |
-merge=1 | off | Merge mode: minimise corpus |
4. Reproduce a crash
libFuzzer writes crash inputs to files named crash-<hash>, oom-<hash>, timeout-<hash>.
# Reproduce
./fuzz_parser crash-abc123
# Debug with GDB
gdb ./fuzz_parser
(gdb) run crash-abc123
5. AFL++ setup
AFL++ is a fork-based fuzzer that works on arbitrary programs (not just those with a fuzz entry point).
# Install
apt install afl++ # or build from source
# Instrument the target
CC=afl-clang-fast CXX=afl-clang-fast++ \
cmake -S . -B build-afl -DCMAKE_BUILD_TYPE=Debug
cmake --build build-afl
# Or compile directly
afl-clang-fast -g -O1 -o prog_afl main.c myparser.c
# Create input corpus
mkdir -p afl-input afl-output
echo "hello" > afl-input/seed1
# Run
afl-fuzz -i afl-input -o afl-output -- ./prog_afl @@
# @@ is replaced with the input file path
# For stdin-based programs: remove @@
afl-fuzz -i afl-input -o afl-output -- ./prog_afl
6. AFL++ with persistent mode (faster)
Persistent mode avoids fork() per input — much faster for library fuzzing:
// In your harness:
#include "myparser.h"
int main(int argc, char **argv) {
while (__AFL_LOOP(1000)) {
// Read input
unsigned char *buf = NULL;
ssize_t len = read(0, &buf, MAX_SIZE); // or use afl_custom_mutator
parser_feed((char*)buf, len);
free(buf);
}
return 0;
}
7. Corpus management
# AFL++ corpus minimisation
afl-cmin -i afl-output/default/queue -o corpus_min -- ./prog_afl @@
# Merge libFuzzer corpora from multiple runs
./fuzz_parser -merge=1 merged_corpus/ run1_corpus/ run2_corpus/
# Show coverage (libFuzzer)
./fuzz_parser corpus/ -runs=0 -print_coverage=1
8. CI integration
# GitHub Actions example
- name: Build fuzz targets
run: |
clang -fsanitize=fuzzer,address,undefined -g -O1 \
fuzz_parser.c myparser.c -o fuzz_parser
- name: Short fuzz run (regression check)
run: |
./fuzz_parser corpus/ -max_total_time=60 -error_exitcode=1
# Also run known crash inputs if any:
ls known_crashes/ 2>/dev/null | xargs -I{} ./fuzz_parser known_crashes/{}
For long-duration fuzzing, use OSS-Fuzz or ClusterFuzz infrastructure.
9. Structure-aware fuzzing (libFuzzer)
// Custom mutator hook — preserve format invariants
size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
size_t MaxSize, unsigned int Seed) {
// Delegate to default mutator then fix up structure
Size = LLVMFuzzerMutate(Data, Size, MaxSize);
if (Size >= 4)
fix_checksum(Data, Size);
return Size;
}
// Register custom crossover for structured inputs
extern "C" size_t LLVMFuzzerCustomCrossOver(
const uint8_t *Data1, size_t Size1,
const uint8_t *Data2, size_t Size2,
uint8_t *Out, size_t MaxOutSize, unsigned int Seed);
Use when naive bit-flipping breaks checksums/headers before reaching deep code paths.
10. Atheris (Python fuzzing)
import atheris
import sys
with atheris.instrument_imports():
import myparser
def TestOneInput(data: bytes) -> None:
fdp = atheris.FuzzedDataProvider(data)
try:
myparser.parse(fdp.ConsumeString(sys.maxsize))
except myparser.ParseError:
pass
if __name__ == "__main__":
atheris.Setup(sys.argv, TestOneInput)
atheris.Fuzz()
pip install atheris
python fuzz_myparser.py corpus/ -max_total_time=300
11. Dataflow tracing
# Track tainted bytes through execution (LLVM dataflow sanitizer + libFuzzer)
clang -fsanitize=fuzzer,dataflow -g -O1 fuzz.c target.c -o fuzz
LIBFUZZER_DATAFLOW_TRACE=1 ./fuzz corpus/
Produces traces showing which input bytes influenced branches — guides dictionary and structure-aware mutators.
12. OSS-Fuzz integration
OSS-Fuzz workflow
├── Add project/ in google/oss-fuzz repo (Dockerfile + build.sh)
├── Fuzz targets linked with -fsanitize=fuzzer,address
├── ClusterFuzz runs continuously on GCE
└── Crash reproducers uploaded to issue tracker
# project/Dockerfile (minimal)
FROM gcr.io/oss-fuzz-base/base-builder
RUN git clone --depth 1 https://github.com/you/yourproject
WORKDIR yourproject
COPY build.sh $SRC/
# Local OSS-Fuzz repro
python infra/helper.py build_image yourproject
python infra/helper.py build_fuzzers yourproject
python infra/helper.py run_fuzzer yourproject fuzz_target
13. Zig fuzz testing
# Zig 0.11+ built-in fuzzing
zig build test --fuzz
# fuzz target in build.zig
# .root_module.fuzz_tests = &.{
# .{ .name = "parser", .path = "src/fuzz/parser.zig" },
# };
Zig fuzz integrates with zig test and sanitizer builds for native targets.
14. Dictionary files
Dictionaries contain interesting tokens to guide mutation:
# parser.dict
kw1="<"
kw2=">"
kw3="</"
kw4='="'
kw5="\x00"
kw6="\xff\xfe"
./fuzz_parser corpus/ -dict=parser.dict
References
For fuzz target templates, corpus seed examples, and OSS-Fuzz integration guidance, see references/targets.md.
Related skills
- Use
skills/runtimes/sanitizersto add ASan/UBSan to fuzz builds - Use
skills/compilers/clangfor Clang-specific libFuzzer flags - Use
skills/debuggers/gdbto debug crash inputs found by the fuzzer - Use
skills/zig/zig-testingfor Zigbuild test --fuzzworkflows - Use
skills/security/kernel-securityfor kernel fuzzing with syzkaller
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/mohitmishra786/low-level-dev-skills/fuzzing">View fuzzing on skillZs</a>