From 2e136a7190063322e9f982e7fbc3f4a523f1af4e Mon Sep 17 00:00:00 2001 From: DRC Date: Mon, 8 Aug 2022 14:17:51 -0500 Subject: [PATCH] Re-fix buf img mode decompr err w/short prog JPEGs This commit reverts 4dbc293125b417f97e5b1ca9e7260c82ff199a06 and 9f8f683e745972720433406cff4b31e95bd6a33e (the previous two commits) and fixes #613 the correct way. The crux of the issue wasn't the size of the whole_image virtual array but rather that, since last_iMCU_row is unsigned, (last_iMCU_row - 1) wrapped around to 0xFFFFFFFF when last_iMCU_row was 0. This caused the interblock smoothing algorithm introduced in 6d91e950c871103a11bac2f10c63bf998796c719 to erroneously try to access the next two iMCU rows, neither of which existed. The first attempt at a fix (4dbc293125b417f97e5b1ca9e7260c82ff199a06) exposed a NULL dereference, detected by OSS-Fuzz, that occurred when attempting to decompress a specially-crafted malformed JPEG image to a YUV buffer using tjDecompressToYUV*() with 1/4 IDCT scaling. Fixes #613 (again) Also fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49898 --- ChangeLog.md | 7 ++++--- jdcoefct.c | 15 ++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 995e0e83..59ca516c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -18,9 +18,10 @@ This allows both AltiVec-equipped (PowerPC G4 and G5) and non-AltiVec-equipped (PowerPC G3) CPUs to be supported using the same build of libjpeg-turbo. 4. Fixed an error ("Bogus virtual array access") that occurred when attempting -to decompress a progressive JPEG image with a height less than or equal to -(32 * the vertical sampling factor) using buffered image mode. This was a -regression introduced by 2.1 beta1[6(b)]. +to decompress a progressive JPEG image with a height less than or equal to one +iMCU (8 * the vertical sampling factor) using buffered-image mode with +interblock smoothing enabled. This was a regression introduced by +2.1 beta1[6(b)]. 2.1.3 diff --git a/jdcoefct.c b/jdcoefct.c index 19eb56a4..88e10c08 100644 --- a/jdcoefct.c +++ b/jdcoefct.c @@ -475,7 +475,7 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) if (!compptr->component_needed) continue; /* Count non-dummy DCT block rows in this iMCU row. */ - if (cinfo->output_iMCU_row < last_iMCU_row - 1) { + if (cinfo->output_iMCU_row + 1 < last_iMCU_row) { block_rows = compptr->v_samp_factor; access_rows = block_rows * 3; /* this and next two iMCU rows */ } else if (cinfo->output_iMCU_row < last_iMCU_row) { @@ -560,7 +560,7 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) next_block_row = buffer_ptr; if (block_row < block_rows - 2 || - cinfo->output_iMCU_row < last_iMCU_row - 1) + cinfo->output_iMCU_row + 1 < last_iMCU_row) next_next_block_row = buffer[block_row + 2] + cinfo->master->first_MCU_col[ci]; else @@ -835,21 +835,18 @@ jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer) for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - JDIMENSION num_rows = - (JDIMENSION)jround_up((long)compptr->height_in_blocks, - (long)compptr->v_samp_factor); access_rows = compptr->v_samp_factor; #ifdef BLOCK_SMOOTHING_SUPPORTED /* If block smoothing could be used, need a bigger window */ - if (cinfo->progressive_mode) { + if (cinfo->progressive_mode) access_rows *= 5; - num_rows = MAX(num_rows, (JDIMENSION)access_rows); - } #endif coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) ((j_common_ptr)cinfo, JPOOL_IMAGE, TRUE, (JDIMENSION)jround_up((long)compptr->width_in_blocks, - (long)compptr->h_samp_factor), num_rows, + (long)compptr->h_samp_factor), + (JDIMENSION)jround_up((long)compptr->height_in_blocks, + (long)compptr->v_samp_factor), (JDIMENSION)access_rows); } coef->pub.consume_data = consume_data;