php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48378 exif_read_data() segfaults on certain corrupted .jpeg files
Submitted: 2009-05-24 20:58 UTC Modified: 2009-05-28 14:04 UTC
From: phpbug dot exif at sub dot noloop dot net Assigned: pajoye
Status: Closed Package: EXIF related
PHP Version: 5.*, 6CVS (2009-05-27) OS: *
Private report: No CVE-ID:
 [2009-05-24 20:58 UTC] phpbug dot exif at sub dot noloop dot net
Description:
------------
There seems to be a problem in exif_read_data(), where some fields representing offsets(?) are taken directly from the file without being validated, resulting in a segmentation fault.

I originally found this issue by fooling around with the "zzuf" fuzzer, and reported a very similar bug in the "jhead" exif utility at http://bugs.debian.org/530401

Original image can be found at: http://www.noloop.net/bugs/php/001-exif/hello.jpeg
Corrupted image can be found at: http://www.noloop.net/bugs/php/001-exif/hello-s148.jpeg


Reproduce code:
---------------
<?php
 var_dump(exif_read_data($_SERVER['argv'][1], array("FILE", "COMPUTED", "ANY_TAG") ));

Expected result:
----------------
Dump of exif data if possible, or FALSE (since the jpeg file is indeed corrupt)

Actual result:
--------------
Segmentation fault.

Quick GDB dump:
(gdb) run
Starting program: /home/frode/temp/z/z3/php5.2-200905241830/sapi/cli/php /home/frode/temp/z/s.php /home/frode/temp/z/a-s6.jpeg

Program received signal SIGSEGV, Segmentation fault.
0x0808bcd3 in exif_process_IFD_in_JPEG (ImageInfo=0xbfc893b8, 
    dir_start=0x92f76c0 <Address 0x92f76c0 out of bounds>, offset_base=0x8ef76b8 "II*", IFDlength=15055, 
    displacement=30, section_index=3) at /home/frode/temp/z/z3/php5.2-200905241830/ext/exif/exif.c:1088
1088                    return (((uchar *)value)[1] << 8) | ((uchar *)value)[0];
(gdb) up
#1  0x0808e6ca in exif_read_file (ImageInfo=0xbfc893b8, FileName=<value optimized out>, 
    read_thumbnail=<value optimized out>, read_all=0)
    at /home/frode/temp/z/z3/php5.2-200905241830/ext/exif/exif.c:3221
3221            exif_process_IFD_in_JPEG(ImageInfo, CharBuf+offset_of_ifd, CharBuf, length/*-14*/, displacement, SECTION_IFD0 TSRMLS_CC);


Note the "dir_start" address being out of bounds, which causes the "((uchar *)value)[1]" to segfault. (The function names are a bit confusing, maybe it's because of method inlining?)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-05-25 19:59 UTC] iliaa@php.net
I am getting the following error messages, but no crash:

Warning: exif_read_data(hello-s148.jpeg): Illegal IFD size: x40000B + 2 
+ x0000*12 = x40000B > x007E in exif.php on line 2

Warning: exif_read_data(hello-s148.jpeg): Error reading from file: 
got=x08B4(=2228) != itemlen-2=x1FFE(=8190) in exif.php on line 2

Warning: exif_read_data(hello-s148.jpeg): Invalid JPEG file in exif.php 
on line 2


 [2009-05-25 20:49 UTC] phpbug dot exif at sub dot noloop dot net
That's odd. I'm getting 100% reproducible crash on both the latest 5.2 cvs snapshot, as well as the php build included in Debian Linux 5.0.1 (stable) (which is 5.2.6+some debian patches)

I'm using Linux 2.6.29.4, Debian 5.0.1, gcc version 4.3.2 (Debian 4.3.2-1.1) on an i686 (32bit) machine with 3gb ram. 

To compile, I did:

'./configure'  '--prefix=/home/frode/temp/z/zinst3' '--disable-all' '--enable-exif'
make cli

Are you running on 64bit, or perhaps some other distro with a different version of gcc etc?
 [2009-05-26 05:24 UTC] scottmac@php.net
I can confirm here on OSX.

#0  0x00033397 in php_ifd_get16u (value=0x7100b1, motorola_intel=0) at /Users/scott/dev/php5_2/ext/exif/exif.c:1088
1088			return (((uchar *)value)[1] << 8) | ((uchar *)value)[0];
(gdb) bt
#0  0x00033397 in php_ifd_get16u (value=0x7100b1, motorola_intel=0) at /Users/scott/dev/php5_2/ext/exif/exif.c:1088
#1  0x00037a01 in exif_process_IFD_in_JPEG (ImageInfo=0xbfffef8c, dir_start=0x7100b1 <Address 0x7100b1 out of bounds>, offset_base=0x3100a8 "II*", IFDlength=126, displacement=12, section_index=3) at /Users/scott/dev/php5_2/ext/exif/exif.c:3140
#2  0x00037d92 in exif_process_TIFF_in_JPEG (ImageInfo=0xbfffef8c, CharBuf=0x3100a8 "II*", length=126, displacement=12) at /Users/scott/dev/php5_2/ext/exif/exif.c:3221
#3  0x00037e92 in exif_process_APP1 (ImageInfo=0xbfffef8c, CharBuf=0x3100a0 "", length=134, displacement=4) at /Users/scott/dev/php5_2/ext/exif/exif.c:3246
#4  0x000384d2 in exif_scan_JPEG_header (ImageInfo=0xbfffef8c) at /Users/scott/dev/php5_2/ext/exif/exif.c:3385
#5  0x000393c4 in exif_scan_FILE_header (ImageInfo=0xbfffef8c) at /Users/scott/dev/php5_2/ext/exif/exif.c:3757
#6  0x0003a073 in exif_read_file (ImageInfo=0xbfffef8c, FileName=0x30d2d4 "hello-s148.jpeg", read_thumbnail=0, read_all=0) at /Users/scott/dev/php5_2/ext/exif/exif.c:3902

 [2009-05-27 19:05 UTC] jani@php.net
Verified with proper test script, this function never accepted array 
parameters:

<?php
exif_read_data(
"http://www.noloop.net/bugs/php/001-exif/hello-s148.jpeg", 
"FILE,COMPUTED,ANY_TAG"
);

Same backtrace (just a bit different line numbers) with all branches.
 [2009-05-28 12:49 UTC] iliaa@php.net
On 64 bit linux I get no crash and no complaints from valgrind either.
 [2009-05-28 14:04 UTC] pajoye@php.net
This bug has been fixed in CVS.

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/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 16 16:02:23 2014 UTC