跳到正文
cccskills
免费在 GitHub 公开

fuzzing

Use when planning an end-to-end fuzzing program for a project: engine and target selection, corpus management, and CI or nightly wiring. Not for harness design: use fuzz-harness-writing. Not for engine operation or triage: use libfuzzer. Not for sanitizer flag reference: use sanitizers.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(3)

  • SKILL.md7.2 KB
  • agents/openai.yaml197 B
  • references/targets.md5.7 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Fuzzing

Contract

FieldBound contract
TriggerCoverage-guided fuzz testing for a parser, deserializer, codec, or API boundary: harness writing, libFuzzer or AFL++ setup, corpus management, crash reproduction, or CI runs.
AuthorityReversible local. Writes are limited to fuzz binaries, corpora, dictionaries, findings, and logs under the project tree; rollback is deleting those directories. No remote mutation.
Side effectBuilt fuzz targets, corpus directories, crash artifacts, and coverage measurements.
DoneA fuzz target runs against a seeded corpus, the crash or clean verdict is reproduced on demand, and the CI or nightly plan is written down.

Inputs

  1. Target code (required): the library or entry point to fuzz, ideally a parse or I/O boundary.
  2. Seeds (required when they exist): known-good inputs from tests or real traffic.
  3. Toolchain (required): Clang for libFuzzer; AFL++ installed for fork-mode fuzzing. Grounded channels: Clang 23.1.0, AFL++ v5.03c (AGPL 3.0+ since v5.00c, mixed licensing in the repo).
  4. Time budget (optional): seconds for CI regression runs, hours for nightly.

Procedure

  1. Write the target as a function of arbitrary bytes. The harness owns every guarantee:
// fuzz_parser.c
#include <stdint.h>
#include <stddef.h>
#include "myparser.h"

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    MyParser *p = parser_create();
    if (p) {
        parser_feed(p, (const char *)data, size);
        parser_destroy(p);
    }
    return 0;
}

Rules: return 0 for uninteresting input instead of exiting; never call abort or exit; never read or write outside [data, data + size); keep no state between calls; stay fast, since the fuzzer calls it millions of times. Done when: the harness passes a review against each rule. 2. Build with libFuzzer and the sanitizer set. -fsanitize=fuzzer links libFuzzer and supplies main, so the target must not define one:

clang -fsanitize=fuzzer,address,undefined -fno-omit-frame-pointer -g -O1 \
    fuzz_parser.c myparser.c -o fuzz_parser

Done when: the binary links without a duplicate main and runs -help=1 cleanly. 3. Seed and run:

mkdir -p corpus
cp tests/inputs/* corpus/          # real seeds sharply cut time to coverage
./fuzz_parser corpus/ -max_len=65536 -timeout=10
./fuzz_parser corpus/ -max_total_time=3600
./fuzz_parser corpus/ -jobs=4 -workers=4

Defaults worth knowing: -max_len 4096 when unset, -timeout 1200 seconds, -rss_limit_mb 2048, -error_exitcode 77, -len_control 100. Workers default to half the core count when unset. Done when: the run starts consuming the corpus and reporting new coverage. 4. Reproduce and minimize every finding. Artifacts land as crash-<hash>, oom-<hash>, or timeout-<hash> in the artifact prefix directory:

./fuzz_parser crash-abc123                 # reproduce
./fuzz_parser -minimize_crash=1 -max_total_time=60 crash-abc123

Re-run the minimized case under gdb (gdb --args ./fuzz_parser crash-min) to name the faulting frame. Done when: one small input reproduces the bug deterministically. 5. Add AFL++ where process-level isolation or non-library targets are needed:

afl-clang-fast -g -O1 -o prog_afl main.c myparser.c
afl-fuzz -i afl-input -o afl-output -- ./prog_afl @@    # @@ = input file path
afl-fuzz -i afl-input -o afl-output -- ./prog_afl       # stdin target: drop @@

Persistent mode avoids a fork per input and raises throughput for library targets; __AFL_LOOP(1000) bounds each iteration batch. Scale out with -M main plus one -S name instance per spare core, and read status with afl-whatsup afl-output. Done when: at least one AFL++ instance reports stable cycles with new paths. 6. Manage the corpus as an asset. Merge runs to the coverage-unique subset, and keep the corpus in version control or CI cache:

./fuzz_parser -merge=1 corpus_min/ corpus/ run1/ run2/
afl-cmin -i afl-output/default/queue -o corpus_min -- ./prog_afl @@
./fuzz_parser corpus/ -runs=0 -print_coverage=1     # coverage of the corpus

Done when: one minimized corpus exists and reproduces the union of coverage. 7. Guide mutation with a dictionary when the format has tokens:

# parser.dict
kw1="<"
kw2=">"
null_byte="\x00"
magic1="\x89PNG"
./fuzz_parser corpus/ -dict=parser.dict
afl-fuzz -i corpus/ -o out/ -x parser.dict -- ./prog_afl @@

For structured formats that checksum or length-prefix, implement LLVMFuzzerCustomMutator and repair the invariant after LLVMFuzzerMutate, or the fuzzer never passes the header. Done when: deep paths are reached without human-crafted inputs. 8. Wire CI as a fixed-time regression, not an open-ended run:

- name: Build fuzz target
  run: |
    clang -fsanitize=fuzzer,address,undefined -g -O1 \
      fuzz_parser.c myparser.c -o fuzz_parser
- name: Fuzz regression (60 seconds)
  run: |
    ./fuzz_parser corpus/ -max_total_time=60 -error_exitcode=1 \
      -artifact_prefix=artifacts/
- name: Reproduce known crashes
  run: |
    for f in known_crashes/*; do ./fuzz_parser "$f" || exit 1; done

Longer campaigns go to scheduled jobs with -max_total_time=3600 or to OSS-Fuzz infrastructure. Done when: a pull request cannot merge with a target that regresses. 9. Add Python targets with Atheris, and Zig targets through the built-in fuzzer (Zig 0.13 and later):

import atheris, 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()
zig build test --fuzz

Done when: each language boundary has its own target or a recorded decision not to fuzz it.

Harness templates and the full flag tables live in references/targets.md.

Failure and recovery

Failure classBehavior
Fuzzer finds no coverage growthThe harness or sanitizer set blocks depth. Check that -fsanitize=fuzzer is in the build and seeds are real inputs.
Crash does not reproduceThe bug depends on corpus state or is flaky. Re-run the single input ten times; check for uninitialized reads (initcheck) or a race.
OOM artifacts flood the runLower -rss_limit_mb, cap -max_len, or bound allocations inside the harness.
AFL++ target dies at startupMemory limit too low for the target. Raise -m or add -t for slow inputs.
CI run too slowShrink -max_total_time, run -workers=$(nproc), and cache the corpus between runs.
Fuzzer slows to a crawl mid-runThe target leaks or retains state between calls. Audit the harness against the step 1 rules.

Output

The built targets, the seeded and minimized corpora, the crash reproduction commands, and the CI configuration. Every finding carries its minimized artifact and the sanitizer report that explains it.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Use when explaining System V AMD64, ARM AAPCS, RISC-V psABI, stack frames, variadic calls, or FFI register rules. Not for the Rust FFI binding layer: use rust-ffi.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when configuring ADC sampling time, DMA-driven ADC, calibration, or DAC channel setup on bare-metal MCUs. Not for the DMA stream itself: use dma-baremetal.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

af-xdp

免费

Use when creating AF_XDP sockets, configuring UMEM and XSK rings, writing an XDP redirect program, or choosing copy versus zero-copy mode. Not for full kernel bypass: use dpdk.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when a completed session needs an agent-environment retrospective. Not for an engineering retrospective from telemetry: use engineering-retrospective.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when a redacted, trimmed agent transcript must be appended to a GitHub PR or issue body, with human approval and preview. Not for automated or model-initiated insertion.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

agents-md

免费

Use when a repo needs agent setup, AGENTS.md added or made lean, CLAUDE.md audited, or agent instructions scored or pruned. Not for remote, credential, publish, deploy, or irreversible changes.

中文简介正在准备中。当前显示原文说明。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

查看 OutlineDriven 的全部技能

报告此技能的问题