Skip to content

Fix heap overflow and underflow in EXR decoder#214

Open
sharadboni wants to merge 1 commit intogoogle:mainfrom
sharadboni:fix/security-exr-decoder-bounds-checks
Open

Fix heap overflow and underflow in EXR decoder#214
sharadboni wants to merge 1 commit intogoogle:mainfrom
sharadboni:fix/security-exr-decoder-bounds-checks

Conversation

@sharadboni
Copy link
Copy Markdown

Summary

Two memory-safety fixes in lib/extras/dec/exr.cc (DecodeImageEXR):

Heap overflow — non-overlapping data/display windows (exr.cc:365)

When the EXR data window and display window have no horizontal overlap,
exr_x1 = max(dataWindow.min.x, displayWindow.min.x) and
exr_x2 = min(dataWindow.max.x, displayWindow.max.x) satisfy exr_x2 < exr_x1.
The expression (exr_x2 - exr_x1 + 1) is then negative, which wraps to a
very large size_t, and the subsequent memcpy reads and writes far beyond
the allocated buffer.

Fix: guard the copy block with if (exr_x1 <= exr_x2) so it is skipped when
the windows have no horizontal overlap.

Heap underflow write — extra-channel framebuffer stride mismatch (exr.cc:332–334)

The virtual base pointer for extra-channel framebuffer slices was computed
once using the aggregate extraPixelBytes stride (sum of all extra-channel
sizes) and then shared across every channel's OpenEXR::Slice. When
dataWindow.min.x > 0 and there are multiple extra channels whose individual
sizes differ from extraPixelBytes, the shared offset walks the pointer before
the start of the allocation.

Fix: compute an independent ch_base_ptr for each channel using that
channel's own per-element size as the stride, matching the per-channel
stride passed to Slice.

Two bounds-safety fixes in DecodeImageEXR:

1. Heap overflow (exr.cc:365): when the EXR data window and display
   window have no horizontal overlap, exr_x2 < exr_x1 and the expression
   (exr_x2 - exr_x1 + 1) wraps to a very large size_t, causing memcpy to
   read and write far beyond the allocated buffer.  Guard the copy block
   with `if (exr_x1 <= exr_x2)` so it is skipped when the windows do not
   overlap.

2. Heap underflow write (exr.cc:332-334): the virtual base pointer for
   extra-channel framebuffer slices was computed once using the aggregate
   extraPixelBytes stride and then shared across all extra channels.
   When dataWindow.min.x > 0 and there are multiple extra channels with
   different per-channel sizes, the shared offset calculation walks the
   base pointer before the start of the allocation.  Fix by computing an
   independent ch_base_ptr for each channel using that channel's own size
   as the stride.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant