Skip to content

Commit f5f7f32

Browse files
cary-ilmmusicinmybrain
authored andcommitted
Security: fix signed integer overflow in undo_pxr24_impl() (PXR24 decoder) (PixarAnimationStudios#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 0512b6c commit f5f7f32

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

pxr/imaging/plugin/hioOpenEXR/OpenEXR/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;
@@ -371,7 +371,7 @@ undo_pxr24_impl (
371371
ptr[2] = lastIn;
372372
lastIn += w;
373373

374-
if (nDec + (uint64_t) (w * 3) > outSize)
374+
if (nDec + (uint64_t) w * 3 > outSize)
375375
return EXR_ERR_CORRUPT_CHUNK;
376376

377377
for (int x = 0; x < w; ++x)
@@ -384,7 +384,7 @@ undo_pxr24_impl (
384384
unaligned_store32 (dout, pixel);
385385
++dout;
386386
}
387-
nDec += (uint64_t) (w * 3);
387+
nDec += (uint64_t) w * 3;
388388
break;
389389
}
390390
default: return EXR_ERR_INVALID_ARGUMENT;

0 commit comments

Comments
 (0)