Skip to content

Reject oversized sequence headers in the libgav1 codec - #3404

Open
17krishna8 wants to merge 1 commit into
AOMediaCodec:mainfrom
17krishna8:libgav1-frame-size-limit
Open

17krishna8 wants to merge 1 commit into
AOMediaCodec:mainfrom
17krishna8:libgav1-frame-size-limit

Conversation

@17krishna8

Copy link
Copy Markdown

Description

dav1d enforces the decoder's imageSizeLimit through its frame_size_limit setting, and libaom through the AOMD_SET_FRAME_SIZE_LIMIT codec control (or the aom_codec_peek_stream_info() + avifDimensionsTooLarge() fallback when that control is not available). The libgav1 API has no equivalent, so gav1CodecGetNextImage() handed the full data to libgav1 regardless of the maximum frame size declared by the AV1 sequence header:

  • a crafted AVIF whose sequence header declares max_frame 65536x65536 (way above the default imageSizeLimit of 16384x16384) is rejected by the dav1d and aom decoders, but libgav1 accepts the sequence header and proceeds to decode. The oversized dimensions are only caught after the fact, if at all, depending on the actual frame sizes.

Change

gav1CodecGetNextImage() now pre-parses the sequence header with avifSequenceHeaderParse() and rejects the sample when avifDimensionsTooLarge(maxWidth, maxHeight, codec->imageSizeLimit, codec->imageDimensionLimit), mirroring the libaom fallback path in codec_aom.c (same check, same error message). The check is skipped when no sequence header is found in the sample, so partial/incremental reads are unaffected.

With this change the same crafted file is rejected by every decoder libavif can be built with.

Test

CodecTest.OversizedSequenceHeaderRejected builds a hand-crafted minimal AVIF (no test data needed):

  • the item ispe advertises a small 64x64 image so parsing succeeds,
  • the mdat contains a hand-built sequence header OBU declaring a 65536x65536 maximum frame size,
  • for each available decoder (aom, dav1d, libgav1): avifDecoderParse must succeed and avifDecoderNextImage must fail,
  • for libgav1 specifically, the diagnostic must mention the oversized dimensions — this assertion fails at head (libgav1's diagnostic is just the generic tile->codec->getNextImage() failed) and passes with this change.

Verified locally with a AVIF_CODEC_LIBGAV1=LOCAL build (libgav1 from ext/), plus avifdecodetest/avifreadimagetest regressions on the regular build.

Suggested changelog entry: libgav1 now rejects AV1 sequence headers exceeding the decoder's image size limits, like dav1d and libaom already did.

dav1d enforces the decoder's imageSizeLimit through its frame_size_limit
setting, and libaom through AOMD_SET_FRAME_SIZE_LIMIT (or the
aom_codec_peek_stream_info() fallback for older versions). The libgav1
API has no equivalent, so gav1CodecGetNextImage() handed the full data
to libgav1 regardless of the maximum frame size declared by the AV1
sequence header, and the oversized frames were only caught after the
fact, if at all.

Pre-parse the sequence header with avifSequenceHeaderParse() and reject
the sample with avifDimensionsTooLarge(), matching the libaom fallback.
The same crafted file is now rejected by every decoder libavif builds
with.

CodecTest.OversizedSequenceHeaderRejected builds a hand-crafted minimal
AVIF whose sequence header declares a 65536x65536 maximum frame size
behind a small ispe. It fails at head (libgav1 accepts the sequence
header) and passes with this change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant