Validate JPEG data size in libtiff.
Upstream commit cf3ce6fa is based on patch set 1 of this CL.
BUG=chromium:925269
Change-Id: Ieaa052987d2195ce9ebd0356baecc119bd5d93ad
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/49132
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/third_party/libtiff/0032-jpeg-decoding-size-check.patch b/third_party/libtiff/0032-jpeg-decoding-size-check.patch
new file mode 100644
index 0000000..fdc528d
--- /dev/null
+++ b/third_party/libtiff/0032-jpeg-decoding-size-check.patch
@@ -0,0 +1,46 @@
+commit cf3ce6fab894414a336546f62adc57f02590a22c
+Author: Even Rouault <even.rouault@spatialys.com>
+Date: Fri Jul 5 18:51:46 2019 +0200
+
+ OJPEG: avoid use of unintialized memory on corrupted files
+
+ Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=925269
+ Patch from Lei Zhang with little adaptations.
+
+diff --git a/third_party/libtiff/tif_ojpeg.c b/third_party/libtiff/tif_ojpeg.c
+index c01d71a2..ad3e1e71 100644
+--- a/third_party/libtiff/tif_ojpeg.c
++++ b/third_party/libtiff/tif_ojpeg.c
+@@ -831,6 +831,32 @@ OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc)
+ {
+ if (sp->subsampling_convert_state==0)
+ {
++ const jpeg_decompress_struct* cinfo = &sp->libjpeg_jpeg_decompress_struct;
++ int width = 0;
++ int last_col_width = 0;
++ int jpeg_bytes;
++ int expected_bytes;
++ int i;
++ if (cinfo->MCUs_per_row == 0)
++ return 0;
++ for (i = 0; i < cinfo->comps_in_scan; ++i)
++ {
++ const jpeg_component_info* info = cinfo->cur_comp_info[i];
++#if JPEG_LIB_VERSION >= 70
++ width += info->MCU_width * info->DCT_h_scaled_size;
++ last_col_width += info->last_col_width * info->DCT_h_scaled_size;
++#else
++ width += info->MCU_width * info->DCT_scaled_size;
++ last_col_width += info->last_col_width * info->DCT_scaled_size;
++#endif
++ }
++ jpeg_bytes = (cinfo->MCUs_per_row - 1) * width + last_col_width;
++ expected_bytes = sp->subsampling_convert_clinelenout * sp->subsampling_ver * sp->subsampling_hor;
++ if (jpeg_bytes != expected_bytes)
++ {
++ TIFFErrorExt(tif->tif_clientdata,module,"Inconsistent number of MCU in codestream");
++ return(0);
++ }
+ if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+ return(0);
+ }
diff --git a/third_party/libtiff/README.pdfium b/third_party/libtiff/README.pdfium
index 72b3257..21a5fff 100644
--- a/third_party/libtiff/README.pdfium
+++ b/third_party/libtiff/README.pdfium
@@ -18,3 +18,4 @@
0029-CVE-2018-17000.patch: Avoid a null pointer dereference in TIFFWriteDirectoryTagTransferfunction().
0030-CVE-2018-19210.patch: Avoid a null pointer dereference inside _TIFFVSetField().
0031-safe_size_ingtStripContig.patch: return error if the size to read overflow from int32.
+0032-jpeg-decoding-size-check.patch: Avoid use of unintialized memory on corrupted files.
diff --git a/third_party/libtiff/tif_ojpeg.c b/third_party/libtiff/tif_ojpeg.c
index 8a33f5a..80ad823 100644
--- a/third_party/libtiff/tif_ojpeg.c
+++ b/third_party/libtiff/tif_ojpeg.c
@@ -840,6 +840,32 @@
{
if (sp->subsampling_convert_state==0)
{
+ const jpeg_decompress_struct* cinfo = &sp->libjpeg_jpeg_decompress_struct;
+ int width = 0;
+ int last_col_width = 0;
+ int jpeg_bytes;
+ int expected_bytes;
+ int i;
+ if (cinfo->MCUs_per_row == 0)
+ return 0;
+ for (i = 0; i < cinfo->comps_in_scan; ++i)
+ {
+ const jpeg_component_info* info = cinfo->cur_comp_info[i];
+#if JPEG_LIB_VERSION >= 70
+ width += info->MCU_width * info->DCT_h_scaled_size;
+ last_col_width += info->last_col_width * info->DCT_h_scaled_size;
+#else
+ width += info->MCU_width * info->DCT_scaled_size;
+ last_col_width += info->last_col_width * info->DCT_scaled_size;
+#endif
+ }
+ jpeg_bytes = (cinfo->MCUs_per_row - 1) * width + last_col_width;
+ expected_bytes = sp->subsampling_convert_clinelenout * sp->subsampling_ver * sp->subsampling_hor;
+ if (jpeg_bytes != expected_bytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Inconsistent number of MCU in codestream");
+ return(0);
+ }
if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
return(0);
}