Author: DRC <information@libjpeg-turbo.org>
Date:   Thu Mar 31 09:49:49 2016 -0500

    cjpeg: Fix buf overrun caused by bad bin PPM input

    This extends the fix in CVE-2016-3616 to
    include binary PPM/PGM files, thus preventing a malformed binary
    PPM/PGM input file from triggering an overrun of the rescale array and
    potentially crashing cjpeg.

    Note that this issue affected only cjpeg and not the underlying
    libjpeg-turbo libraries, and thus it did not represent a security
    threat.

    Thanks to @hughdavenport for the discovery.

Index: libjpeg9-9b/rdppm.c
===================================================================
--- libjpeg9-9b.orig/rdppm.c
+++ libjpeg9-9b/rdppm.c
@@ -251,6 +251,7 @@ get_word_gray_row (j_compress_ptr cinfo,
   register U_CHAR * bufferptr;
   register JSAMPLE *rescale = source->rescale;
   JDIMENSION col;
+  unsigned int maxval = source->maxval;
 
   if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
     ERREXIT(cinfo, JERR_INPUT_EOF);
@@ -260,6 +261,8 @@ get_word_gray_row (j_compress_ptr cinfo,
     register int temp;
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
+    if (temp > maxval)
+      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
     *ptr++ = rescale[temp];
   }
   return 1;
@@ -275,6 +278,7 @@ get_word_rgb_row (j_compress_ptr cinfo,
   register U_CHAR * bufferptr;
   register JSAMPLE *rescale = source->rescale;
   JDIMENSION col;
+  unsigned int maxval = source->maxval;
 
   if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
     ERREXIT(cinfo, JERR_INPUT_EOF);
@@ -284,12 +288,18 @@ get_word_rgb_row (j_compress_ptr cinfo,
     register int temp;
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
+    if (temp > maxval)
+      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
     *ptr++ = rescale[temp];
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
+    if (temp > maxval)
+      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
     *ptr++ = rescale[temp];
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
+    if (temp > maxval)
+      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
     *ptr++ = rescale[temp];
   }
   return 1;
