Skip to content

Commit 31a3013

Browse files
committed
jchuff.c: Test for out-of-range coefficients
Restore two coefficient range checks from libjpeg to the C baseline Huffman encoder. This fixes an issue (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60253) whereby the encoder could read from uninitialized memory when attempting to transform a specially-crafted malformed arithmetic-coded JPEG source image into a baseline Huffman-coded JPEG destination image with default Huffman tables. More specifically, the out-of-range coefficients caused r to equal 256, which overflowed the actbl->ehufsi[] array. Because the overflow was contained within the huff_entropy_encoder structure, this issue was not exploitable (nor was it observable at all on x86 or Arm CPUs unless JSIMD_NOHUFFENC=1 or JSIMD_FORCENONE=1 was set in the environment or unless libjpeg-turbo was built with WITH_SIMD=0.) The fix is performance-neutral (+/- 1-2%) for x86-64 code and causes a 0-4% (avg. 1-2%, +/- 1-2%) compression regression for i386 code on Intel CPUs when the C baseline Huffman encoder is used (JSIMD_NOHUFFENC=1). The fix is performance-neutral (+/- 1-2%) on Intel CPUs when all of the libjpeg-turbo SIMD extensions are disabled (JSIMD_FORCENONE=1). The fix causes a 0-2% (avg. <1%, +/- 1%) compression regression for PowerPC code.
1 parent 369b84a commit 31a3013

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

ChangeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ cannot reliably transform JPEG source images that contain a large amount of
3333
metadata unless automatic JPEG destination buffer (re)allocation is used or
3434
`TJXOPT_COPYNONE` is set.
3535

36+
4. Fixed an issue that caused the C Huffman encoder (which is not used by
37+
default on x86 and Arm CPUs) to read from uninitialized memory when attempting
38+
to transform a specially-crafted malformed arithmetic-coded JPEG source image
39+
into a baseline Huffman-coded JPEG destination image.
40+
3641

3742
2.1.5.1
3843
=======

jchuff.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This file was part of the Independent JPEG Group's software:
55
* Copyright (C) 1991-1997, Thomas G. Lane.
66
* libjpeg-turbo Modifications:
7-
* Copyright (C) 2009-2011, 2014-2016, 2018-2022, D. R. Commander.
7+
* Copyright (C) 2009-2011, 2014-2016, 2018-2023, D. R. Commander.
88
* Copyright (C) 2015, Matthieu Darbois.
99
* Copyright (C) 2018, Matthias Räncker.
1010
* Copyright (C) 2020, Arm Limited.
@@ -588,6 +588,11 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
588588

589589
/* Find the number of bits needed for the magnitude of the coefficient */
590590
nbits = JPEG_NBITS(nbits);
591+
/* Check for out-of-range coefficient values.
592+
* Since we're encoding a difference, the range limit is twice as much.
593+
*/
594+
if (nbits > MAX_COEF_BITS + 1)
595+
ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
591596

592597
/* Emit the Huffman-coded symbol for the number of bits.
593598
* Emit that number of bits of the value, if positive,
@@ -613,6 +618,9 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
613618
temp += nbits; \
614619
nbits ^= temp; \
615620
nbits = JPEG_NBITS_NONZERO(nbits); \
621+
/* Check for out-of-range coefficient values */ \
622+
if (nbits > MAX_COEF_BITS) \
623+
ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); \
616624
/* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
617625
while (r >= 16 * 16) { \
618626
r -= 16 * 16; \

0 commit comments

Comments
 (0)