test(proto): add decoder fuzzing
Add isolated cargo-fuzz/libFuzzer infrastructure for irtt-proto, fuzzing decode_request, decode_open_reply, decode_echo_reply, Params::decode(_with_presence), and the varint codec against arbitrary and structurally-derived wire input. Each target's core invariant is that arbitrary bytes must never panic; a small clean-room seed corpus (generated from irtt-proto's own encoders) and a bounded nightly smoke CI workflow are included. The fuzz project is its own isolated cargo workspace and does not affect the root workspace, its lockfile, or any published crate's dependency graph.
This commit is contained in:
29 files changed
+766
No files matched your search
@@ -0,0 +1,45 @@
|
||||
#![no_main]
|
||||
|
||||
use irtt_proto::{decode_request, verify_packet_hmac, DecodedRequestKind, Params};
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
|
||||
/// Keeps individual cases bounded so libFuzzer explores protocol structure
|
||||
/// instead of spending time allocating/copying megabytes. This is UDP wire
|
||||
/// protocol code; production datagrams are well under this bound.
|
||||
const MAX_INPUT_LEN: usize = 128 * 1024;
|
||||
|
||||
/// Fixed key used only to exercise the HMAC verification path. Never treated
|
||||
/// as a secret.
|
||||
const FUZZ_HMAC_KEY: &[u8] = b"fuzz-decode-request-key";
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
if data.len() > MAX_INPUT_LEN {
|
||||
return;
|
||||
}
|
||||
|
||||
// The core invariant: arbitrary bytes must never panic. Ok/Err are both
|
||||
// normal outcomes.
|
||||
let decoded = match decode_request(data) {
|
||||
Ok(decoded) => decoded,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
match decoded.kind {
|
||||
DecodedRequestKind::Open { params, .. } => {
|
||||
// Structural Open decoding deliberately permits malformed
|
||||
// parameter bytes; both Ok and Err from the secondary parser are
|
||||
// acceptable, and a structurally decoded Open is not required to
|
||||
// contain valid Params.
|
||||
let _ = Params::decode(params);
|
||||
}
|
||||
DecodedRequestKind::Close { .. } | DecodedRequestKind::Echo { .. } => {
|
||||
// No token/session policy belongs here; that's above irtt-proto.
|
||||
}
|
||||
}
|
||||
|
||||
if decoded.hmac_present {
|
||||
// Most arbitrary HMAC fields will fail authentication; both outcomes
|
||||
// are acceptable, we're only exercising the verifier for panics.
|
||||
let _ = verify_packet_hmac(FUZZ_HMAC_KEY, data);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user