Fix heap buffer overflow in JPEG encoder xsize/ysize handling#213
Fix heap buffer overflow in JPEG encoder xsize/ysize handling#213sharadboni wants to merge 1 commit intogoogle:mainfrom
Conversation
|
Hi @eustas — would you be able to review this security fix? It addresses heap buffer overflows in the JPEG encoder (xsize/ysize mismatch) and EXR decoder (negative-count memcpy when display/data windows don't overlap). |
|
Hi. Lets split this to 2 PRs. One of them (about EXR) will be useful for JPEG XL as well. And for EXR let's do some combing: pull |
1098e2b to
337c67e
Compare
|
Thanks for the review, split done.
|
|
Good. Now let's deal with root cause. Both Moreover, So, instead of "plumbing" let's do the same thing other encoders: use |
When a PackedPixelFile is constructed with frame[0].color dimensions that disagree with info.xsize/ysize, the encoder's pixel-copy loops in EncodeJpeg iterate up to info.* while pixels and row_bytes are sized for image.*, causing OOB reads and writes past the source buffer and the destination row buffer. VerifyInput already calls Encoder::VerifyImageSize, but that helper intentionally leaves the xsize/ysize equality check disabled (TODO in encode.cc) since some encoders allow per-frame sizes to differ from the basic info. jpegli is not such an encoder: cinfo.image_width/height and the buffer math both come from info.*, so the assumption is load-bearing and must be enforced locally. Adds the dim-equality check to VerifyInput right after the existing VerifyImageSize call. Also adds a regression test in jpegli_test.cc covering all three mismatch directions. The first attempt at this fix (clamping the encoder loops to image.*) was rejected during review as plumbing rather than a root-cause fix.
337c67e to
c38e270
Compare
|
Pushed an updated version that addresses the root cause per your suggestion (force-push, head now Approach. Instead of clamping the encoder loops, const PackedImage& image = ppf.frames[0].color;
JPEGLI_RETURN_IF_ERROR(Encoder::VerifyImageSize(image, info));
if (image.xsize != info.xsize || image.ysize != info.ysize) {
return JPEGLI_FAILURE("Frame size does not match image size.");
}The encoder's pixel-copy loops are back to Why a local check rather than uncommenting the equality test in Regression test. Added
Also rebased on current |
Security fix
Heap buffer overflow in JPEG encoder (xsize/ysize mismatch) (
lib/extras/enc/jpegli.cc)In
EncodeJpeg, the pixel-copy loops iterate up toinfo.ysize/info.xsize, butrow_bytesandpixelsare sized forimage.ysize/image.xsize. WhenPackedImagedimensions differ fromJxlBasicInfodimensions, the loop reads past the end of the source buffer and writes past the end ofrow_bytes.Fixed by clamping the loop bounds to
image.ysize/image.xsize.The original PR also bundled an unrelated EXR decoder fix; per @eustas's review that has been split out into #216.