Blob Blame History Raw
From c51b66ebcace2adec0cfbe42d25cb418ed0c02a2 Mon Sep 17 00:00:00 2001
From: DRC <information@libjpeg-turbo.org>
Date: Fri, 20 Jul 2018 17:21:36 -0500
Subject: [PATCH] cjpeg: Fix OOB read caused by malformed 8-bit BMP

... in which one or more of the color indices is out of range for the
number of palette entries.

Fix partly borrowed from jpeg-9c.  This commit also adopts Guido's
JERR_PPM_OUTOFRANGE enum value in lieu of our project-specific
JERR_PPM_TOOLARGE enum value.

Fixes #258
---
 cderror.h | 5 +++--
 rdbmp.c   | 7 ++++++-
 rdppm.c   | 4 ++--
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/cderror.h b/cderror.h
index d69b501..46b0f49 100644
--- a/cderror.h
+++ b/cderror.h
@@ -2,7 +2,7 @@
  * cderror.h
  *
  * Copyright (C) 1994-1997, Thomas G. Lane.
- * Modified 2009 by Guido Vollbeding.
+ * Modified 2009-2017 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -48,6 +48,7 @@ JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
 JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
 JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
 JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
+JMESSAGE(JERR_BMP_OUTOFRANGE, "Numeric value out of range in BMP file")
 JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
 JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
 JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
@@ -74,8 +75,8 @@ JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
 #ifdef PPM_SUPPORTED
 JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
 JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
-JMESSAGE(JERR_PPM_TOOLARGE, "Integer value too large in PPM file")
 JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
+JMESSAGE(JERR_PPM_OUTOFRANGE, "Numeric value out of range in PPM file")
 JMESSAGE(JTRC_PGM, "%ux%u PGM image")
 JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
 JMESSAGE(JTRC_PPM, "%ux%u PPM image")
diff --git a/rdbmp.c b/rdbmp.c
index c053074..7a27cab 100644
--- a/rdbmp.c
+++ b/rdbmp.c
@@ -3,7 +3,7 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1996, Thomas G. Lane.
- * Modified 2009-2010 by Guido Vollbeding.
+ * Modified 2009-2017 by Guido Vollbeding.
  * Modifications:
  * Modified 2011 by Siarhei Siamashka.
  * For conditions of distribution and use, see the accompanying README file.
@@ -64,6 +64,7 @@ typedef struct _bmp_source_struct {
   JDIMENSION row_width;		/* Physical width of scanlines in file */
 
   int bits_per_pixel;		/* remembers 8- or 24-bit format */
+  int cmap_length;          /* colormap length */
 } bmp_source_struct;
 
 
@@ -124,6 +125,7 @@ get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
 {
   bmp_source_ptr source = (bmp_source_ptr) sinfo;
   register JSAMPARRAY colormap = source->colormap;
+  int cmaplen = source->cmap_length;
   JSAMPARRAY image_ptr;
   register int t;
   register JSAMPROW inptr, outptr;
@@ -140,6 +142,8 @@ get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
   outptr = source->pub.buffer[0];
   for (col = cinfo->image_width; col > 0; col--) {
     t = GETJSAMPLE(*inptr++);
+    if (t >= cmaplen)
+        ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
     *outptr++ = colormap[0][t];	/* can omit GETJSAMPLE() safely */
     *outptr++ = colormap[1][t];
     *outptr++ = colormap[2][t];
@@ -399,6 +403,7 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
     source->colormap = (*cinfo->mem->alloc_sarray)
       ((j_common_ptr) cinfo, JPOOL_IMAGE,
        (JDIMENSION) biClrUsed, (JDIMENSION) 3);
+    source->cmap_length = (int)biClrUsed;
     /* and read it from the file */
     read_colormap(source, (int) biClrUsed, mapentrysize);
     /* account for size of colormap */
diff --git a/rdppm.c b/rdppm.c
index 5da1646..59da2bb 100644
--- a/rdppm.c
+++ b/rdppm.c
@@ -76,7 +76,7 @@ typedef struct {
   JSAMPROW pixrow;		/* FAR pointer to same */
   size_t buffer_width;		/* width of I/O buffer */
   JSAMPLE *rescale;		/* => maxval-remapping array, or NULL */
-  int maxval;
+  unsigned int maxval;
 } ppm_source_struct;
 
 typedef ppm_source_struct * ppm_source_ptr;
@@ -126,7 +126,7 @@ read_pbm_integer (j_compress_ptr cinfo, FILE * infile, int maxval)
   }
 
   if (val > maxval)
-    ERREXIT(cinfo, JERR_PPM_TOOLARGE);
+    ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
 
   return val;
 }
-- 
2.17.2