From ebaa67ea32b3f3f28e10ab1ee4ed9bbacd632013 Mon Sep 17 00:00:00 2001 From: DRC Date: Mon, 12 Apr 2021 10:38:52 -0500 Subject: [PATCH] rdbmp.c: Fix more innocuous UBSan errors - Referring to 3311fc00010c6cb305d87525c9ef60ebdf036cfc, we need to use unsigned intermediate math in order to make UBSan happy, even though (JDIMENSION)(A * B) is effectively the same as (JDIMENSION)A *(JDIMENSION)B, regardless of intermediate overflow. - Because of the previous commit, it is now possible for bfOffBits to be INT_MIN, which would cause the initial computation of bPad to underflow a signed integer. Thus, we need to check for that possibility as soon as we know the values of bfOffBits and headerSize. The worst case from this regression is that bPad could wrap around to a large positive value, which would cause a "Premature end of input file" error in the subsequent read_byte() loop. Thus, this issue was effectively innocuous as well, since it resulted in catching the same error later and in a different way. Also, the issue was very well-contained, since it was both introduced and fixed as part of the ongoing OSS-Fuzz integration project. --- rdbmp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rdbmp.c b/rdbmp.c index 56470c37..17f0f9cd 100644 --- a/rdbmp.c +++ b/rdbmp.c @@ -450,7 +450,7 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) if (!ReadOK(source->pub.input_file, bmpinfoheader, 4)) ERREXIT(cinfo, JERR_INPUT_EOF); headerSize = GET_4B(bmpinfoheader, 0); - if (headerSize < 12 || headerSize > 64) + if (headerSize < 12 || headerSize > 64 || (headerSize + 14) > bfOffBits) ERREXIT(cinfo, JERR_BMP_BADHEADER); if (!ReadOK(source->pub.input_file, bmpinfoheader + 4, headerSize - 4)) ERREXIT(cinfo, JERR_INPUT_EOF); @@ -577,7 +577,7 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); if ((unsigned long long)biWidth * 3ULL > 0xFFFFFFFFULL) ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - row_width = (JDIMENSION)(biWidth * 3); + row_width = (JDIMENSION)biWidth * 3; break; case 32: if (cinfo->in_color_space == JCS_UNKNOWN) @@ -590,7 +590,7 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); if ((unsigned long long)biWidth * 4ULL > 0xFFFFFFFFULL) ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - row_width = (JDIMENSION)(biWidth * 4); + row_width = (JDIMENSION)biWidth * 4; break; default: ERREXIT(cinfo, JERR_BMP_BADDEPTH);