fix(jpeg2000): guard against oversized and decompression-bomb headers before decode#5327
Open
lgritz wants to merge 2 commits into
Open
fix(jpeg2000): guard against oversized and decompression-bomb headers before decode#5327lgritz wants to merge 2 commits into
lgritz wants to merge 2 commits into
Conversation
… before decode check_open() validated the resolution only after opj_decode() had already run, so a corrupt or malicious header could make openjpeg spend a long time and allocate a huge buffer before OIIO ever rejected the file. Add two pre-decode guards right after opj_read_header(): 1. Build a provisional ImageSpec from the header's canvas size and per-component precision (channel count can still grow later from palette expansion, but that only makes the image larger, so the header-based estimate is a safe lower bound), and run it through check_open() before calling opj_decode(). 2. That absolute-size check alone isn't enough: a 171-byte fuzzed codestream declared a 32 x 50331680 image (9216 MB), under the default limits:imagesize_MB (32 GB), so opj_decode still hung allocating ~9 GB and decoding 1.6 billion pixels. Add a decompression-bomb check that rejects when the claimed uncompressed size both exceeds 1 GB and dwarfs the actual file size by more than 10000x -- a ratio far beyond anything a real JPEG2000 codestream produces. The existing post-decode check_open() call stays in place as the authoritative check once the final channel count is known. Verified the openjpeg conformance suite still decodes correctly, so neither guard rejects real files. Also drop dead commented-out debug std::cout lines and an unused chantypes vector left over from earlier work. Assisted-by: Claude Code / Claude Opus 4.8 Signed-off-by: Larry Gritz <lg@larrygritz.com>
Signed-off-by: Larry Gritz <lg@larrygritz.com>
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.
check_open() validated the resolution only after opj_decode() had already run, so a corrupt or malicious header could make openjpeg spend a long time and allocate a huge buffer before OIIO ever rejected the file.
Add two pre-decode guards right after opj_read_header():
Build a provisional ImageSpec from the header's canvas size and per-component precision (channel count can still grow later from palette expansion, but that only makes the image larger, so the header-based estimate is a safe lower bound), and run it through check_open() before calling opj_decode().
Add a decompression-bomb check that rejects when the claimed uncompressed size both exceeds 1 GB and dwarfs the actual file size by more than 10000x -- a ratio far beyond anything a real JPEG2000 codestream produces.
The existing post-decode check_open() call stays in place as the authoritative check once the final channel count is known.
Also drop dead commented-out debug std::cout lines and an unused chantypes vector left over from earlier work.
Assisted-by: Claude Code / Claude Opus 4.8