# Image decoder plane dimension mismatch

Decoder sizes a plane from one mode/geometry table but fills it using a different channel count or resolution

_Area: Memory corruption and native code. Seen in 3 disclosed reports; latest 2026-10-23. Updated 2026-11-01._

## How it works
A decoder allocates an output buffer from one source of truth (a mode table, a component's declared resolution, a channel-association field) but fills it using another (the actual number of components libjpeg emits, the sample precision, a remapped channel's true size). When the two disagree, the write loop runs past the buffer. The broken assumption is that the geometry used to size a plane equals the geometry used to write into it. Any fallback branch, unrecognized mode string, or rarely-audited remapping field can break that equality.

## Where it shows up
- Mode/colorspace tables mapping an input identifier to a rawmode or pixel format, with a default/fallback branch for unrecognized values [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-5x8w-8jj5-q52h.md)
- Decoder code that reads component count or precision from the file header (SOF marker, sample precision) rather than from the buffer's declared format [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-5x8w-8jj5-q52h.md)[E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md)
- Sub-byte sample precision combined with mismatched per-component resolutions [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md)
- Channel-association / remapping fields (e.g. JPEG2000 cdef Asoc) that can point a full-resolution channel at a smaller plane [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md)
- Wrappers that "just pass bytes" to cv2/FFmpeg/ImageMagick/Ghostscript, inheriting codec-level bugs several layers down [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md)[E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md)
- Error strings returned to clients that embed heap addresses [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md)

## How to review
Find every buffer allocation and trace what sizes it versus what fills it. The invariant: bytes written per row/pixel must never exceed the allocated plane size for every reachable mode, including fallback and unknown paths. Check that the fallback branch's emitted component count matches the rawmode-sized buffer [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-5x8w-8jj5-q52h.md); that sub-byte samples are packed, not written one byte each [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md); and that channel remapping cannot direct a larger-resolution source into a smaller destination plane [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md). Confirm error paths don't leak addresses.

## How finders spotted it
- Compared the FPX MODES table against JpegDecode.c and noticed 'LA'/'YCC;P' rawmodes fall through to JCS_UNKNOWN, where libjpeg emits SOF num_components bytes/px into a rawmode-sized buffer [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-5x8w-8jj5-q52h.md)
- Traced an uploaded file past the PHP handler through Imagick/ImageMagick into Ghostscript's JPEG2000 decoder, then reduced to a tiny PDF differing by one byte in a component resolution field [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md)
- Followed vLLM's video_url into cv2.VideoCapture/FFmpeg, studied cdef channel-remapping semantics, and saw Y (W×H) could map into the smaller U plane; separately noticed PIL errors leaking BytesIO addresses [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md)

## Variants seen
- Unrecognized rawmode string falling to a generic colorspace path with a higher component count [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-5x8w-8jj5-q52h.md)
- Sub-byte precision with mismatched component resolutions overflowing a packed row buffer [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md)
- Channel-association remap writing full-res data into a quarter-res plane [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md)

## Impact and severity
All three reached RCE. E1 turned the heap overflow into control-flow hijack of a Python object vtable [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-5x8w-8jj5-q52h.md). E2 succeeded across four setups sharing one Ghostscript build, making it a mass-attack risk on shared container images [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md). E3 chained an ASLR-defeating info leak with an overflow scaling at 0.75×W×H, giving larger controlled writes [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md). Impact rises with reachability from mundane upload/fetch features and with any companion info leak.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-5x8w-8jj5-q52h.md
- E2: https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-4r2x-xpjr-7cvv.md
