CVE-2020-13790: Out-of-bounds Read (CWE-125)
value: libjpeg-turbo 2.0.4, and mozjpeg 4.0.0, has a heap-based buffer over-read in get_rgb_row() in rdppm.c via a malformed PPM input file.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 8.1
Published: 2020-06-03T19:15Z
Repository: https://github.com/libjpeg-turbo/libjpeg-turbo
Language: C
Files changed: ChangeLog.md, rdppm.c
Commit date: 2020-06-02 14:51:17 -0500
Commit message: rdppm.c: Fix buf overrun caused by bad binary PPM

This extends the fix in 1e81b0c3ea26f4ea8f56de05367469333de64a9f to
include binary PPM files with maximum values < 255, thus preventing a
malformed binary PPM input file with those specifications from
triggering an overrun of the rescale array and potentially crashing
cjpeg, TJBench, or any program that uses the tjLoadImage() function.

Fixes #433

Diff: diff --git a/ChangeLog.md b/ChangeLog.md
index d63ad90f..ab58b9bd 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -11,10 +11,16 @@ disabled when building libjpeg-turbo for such CPUs.
 2. Fixed an oversight in the `TJCompressor.compress(int)` method in the
 TurboJPEG Java API that caused an error ("java.lang.IllegalStateException: No
 source image is associated with this instance") when attempting to use that
 method to compress a YUV image.
 
+3. Fixed an issue in the PPM reader that caused a buffer overrun in cjpeg,
+TJBench, or the `tjLoadImage()` function if one of the values in a binary
+PPM/PGM input file exceeded the maximum value defined in the file's header and
+that maximum value was less than 255.  libjpeg-turbo 1.5.0 already included a
+similar fix for binary PPM/PGM files with maximum values greater than 255.
+
 
 2.0.4
 =====
 
 ### Significant changes relative to 2.0.3:
@@ -576,14 +582,14 @@ infrastructure libraries, such as OpenSSL and libpng, because it makes it easy
 to examine an application binary and determine which version of the library the
 application was linked against.
 
 3. Fixed a couple of issues in the PPM reader that would cause buffer overruns
 in cjpeg if one of the values in a binary PPM/PGM input file exceeded the
-maximum value defined in the file's header.  libjpeg-turbo 1.4.2 already
-included a similar fix for ASCII PPM/PGM files.  Note that these issues were
-not security bugs, since they were confined to the cjpeg program and did not
-affect any of the libjpeg-turbo libraries.
+maximum value defined in the file's header and that maximum value was greater
+than 255.  libjpeg-turbo 1.4.2 already included a similar fix for ASCII PPM/PGM
+files.  Note that these issues were not security bugs, since they were confined
+to the cjpeg program and did not affect any of the libjpeg-turbo libraries.
 
 4. Fixed an issue whereby attempting to decompress a JPEG file with a corrupt
 header using the `tjDecompressToYUV2()` function would cause the function to
 abort without returning an error and, under certain circumstances, corrupt the
 stack.  This only occurred if `tjDecompressToYUV2()` was called prior to
diff --git a/rdppm.c b/rdppm.c
index 87bc3309..a8507b90 100644
--- a/rdppm.c
+++ b/rdppm.c
@@ -3,11 +3,11 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * Modified 2009 by Bill Allombert, Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015-2017, D. R. Commander.
+ * Copyright (C) 2015-2017, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
  * This file contains routines to read input images in PPM/PGM format.
  * The extended 2-byte-per-sample raw PPM/PGM formats are supported.
@@ -718,11 +718,11 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
     long val, half_maxval;
 
     /* On 16-bit-int machines we have to be careful of maxval = 65535 */
     source->rescale = (JSAMPLE *)
       (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                  (size_t)(((long)maxval + 1L) *
+                                  (size_t)(((long)MAX(maxval, 255) + 1L) *
                                            sizeof(JSAMPLE)));
     half_maxval = maxval / 2;
     for (val = 0; val <= (long)maxval; val++) {
       /* The multiplication here must be done in 32 bits to avoid overflow */
       source->rescale[val] = (JSAMPLE)((val * MAXJSAMPLE + half_maxval) /

Vulnerable code: maximum value defined in the file's header.  libjpeg-turbo 1.4.2 already
included a similar fix for ASCII PPM/PGM files.  Note that these issues were
not security bugs, since they were confined to the cjpeg program and did not
affect any of the libjpeg-turbo libraries.
 * Copyright (C) 2015-2017, D. R. Commander.
                                  (size_t)(((long)maxval + 1L) *
Fixed code: 3. Fixed an issue in the PPM reader that caused a buffer overrun in cjpeg,
TJBench, or the `tjLoadImage()` function if one of the values in a binary
PPM/PGM input file exceeded the maximum value defined in the file's header and
that maximum value was less than 255.  libjpeg-turbo 1.5.0 already included a
similar fix for binary PPM/PGM files with maximum values greater than 255.

maximum value defined in the file's header and that maximum value was greater
than 255.  libjpeg-turbo 1.4.2 already included a similar fix for ASCII PPM/PGM
files.  Note that these issues were not security bugs, since they were confined
to the cjpeg program and did not affect any of the libjpeg-turbo libraries.
 * Copyright (C) 2015-2017, 2020, D. R. Commander.
                                  (size_t)(((long)MAX(maxval, 255) + 1L) *