fuzz: adopt fuzzing (wave 1) + alkcall 0.8.1 / alktunnels 0.2.1 bumps
Adopt the alk*/fuzzing posture (alkcall 0.8.1 + alktunnels 0.2.1 precedent) before the v0.1 publish — the cheapest moment this crate will ever have for it: - alkcall 0.8.1 + alktunnels 0.2.1: the duplicate-adopt/open fix is directly relevant to this crate's consumer open/adopt paths - fuzz/ workspace (the sibling layout): nightly-pinned subtree, stable fuzz/shared library (corpus replay = the fuzz gate), detached runner, JSON dict, deterministic seed generator; 129 committed seeds - three wave-1 targets over already-pub APIs: datagram_codec (the ASSOCIATE frame codec — the alkcall-fuzz-doc-assigned downstream target), rfc1928_codec (the forked RFC 1928 core's handshake state machines, both protocol directions), params_parse (the wire-stable open-op surface) - one diagnostic: DatagramReader::retained_bytes() (the decoder-state bound's assertion target, the alktunnels retained_bytes() posture) - docs/research/fuzzing.md: the scoped plan + implementation log; AGENTS.md gains the corpus-replay verification line - campaigns: 3 × 10-min detached runs exited 0 (datagram ~1.9M execs, rfc1928 ~2.0M, params ~3.1M; oom/timeout/crash 0/0/0 on all 33 fork jobs per target; coverage saturated on both codec targets). No crate bugs; three harness-model defects found + fixed (2 pre-campaign by corpus replay, 2 campaign-found, crash inputs promoted as seeds 900/ 901): the len==0 well-framed decode partition, the fieldless-struct serde-seq form, the BadAtyp re-frame arm, the short-domain count-walk gate - wave 2 (session_pumps stateful target) deferred to post-0.1 — the byte-level targets carry the attacker-reachable load for the publish Verification: cargo test (15 suites ok, default + all-features), clippy (all-targets + wasm + fuzz/shared), fmt, cargo doc, publish --dry-run, corpus replay 129 seeds green, cargo fuzz build clean. Refs: alkcall docs/research/fuzzing.md (§7.9 posture), alktunnels docs/research/fuzzing.md; docs/research/fuzzing.md (this crate's copy)
This commit is contained in:
1 parent
8af23eeee0
commit
08a3694464
149 files changed
+1822
-5
No files matched your search
@@ -0,0 +1,7 @@
|
||||
target
|
||||
corpus/*
|
||||
!corpus/datagram_codec
|
||||
!corpus/rfc1928_codec
|
||||
!corpus/params_parse
|
||||
artifacts
|
||||
coverage
|
||||
@@ -0,0 +1,38 @@
|
||||
[package]
|
||||
name = "alksocks-fuzz"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
libfuzzer-sys = "0.4"
|
||||
alksocks-fuzz-shared = { path = "shared" }
|
||||
|
||||
[dependencies.alksocks]
|
||||
path = ".."
|
||||
|
||||
[[bin]]
|
||||
name = "datagram_codec"
|
||||
path = "fuzz_targets/datagram_codec.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
|
||||
[[bin]]
|
||||
name = "rfc1928_codec"
|
||||
path = "fuzz_targets/rfc1928_codec.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
|
||||
[[bin]]
|
||||
name = "params_parse"
|
||||
path = "fuzz_targets/params_parse.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
|
||||
[workspace]
|
||||
@@ -0,0 +1,55 @@
|
||||
# alksocks fuzzing
|
||||
|
||||
libFuzzer targets for alksocks' wire surfaces (see
|
||||
`docs/research/fuzzing.md` for the full rationale and campaign plan).
|
||||
|
||||
## Layout
|
||||
|
||||
- `fuzz_targets/` — one binary per target; thin `fuzz_target!` wrappers.
|
||||
- `shared/` — the invariant logic, as a plain library so normal
|
||||
`cargo test` (stable toolchain) can replay the committed corpora
|
||||
through the same invariants (`fuzz/shared/src/*.rs` `#[cfg(test)]`
|
||||
modules; quinn's CI pattern). The fuzz binaries are nightly-only;
|
||||
the shared crate is stable-clean.
|
||||
- `corpus/<target>/` — committed hand-made seeds (regenerate with
|
||||
`python3 fuzz/gen_fuzz_seeds.py` from the repo root). Grown corpora
|
||||
and artifacts are gitignored.
|
||||
- `run-detached.sh` — mandatory runner for agent sessions: wraps
|
||||
`cargo fuzz run` in `setsid` + `nohup` + log redirection so an OOM
|
||||
in a target can never take down the agent host (research doc §5).
|
||||
- `json.dict` — JSON token dictionary for the params target.
|
||||
|
||||
## Targets
|
||||
|
||||
| Target | Drives | Invariants |
|
||||
|---|---|---|
|
||||
| `datagram_codec` | `DatagramReader::feed` / `frame` / `frame_inner` (`src/wire.rs`) | no-panic; infallible reassembly with the decode-error partition; empty-payload F-2 layering; bad-ATYP loudness; splitting transparency; round-trips; the joint bound (incl. the 65766 shape); the decoder-state retained-bytes bound |
|
||||
| `rfc1928_codec` | the forked RFC 1928 core (`src/rfc1928/`): `read_address`, the server typestate handshake, the RFC 1929 sub-handshake, the RFC UDP header codec, `ReplyError::from_u8` | no-panic on any byte sequence, both protocol directions; typed failures only (the F-1 class); round-trips; the full-domain reply table |
|
||||
| `params_parse` | `Socks5Params` / `socks5_open_spec()` / the reason surface (`src/params.rs`) | no-panic; the trivial-params pin; the spec is a constant (the wire-stable ADR-001 surface + the schema/typed-view drift guard); the pass-through reason-extraction posture |
|
||||
|
||||
## Commands
|
||||
|
||||
`cargo fuzz build` and `cargo fuzz run` must be executed with `fuzz/`
|
||||
(or deeper) as the working directory so rustup selects the pinned
|
||||
nightly toolchain — the detached runner handles that itself.
|
||||
|
||||
```sh
|
||||
# build (nightly, pinned by rust-toolchain.toml inside fuzz/; run from fuzz/)
|
||||
cargo fuzz build
|
||||
|
||||
# agent sessions: detached campaign (never foreground; CWD-independent)
|
||||
FUZZ_RUNTIME_SECS=600 fuzz/run-detached.sh datagram_codec -max_len=65536
|
||||
FUZZ_RUNTIME_SECS=600 fuzz/run-detached.sh rfc1928_codec -max_len=4096 -use_value_profile=1
|
||||
FUZZ_RUNTIME_SECS=600 fuzz/run-detached.sh params_parse -dict=json.dict -use_value_profile=1
|
||||
|
||||
# corpus replay through the invariants (stable toolchain, no nightly)
|
||||
cargo test --manifest-path fuzz/shared/Cargo.toml
|
||||
|
||||
# coverage
|
||||
cargo fuzz coverage <target>
|
||||
```
|
||||
|
||||
The fuzz workspace is excluded from the main workspace and from the
|
||||
published package (`exclude` in the root `Cargo.toml`); it pins its own
|
||||
nightly toolchain via `rust-toolchain.toml` and does not affect the
|
||||
crate's stable MSRV.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{"resource": "sneaky"}
|
||||
@@ -0,0 +1 @@
|
||||
{"substrate": "tcp"}
|
||||
@@ -0,0 +1 @@
|
||||
{"code": "channel:open_failed", "details": {"reason": "dial_failed"}}
|
||||
@@ -0,0 +1 @@
|
||||
{"code": "channel:open_failed", "details": {"reason": "made_up_reason"}}
|
||||
@@ -0,0 +1 @@
|
||||
{"code": "FORBIDDEN", "details": {"reason": "no"}}
|
||||
@@ -0,0 +1 @@
|
||||
{"reason": {"enum": ["dial_failed", 1]}}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
{"nested": {"deep": {"deeper": [1, {"a": null}]}}}
|
||||
@@ -0,0 +1 @@
|
||||
{"channel_open": {"alpn": "alk/tunnel"}}
|
||||
@@ -0,0 +1 @@
|
||||
{"access_control": {"required_scopes": ["socks5:open"]}}
|
||||
@@ -0,0 +1 @@
|
||||
{"details": {"reason": 1}}
|
||||
@@ -0,0 +1 @@
|
||||
{"details": {"reason": {"enum": "dial_failed"}}}
|
||||
@@ -0,0 +1 @@
|
||||
{"code": {"channel:open_failed": true}, "details": null}
|
||||
@@ -0,0 +1 @@
|
||||
{"type": "object", "additionalProperties": false}
|
||||
@@ -0,0 +1 @@
|
||||
"{}"
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
{"a": {"a": {"a": {"a": {"a": {"a": {"a": {"a": {"a": {"a": {"a": {"a": 1}}}}}}}}}}}}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
�uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu�ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp
|
||||
Binary file not shown.
Binary file not shown.
Loaded 100 of 149 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user