Skip to content
Development
Skill

/libfuzzer

Use when asked to build, run, or triage a coverage-guided C/C++ fuzz campaign on the libFuzzer or AFL++ engine. Not for harness design: use fuzz-harness-writing.

From plugin
odin-claude-plugin
40200 skills

Claude Code

$ npx -y skills add OutlineDriven/odin-claude-plugin --skill libfuzzer --agent claude-code

SKILL.md

libfuzzer.SKILL.md
name: libfuzzer
description: 'Use when asked to build, run, or triage a coverage-guided C/C++ fuzz campaign on the libFuzzer or AFL++ engine. Not for harness design: use fuzz-harness-writing.'

libFuzzer and AFL++

Contract

| Field | Bound contract | |---|---| | Trigger | User needs to build, run, tune, or triage a coverage-guided C/C++ fuzzing campaign or `LLVMFuzzerTestOneInput` harness on the libFuzzer engine (default) or the AFL++ engine (afl mode). | | Authority | Human-gated: in afl mode, request explicit user approval before a package installation or a Docker image pull; otherwise reversible local: writes only named fuzzing artifacts (binary, corpus and output directories, crash files, logs); rollback is deleting them and killing campaign processes. Kernel-tuning steps that need a reboot or degrade OS security are out of scope. No remote mutation. | | Side effect | Local write to a compiled fuzzing binary, its corpus or output directory, log files, and any crash artifacts written by the target; afl mode may run a short-lived Docker container. | | Done | The instrumented binary runs against its corpus and any crash artifact reproduces in the same target with identical sanitizer output or signal. |

Inputs

  • Required: Engine: `libfuzzer` (default) or `afl`.
  • Required: Source or object files for the code under test.
  • Required (libfuzzer engine): Clang compiler (`clang++`) with the libFuzzer runtime present, and one `LLVMFuzzerTestOneInput` harness function visible to the linker.
  • Required (afl engine): `afl-fuzz` on the host or the `aflplusplus/aflplusplus` Docker image, and a harness or a program that reads stdin, files, or argv.
  • Optional: Seed corpus directory. It may be empty; when omitted, create `./corpus/` (libfuzzer) or `seeds/` with one non-empty file (afl).
  • Optional: Fuzzing dictionary file (see Dictionary format below).
  • Optional (libfuzzer): Clang build flags: `-fsanitize=address`, `-fsanitize=undefined`, `-g`, `-O2`, `-max_len`, `-dict`, `-timeout`, `-close_fd_mask`, `-fork`, `-ignore_crashes`.
  • Optional (afl): run location host or Docker (default Docker); instrumentation mode LTO, LLVM, or GCC (default tries LTO, falls back to LLVM); core count (default single instance); sanitizer selection ASan, UBSan, or none (default none).

Procedure

1. **Select the engine.** `libfuzzer` is the default. Choose `afl` when the user names AFL++, needs multi-core `afl-fuzz` campaigns, or lacks a Clang libFuzzer runtime. Done when: the engine is selected.

2. **Verify the toolchain.** libfuzzer: run `clang++ --version`; stop if Clang is absent and install it before proceeding. Mode `afl`: verify `afl-fuzz --version` on the host or `docker run --rm aflplusplus/aflplusplus:stable afl-fuzz --version`; request explicit approval before `apt install afl++ lld` or `docker pull aflplusplus/aflplusplus:stable`. Done when: the engine binary is verified and any install was approved.

3. **Build the harness binary.** libfuzzer: compile with:

   clang++ -fsanitize=fuzzer[,address,undefined] -g -O2 -U_FORTIFY_SOURCE <harness>.cc <target>.cc -o <binary>

`-fsanitize=fuzzer` links the libFuzzer runtime and provides `main`. Add `,address` for heap/stack buffer overflow, use-after-free, and double-free detection. Add `,undefined` for signed-integer overflow, null dereference, and similar undefined behavior. Add `-U_FORTIFY_SOURCE` when using ASan to avoid fortification interference. Omit `-fsanitize=address` for a faster build when only checking sanitizer-uncovered defects. Mode `afl`: compile with the chosen instrumentation mode; try LTO first, fall back to LLVM mode if LTO fails to link, and use the GCC plugin only when the project requires GCC:

   afl-clang-lto++  -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz   # LTO (preferred)
   afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz   # LLVM (fallback)
   afl-g++-fast     -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz   # GCC plugin

`-DNO_MAIN=1` skips the main function when using a libFuzzer harness. For programs reading stdin or files, no harness is needed: compile the program directly and fuzz via stdin or the `@@` file placeholder. For static libraries and object files, use `-fsanitize=fuzzer-no-link` to instrument without linking the fuzzer runtime. The GCC version must match the version used to compile the AFL++ GCC plugin. Add `AFL_USE_ASAN=1` or `AFL_USE_UBSAN=1` when sanitizers are requested. The `-m` memory limit flag is unsupported with ASan because ASan reserves 20 TB of virtual memory; in multi-core setups run only one ASan job per 4-8 non-ASan jobs. Done when: the binary compiles and links with the chosen instrumentation and sanitizer flags.

4. **Prepare the corpus.** libfuzzer: create `<corpus_dir>/` and optionally seed it with valid example inputs representing the target format. Mode `afl`: create `seeds/` with at least one non-empty file; for real projects gather representative inputs from example files, the project test suite, or minimal valid inputs for the target format. Done when: the corpus directory exists and is seeded.

5. **Run the campaign.** libfuzzer:

   <binary> [-max_len=<N>] [-timeout=<S>] [-dict=<dict_file>] [-close_fd_mask=3] [-fork=1 -ignore_crashes=1] [-jobs=<N> -workers=<N>] <corpus_dir>/

`-max_len`: cap per-input byte size (2x minimal realistic input is a reasonable start; omit to let libFuzzer grow dynamically). `-timeout`: abort test cases exceeding this many seconds. `-dict`: pass a fuzzing dictionary for format-aware mutation. `-close_fd_mask=3`: close stdout and stderr for a speed boost when the target writes to them. `-fork=1 -ignore_crashes=1`: continue after finding a crash rather than exiting. `-jobs`/`-workers`: run N parallel jobs sharing the corpus. Mode `afl`: set the environment variables that matter: `AFL_TMPDIR=/dev/shm` always (tmpfs improves performance

Read more
@outlinedriven
Ships withodin-claude-plugin

Formerly the ODIN Claude Plugin. The repository URL is unchanged. Outline-Driven Development, nicknamed ODIN, is a highly opinionated code-agent skill library: principles-first engineering, surgical editing, and workflow automation, published as installable

Stars on GitHub

Momentum

stars in total
40
Star history of OutlineDriven/odin-claude-plugin on GitHub, a chart by star-history.com

Other skills on odin-claude-plugin.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about libfuzzer.

Which coding agents can use libfuzzer?
libfuzzer installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.