php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72926 Uninitialized Thumbail Data Leads To Memory Leakage in exif_process_IFD_in_TIFF
Submitted: 2016-08-23 03:19 UTC Modified: 2017-02-13 01:29 UTC
From: nguyenvuhoang199321 at gmail dot com Assigned: stas
Status: Closed Package: EXIF related
PHP Version: 5.6.26 OS: ALL
Private report: No CVE-ID:
 [2016-08-23 03:19 UTC] nguyenvuhoang199321 at gmail dot com
Description:
------------
I found other code chunk that leads to memory leakage.
```
	exif_process_IFD_in_TIFF(ImageInfo, entry_offset, sub_section_index);
	if (section_index!=SECTION_THUMBNAIL && entry_tag==TAG_SUB_IFD) {
		if (ImageInfo->Thumbnail.filetype != IMAGE_FILETYPE_UNKNOWN
		&&  ImageInfo->Thumbnail.size
		&&  ImageInfo->Thumbnail.offset
		&&  ImageInfo->read_thumbnail
		) {
#ifdef EXIF_DEBUG
			exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "%s THUMBNAIL @0x%04X + 0x%04X", ImageInfo->Thumbnail.data ? "Ignore" : "Read", ImageInfo->Thumbnail.offset, ImageInfo->Thumbnail.size);
#endif
			if (!ImageInfo->Thumbnail.data) {
				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)
				}
				exif_thumbnail_build(ImageInfo);
			}
		}
	}
```
As you can see this code is processing SUB_IFD_TAG and not verify offset of Thumbnail data. Because lack of checking ImageInfo->Thumbnail.offset if an attack set ImageInfo->Thumbnail.offset larger than ImageInfo->FileSize then *php_stream_read* return 0 to fgot, because  EXIF_ERRLOG_THUMBEOF was defined as : 
```
#define EXIF_ERRLOG_THUMBEOF(ImageInfo)   exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "%s", EXIF_ERROR_THUMBEOF);

```
As you can see there is no exit after this error is output.

This bug does same problem with this bug i reported before https://bugs.php.net/bug.php?id=72627

Here tiff file : https://drive.google.com/file/d/0B0D1DYQpkA9USUt4c2ZBT21SWE0/view?usp=sharing



Test script:
---------------
<?php
	$exif = exif_read_data('exif/gen.tiff',0,0,true);
	var_dump($exif);

	$thumb = $exif['THUMBNAIL']['THUMBNAIL'];
	echo bin2hex($thumb);
?>

Actual result:
--------------
PHP Warning:  exif_read_data(gen.tiff): Error in TIFF: filesize(x00D6) less than size of IFD dir(x0FA0) in /vagrant_extend/audit/exif.php on line 15

Warning: exif_read_data(gen.tiff): Error in TIFF: filesize(x00D6) less than size of IFD dir(x0FA0) in /vagrant_extend/audit/exif.php on line 15
PHP Warning:  exif_read_data(gen.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 15

Warning: exif_read_data(gen.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 15
PHP Warning:  exif_read_data(gen.tiff): Error in TIFF: filesize(x00D6) less than start of IFD dir(x829A0004) in /vagrant_extend/audit/exif.php on line 15

Warning: exif_read_data(gen.tiff): Error in TIFF: filesize(x00D6) less than start of IFD dir(x829A0004) in /vagrant_extend/audit/exif.php on line 15
array(9) {
  ["FileName"]=>
  string(8) "gen.tiff"
  ["FileDateTime"]=>
  int(1471921626)
  ["FileSize"]=>
  int(214)
  ["FileType"]=>
  int(7)
  ["MimeType"]=>
  string(10) "image/tiff"
  ["SectionsFound"]=>
  string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF"
  ["COMPUTED"]=>
  array(9) {
    ["html"]=>
    string(24) "width="128" height="132""
    ["Height"]=>
    int(132)
    ["Width"]=>
    int(128)
    ["IsColor"]=>
    int(0)
    ["ByteOrderMotorola"]=>
    int(0)
    ["Thumbnail.FileType"]=>
    int(2)
    ["Thumbnail.MimeType"]=>
    string(10) "image/jpeg"
    ["Thumbnail.Height"]=>
    int(132)
    ["Thumbnail.Width"]=>
    int(128)
  }
  ["XResolution"]=>
  string(16) "8388608/16842752"
  ["THUMBNAIL"]=>
  array(5) {
    ["ImageWidth"]=>
    int(128)
    ["ImageLength"]=>
    int(132)
    ["JPEGInterchangeFormat"]=>
    int(386)
    ["JPEGInterchangeFormatLength"]=>
    int(128)
    ["THUMBNAIL"]=>
    string(128) "�R��M" => leak leak
  }
}
8052e6d14d7f0000000000000000 => (0x7f4dd1e65280)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-05 04:00 UTC] stas@php.net
-Type: Security +Type: Bug -PHP Version: 7.0Git-2016-08-23 (Git) +PHP Version: 5.6.26
 [2016-09-05 04:00 UTC] stas@php.net
Same issue as 72627, now fixed in both places.
 [2016-09-05 06:45 UTC] nguyenvuhoang199321 at gmail dot com
I think it is still security issue. Because, it will lead to memory leakage.
 [2016-09-05 06:49 UTC] nguyenvuhoang199321 at gmail dot com
This bug does the same impact with https://bugs.php.net/bug.php?id=72627 not the same bug. The root of this bug is exif_process_IFD_in_TIFF try to process TAG_SUB_IFD , i tested this bug in lasted php version.
 [2016-09-06 04:52 UTC] nguyenvuhoang199321 at gmail dot com
I will give you here my test with this bug #72627 i reported before
Bug #72627
PHP Warning:  exif_read_data(leak.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 3

Warning: exif_read_data(leak.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 3
PHP Warning:  exif_read_data(leak.tiff): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in /vagrant_extend/audit/exif.php on line 3

Warning: exif_read_data(leak.tiff): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in /vagrant_extend/audit/exif.php on line 3
PHP Warning:  exif_read_data(leak.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 3

Warning: exif_read_data(leak.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 3
array(11) {
  ["FileName"]=>
  string(9) "leak.tiff"
  ["FileDateTime"]=>
  int(1468988151)
  ["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"
}

And here output of my bug

PHP Warning:  exif_read_data(leak2.tiff): Error in TIFF: filesize(x00D6) less than size of IFD dir(x0FA0) in /vagrant_extend/audit/exif.php on line 7

Warning: exif_read_data(leak2.tiff): Error in TIFF: filesize(x00D6) less than size of IFD dir(x0FA0) in /vagrant_extend/audit/exif.php on line 7
PHP Warning:  exif_read_data(leak2.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 7

Warning: exif_read_data(leak2.tiff): Thumbnail goes IFD boundary or end of file reached in /vagrant_extend/audit/exif.php on line 7
PHP Warning:  exif_read_data(leak2.tiff): Error in TIFF: filesize(x00D6) less than start of IFD dir(x829A0004) in /vagrant_extend/audit/exif.php on line 7

Warning: exif_read_data(leak2.tiff): Error in TIFF: filesize(x00D6) less than start of IFD dir(x829A0004) in /vagrant_extend/audit/exif.php on line 7
array(9) {
  ["FileName"]=>
  string(10) "leak2.tiff"
  ["FileDateTime"]=>
  int(1471922107)
  ["FileSize"]=>
  int(214)
  ["FileType"]=>
  int(7)
  ["MimeType"]=>
  string(10) "image/tiff"
  ["SectionsFound"]=>
  string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF"
  ["COMPUTED"]=>
  array(9) {
    ["html"]=>
    string(24) "width="128" height="132""
    ["Height"]=>
    int(132)
    ["Width"]=>
    int(128)
    ["IsColor"]=>
    int(0)
    ["ByteOrderMotorola"]=>
    int(0)
    ["Thumbnail.FileType"]=>
    int(2)
    ["Thumbnail.MimeType"]=>
    string(10) "image/jpeg"
    ["Thumbnail.Height"]=>
    int(132)
    ["Thumbnail.Width"]=>
    int(128)
  }
  ["XResolution"]=>
  string(16) "8388608/16842752"
  ["THUMBNAIL"]=>
  array(5) {
    ["ImageWidth"]=>
    int(128)
    ["ImageLength"]=>
    int(132)
    ["JPEGInterchangeFormat"]=>
    int(386)
    ["JPEGInterchangeFormatLength"]=>
    int(128)
    ["THUMBNAIL"]=>
    string(128) "�R��%�A��%��A��%���%�)��%d"
  }
}
 [2016-09-06 04:54 UTC] nguyenvuhoang199321 at gmail dot com
-Type: Bug +Type: Security -Private report: No +Private report: Yes
 [2016-09-06 04:54 UTC] nguyenvuhoang199321 at gmail dot com
As output above, i think you should reproduce my bug and see
 [2016-09-12 04:01 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-09-12 04:01 UTC] stas@php.net
Wasn't able to reproduce with latest code, which version did you use to reproduce?
 [2016-09-12 04:05 UTC] nguyenvuhoang199321 at gmail dot com
-Status: Feedback +Status: Open
 [2016-09-12 04:05 UTC] nguyenvuhoang199321 at gmail dot com
I use version php-7.0.11 clone from github, here leak2.tiff file https://drive.google.com/open?id=0B0D1DYQpkA9UbGhzM3BzZHZCREk you can check it again :)
 [2016-09-12 04:21 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-09-12 04:21 UTC] stas@php.net
There's no version 7.0.11. Please specify which source you used to reproduce it.
 [2016-09-12 04:24 UTC] nguyenvuhoang199321 at gmail dot com
-Status: Feedback +Status: Open
 [2016-09-12 04:24 UTC] nguyenvuhoang199321 at gmail dot com
Ok you can test with version 7.0.8
 [2016-09-12 04:42 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-09-12 04:42 UTC] stas@php.net
7.0.8 is not a current version, Please test with current code that includes https://github.com/php/php-src/commit/a2fdf0f4135f5a29e613c1c6c53d378dc6ff7bed
 [2016-09-12 04:45 UTC] nguyenvuhoang199321 at gmail dot com
-Status: Feedback +Status: Open
 [2016-09-12 04:45 UTC] nguyenvuhoang199321 at gmail dot com
OK i will test again on another version i give use feedback as soon as possible
 [2016-09-12 06:06 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-09-12 14:02 UTC] nguyenvuhoang199321 at gmail dot com
-Status: Feedback +Status: Open
 [2016-09-12 14:02 UTC] nguyenvuhoang199321 at gmail dot com
I checked again and found that this bug had been fixed after i submitted this report and then you changed this report status from SecBug to Bug, so i think you misunderstand my report.
Finally, if you consider my last report #72627 is a SecBug, i think you should assign this bug is SecBug, because this bug occur in a different way.
 [2016-09-12 18:42 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2016-09-12 18:42 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2017-02-13 01:27 UTC] stas@php.net
-CVE-ID: +CVE-ID: needed
 [2017-02-13 01:29 UTC] stas@php.net
See also: bug #72627
 [2017-02-13 01:29 UTC] stas@php.net
-CVE-ID: needed +CVE-ID:
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC