feat(fuzz): add pdu_round_trip oracle and target#1291
feat(fuzz): add pdu_round_trip oracle and target#1291Greg Lamberson (glamberson) wants to merge 1 commit into
Conversation
Adds a fuzz oracle that exercises decode -> encode_vec -> re-decode for each PDU type currently covered by pdu_decode, plus a dedicated pdu_round_trip target binary (auto-discovers into CI per Devolutions#1290). The property tested is *no internal panic from inside the encoder or decoder when fed a decoder-accepted input through both directions of the round-trip*. Asymmetric Err returns (decoder accepts something the encoder reports as "Encoding not implemented", or vice-versa) are not in scope: those are tolerated incomplete-impl cases tracked separately. The oracle catches: - unreachable!() reached during encoding of a valid decoded state - Integer overflow / index-out-of-bounds inside the encoder on decoder-accepted inputs - Panics in the decoder when fed encoder-produced bytes (re-decode path) Initial type coverage mirrors pdu_decode minus two known-asymmetric types that hit `unreachable!()` in the encoder: - `capability_sets::CapabilitySet`: encoder match at crates/ironrdp-pdu/src/rdp/capability_sets/mod.rs:447 reaches `unreachable!()` on a variant the decoder accepts but the encoder's match arms don't cover. Smoke-fuzz reproducer: `[6, 0, 4, 0]`. - `headers::ShareControlHeader`: transits through CapabilitySet's encoder for DemandActive/ConfirmActive PDU contents and hits the same internal panic. Both are tracked as follow-up filings; the oracle re-includes them once the encoder's match arms are completed. Verification: - cargo xtask check fmt/lints/typos/locks/tests all green - check_pdu_round_trip regression-replay test passes - 60-second smoke fuzz: 2,220,481 runs, no crashes on the current type set Refs Devolutions#1120 (umbrella) and Devolutions#1124 (oracle infrastructure).
|
Filed #1292 for the underlying |
There was a problem hiding this comment.
Pull request overview
Adds a new fuzzing oracle and target to exercise PDU decode/encode round-trips, with a companion regression-replay test to ensure minimized inputs remain covered in CI. This extends the existing fuzz oracle suite in ironrdp-fuzzing and integrates cleanly with the fuzz target discovery CI approach referenced in #1290.
Changes:
- Add
pdu_round_triporacle that performsdecode -> encode_vec -> re-decode, droppingErrresults but surfacing internal panics. - Add a dedicated
pdu_round_triplibFuzzer target and register it infuzz/Cargo.toml. - Add regression-replay coverage via
check_pdu_round_tripplus an initial (empty) seed corpus file.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
crates/ironrdp-fuzzing/src/oracles/mod.rs |
Adds the pdu_round_trip oracle and helper macro, mirroring the pdu_decode type list with documented exclusions. |
fuzz/fuzz_targets/pdu_round_trip.rs |
New fuzz target wrapper calling the oracle on raw input bytes. |
fuzz/Cargo.toml |
Registers the new fuzz target as a [[bin]] so it’s discoverable/buildable. |
crates/ironrdp-testsuite-core/tests/fuzz_regression.rs |
Adds a regression-replay test entry for the new oracle. |
crates/ironrdp-testsuite-core/test_data/fuzz_regression/pdu_round_trip/seed-empty.bin |
Seeds the regression folder so the replay test has at least one input to run. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
There's real overlap.
The type lists also differ slightly: This matches the existing workspace pattern too: |
Summary
Adds a fuzz oracle and dedicated target for round-trip exercise of PDU
encode/decode pathways. For each PDU type currently covered by
pdu_decode, the oracle attemptsdecode->encode_vec-> re-decodeon the encoded bytes. Auto-discovers into CI per #1290.
Property tested
No internal panic from inside the encoder or decoder when fed a
decoder-accepted input through both directions of the round-trip.
Asymmetric
Errreturns (decoder accepts something the encoder reportsas
"Encoding not implemented", or vice-versa) are NOT in scope here:those are tolerated incomplete-impl cases tracked separately. The
oracle silently drops
Errresults from any of the three stages.What this catches:
unreachable!()reached during encoding of a valid decoded state(i.e. the encoder's match arms are missing a variant the decoder
produces).
decoder-accepted inputs.
path).
Initial type coverage
Mirrors
pdu_decode's type list minus two exclusions documented inlinewith their reproducers. As new PDU types gain
Encodeimpls, theyextend coverage when added to the macro list.
Excluded pending follow-up
Two types are temporarily excluded because they hit
unreachable!()inthe encoder during smoke fuzzing, which is an internal-panic bug that
the oracle cannot silently drop:
capability_sets::CapabilitySet: the encoder's match atcrates/ironrdp-pdu/src/rdp/capability_sets/mod.rs:447reachesunreachable!()on a variant the decoder accepts but the encoder'smatch arms don't cover. Smoke-fuzz reproducer:
[6, 0, 4, 0].headers::ShareControlHeader: transits throughCapabilitySet'sencoder for
DemandActive/ConfirmActivePDU contents and hitsthe same internal panic.
Both inclusions return once the encoder's match arms are completed. I
will file the underlying bug as a separate issue and link it back here.
Files
crates/ironrdp-fuzzing/src/oracles/mod.rs: newpdu_round_tripfunction and
pdu_round_trip_one!helper macro.fuzz/fuzz_targets/pdu_round_trip.rs: new fuzz target binary.fuzz/Cargo.toml:[[bin]]entry for the new target.crates/ironrdp-testsuite-core/tests/fuzz_regression.rs: newcheck_pdu_round_tripregression-replay test.crates/ironrdp-testsuite-core/test_data/fuzz_regression/pdu_round_trip/seed-empty.bin:empty seed file for the regression-replay test.
Verification
cargo xtask check fmt -vgreencargo xtask check lints -vgreencargo xtask check typos -vgreencargo xtask check locks -vgreencargo xtask check tests -vgreen (includingcheck_pdu_round_trip)type set
cargo xtask fuzz list(per ci(fuzz): discover fuzz targets dynamically #1290)Refs #1120 (umbrella) and #1124 (oracle infrastructure).