php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #77509 Uninitialized read in exif_process_IFD_in_TIFF
Submitted: 2019-01-23 16:18 UTC Modified: 2019-03-12 19:55 UTC
From: chamal dot desilva at gmail dot com Assigned: stas (profile)
Status: Closed Package: EXIF related
PHP Version: 7.1.26 OS: Windows, Linux 32bit
Private report: No CVE-ID: 2019-9641
 [2019-01-23 16:18 UTC] chamal dot desilva at gmail dot com
Description:
------------
Version
-------
PHP 7.3.1
PHP Git Master branch

This bug can be reproduced only in 32 bit PHP builds.
This bug is present in exif_process_IFD_in_TIFF method of ext/exif/exif.c file.

exif_process_IFD_in_TIFF method has below mentioned lines, which cause this bug.

//dir_offset has size_t type. On 32 bit systems size_t uses 4 bytes.
//If we set FF FF FF FF for dir_offset in image file, then this value becomes 4294967295.
// 4294967295 + 2 becomes 1 on a 32 bit system. So below if condition becomes true.
if (ImageInfo->FileSize >= dir_offset+2) {
		sn = exif_file_sections_add(ImageInfo, M_PSEUDO, 2, NULL);
                .....

                //This seek and read operations fail because dir_offset is larger than file size.
		php_stream_seek(ImageInfo->infile, dir_offset, SEEK_SET); 
		php_stream_read(ImageInfo->infile, (char*)ImageInfo->file.list[sn].data, 2);
 
                //So ImageInfo->file.list[sn].data will have uninitialized data.
		num_entries = php_ifd_get16u(ImageInfo->file.list[sn].data, ImageInfo->motorola_intel);

Configure Line
---------------
./configure --prefix=/programs/php/install --enable-cli --enable-exif --enable-debug --without-pear --disable-libxml --without-sqlite3 --disable-dom --without-pdo-sqlite --disable-simplexml --disable-xml --disable-xmlreader --disable-xmlwriter

 * I had to disable some modules because I did not have the dependencies to build them.



Test script:
---------------
<?php
exif_read_data(dirname(__FILE__).'\exif.jpg','ANY_TAG');
?>

Actual result:
--------------
Valgrind Output
--------------- 

Source line numbers are from PHP 7.3.1

export ZEND_DONT_UNLOAD_MODULES=1
export USE_ZEND_ALLOC=0
valgrind ./php/TestCases/test.php


==4568== Memcheck, a memory error detector
==4568== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4568== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4568== Command: ./php test.php
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x24F2D1: exif_process_IFD_in_TIFF (exif.c:3972)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568==    by 0x598C98: do_cli (php_cli.c:997)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x49BAC0: zend_safe_address (zend_multiply.h:175)
==4568==    by 0x49BB0E: zend_safe_address_guarded (zend_multiply.h:321)
==4568==    by 0x49FB53: _safe_erealloc (zend_alloc.c:2566)
==4568==    by 0x24AE52: exif_file_sections_realloc (exif.c:2012)
==4568==    by 0x24F2EA: exif_process_IFD_in_TIFF (exif.c:3976)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x483237E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4568==    by 0x4A053B: __zend_realloc (zend_alloc.c:2923)
==4568==    by 0x49F967: _erealloc (zend_alloc.c:2523)
==4568==    by 0x49FB76: _safe_erealloc (zend_alloc.c:2566)
==4568==    by 0x24AE52: exif_file_sections_realloc (exif.c:2012)
==4568==    by 0x24F2EA: exif_process_IFD_in_TIFF (exif.c:3976)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x464CFB: _php_stream_read (streams.c:655)
==4568==    by 0x24F334: exif_process_IFD_in_TIFF (exif.c:3979)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x464BF5: _php_stream_read (streams.c:676)
==4568==    by 0x24F334: exif_process_IFD_in_TIFF (exif.c:3979)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x4649D9: _php_stream_fill_read_buffer (streams.c:620)
==4568==    by 0x464C51: _php_stream_read (streams.c:687)
==4568==    by 0x24F334: exif_process_IFD_in_TIFF (exif.c:3979)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x464C6E: _php_stream_read (streams.c:690)
==4568==    by 0x24F334: exif_process_IFD_in_TIFF (exif.c:3979)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568== 
==4568== Use of uninitialised value of size 4
==4568==    at 0x24A53B: php_ifd_get32s (exif.c:1471)
==4568==    by 0x24A58C: php_ifd_get32u (exif.c:1483)
==4568==    by 0x24F36F: exif_process_IFD_in_TIFF (exif.c:3981)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568== 
==4568== Use of uninitialised value of size 4
==4568==    at 0x24A54C: php_ifd_get32s (exif.c:1472)
==4568==    by 0x24A58C: php_ifd_get32u (exif.c:1483)
==4568==    by 0x24F36F: exif_process_IFD_in_TIFF (exif.c:3981)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568== 
==4568== Use of uninitialised value of size 4
==4568==    at 0x24A55D: php_ifd_get32s (exif.c:1473)
==4568==    by 0x24A58C: php_ifd_get32u (exif.c:1483)
==4568==    by 0x24F36F: exif_process_IFD_in_TIFF (exif.c:3981)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568== 
==4568== Use of uninitialised value of size 4
==4568==    at 0x24A56B: php_ifd_get32s (exif.c:1474)
==4568==    by 0x24A58C: php_ifd_get32u (exif.c:1483)
==4568==    by 0x24F36F: exif_process_IFD_in_TIFF (exif.c:3981)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x24F615: exif_process_IFD_in_TIFF (exif.c:3987)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568==    by 0x598C98: do_cli (php_cli.c:997)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x24F648: exif_process_IFD_in_TIFF (exif.c:4055)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568==    by 0x598C98: do_cli (php_cli.c:997)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x24F654: exif_process_IFD_in_TIFF (exif.c:4056)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568==    by 0x598C98: do_cli (php_cli.c:997)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x24FACB: exif_process_IFD_in_TIFF (exif.c:4074)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568==    by 0x598C98: do_cli (php_cli.c:997)
==4568== 
==4568== Conditional jump or move depends on uninitialised value(s)
==4568==    at 0x24FAD5: exif_process_IFD_in_TIFF (exif.c:4144)
==4568==    by 0x24FECD: exif_scan_FILE_header (exif.c:4219)
==4568==    by 0x250664: exif_read_from_impl (exif.c:4344)
==4568==    by 0x2506CF: exif_read_from_stream (exif.c:4361)
==4568==    by 0x250775: exif_read_from_file (exif.c:4388)
==4568==    by 0x250FF1: zif_exif_read_data (exif.c:4461)
==4568==    by 0x52EA5B: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:690)
==4568==    by 0x59146D: execute_ex (zend_vm_execute.h:55418)
==4568==    by 0x59608D: zend_execute (zend_vm_execute.h:60834)
==4568==    by 0x4D2103: zend_execute_scripts (zend.c:1568)
==4568==    by 0x44904D: php_execute_script (main.c:2630)
==4568==    by 0x598C98: do_cli (php_cli.c:997)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-23 16:28 UTC] chamal dot desilva at gmail dot com
I can't find a way to attach the test image file 'exif.jpg'.
exif.jpg has these 8 bytes.

49 49 2A 00 FF FF FF FF

Can you please instruct me how to attach this test file?
 [2019-01-23 16:47 UTC] cmb@php.net
This issue tracker does not allow to attach arbitrary files.  In
this case exif.jpg could easily be generated by

  file_put_contents('exif.jpeg', hex2bin('49492A00FFFFFFFF'));

For larger images, you would have to make them available for
download somewhere else.
 [2019-01-23 16:47 UTC] cmb@php.net
-Operating System: Windows, Linux +Operating System: Windows, Linux 32bit
 [2019-01-24 01:20 UTC] chamal dot desilva at gmail dot com
Thanks cmb. This is updated test case.

<?php
file_put_contents(dirname(__FILE__).'\exif.jpg',hex2bin('49492A00FFFFFFFF'));
exif_read_data(dirname(__FILE__).'\exif.jpg','ANY_TAG');
?>
 [2019-03-02 07:28 UTC] stas@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: stas -CVE-ID: +CVE-ID: needed
 [2019-03-02 07:28 UTC] stas@php.net
Proposed fix in security repo as 25aa5f434dfb3337a6617b46224f1b505053d8e9 and in https://gist.github.com/smalyshev/37b30041c1ca47225dd0993d1683097f

Please verify.
 [2019-03-02 08:04 UTC] stas@php.net
-PHP Version: 7.3.1 +PHP Version: 7.1.26
 [2019-03-08 07:37 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2019-03-08 07:37 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.


 [2019-03-12 08:29 UTC] chamal dot desilva at gmail dot com
Is it possible to add a CVE ID for this bug?
 [2019-03-12 19:55 UTC] stas@php.net
-CVE-ID: needed +CVE-ID: 2019-9641
 [2022-03-18 20:24 UTC] tekashiixine359 at gmail dot com
Score: 9.8
An issue was discovered in PHP before 5.6.40, 7.x before 7.1.26, 7.2.x before 7.2.14, and 7.3.x before 7.3.1.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 17:01:29 2024 UTC