本文へ移動
cccskills
無料GitHub で公開

atheris

Use when a user needs coverage-guided fuzzing for Python code or a Python native extension using Atheris. Not for remote, credential, publish, deploy, or irreversible changes.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md8.4 KB
  • agents/openai.yaml166 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Atheris

Contract

FieldBound contract
TriggerUser needs coverage-guided fuzzing for Python code or a Python native extension using Atheris.
AuthorityReversible local: writes only the Atheris harness file, a corpus directory, and when required for dependency management pyproject.toml and uv.lock in the harness directory; rollback is deleting the harness file and corpus directory and restoring pyproject.toml and uv.lock to their pre-run state. No remote mutation. No source under test is mutated.
Side effectLocal writes: a fuzz.py (or named) harness, a corpus/ directory of seed and crash artifacts, and a transient fuzzing process.
DoneAtheris executes an instrumented target through a deterministic TestOneInput harness, reports coverage, and any saved crash artifact reproduces the same failure when replayed.

Inputs

  • Target: the Python function or module to fuzz, or the Python C extension to fuzz. Required.
  • Target kind: pure Python, or native C extension. Required; it selects the instrumentation and build path.
  • Expected exceptions: the exception types the target legitimately raises on bad input, so the harness catches them instead of crashing. Optional but recommended.
  • Seed corpus: initial input files for corpus/. Optional; Atheris can start empty.
  • Time/length budget: -max_total_time and -max_len values. Optional; defaults are libFuzzer defaults.
  • Sanitizers: whether AddressSanitizer and/or UndefinedBehaviorSanitizer are enabled. Optional; ASan is the default for native extensions.

Procedure

  1. Determine target kind. If the target is pure Python, follow the pure-Python path. If it is a C extension compiled from source, follow the native-extension path. Do not guess; ask the user when the kind is ambiguous. Done when: the target kind is determined as pure Python or native C extension.

  2. Install Atheris. If the harness directory is not already a uv project (no pyproject.toml present), run uv init --bare once. Then uv add atheris. Verify with python -c "import atheris; print(atheris.__version__)". Done when: Atheris is installed and importable.

  3. Write the harness (fuzz.py or a named file). The harness must be deterministic: no random, time, or other nondeterministic input inside TestOneInput.

    • Decorate the entry point with @atheris.instrument_func.
    • Define TestOneInput(data: bytes). Return early on inputs too short to be meaningful. Call the target. Catch only the expected exception types and pass; let every other exception propagate so the fuzzer records it as a crash.
    • In main(), call atheris.Setup(sys.argv, TestOneInput) then atheris.Fuzz().
    • For structured input, use atheris.FuzzedDataProvider(data) to split one bytes input into typed values (ConsumeUnicodeNoSurrogates, ConsumeBool, ConsumeIntInRange, etc.). Draw in a fixed order; once the buffer runs dry each remaining method returns a zero-value of its type. Do not slice data by hand when the target takes several typed arguments, because every mutation shifts the byte offsets of everything after it. Done when: the harness is written with a deterministic TestOneInput and main().
  4. Instrument pure-Python targets. Wrap imports of the code under test in with atheris.instrument_imports(): so coverage is collected. Do not import the target module after atheris.Setup(). Use atheris.instrument_func for a single function, atheris.instrument_imports() for selected modules, or atheris.instrument_all() only when system-wide instrumentation is intended. Done when: the target is instrumented with the appropriate Atheris mechanism.

  5. Build native C extensions with instrumentation. Before installing the extension from source, export:

    CC=clang
    CXX=clang++
    CFLAGS="-fsanitize=address,fuzzer-no-link"
    CXXFLAGS="-fsanitize=address,fuzzer-no-link"
    LDSHARED="clang -shared"
    LDSHAREDXX="clang++ -shared"
    

    For uv-managed projects, set no-binary = ["<pkg>"] under [tool.uv] in pyproject.toml and run uv sync --reinstall-package <pkg> so the package is built from source; a later uv sync can otherwise silently swap in an uninstrumented wheel. Add undefined to the sanitizer list (-fsanitize=address,undefined,fuzzer-no-link) when UBSan is requested. Done when: the native extension is built from source with sanitizer and fuzzer instrumentation flags.

  6. Configure the native-extension runtime. Set LD_PRELOAD to the Atheris sanitizer shared library:

    export LD_PRELOAD="$(python -c 'import atheris, os; print(os.path.join(os.path.dirname(atheris.__file__), "asan_with_fuzzer.so"))')"
    

    Set ASAN_OPTIONS="allocator_may_return_null=1,detect_leaks=0" to suppress allocation-failure and leak noise. Set ASAN_SYMBOLIZER_PATH to the llvm-symbolizer for the installed clang when stack traces are needed. Done when: LD_PRELOAD and ASAN_OPTIONS are set for the native-extension runtime.

  7. Create the corpus. mkdir corpus and add seed inputs as individual files. Run uv run python fuzz.py corpus/ so libFuzzer loads and grows the corpus. Minimize a merged corpus with uv run python fuzz.py -merge=1 new_corpus/ old_corpus/. Done when: the corpus directory is created and seeded.

  8. Run the campaign. uv run python fuzz.py corpus/ with optional -max_total_time=<seconds>, -max_len=<bytes>, and -workers=N -jobs=N for parallel exploration. Read the output: NEW cov: X means new coverage and corpus growth; ERROR: libFuzzer means a crash was detected and a crash artifact was written. Done when: the campaign runs and produces coverage output or crash artifacts.

  9. Reproduce failures. A crash artifact (named crash-* or leak-*) is written next to the harness. Replay it deterministically with uv run python fuzz.py <artifact> and confirm the same failure recurs. Done when: each saved artifact reproduces the same failure or is classified as nondeterministic.

Failure and recovery

  • No coverage increase. Cause: poor seed corpus or target not instrumented. Recovery: add representative seeds; confirm instrument_imports() wraps the target imports and @atheris.instrument_func wraps the entry point. Do not declare success on a stall.
  • Import errors / modules imported before instrumentation. Recovery: move the target imports inside the atheris.instrument_imports() context manager, before atheris.Setup().
  • Segfault with no ASan output. Cause: LD_PRELOAD not set for a native extension. Recovery: export LD_PRELOAD to asan_with_fuzzer.so and rerun.
  • Build failures for a native extension. Cause: wrong compiler or missing flags. Recovery: verify CC, CXX, CFLAGS, CXXFLAGS, and the clang version; configure no-binary = ["<pkg>"] under [tool.uv] and run uv sync --reinstall-package <pkg>.
  • Memory-allocation or leak noise. Recovery: set ASAN_OPTIONS=allocator_may_return_null=1,detect_leaks=0.
  • Crash artifact does not reproduce. Cause: nondeterminism in the harness (randomness, time, unordered iteration over mutable state). Recovery: remove the nondeterminism so TestOneInput is a pure function of data, then rerun. A non-reproducing crash is not a confirmed defect.
  • Partial-result rule. A campaign that finds no crash is a partial result (coverage gained, no defect proven), not proof of absence. Report coverage and corpus growth; do not claim the target is bug-free.
  • Rollback. Delete the harness file and the corpus/ directory. Restore pyproject.toml and uv.lock to their pre-run state, or if they were created by this skill, remove the added atheris entry and no-binary configuration. The source under test is never modified by this skill.

Output

  • A deterministic, instrumented Atheris harness file.
  • A corpus/ directory of seed and discovered inputs, plus any crash-*/leak-* artifacts.
  • A campaign report: coverage reached, corpus size, executions per second, and for each crash artifact a confirmed reproduction (same failure on replay) or a nondeterminism flag.
  • Terminal classification per crash: confirmed defect (reproduces), nondeterministic (does not reproduce), or no crash found (partial result, not proof of absence).

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

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 のスキルをすべて見る

このスキルの問題を報告する