yams/tools/fuzzing
2026-04-25 14:48:44 -04:00
..
.dockerignore resolved concurrency bugs in daemon. added fuzzing work in progress per issue #8 2025-11-11 10:10:07 -05:00
asan_cluster.py feat: adding fuzzing updates and fixes in ipc 2026-02-08 22:20:47 -05:00
Dockerfile build(ci,tests): cleaning build system and updates related to ci test failures and compat 2026-04-25 14:48:44 -04:00
fuzz.sh feat: fuzzing and config expansion. Moving to optimizing ingestion. Adding tunable embedding (chunk size etc.) 2026-02-11 23:21:26 -05:00
fuzz_abi_negotiation_plugin.c merge: integrate main into experimental (preserve PBI-081 simplification) 2026-02-19 10:01:01 -05:00
fuzz_abi_test_plugin.c merge: integrate main into experimental (preserve PBI-081 simplification) 2026-02-19 10:01:01 -05:00
fuzz_add_document.cpp fix: license header file updates, mcp improvements, windows build fixes 2026-01-30 17:23:33 -05:00
fuzz_download_jobs.cpp feat: adding fuzz test for new download logic, removing r2 endpoint from tests, decoupling embedding / onnxruntime logic for work from previous commit 2026-03-21 18:08:23 -04:00
fuzz_ipc_protocol.cpp fix: license header file updates, mcp improvements, windows build fixes 2026-01-30 17:23:33 -05:00
fuzz_ipc_roundtrip.cpp feat: updating metrics for search and retrieval for future learning system. Additional tuning for search performance 2026-02-13 21:09:26 -05:00
fuzz_plugin_abi_mount.cpp feat: updating embedding default checking to paragraph 2026-02-12 11:55:59 -05:00
fuzz_plugin_abi_negotiation.cpp feat: updating embedding default checking to paragraph 2026-02-12 11:55:59 -05:00
fuzz_plugin_trust.cpp feat: adding fuzzing updates and fixes in ipc 2026-02-08 22:20:47 -05:00
fuzz_proto_serializer.cpp feat: fuzzing tooling 2026-02-08 18:48:54 -05:00
fuzz_query_parser.cpp feat: updating metrics for search and retrieval for future learning system. Additional tuning for search performance 2026-02-13 21:09:26 -05:00
fuzz_request_handler.cpp fix: fixing leakage of build artifacts in release, unifying repair path, adding cache to tuning path and bumping simeon version 2026-04-23 10:20:25 -04:00
fuzz_streaming_processor.cpp feat: fuzzing tooling 2026-02-08 18:48:54 -05:00
generate_corpus.sh feat: adding fuzz test for new download logic, removing r2 endpoint from tests, decoupling embedding / onnxruntime logic for work from previous commit 2026-03-21 18:08:23 -04:00
meson.build feat: adding fuzz test for new download logic, removing r2 endpoint from tests, decoupling embedding / onnxruntime logic for work from previous commit 2026-03-21 18:08:23 -04:00
README.md fix(docs,ci): addressing breaking changes in zig v0.16.x in Dockerfile, docs update and code cleanup 2026-04-25 11:27:18 -04:00
seedgen.cpp feat: updating metrics for search and retrieval for future learning system. Additional tuning for search performance 2026-02-13 21:09:26 -05:00

YAMS Fuzzing Infrastructure

AFL++ fuzzing harnesses for CLI/daemon IPC protocol testing per issue #8.

Targets

Protocol Layer

  • fuzz_ipc_protocol - MessageFramer, CRC32 validation, frame header parsing
  • fuzz_add_document - AddDocumentRequest/UpdateDocumentRequest deserialization
  • fuzz_ipc_roundtrip - CLI<->daemon framing + payload decode/encode roundtrip

Daemon Services & IPC Bus

  • fuzz_proto_serializer - Protobuf encoding/decoding of IPC message payloads
  • fuzz_request_handler - Request processing, message framing, and handler configuration
  • fuzz_streaming_processor - Chunked streaming response handling and processor delegation
  • fuzz_query_parser - User-facing search query parsing + FTS5 translation
  • fuzz_plugin_trust - Plugin trust list parsing + safe path containment checks
  • fuzz_plugin_abi_mount - ABI plugin mount/load/unload path via AbiPluginLoader
  • fuzz_plugin_abi_negotiation - ABI manifest/interface negotiation across controlled plugins
  • fuzz_download_jobs - Daemon download job IPC request/response encoding and roundtrip stability

Planned Surfaces

  • Daemon download job IPC and policy boundary
    • initial IPC roundtrip target now exists
    • next target: policy decision / persisted job-state load-save / progress framing
    • security focus: SSRF-like inputs, redirect escapes, oversized metadata, hostile cancel/resume state

Fuzzers run in aflplusplus/aflplusplus Docker container for reproducibility.

Usage

Build fuzzers:

./tools/fuzzing/fuzz.sh build

Run a fuzzer (interactive / live AFL++ UI):

./tools/fuzzing/fuzz.sh fuzz ipc_protocol
./tools/fuzzing/fuzz.sh fuzz add_document
./tools/fuzzing/fuzz.sh fuzz ipc_roundtrip
./tools/fuzzing/fuzz.sh fuzz proto_serializer
./tools/fuzzing/fuzz.sh fuzz request_handler
./tools/fuzzing/fuzz.sh fuzz streaming_processor
./tools/fuzzing/fuzz.sh fuzz query_parser
./tools/fuzzing/fuzz.sh fuzz plugin_trust
./tools/fuzzing/fuzz.sh fuzz plugin_abi_mount
./tools/fuzzing/fuzz.sh fuzz plugin_abi_negotiation
./tools/fuzzing/fuzz.sh fuzz download_jobs

Notes:

  • Run each fuzzer in its own terminal tab/pane if you want multiple live dashboards.
  • If you copy/paste commands from VS Code, paste the raw command text rather than a formatted Markdown link.

Monitor:

./tools/fuzzing/fuzz.sh exec afl-whatsup /fuzz/findings/ipc_protocol
./tools/fuzzing/fuzz.sh exec afl-whatsup /fuzz/findings/proto_serializer

Lightweight live stats (host-side):

watch -n 1 "sed -n '1,80p' data/fuzz/findings/ipc_roundtrip/default/fuzzer_stats"

Reproduce crash:

./tools/fuzzing/fuzz.sh exec \
  /src/build/fuzzing/tools/fuzzing/fuzz_ipc_protocol /fuzz/findings/ipc_protocol/crashes/id:000000*
./tools/fuzzing/fuzz.sh exec \
  /src/build/fuzzing/tools/fuzzing/fuzz_proto_serializer /fuzz/findings/proto_serializer/crashes/id:000000*

Architecture

Directory Structure

tools/fuzzing/
├── README.md                       # This file
├── fuzz.sh                         # Docker wrapper script
├── meson.build                    # Build definitions
├── fuzz_ipc_protocol.cpp          # IPC protocol fuzzer harness
├── fuzz_add_document.cpp          # Document fuzzer harness
├── fuzz_proto_serializer.cpp      # Protobuf serializer fuzzer
├── fuzz_request_handler.cpp       # Request handler fuzzer
├── fuzz_streaming_processor.cpp   # Streaming processor fuzzer
└── generate_corpus.sh             # Seed corpus generator

data/fuzz/
├── corpus/                        # Input seeds (read-only for fuzzer)
│   ├── ipc_protocol/             # IPC protocol seeds
│   ├── ipc_roundtrip/             # CLI/daemon roundtrip seeds
│   ├── add_document/             # Document request seeds
│   ├── proto_serializer/         # Protobuf message seeds
│   ├── request_handler/          # Request handler seeds
│   └── streaming_processor/      # Streaming processor seeds
│   └── plugin_trust/             # Plugin trust/path seeds
│   └── plugin_abi_mount/         # Plugin ABI mount/load seeds
│   └── plugin_abi_negotiation/   # Plugin ABI negotiation seeds
│   └── download_jobs/            # Daemon download job IPC seeds
└── findings/                      # AFL++ output (crashes, hangs, queue)
    ├── ipc_protocol/
    ├── ipc_roundtrip/
    ├── add_document/
    ├── proto_serializer/
    ├── request_handler/
    └── streaming_processor/
    └── plugin_trust/
    └── plugin_abi_mount/
    └── plugin_abi_negotiation/
    └── download_jobs/

Instrumentation Flow

1. Conan Profile       → conan/profiles/aflplusplus-docker
                         Sets: AFL_USE_ASAN=1
                         Compiler: afl-clang-fast++ (via afl-clang-fast wrappers)

2. Meson Build         → tools/fuzzing/meson.build
                         Flags: -fsanitize=fuzzer (AFL++ libFuzzer-compat mode)
                         Links: yams_daemon_lib (IPC/framing/protocol code)

3. Fuzzer Binary       → build/fuzzing/tools/fuzzing/fuzz_*
                         Entry: LLVMFuzzerTestOneInput()
                         ASAN: Memory safety checks (AFL_USE_ASAN)
                         AFL++: Coverage-guided mutation + queue management

Configuration

Conan profile (conan/profiles/aflplusplus-docker):

  • AFL_USE_ASAN=1 - Address sanitizer
  • AFL_LLVM_INSTRUMENT=AFL - AFL instrumentation mode
  • Compiler: afl-clang-fast++
  • libcxx: libstdc++11

Container build flags (tools/fuzzing/Dockerfile):

  • Sets CXXFLAGS to relax a couple of warning-to-error cases seen in dependencies.

Compiler flags:

  • -fsanitize=fuzzer (compile and link)
  • Enables AFL++ libFuzzer compatibility mode with automatic persistent mode

Advanced

Parallel fuzzing (main + secondary workers):

# Terminal 1
./tools/fuzzing/fuzz.sh fuzz ipc_protocol

# Terminal 2-N
docker run -ti --rm -v "$(pwd)/data/fuzz:/fuzz" yams-fuzz \
  afl-fuzz -i /fuzz/corpus/ipc_protocol -o /fuzz/findings/ipc_protocol \
  -S worker1 -m none /src/build/fuzzing/tools/fuzzing/fuzz_ipc_protocol

Generate HTML plots:

./tools/fuzzing/fuzz.sh exec \
  afl-plot /fuzz/findings/ipc_protocol/default /fuzz/findings/ipc_protocol/plot

Then open: data/fuzz/findings/ipc_protocol/plot/index.html

Corpus minimization:

./tools/fuzzing/fuzz.sh exec bash -c \
  "afl-cmin -i /fuzz/findings/ipc_protocol/queue -o /fuzz/corpus/ipc_min -m none \
  -- /src/build/fuzzing/tools/fuzzing/fuzz_ipc_protocol"

Crash minimization:

./tools/fuzzing/fuzz.sh exec bash -c \
  "afl-tmin -i /fuzz/findings/ipc_protocol/crashes/id:000000 -o crash_min -m none \
  -- /src/build/fuzzing/tools/fuzzing/fuzz_ipc_protocol"

Seed Corpus

Location: data/fuzz/corpus/<target>/

Generate minimal seeds:

./tools/fuzzing/generate_corpus.sh

If the yams-fuzz Docker image is already built, generate_corpus.sh also runs a small structured seed generator (seedgen) that emits framed protobuf messages for edge-case SearchRequest, GrepRequest, and DeleteRequest variants (roughly 10–50 inputs).

Note: this script creates directories matching fuzz.sh fuzz <target> (e.g. ipc_protocol, ipc_roundtrip).

Add custom seeds from:

  • Integration test traffic capture
  • Sanitized CLI→daemon messages
  • Manual construction

Corpus should cover request types, edge cases, and real-world patterns. Do not include secrets.

Planned Download Boundary Seeds

Seed the existing fuzz_download_jobs target with sanitized inputs for:

  • allowed vs disallowed schemes
  • allowed vs disallowed hosts
  • redirect chains that escape host policy
  • missing checksum vs required-checksum requests
  • resume/job-state collisions on same URL with different owners or fingerprints
  • oversized content-length metadata
  • malformed progress/job-status payloads

CI Integration

Not wired up yet in this repo. If you want CI fuzz smoke tests, a common pattern is:

  • Build yams-fuzz image in CI
  • Run each fuzzer for a short, fixed time budget (e.g. 60–300s)
  • Upload data/fuzz/findings/** as artifacts when crashes are found

Crash Triage

Reproduce:

./tools/fuzzing/fuzz.sh exec \
  /src/build/fuzzing/tools/fuzzing/fuzz_ipc_protocol /fuzz/findings/ipc_protocol/crashes/id:000000*

ASAN provides automatic stack traces. After fixing:

  1. Rebuild fuzzers
  2. Verify crash input no longer crashes
  3. Add crash input to corpus for regression prevention

LLM-assisted workflow (optional)

LLMs can complement AFL++ by speeding up the human parts (seed quality, triage, and variant hunting):

  1. Seed generation (coverage boost)
  • Ask the LLM to propose edge-case inputs for a specific request type (e.g. GrepRequest, SearchRequest).
  • Turn those into a small seed set (even 10–50 good seeds often helps AFL explore faster).
  1. Crash triage (faster root-cause)
  • Provide: minimized crashing input + ASAN stack trace + the immediate code around the top frames.
  • Ask for: likely root cause, invariants violated, and a minimal patch + regression test idea.
  1. Dedup + prioritize
  • Feed multiple ASAN traces; ask the LLM to cluster by top frame / signature and identify the highest-risk classes (OOB write, UAF, etc.).

You can also do this locally with the helper:

python3 ./tools/fuzzing/asan_cluster.py ./asan_logs/*.txt
  1. Variant analysis
  • Once you fix one bug, ask the LLM to search for similar patterns across the codebase (same API misuse, same unchecked length assumptions, etc.).

Safety note: don’t paste secrets from real documents into prompts; use minimized test inputs and scrubbed logs.

Troubleshooting

AFL++ compiler not detected: Use ./tools/fuzzing/fuzz.sh build

No instrumentation: Verify Conan profile conan/profiles/aflplusplus-docker sets afl-clang-fast++

Out of memory: Increase Docker limit or disable ASAN for throughput fuzzing

Corpus too large: Run afl-cmin for minimization

Existing findings directory: fuzz.sh fuzz <target> sets AFL_AUTORESUME=1 so it resumes safely. To start a fresh run while keeping old results, rename data/fuzz/findings/<target>/ first.

Directory is in use: if you see ".../default is in use", another afl-fuzz is already running. By default fuzz.sh now runs with a unique -S fuzzer id per terminal. To resume the original instance explicitly, run:

AFL_FUZZER_ID=default ./tools/fuzzing/fuzz.sh fuzz <target>

References