Skip to content

Commit f5beec2

Browse files
authored
Security: fix signed integer overflow in undo_pxr24_impl() (PXR24 decoder) (#2323)
In the `EXR_PIXEL_FLOAT` branch of `undo_pxr24_impl()`, the expressions (uint64_t)(w * 3) compute the signed 32-bit product `w * 3` before the cast to `uint64_t`. When `w` is large this is undefined behavior under the C standard; on two's-complement builds without sanitizers the result wraps to a small positive value, which can cause the bounds check if (nDec + (uint64_t)(w * 3) > outSize) to pass incorrectly. If the check is bypassed the decode loop proceeds to write `4*w` bytes through `dout`, potentially far beyond the allocated output buffer. Fix: cast `w` to `uint64_t` before multiplying so that both the bounds check and the counter update are performed entirely in 64-bit unsigned arithmetic: (uint64_t)w * 3 (cast before multiply, not after) The `EXR_PIXEL_UINT` and `EXR_PIXEL_HALF` decode branches are unaffected: they reuse the pre-computed `nBytes` variable, which is already formed as `(uint64_t)(w) * (uint64_t)(bytes_per_element)`. Also fix the symmetric issue in `apply_pxr24_impl()` (the encoder): lastIn += w * 4 advances a pointer by a signed 32-bit product; corrected to lastIn += (uint64_t)w * 4 Made-with: Cursor Signed-off-by: Cary Phillips <cary@ilm.com>
1 parent 2c19a5a commit f5beec2

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

src/lib/OpenEXRCore/internal_pxr24.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ apply_pxr24_impl (exr_encode_pipeline_t* encode)
182182
if (nOut + nBytes > encode->scratch_alloc_size_1)
183183
return EXR_ERR_OUT_OF_MEMORY;
184184
nOut += nBytes;
185-
lastIn += w * 4;
185+
lastIn += (uint64_t) w * 4;
186186

187187
ptr[0] = out;
188188
out += w;
@@ -374,7 +374,7 @@ undo_pxr24_impl (
374374
ptr[2] = lastIn;
375375
lastIn += w;
376376

377-
if (nDec + (uint64_t) (w * 3) > outSize)
377+
if (nDec + (uint64_t) w * 3 > outSize)
378378
return EXR_ERR_CORRUPT_CHUNK;
379379

380380
for (int x = 0; x < w; ++x)
@@ -387,7 +387,7 @@ undo_pxr24_impl (
387387
unaligned_store32 (dout, pixel);
388388
++dout;
389389
}
390-
nDec += (uint64_t) (w * 3);
390+
nDec += (uint64_t) w * 3;
391391
break;
392392
}
393393
default: return EXR_ERR_INVALID_ARGUMENT;

0 commit comments

Comments
 (0)