К основному содержанию
скилл CX Codex

fuzzing — скилл для Claude Code: что делает и как установить

Помогает писать фаззинг-таргеты для C и C++, настраивать libFuzzer и AFL++, подключать санитайзеры и встраивать проверки в CI.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add mohitmishra786/low-level-dev-skills --skill fuzzing -a claude-code
Открыть на GitHub

Что делает fuzzing

Скилл направляет агента при настройке фаззинга для проектов на C и C++ с помощью libFuzzer или AFL++. Он подсказывает, как объявить функцию LLVMFuzzerTestOneInput, собрать проект через Clang с санитайзерами AddressSanitizer и запустить тесты с контролем таймаутов.

В описании даны шаблоны для постоянного режима AFL++ через __AFL_LOOP, правила минимизации тестового корпуса через afl-cmin и настройка мутаторов LLVMFuzzerCustomMutator. Затронуты также библиотеки вроде Atheris для Python.

Параметр -fsanitize=fuzzer сам предоставляет реализацию main(), поэтому собственный main в файле таргета вызовет ошибку линковки. Воспроизводить найденные сбои из файлов crash-* можно прямо в отладчике GDB.

Какие задачи решает

  • Написать функцию-таргет LLVMFuzzerTestOneInput для си-парсера без утечек памяти
  • Собрать бинарник под Clang с санитайзерами AddressSanitizer и UBSan
  • Запустить AFL++ в persistent mode без накладных расходов fork()
  • Сминимизировать размер корпуса тестов перед отправкой в CI

Примеры запросов агенту

  • Помоги написать таргет libFuzzer для парсера JSON на C
  • Как скомпилировать проект с AFL++ и запустить фаззинг через afl-fuzz?
  • Настрой короткий прогон фаззера в GitHub Actions на 60 секунд

Как установить fuzzing

1Через Skills CLI (Vercel)

npx skills add mohitmishra786/low-level-dev-skills --skill fuzzing -a claude-code

2Вручную: положить файлы

~/.claude/skills/fuzzing/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/fuzzing/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о fuzzing

Как установить fuzzing в Claude Code?

Выполните команду npx skills add mohitmishra786/low-level-dev-skills --skill fuzzing -a claude-code. Файл навыка сохранится по пути ~/.claude/skills/fuzzing/SKILL.md.

Что делает скилл fuzzing?

Он предоставляет готовые шаблоны для написания таргетов, сборки с санитайзерами в Clang, запуска libFuzzer и AFL++, а также управления тестовыми корпусами.

Зачем нужен постоянный режим в AFL++?

Постоянный режим с циклом __AFL_LOOP исключает вызов fork() на каждую итерацию проверки. Это заметно ускоряет тестирование библиотечных функций.

Исходный текст

SKILL.md · MIT
---
name: fuzzing
description: 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.
---

# 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 data
int 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 too
clang -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 directory
mkdir -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:

| Flag | Default | Effect |
|------|---------|--------|
| `-max_len=N` | 4096 | Max input size in bytes |
| `-timeout=N` | 1200 | Kill if single run takes > N seconds |
| `-max_total_time=N` | 0 (forever) | Total fuzzing time |
| `-runs=N` | -1 (infinite) | Total number of runs |
| `-dict=file` | none | Dictionary of interesting tokens |
| `-jobs=N` | 1 | Parallel jobs (each writes its own log) |
| `-merge=1` | off | Merge 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 GDB
gdb ./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
# Install
apt install afl++     # or build from source

# Instrument the target
CC=afl-clang-fast CXX=afl-clang-fast++ \
  cmake -S . -B build-afl -DCMAKE_BUILD_TYPE=Debug
cmake --build build-afl

# Or compile directly
afl-clang-fast -g -O1 -o prog_afl main.c myparser.c

# Create input corpus
mkdir -p afl-input afl-output
echo "hello" > afl-input/seed1

# Run
afl-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 minimisation
afl-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 invariants
size_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 inputs
extern "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 atheris
import 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 atheris
python 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 fuzz
LIBFUZZER_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-builder
RUN git clone --depth 1 https://github.com/you/yourproject
WORKDIR yourproject
COPY build.sh $SRC/
```

```bash
# Local OSS-Fuzz repro
python infra/helper.py build_image yourproject
python infra/helper.py build_fuzzers yourproject
python infra/helper.py run_fuzzer yourproject fuzz_target
```

### 13. Zig fuzz testing

```bash
# Zig 0.11+ built-in fuzzing
zig 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.dict
kw1="<"
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](references/targets.md).

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

© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills

Похожие скиллы

Все скиллы по теме «Тесты и QA» →
improve-codebase-architecture Matt Pocock Скилл ищет архитектурные узкие места в кодовой базе и показывает варианты углубления модулей в HTML-отчёте. Подойдёт для ревью перед рефакторингом. 1 163 035установок design-taste-frontend Leonxlnx Скилл задаёт арт-дирекцию для публичных страниц и рабочих экранов, а затем проверяет результат в браузере по скриншотам. Нужен, когда интерфейс выглядит шаблонным или недоработанным. CX Codex +1 678 700установок tdd Matt Pocock Скилл управляет циклом красный-зелёный в TDD: проверяет, что тесты пишутся до кода, держит их на уровне публичных интерфейсов и не завязывает на внутреннюю структуру. 1 141 062установок skill-creator официальный anthropics Помогает создать новый скилл, доработать существующий и проверить результат через тестовые промпты и оценки. 414 180установок agent-browser vercel-labs Скилл управляет браузером через CLI: открывает страницы, заполняет формы, нажимает кнопки и проверяет веб-приложения. Подходит для задач, где агенту нужно действовать в интерфейсе. CX Codex +1 1 200 000установок prototype Matt Pocock Создаёт временный прототип, чтобы проверить логику, модель состояния или вид интерфейса до работы над основным кодом. 986 201установок

Из того же набора79

linux-kernel-modules Ведёт агента по написанию и отладке загружаемых модулей ядра Linux: Kbuild, параметры модуля, /proc, sysfs, символьные устройства, KGDB и ftrace. CX Codex +1 639установок memory-model Скилл для работы с моделью памяти C++ и Rust: подсказывает, какой memory order выбрать, и разбирает гонки данных в атомиках. CX Codex +1 634установок ninja Скилл учит агента диагностировать ошибки сборки Ninja, настраивать параллельные потоки и связывать Ninja с CMake. CX Codex +1 623установок heaptrack Ведёт агента по heaptrack: запись трасс аллокаций, разбор через heaptrack_print, поиск утечек и сравнение запусков. CX Codex +1 623установок msvc-cl Подсказывает агенту, как компилировать C и C++ через MSVC cl.exe и clang-cl: флаги, рантайм, PDB, ошибки линковки. CX Codex +1 617установок ebpf Помогает писать программы eBPF на C и bpftrace для мониторинга Linux и обработки пакетов XDP. Подсказывает структуры карт ядра и чинит ошибки верификатора. CX Codex +1 610установок conan-vcpkg Помогает настроить менеджеры Conan и vcpkg в проектах на C и C++, связать их с CMake и управлять совместимостью библиотек. CX Codex +1 609установок linkers-lto Скилл для настройки линкеров GNU ld, gold и lld, разбора ошибок порядка библиотек и включения LTO в реальных проектах. CX Codex +1 608установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой