Bug #62523 [Fbk]: php crashes with segfault when exif_read_data called

From: Date: Tue, 22 Oct 2013 05:10:40 +0000
Subject: Bug #62523 [Fbk]: php crashes with segfault when exif_read_data called
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-182377@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=62523&edit=1 ID: 62523 Updated by: pajoye@php.net Reported by: bigbug at mafia dot lv Summary: php crashes with segfault when exif_read_data called Status: Feedback Type: Bug Package: Reproducible crash Operating System: linux PHP Version: 5.3Git-2012-07-10 (snap) Assigned To: rasmus Block user comment: N Private report: N New Comment: Same here, using latest 5.5 or snaps: php_exif.dll!php_ifd_get16u(void * value, int motorola_intel) Line 1095 C php_exif.dll!exif_iif_add_value(image_info_type * image_info, int section_index, char * name, int tag, int format, int length, void * value, int motorola_intel, void * * * tsrm_ls) Line 1754 C php_exif.dll!exif_process_IFD_TAG(image_info_type * ImageInfo, char * dir_entry, char * offset_base, unsigned int IFDlength, unsigned int displacement, int section_index, int ReadNextIFD, const tag_info_type * tag_table, void * * * tsrm_ls) Line 3111 C php_exif.dll!exif_process_IFD_in_MAKERNOTE(image_info_type * ImageInfo, char * value_ptr, int value_len, char * offset_base, unsigned int IFDlength, unsigned int displacement, void * * * tsrm_ls) Line 2789 C php_exif.dll!exif_process_IFD_TAG(image_info_type * ImageInfo, char * dir_entry, char * offset_base, unsigned int IFDlength, unsigned int displacement, int section_index, int ReadNextIFD, const tag_info_type * tag_table, void * * * tsrm_ls) Line 3064 C php_exif.dll!exif_process_IFD_in_JPEG(image_info_type * ImageInfo, char * dir_start, char * offset_base, unsigned int IFDlength, unsigned int displacement, int section_index, void * * * tsrm_ls) Line 3139 C php_exif.dll!exif_process_IFD_TAG(image_info_type * ImageInfo, char * dir_entry, char * offset_base, unsigned int IFDlength, unsigned int displacement, int section_index, int ReadNextIFD, const tag_info_type * tag_table, void * * * tsrm_ls) Line 3101 C php_exif.dll!exif_process_IFD_in_JPEG(image_info_type * ImageInfo, char * dir_start, char * offset_base, unsigned int IFDlength, unsigned int displacement, int section_index, void * * * tsrm_ls) Line 3139 C php_exif.dll!exif_process_TIFF_in_JPEG(image_info_type * ImageInfo, char * CharBuf, unsigned int length, unsigned int displacement, void * * * tsrm_ls) Line 3222 C php_exif.dll!exif_process_APP1(image_info_type * ImageInfo, char * CharBuf, unsigned int length, unsigned int displacement, void * * * tsrm_ls) Line 3240 C php_exif.dll!exif_scan_JPEG_header(image_info_type * ImageInfo, void * * * tsrm_ls) Line 3426 C php_exif.dll!exif_scan_FILE_header(image_info_type * ImageInfo, void * * * tsrm_ls) Line 3767 C php_exif.dll!exif_read_file(image_info_type * ImageInfo, char * FileName, int read_thumbnail, int read_all, void * * * tsrm_ls) Line 3908 C php_exif.dll!zif_exif_read_data(int ht, _zval_struct * return_value, _zval_struct * * return_value_ptr, _zval_struct * this_ptr, int return_value_used, void * * * tsrm_ls) Line 3960 C Previous Comments: ------------------------------------------------------------------------ [2013-10-21 23:12:27] info at getid3 dot org Problem exists for me in PHP 5.4.7 that I have installed here. Using the original poster's sample code and sample file (or my own sample file linked above) Apache crashed with this in the log: [notice] Parent: child process exited with status 255 -- Restarting. [notice] Apache/2.2.21 (Win32) PHP/5.4.7 configured -- resuming normal operations ------------------------------------------------------------------------ [2013-10-21 22:26:49] mike@php.net Cannot reproduce with PHP-5.4+ ------------------------------------------------------------------------ [2013-10-17 06:13:54] kbinaz at gmail dot com Any update on this bug? I've also run into this same problem with using exif to read data from some jpeg's. The script dies with a segmentation fault. I've applied Dominic's patch manually and re-compiled, and it seems to fix the issue. Any eta on when it will make it to PHP source? ------------------------------------------------------------------------ [2013-05-21 16:15:22] bigbug at mafia dot lv Thanks! The patch really works! ------------------------------------------------------------------------ [2013-05-21 14:20:58] dominic dot benson at thirdlight dot com I encountered a similar issue reading EXIF from a TIFF, the below patch fixes both my original TIFF issue, and the issue with file "1.orig.jpg" linked in the original report for me. Environment: Linux amd64/i686 (Debian 5/6/7, Ubuntu 13.04) PHP version: 5.3.25 SAPI: CLI/FastCGI Required for the JPEG fix is a change from int type for offset_diff in exif_process_IFD_in_MAKERNOTE. I've changed it to size_t, which is semantically correct for Linux, but I think this isn't portable to Win. Essentially, the issue is that values read from the file are treated as offsets, and used to manipulate the offset_base. Patch (agains 5.3.25) follows: diff -rupN php-5.3.25.orig/ext/exif/exif.c php-5.3.25/ext/exif/exif.c --- php-5.3.25.orig/ext/exif/exif.c 2013-05-08 16:58:52.000000000 +0100 +++ php-5.3.25/ext/exif/exif.c 2013-05-21 14:59:59.579438565 +0100 @@ -2745,7 +2745,8 @@ static int exif_process_unicode(image_in static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * value_ptr, int value_len, char *offset_base, size_t IFDlength, size_t displacement TSRMLS_DC) { int de, i=0, section_index = SECTION_MAKERNOTE; - int NumDirEntries, old_motorola_intel, offset_diff; + int NumDirEntries, old_motorola_intel; + size_t offset_diff; const maker_note_type *maker_note; char *dir_start; @@ -2921,6 +2922,12 @@ static int exif_process_IFD_TAG(image_in } } } else { + if (value_ptr<offset_base) { +#ifdef EXIF_DEBUG + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "EXIF invalid: offset_base (x%016llX) exceed value_ptr (x%016llX)", offset_base, value_ptr); +#endif + return FALSE; + } /* 4 bytes or less and value is in the dir entry itself */ value_ptr = dir_entry+8; offset_val= value_ptr-offset_base; @@ -3724,6 +3731,12 @@ static int exif_process_IFD_in_TIFF(imag exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Next IFD: %s done", exif_get_sectionname(sub_section_index)); #endif } else { + if(dir_offset > ImageInfo->file.list[sn].data) { +#ifdef EXIF_DEBUG + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Skip processing: dir_offset (x%016llX) exceeds data pointer (x%016llX)", ImageInfo->file.list[sn].data, dir_offset); +#endif + return FALSE; + } if (!exif_process_IFD_TAG(ImageInfo, (char*)dir_entry, (char*)(ImageInfo->file.list[sn].data-dir_offset), ifd_size, 0, section_index, 0, tag_table TSRMLS_CC)) { ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=62523 -- Edit this bug report at https://bugs.php.net/bug.php?id=62523&edit=1

« previous php.bugs (#182377) next »