GHSA-m5cq-cx25-qw53
CVE Information
Summary
chunk.c validates three deep-scanline leader fields asymmetrically:
- ddata[1] (packed_size): checked
< 0 || > INT_MAX✓- ddata[2] (unpacked_size): checked
< 0 || > INT_MAX✓- ddata[0] (sample_count_table_size): checked
< 0only — missing> INT_MAX✗Vulnerable Code
chunk.c line ~1009:
if (ddata[0] < 0) { return error(...); } // NO INT_MAX cap if (ddata[1] < 0 || ddata[1] > (int64_t) INT_MAX) { return error(...); } // correct if (ddata[2] < 0 || ddata[2] > (int64_t) INT_MAX) { return error(...); } // correct cinfo->sample_count_table_size = (uint64_t) ddata[0]; // can be > 2^32decoding.c line ~165:
rv = internal_decode_alloc_buffer( decode, EXR_TRANSCODE_BUFFER_PACKED_SAMPLES, &(decode->packed_sample_count_table), &(decode->packed_sample_count_alloc_size), decode->chunk.sample_count_table_size); // uint64_t truncated to size_t on ILP32chunk.c exr_read_deep_chunk line ~1635:
toread = cinfo->sample_count_table_size; // full uint64 value rv = ctxt->do_read(ctxt, sample_data, toread, ...); // writes toread bytes into truncated bufferImpact
On ILP32 / 32-bit size_t builds (32-bit Linux, 32-bit Windows, wasm32): A deep EXR with sample_count_table_size >= 2^32 truncates the allocation, then exr_read_deep_chunk writes the full 64-bit byte count into the undersized buffer → heap buffer overflow.
Relationship to Recent Fixes
Same missing guard pattern fixed in: - commit b78496b3: RLE decode added
if (X != (size_t)X) return OOM- commit 3a4214aa: B44/B44A decode added same guardThe guard was applied to sibling fields but not to sample_count_table_size.
Fix
In chunk.c change line ~1009 from:
to:if (ddata[0] < 0)if (ddata[0] < 0 || ddata[0] > (int64_t) INT_MAX)