Add hostile-network tests, parser fuzzing, and CI fuzz job

Track B (milestone 5 / §16 hardening):

- tests/hostile_network.rs: in-process UDP relay/shim between a test
  client and a real dosh-server that can drop, reorder, and duplicate
  datagrams, and rebind its upstream socket mid-session. Asserts:
  session survives loss/reorder, duplicated/replayed Input is applied at
  most once, stale packets after resume are ignored (not fatal), and a
  client source-address change preserves the session.
- tests/parser_robustness.rs: deterministic randomized tests throwing
  garbage at every reachable public parser (packet decode, from_body for
  all protocol/native structs, authorized_keys, known_hosts, host-key
  line, ssh-ed25519 blob, bootstrap, attach ticket); asserts none panic.
- fuzz/: standalone cargo-fuzz crate (own [workspace], non-default
  member) with libfuzzer-sys harnesses for packet decode, from_body,
  authorized_keys, known_hosts, handshake structs+verifiers, and attach
  tickets. README documents the run command.
- .github/workflows/ci.yml: add fuzz-smoke job (nightly + cargo-fuzz,
  short -max_total_time per target, tolerant if tooling unavailable);
  existing fmt/test/build/bench steps unchanged.

cargo fmt --check and cargo test are green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
DuProcess
2026-06-14 10:31:47 -04:00
parent 6c14d669b8
commit 9b0f09a8a8
12 changed files with 1537 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
[package]
name = "dosh-fuzz"
version = "0.0.0"
publish = false
edition = "2021"
# Standalone workspace so this crate is never absorbed by, and never affects,
# the main `dosh` crate's `cargo build` / `cargo test` / `cargo fmt --check`.
[workspace]
[package.metadata]
cargo-fuzz = true
[dependencies]
libfuzzer-sys = "0.4"
[dependencies.dosh]
path = ".."
# cargo-fuzz needs unwinding to report panics; keep debug assertions on.
[profile.release]
debug = 1
[[bin]]
name = "packet_decode"
path = "fuzz_targets/packet_decode.rs"
test = false
doc = false
bench = false
[[bin]]
name = "from_body"
path = "fuzz_targets/from_body.rs"
test = false
doc = false
bench = false
[[bin]]
name = "authorized_keys"
path = "fuzz_targets/authorized_keys.rs"
test = false
doc = false
bench = false
[[bin]]
name = "known_hosts"
path = "fuzz_targets/known_hosts.rs"
test = false
doc = false
bench = false
[[bin]]
name = "handshake_structs"
path = "fuzz_targets/handshake_structs.rs"
test = false
doc = false
bench = false
[[bin]]
name = "attach_ticket"
path = "fuzz_targets/attach_ticket.rs"
test = false
doc = false
bench = false