CVE-2018-1152: Divide By Zero (CWE-369)
value: libjpeg-turbo 1.5.90 is vulnerable to a denial of service vulnerability caused by a divide by zero when processing a crafted BMP image.
CWE description: The product divides a value by zero.
CVSS v3 base score: 6.5
Published: 2018-06-18T14:29Z
Repository: https://github.com/libjpeg-turbo/libjpeg-turbo
Language: C
Files changed: ChangeLog.md, rdbmp.c
Commit date: 2018-06-12 21:17:34 -0500
Commit message: tjLoadImage(): Fix FPE triggered by malformed BMP

In rdbmp.c, it is necessary to guard against 32-bit overflow/wraparound
when allocating the row buffer, because since BMP files have 32-bit
width and height fields, the value of biWidth can be up to 4294967295.
Specifically, if biWidth is 1073741824 and cinfo->input_components = 4,
then the samplesperrow argument in alloc_sarray() would wrap around to
0, and a division by zero error would occur at line 458 in jmemmgr.c.

If biWidth is set to a higher value, then samplesperrow would wrap
around to a small number, which would likely cause a buffer overflow
(this has not been tested or verified.)

Diff: diff --git a/ChangeLog.md b/ChangeLog.md
index ba400d9..ade31c5 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -28,10 +28,15 @@ threat.
 3. Fixed an issue whereby the `tjLoadImage()` and `tjSaveImage()` functions
 would produce a "Bogus message code" error message if the underlying bitmap and
 PPM readers/writers threw an error that was specific to the readers/writers
 (as opposed to a general libjpeg API error.)
 
+4. Fixed an issue whereby a specially-crafted malformed BMP file, one in which
+the header specified an image width of 1073741824 pixels, would trigger a
+floating point exception (division by zero) in the `tjLoadImage()` function
+when attempting to load the BMP file into a 4-component image buffer.
+
 
 1.5.90 (2.0 beta1)
 ==================
 
 ### Significant changes relative to 1.5.3:
diff --git a/rdbmp.c b/rdbmp.c
index fcabbb1..a02cfd9 100644
--- a/rdbmp.c
+++ b/rdbmp.c
@@ -4,11 +4,11 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * Modified 2009-2010 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
  * Modified 2011 by Siarhei Siamashka.
- * Copyright (C) 2015, 2017, D. R. Commander.
+ * Copyright (C) 2015, 2017-2018, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
  * This file contains routines to read input images in Microsoft "BMP"
  * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
@@ -621,10 +621,16 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
     default:
       ERREXIT(cinfo, JERR_BMP_BADDEPTH);
     }
   }
 
+  /* Ensure that biWidth * cinfo->input_components doesn't exceed the maximum
+     value of the JDIMENSION type.  This is only a danger with BMP files, since
+     their width and height fields are 32-bit integers. */
+  if ((unsigned long long)biWidth *
+      (unsigned long long)cinfo->input_components > 0xFFFFFFFFULL)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
   /* Allocate one-row buffer for returned data */
   source->pub.buffer = (*cinfo->mem->alloc_sarray)
     ((j_common_ptr)cinfo, JPOOL_IMAGE,
      (JDIMENSION)(biWidth * cinfo->input_components), (JDIMENSION)1);
   source->pub.buffer_height = 1;

Vulnerable code:  * Copyright (C) 2015, 2017, D. R. Commander.
Fixed code: 4. Fixed an issue whereby a specially-crafted malformed BMP file, one in which
the header specified an image width of 1073741824 pixels, would trigger a
floating point exception (division by zero) in the `tjLoadImage()` function
when attempting to load the BMP file into a 4-component image buffer.

 * Copyright (C) 2015, 2017-2018, D. R. Commander.
  /* Ensure that biWidth * cinfo->input_components doesn't exceed the maximum
     value of the JDIMENSION type.  This is only a danger with BMP files, since
     their width and height fields are 32-bit integers. */
  if ((unsigned long long)biWidth *
      (unsigned long long)cinfo->input_components > 0xFFFFFFFFULL)
    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);