Fuzzing

mohitmishra786/low-level-dev-skills/skills/runtimes/fuzzing

by mohitmishra786bdc58472fa9fNo license253 starsListed Oct 9, 2026Updated Oct 9, 2026Repository updated 3 months ago

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.

AI-generated overview

Guides setting up coverage-guided fuzz testing with libFuzzer, AFL++, Atheris and OSS-Fuzz for C/C++ and Python targets.

What it does
This skill walks an agent through writing fuzz targets, building them with sanitizers, running and reproducing crashes, managing corpora, and integrating fuzzing into CI. It covers libFuzzer, AFL++ (including persistent mode), Atheris for Python, structure-aware mutators, dictionary files, dataflow tracing, and OSS-Fuzz integration. It produces instructions and code templates rather than executable scripts.
When to use it
Use it when setting up or running fuzz testing for parsers, deserializers, or other input-driven code. It also fits questions about fuzz entry points, corpus management, sanitizer builds, or reproducing a fuzzer-found crash.
Requirements
Requires a C/C++ toolchain with Clang (libFuzzer and sanitizers) or AFL++ installed, and optionally Python with the atheris package, Zig, GDB, and access to OSS-Fuzz infrastructure. Ships no scripts; it is instructions only, with a reference document.

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.

c
// fuzz_parser.c#include <stdint.h>#include <stddef.h>#include "myparser.h"
// Entry point called by libFuzzer with random dataint 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

bash
# Clang (libFuzzer is built into Clang)clang -fsanitize=fuzzer,address -g -O1 \    fuzz_parser.c myparser.c -o fuzz_parser
# With UBSan tooclang -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

bash
# Create corpus directorymkdir -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:

FlagDefaultEffect
-max_len=N4096Max input size in bytes
-timeout=N1200Kill if single run takes > N seconds
-max_total_time=N0 (forever)Total fuzzing time
-runs=N-1 (infinite)Total number of runs
-dict=filenoneDictionary of interesting tokens
-jobs=N1Parallel jobs (each writes its own log)
-merge=1offMerge mode: minimise corpus

4. Reproduce a crash

libFuzzer writes crash inputs to files named crash-<hash>, oom-<hash>, timeout-<hash>.

bash
# Reproduce./fuzz_parser crash-abc123
# Debug with GDBgdb ./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).

bash
# Installapt install afl++     # or build from source
# Instrument the targetCC=afl-clang-fast CXX=afl-clang-fast++ \  cmake -S . -B build-afl -DCMAKE_BUILD_TYPE=Debugcmake --build build-afl
# Or compile directlyafl-clang-fast -g -O1 -o prog_afl main.c myparser.c
# Create input corpusmkdir -p afl-input afl-outputecho "hello" > afl-input/seed1
# Runafl-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:

c
// 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

bash
# AFL++ corpus minimisationafl-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

yaml
# 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)

c
// Custom mutator hook — preserve format invariantssize_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 inputsextern "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)

python
import atherisimport 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()
bash
pip install atherispython fuzz_myparser.py corpus/ -max_total_time=300

11. Dataflow tracing

bash
# Track tainted bytes through execution (LLVM dataflow sanitizer + libFuzzer)clang -fsanitize=fuzzer,dataflow -g -O1 fuzz.c target.c -o fuzzLIBFUZZER_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
dockerfile
# project/Dockerfile (minimal)FROM gcr.io/oss-fuzz-base/base-builderRUN git clone --depth 1 https://github.com/you/yourprojectWORKDIR yourprojectCOPY build.sh $SRC/
bash
# Local OSS-Fuzz repropython infra/helper.py build_image yourprojectpython infra/helper.py build_fuzzers yourprojectpython infra/helper.py run_fuzzer yourproject fuzz_target

13. Zig fuzz testing

bash
# Zig 0.11+ built-in fuzzingzig 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:

bash
# parser.dictkw1="<"kw2=">"kw3="</"kw4='="'kw5="\x00"kw6="\xff\xfe"
bash
./fuzz_parser corpus/ -dict=parser.dict

References

For fuzz target templates, corpus seed examples, and OSS-Fuzz integration guidance, see references/targets.md [blocked].

Related skills

  • Use skills/runtimes/sanitizers to add ASan/UBSan to fuzz builds
  • Use skills/compilers/clang for Clang-specific libFuzzer flags
  • Use skills/debuggers/gdb to debug crash inputs found by the fuzzer
  • Use skills/zig/zig-testing for Zig build test --fuzz workflows
  • Use skills/security/kernel-security for kernel fuzzing with syzkaller

Source and attribution

Source:mohitmishra786/low-level-dev-skillsinskills/runtimes/fuzzingat commitbdc5847

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal