feat(fuzz): add egfx_avc420_decode oracle and target#1326
Open
Greg Lamberson (glamberson) wants to merge 1 commit into
Open
feat(fuzz): add egfx_avc420_decode oracle and target#1326Greg Lamberson (glamberson) wants to merge 1 commit into
Greg Lamberson (glamberson) wants to merge 1 commit into
Conversation
This change adds an assertion-or-panic fuzz oracle for the AVC length-prefix to Annex-B conversion that runs inside `OpenH264Decoder::decode` before any OpenH264 entry point. The same change refactors the conversion from a private method on `OpenH264Decoder` into two public free functions in `ironrdp_egfx::pdu::avc`. The first function, `avc_to_annex_b`, returns a fresh `Vec<u8>` and is symmetric with the existing `annex_b_to_avc`. The second function, `avc_to_annex_b_into`, writes into a caller-provided buffer and preserves the per-frame buffer-reuse optimization that `OpenH264Decoder` relied on. The conversion is now available unconditionally to any consumer of `ironrdp-egfx`. The previous `#[cfg(feature = "openh264")]` gating went with the location, not the bytes-to-bytes logic, so lifting the function out of `decode.rs` removed the gate too. The new oracle exercises two input distributions on every fuzz call: - Direct path: the oracle calls `avc_to_annex_b(data)` on the raw fuzz input. This exercises the wrapper on arbitrary byte distributions, including inputs that do not parse as `Avc420BitmapStream`. - Decode-chain path: the oracle tries `Avc420BitmapStream::decode(data)`; on success it calls `avc_to_annex_b(stream.data)`. This exercises the wrapper on the realistic post-decode payload distribution. The oracle catches panics in the wrapper, OOM allocation from attacker-controlled NAL length encoding, and contract violations on the produced Annex-B byte stream. The oracle does NOT catch OpenH264 internal bugs (OSS-Fuzz coverage), the YUV-to-RGBA conversion path downstream of OpenH264 (separate workstream), or AVC444 luma plus chroma split (sibling target). Smoke fuzz ran 10,922,695 iterations in 31 seconds at ~352K exec/s sustained with zero crashes. Coverage settled at 158 lines, 456 features, 69 corpus entries. The new target auto-discovers into CI via the `cargo xtask fuzz list` dynamic fan-out mechanism. The new `check_egfx_avc420_decode` regression-replay test in `crates/ironrdp-testsuite-core/tests/fuzz_regression.rs` runs against the seed corpus and passes. Refs Devolutions#1316.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change adds an assertion-or-panic fuzz oracle for the AVC
length-prefix to Annex-B conversion that runs inside
OpenH264Decoder::decodebefore any OpenH264 entry point. The samechange refactors the conversion from a private method on
OpenH264Decoderinto two public free functions inironrdp_egfx::pdu::avc. The first function,avc_to_annex_b,returns a fresh
Vec<u8>and is symmetric with the existingannex_b_to_avc. The second function,avc_to_annex_b_into, writesinto a caller-provided buffer and preserves the per-frame buffer-reuse
optimization that
OpenH264Decoderrelied on.The conversion is now available unconditionally to any consumer of
ironrdp-egfx. The previous#[cfg(feature = "openh264")]gatingwent with the location, not the bytes-to-bytes logic, so lifting the
function out of
decode.rsremoved the gate too.The new oracle exercises two input distributions on every fuzz call:
avc_to_annex_b(data)on the raw fuzzinput. This exercises the wrapper on arbitrary byte distributions,
including inputs that do not parse as
Avc420BitmapStream.Avc420BitmapStream::decode(data);on success it calls
avc_to_annex_b(stream.data). This exercises thewrapper on the realistic post-decode payload distribution.
The oracle catches panics in the wrapper, OOM allocation from
attacker-controlled NAL length encoding, and contract violations on the
produced Annex-B byte stream. The oracle does NOT catch OpenH264
internal bugs (OSS-Fuzz coverage), the YUV-to-RGBA conversion path
downstream of OpenH264 (separate workstream), or AVC444 luma plus
chroma split (sibling target).
Smoke fuzz ran 10,922,695 iterations in 31 seconds at ~352K exec/s
sustained with zero crashes. Coverage settled at 158 lines, 456
features, 69 corpus entries.
The new target auto-discovers into CI via the
cargo xtask fuzz listdynamic fan-out mechanism. The new
check_egfx_avc420_decoderegression-replay test in
crates/ironrdp-testsuite-core/tests/fuzz_regression.rsruns againstthe seed corpus and passes.
Refs #1316.