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 (profile)
Status: Closed Package: EXIF related
PHP Version: 5.*, 6CVS (2009-05-27) OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: phpbug dot exif at sub dot noloop dot net
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC