From 43e84cff1bb2bd8293066f6ac4eb0df61ddddbc6 Mon Sep 17 00:00:00 2001 From: DRC Date: Tue, 12 Jun 2018 20:27:00 -0500 Subject: [PATCH] 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.) --- ChangeLog.md | 5 +++++ rdbmp.c | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index ba400d92..ade31c53 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -30,6 +30,11 @@ 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) ================== diff --git a/rdbmp.c b/rdbmp.c index fcabbb13..a02cfd90 100644 --- a/rdbmp.c +++ b/rdbmp.c @@ -6,7 +6,7 @@ * 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. * @@ -623,6 +623,12 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) } } + /* 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,