CVE-2016-7128: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: The exif_process_IFD_in_TIFF function in ext/exif/exif.c in PHP before 5.6.25 and 7.x before 7.0.10 mishandles the case of a thumbnail offset that exceeds the file size, which allows remote attackers to obtain sensitive information from process memory via a crafted TIFF image.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
CVSS v3 base score: 5.3
Published: 2016-09-12T01:59Z
Repository: https://github.com/php/php-src
Language: C
Files changed: ext/exif/exif.c, ext/exif/tests/bug72627.phpt
Commit date: 2016-08-16 22:55:40 -0700
Commit message: Fixed bug #72627: Memory Leakage In exif_process_IFD_in_TIFF

Diff: diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index f95de3a14f1..657a2cc1f26 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -3766,12 +3766,15 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
 						ImageInfo->Thumbnail.data = safe_emalloc(ImageInfo->Thumbnail.size, 1, 0);
 						php_stream_seek(ImageInfo->infile, ImageInfo->Thumbnail.offset, SEEK_SET);
 						fgot = php_stream_read(ImageInfo->infile, ImageInfo->Thumbnail.data, ImageInfo->Thumbnail.size);
 						if (fgot < ImageInfo->Thumbnail.size) {
 							EXIF_ERRLOG_THUMBEOF(ImageInfo)
+							efree(ImageInfo->Thumbnail.data);
+							ImageInfo->Thumbnail.data = NULL;
+						} else {
+							exif_thumbnail_build(ImageInfo TSRMLS_CC);
 						}
-						exif_thumbnail_build(ImageInfo TSRMLS_CC);
 					}
 #ifdef EXIF_DEBUG
 					exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read next IFD (THUMBNAIL) done");
 #endif
 				}
diff --git a/ext/exif/tests/bug72627.phpt b/ext/exif/tests/bug72627.phpt
new file mode 100644
index 00000000000..bb6a1fae99a
--- /dev/null
+++ b/ext/exif/tests/bug72627.phpt
@@ -0,0 +1,71 @@
+--TEST--
+Bug #72627 (Memory Leakage In exif_process_IFD_in_TIFF)
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+	$exif = exif_read_data(__DIR__ . '/bug72627.tiff',0,0,true);
+	var_dump($exif);
+?>
+--EXPECTF--
+Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d
+
+Warning: exif_read_data(%s): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in %sbug72627.php on line %d
+
+Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d
+array(11) {
+  ["FileName"]=>
+  string(13) "bug72627.tiff"
+  ["FileDateTime"]=>
+  int(%d)
+  ["FileSize"]=>
+  int(1250)
+  ["FileType"]=>
+  int(7)
+  ["MimeType"]=>
+  string(10) "image/tiff"
+  ["SectionsFound"]=>
+  string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF"
+  ["COMPUTED"]=>
+  array(10) {
+    ["html"]=>
+    string(24) "width="128" height="132""
+    ["Height"]=>
+    int(132)
+    ["Width"]=>
+    int(128)
+    ["IsColor"]=>
+    int(0)
+    ["ByteOrderMotorola"]=>
+    int(0)
+    ["ApertureFNumber"]=>
+    string(5) "f/1.0"
+    ["Thumbnail.FileType"]=>
+    int(2)
+    ["Thumbnail.MimeType"]=>
+    string(10) "image/jpeg"
+    ["Thumbnail.Height"]=>
+    int(132)
+    ["Thumbnail.Width"]=>
+    int(128)
+  }
+  ["XResolution"]=>
+  string(21) "1414812756/1414812756"
+  ["THUMBNAIL"]=>
+  array(5) {
+    ["ImageWidth"]=>
+    int(128)
+    ["ImageLength"]=>
+    int(132)
+    ["JPEGInterchangeFormat"]=>
+    int(1280)
+    ["JPEGInterchangeFormatLength"]=>
+    int(100)
+    ["THUMBNAIL"]=>
+    NULL
+  }
+  ["ExposureTime"]=>
+  string(21) "1414812756/1414812756"
+  ["FNumber"]=>
+  string(21) "1414812756/1414812756"
+}
diff --git a/ext/exif/tests/bug72627.tiff b/ext/exif/tests/bug72627.tiff
new file mode 100644
index 00000000000..229190a6041
Binary files /dev/null and b/ext/exif/tests/bug72627.tiff differ

Vulnerable code: 						exif_thumbnail_build(ImageInfo TSRMLS_CC);
Fixed code: 							efree(ImageInfo->Thumbnail.data);
							ImageInfo->Thumbnail.data = NULL;
						} else {
							exif_thumbnail_build(ImageInfo TSRMLS_CC);
--TEST--
Bug #72627 (Memory Leakage In exif_process_IFD_in_TIFF)
--SKIPIF--
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
--FILE--
<?php
	$exif = exif_read_data(__DIR__ . '/bug72627.tiff',0,0,true);
	var_dump($exif);
?>
--EXPECTF--
Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d

Warning: exif_read_data(%s): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in %sbug72627.php on line %d

Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d
array(11) {
  ["FileName"]=>
  string(13) "bug72627.tiff"
  ["FileDateTime"]=>
  int(%d)
  ["FileSize"]=>
  int(1250)
  ["FileType"]=>
  int(7)
  ["MimeType"]=>
  string(10) "image/tiff"
  ["SectionsFound"]=>
  string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF"
  ["COMPUTED"]=>
  array(10) {
    ["html"]=>
    string(24) "width="128" height="132""
    ["Height"]=>
    int(132)
    ["Width"]=>
    int(128)
    ["IsColor"]=>
    int(0)
    ["ByteOrderMotorola"]=>
    int(0)
    ["ApertureFNumber"]=>
    string(5) "f/1.0"
    ["Thumbnail.FileType"]=>
    int(2)
    ["Thumbnail.MimeType"]=>
    string(10) "image/jpeg"
    ["Thumbnail.Height"]=>
    int(132)
    ["Thumbnail.Width"]=>
    int(128)
  }
  ["XResolution"]=>
  string(21) "1414812756/1414812756"
  ["THUMBNAIL"]=>
  array(5) {
    ["ImageWidth"]=>
    int(128)
    ["ImageLength"]=>
    int(132)
    ["JPEGInterchangeFormat"]=>
    int(1280)
    ["JPEGInterchangeFormatLength"]=>
    int(100)
    ["THUMBNAIL"]=>
    NULL
  }
  ["ExposureTime"]=>
  string(21) "1414812756/1414812756"
  ["FNumber"]=>
  string(21) "1414812756/1414812756"
}