php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #73737 FPE when parsing a tag format
Submitted: 2016-12-14 10:15 UTC Modified: 2017-01-25 11:10 UTC
From: eyal dot itkin at gmail dot com Assigned: stas (profile)
Status: Closed Package: EXIF related
PHP Version: 5.6.29 OS:
Private report: No CVE-ID: 2016-10158
 [2016-12-14 10:15 UTC] eyal dot itkin at gmail dot com
Description:
------------
In the ext\exif\exif.c function there are general parsing methods, for parsing according to a format:
* exif_convert_any_format
* exif_convert_any_to_int

When these function are used to parse TIFF and JPEG tags from a malicious file, they can lead to an exception in intel chipsets. The targeted formats are:
* TAG_FMT_URATIONAL
* TAG_FMT_SRATIONAL
This is since intel raise an exception in division by zero (checked) and in another division exception (see link: http://x86.renejeschke.de/html/file_module_x86_id_72.html):
MIN_INT / -1 ==> divide error exception

These corner cases should be added to ensure the PHP program won't terminate.

Test script:
---------------
No script is needed, only a TIFF/JPEG file, and it is somewhat unneeded. The use of the generic functions is quite straightforward, and so does intel's instructions regarding the DIV command.


Patches

new (last revision 2017-04-08 10:06 UTC by 20february2016 at gmail dot com)

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-14 10:54 UTC] eyal dot itkin at gmail dot com
Typo fix: the division exception happens on the case -1 / MIN_INT
 [2016-12-30 23:22 UTC] stas@php.net
-Status: Open +Status: Feedback
 [2016-12-30 23:22 UTC] stas@php.net
I can't find any problem in that code - as far as I can see, there's a double division, and I can't see why it would fail. Do you have any image that reproduces the issue?
 [2016-12-31 09:13 UTC] eyal dot itkin at gmail dot com
-Status: Feedback +Status: Open
 [2016-12-31 09:13 UTC] eyal dot itkin at gmail dot com
My bad, the cast to (double) indeed blocks it.
The ticket can be closed, sorry for your time.
 [2016-12-31 09:15 UTC] stas@php.net
-Status: Open +Status: Not a bug
 [2016-12-31 09:15 UTC] stas@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2016-12-31 09:17 UTC] eyal dot itkin at gmail dot com
I was mistaken, there are 2 functions:
1) exif_convert_any_to_int
2) exif_convert_any_format

Only the 2nd function has a cast. the 1st function is indeed an integer division, and so it does apply. should I upload a crash trace?
 [2016-12-31 11:42 UTC] eyal dot itkin at gmail dot com
Here is the PHP script that reproduces the crash on the 1st function, as I mentioned in my previous comment:
<?php
	$e = exif_thumbnail("example_hostile.exif");
	echo "Loaded the exif picture\n";
?>

And here is the trace:
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0xb4fd9d74 in ?? () from /usr/lib/php/20151012/exif.so
(gdb) bt
#0  0xb4fd9d74 in ?? () from /usr/lib/php/20151012/exif.so
#1  0xb4fdb11f in ?? () from /usr/lib/php/20151012/exif.so
#2  0xb4fdbd40 in ?? () from /usr/lib/php/20151012/exif.so
#3  0xb4fdbc11 in ?? () from /usr/lib/php/20151012/exif.so
#4  0xb4fdc134 in ?? () from /usr/lib/php/20151012/exif.so
#5  0xb4fdc886 in zif_exif_thumbnail () from /usr/lib/php/20151012/exif.so
#6  0x802f8662 in execute_internal ()
#7  0x80251dce in dtrace_execute_internal ()
#8  0x802e9f65 in ?? ()
#9  0x802a26da in execute_ex ()
#10 0x80251c35 in dtrace_execute_ex ()
#11 0x802fa1b6 in zend_execute ()
#12 0x8026210d in zend_execute_scripts ()
#13 0x80201054 in php_execute_script ()
#14 0x802fc01f in ?? ()
#15 0x800db64f in main ()
(gdb) info reg
eax            0x80000000	-2147483648
ecx            0x1	1
edx            0xffffffff	-1
ebx            0x0	0
esp            0xbff4c188	0xbff4c188
ebp            0xb525d302	0xb525d302
esi            0xb525d30a	-1255812342
edi            0xffffffff	-1
eip            0xb4fd9d74	0xb4fd9d74
eflags         0x210202	[ IF RF ID ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51

One can see that the registers involved are edx (-1) and eax (MIN_INT), as intel describes in their chipset specs.

The .exif file that reproduces this crash can be found in this link:
http://www.cs.tau.ac.il/~eyalitki/Upload/73737/
 [2017-01-01 02:53 UTC] stas@php.net
-Status: Not a bug +Status: Open
 [2017-01-01 02:53 UTC] stas@php.net
You are right, exif_convert_any_to_int doesn't have conversion, I didn't notice it.
 [2017-01-01 03:11 UTC] stas@php.net
-PHP Version: 7.1.0 +PHP Version: 5.6.29
 [2017-01-01 03:33 UTC] stas@php.net
-Summary: Crash when parsing a tag format +Summary: FPE when parsing a tag format -Assigned To: +Assigned To: stas
 [2017-01-01 03:33 UTC] stas@php.net
The fix is in security repo as 1cda0d7c2ffb62d8331c64e703131d9cabdc03ea and in https://gist.github.com/b2739f6f3fa7b1ddb4395c14f21e43dc

please verify
 [2017-01-01 03:33 UTC] stas@php.net
-CVE-ID: +CVE-ID: needed
 [2017-01-01 04:07 UTC] eyal dot itkin at gmail dot com
I'm not sure about the casting a double to size_t, however it does solves the vulnerability. If it indeed passes the rest of the exif unit tests than it's probably OK.
 [2017-01-03 05:11 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1cda0d7c2ffb62d8331c64e703131d9cabdc03ea
Log: Fix bug #73737 FPE when parsing a tag format
 [2017-01-03 05:11 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2017-01-03 05:26 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1cda0d7c2ffb62d8331c64e703131d9cabdc03ea
Log: Fix bug #73737 FPE when parsing a tag format
 [2017-01-25 11:10 UTC] kaplan@php.net
-CVE-ID: needed +CVE-ID: 2016-10158
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 10:01:30 2024 UTC