- Bump alkcall 0.8.0 -> 0.8.1 (duplicate adopt/open channel-state destruction fix from alkcall's fuzz campaign; AGENTS.md stale-pin fix). - Adopt fuzzing per docs/plans/fuzzing.md (mirrors alkcall's docs/research/fuzzing.md as-built layout): fuzz/ workspace with own [workspace] table, nightly pinned for the subtree only, invariant logic in a stable-toolchain shared crate. - Targets: chunk_frame (5-byte chunk codec), negotiation_frame (negotiation framing + NegotiateRequest + error_response_bytes + the cross-codec peek-disambiguation seam), control_json (ControlMessage JSON + signal_from_name). src/local/ out of scope (not wire-attacker-shaped). - 328 committed seeds (deterministic generator); grown corpora gitignored. Corpus replay on stable is the standing fuzz gate (cargo test --manifest-path fuzz/shared/Cargo.toml). - Detached-runner rule (fuzz/run-detached.sh): campaigns never run in the foreground of an agent session - OOM in a target must cost the fuzzer, never the session host. - Root Cargo.toml gained [workspace] members/exclude (MSRV vs fuzz nightly dev-deps footgun) and fuzz/ in the publish exclude. Verification: cargo test (113), cargo test --all-features (156), clippy stable + wasm32-unknown-unknown, fmt, doc, publish dry-run, corpus replay 328 seeds - all green. 10-min detached campaigns on all three targets: 0 crashes/hangs/OOMs/leaks (chunk_frame cov-saturated at 710 edges; negotiation_frame 3.69M execs cov 3157; control_json 8.6M execs cov 2035). Corpus replay caught three harness-model mismatches pre-campaign (payload-slice shape; the negotiation framing layer is length-prefix-only - Json unreachable from read_frame; zero-length frames admitted by the reader, rejected by the adapter's parse). Campaigns recorded in docs/plans/fuzzing.md section 8.
29 lines
1.1 KiB
Bash
Executable File
29 lines
1.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Detached fuzzing runner for agent sessions: the fuzz campaign never
|
|
# runs as a foreground child of the session (OOM in a target must not
|
|
# take down the agent host), and survives the session ending.
|
|
#
|
|
# Usage: fuzz/run-detached.sh <target> [extra libfuzzer args...]
|
|
# (works from the repo root or from fuzz/; CWD-independent)
|
|
# FUZZ_RUNTIME_SECS overrides the per-campaign budget (default 600 s).
|
|
#
|
|
# Poll instead of waiting:
|
|
# tail -n 50 fuzz/artifacts/<target>-*.log
|
|
# ls fuzz/artifacts/<target>/ (crash-* / oom-* / timeout-* files)
|
|
# pgrep -f "cargo fuzz run <target>"
|
|
set -euo pipefail
|
|
target="${1:?usage: run-detached.sh <target> [extra libfuzzer args...]}"
|
|
shift
|
|
|
|
root="$(git rev-parse --show-toplevel)"
|
|
fuzz_dir="$root/fuzz"
|
|
mkdir -p "$fuzz_dir/artifacts"
|
|
runtime="${FUZZ_RUNTIME_SECS:-600}"
|
|
log="$fuzz_dir/artifacts/${target}-$(date -u +%Y%m%d-%H%M%S).log"
|
|
|
|
cd "$fuzz_dir"
|
|
setsid nohup cargo fuzz run "$target" -- \
|
|
-fork=1 -rss_limit_mb=2048 -malloc_limit_mb=2048 -timeout=25 \
|
|
-max_total_time="$runtime" "$@" \
|
|
>"$log" 2>&1 < /dev/null &
|
|
echo "pid=$! log=$log" |