Skip to content
Development
Skill

/libafl

Use when a LibAFL fuzzer needs an executor, observer, feedback, mutator, scheduler, or objective composed around a target. Not for remote, credential, publish, deploy, or irreversible changes.

From plugin
odin-claude-plugin
40200 skills

Claude Code

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

SKILL.md

libafl.SKILL.md
name: libafl
description: 'Use when a LibAFL fuzzer needs an executor, observer, feedback, mutator, scheduler, or objective composed around a target. Not for remote, credential, publish, deploy, or irreversible changes.'
disable-model-invocation: true

LibAFL custom fuzzer composition

Contract

| Field | Bound contract | |---|---| | Trigger | User needs a custom LibAFL fuzzer, observer, feedback, mutator, scheduler, or executor composition. | | Authority | Reversible local: writes named local Rust source artifacts, corpus entries, and objective findings under the output directory; rollback is deleting the generated crate, the output directory, or reverting VCS changes. No remote mutation. | | Side effect | Local-write: creates or modifies Rust source files implementing the composed fuzzing engine and target integration, plus corpus entries and crash/timeout findings under the output directory. | | Done | The composed LibAFL fuzzer compiles, runs the target, records coverage feedback, and persists objective findings to disk. |

Inputs

  • Target: the function, binary, or harness to fuzz. Required.
  • Components: which LibAFL modules to compose, at minimum an executor, observer, feedback, and mutator. Optional; defaults to a coverage-guided in-process fuzzer with `StdScheduledMutator` and `HitcountsMapObserver`.
  • Objective: the stopping condition or crash classification (e.g., timeout, crash, custom `ExitKind`). Optional; defaults to crash detection.
  • Output directory: where corpus and findings persist. Optional; defaults to `./fuzz_out`.

Procedure

1. **Identify the target boundary.** Determine the function signature or binary entry point to fuzz. Confirm the target accepts byte-slice input (`&[u8]`) or can be wrapped in a `BytesInput` harness. Done when: the target boundary is identified and confirmed compatible with byte-slice input.

2. **Select the executor.** Choose `InProcessExecutor` for in-process fuzzing or `ForkserverExecutor` / `CommandExecutor` for out-of-process. `InProcessExecutor` has no crash isolation in-process; when crash handling is needed, select `InProcessForkExecutor`, which forks per execution and catches crashes in the parent. Done when: one executor is selected and crash handling is configured.

3. **Select the observer.** Create a `HitcountsMapObserver` backed by a `CoverageMap` (typically `AFL-style` shared memory). Wrap in `MultiMapObserver` if tracking multiple maps. Done when: one observer is selected and backed by a coverage map.

4. **Select the feedback.** Combine `MaxMapFeedback` (coverage novelty) with `TimeoutFeedback` or `CrashFeedback` for objective classification. Use `feedback_or!` / `feedback_and!` macros to compose. Done when: feedback is composed with coverage novelty and objective classification.

5. **Select the objective.** Define the stopping condition using `CrashFeedback`, `TimeoutFeedback`, or a custom `ExitKind`-based feedback. This determines what the fuzzer reports as a finding. Done when: one objective feedback is selected.

6. **Select the mutator.** Choose `StdScheduledMutator` with a stack of mutations (`havoc_mutations`, `token_mutations`, or custom). For structured inputs, implement `HasMaxSize` and use `encoded_mutations`. Done when: one mutator is selected with its mutation stack.

7. **Select the scheduler.** Use `QueueScheduler` for corpus cycling, `PowerScheduleScheduler` for power scheduling, or `MinimizerScheduler` wrapping another scheduler for corpus minimization. Done when: one scheduler is selected.

8. **Assemble the fuzzer.** Create a `StdFuzzer` with the chosen scheduler and feedback. Wire the executor, observer, and objective. Done when: the `StdFuzzer` is assembled with all components wired.

9. **Set up the event manager.** Use `SimpleEventManager` for single-process or `LlmpEventManager` for multi-process. Connect to a `StatsMonitor` (e.g., `MultiMonitor` printing to stdout). Done when: the event manager is set up and connected to a stats monitor.

10. **Initialize state and corpus.** Create `StdState` with the initial corpus directory, the feedback, and the objective. Load seed inputs from the corpus directory or provide inline `BytesInput` seeds. Done when: `StdState` is initialized with corpus and seeds loaded.

11. **Run the fuzzer.** Call `fuzzer.fuzz_loop(...)`. The fuzzer will mutate inputs, execute the target, observe coverage, and persist new corpus entries and objective findings to the output directory. Done when: the fuzz loop runs and persists corpus entries and findings.

12. **Verify findings.** After the run, inspect the output directory for crash/timeout artifacts. Replay each finding against the target to confirm reproducibility. Done when: every finding artifact is inspected and replayed against the target.

Failure and recovery

  • Compilation failure: LibAFL API changes between versions. Pin the `libafl` crate version in `Cargo.toml`. If compilation fails, check the LibAFL changelog for breaking API changes and adjust component wiring.
  • No coverage observed: the observer map may not be linked to the target. Verify the `CoverageMap` is shared with the executor (e.g., via `OwnedMutRawPtr` or forkserver shared memory). Fix the map linkage before re-running.
  • Target crash before fuzzing starts: the harness panics or aborts on initialization. Wrap the target in `catch_unwind` or fix the harness. Do not widen scope to debug the target itself.
  • Empty corpus: no seed inputs loaded. Provide at least one valid input in the corpus directory or inline. The fuzzer cannot make progress without seeds.
  • Non-convergent mutation: the mutator produces only invalid inputs that the target rejects immediately. Add a `MapFeedback` or custom `IsInteresting` feedback to guide toward valid input regions, or switch to a structured mutator.

Output

Compiled fuzzing engine binary in `target/`, live corpus in the output directory, persisted crash and timeout findings (each replayable against

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.

skills2w309k
@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,…

ecc2w293k
@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…

react5d252k
@facebook@facebookInstall Skill

Questions about libafl.

Which coding agents can use libafl?
libafl 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.