Commit e464a33
authored
fix integer overflow in PIZ wavelet buffer arithmetic (#2328)
Three classes of signed integer overflow in the PIZ codec path, all
reachable from corrupt `dataWindow` dimensions in the EXR file header.
**`wav_2D_encode` / `wav_2D_decode` — wavelet loop pointer arithmetic**
`oy` is passed as `int` (value `wcount * nx`, at most ~INT32_MAX after
the guard below). Inside the hierarchical wavelet loop the expressions
ey = in + oy * (ny - p2) // pointer end-of-row sentinel
oy1 = oy * p // row stride at level p
oy2 = oy * p2 // row stride at level p2
multiply two values that can each approach INT32_MAX, producing a
signed 32-bit product that wraps to a small or negative value. The
wrapped value is used as a pointer offset, causing reads and writes
through `px` / `py` to land outside the allocated wavelet buffer.
Fix: widen by introducing `int64_t oy64 = oy` and using it for all
three expressions; `oy1` and `oy2` are also declared `int64_t`.
**`wavbuf += nx * ny * wcount` — per-channel buffer advance**
`nx`, `ny`, and `wcount` are all `int`. Their triple product overflows
int32 for moderately large images, causing subsequent channels to be
processed at an incorrect (too-small) offset into the wavelet buffer,
corrupting both encode and decode output.
Fix: cast to `(uint64_t)` before multiplying.
**`wcount * nx` — call-site argument overflow**
The fifth argument to `wav_2D_encode` / `wav_2D_decode` is `wcount * nx`
(`oy` = y-stride = elements per row). `wcount` is 1 or 2
(`bytes_per_element / 2`); for `wcount = 2` the product overflows int32
when `nx > INT32_MAX / 2`.
Fix: add an early bounds check `if (wcount > 0 && nx > INT_MAX / wcount)`
that rejects such input as `EXR_ERR_CORRUPT_CHUNK` before any arithmetic
is performed. This also keeps `wcount * nx` within int32 range at the
call site, ensuring `oy` arrives in the wavelet functions with a valid
non-overflowed value.
Made-with: Cursor
Signed-off-by: Cary Phillips <cary@ilm.com>1 parent f5beec2 commit e464a33
1 file changed
Lines changed: 23 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
232 | 233 | | |
233 | 234 | | |
234 | 235 | | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
239 | 241 | | |
240 | 242 | | |
241 | 243 | | |
| |||
244 | 246 | | |
245 | 247 | | |
246 | 248 | | |
247 | | - | |
248 | | - | |
249 | | - | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
250 | 252 | | |
251 | 253 | | |
252 | 254 | | |
| |||
345 | 347 | | |
346 | 348 | | |
347 | 349 | | |
348 | | - | |
349 | | - | |
350 | | - | |
351 | | - | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
352 | 355 | | |
353 | 356 | | |
354 | 357 | | |
| |||
368 | 371 | | |
369 | 372 | | |
370 | 373 | | |
371 | | - | |
372 | | - | |
373 | | - | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
374 | 377 | | |
375 | 378 | | |
376 | 379 | | |
| |||
566 | 569 | | |
567 | 570 | | |
568 | 571 | | |
| 572 | + | |
| 573 | + | |
569 | 574 | | |
570 | 575 | | |
571 | 576 | | |
572 | 577 | | |
573 | | - | |
| 578 | + | |
574 | 579 | | |
575 | 580 | | |
576 | 581 | | |
| |||
722 | 727 | | |
723 | 728 | | |
724 | 729 | | |
| 730 | + | |
| 731 | + | |
725 | 732 | | |
726 | 733 | | |
727 | 734 | | |
728 | 735 | | |
729 | | - | |
| 736 | + | |
730 | 737 | | |
731 | 738 | | |
732 | 739 | | |
| |||
0 commit comments