rdbmp.c: Fix more innocuous UBSan errors

- Referring to 3311fc0001, 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.
This commit is contained in:
DRC
2021-04-12 10:38:52 -05:00
parent dd830b3ffe
commit ebaa67ea32

View File

@@ -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);