php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72489 PHP Crashes When Modifying Array Containing MySQLi Result Data
Submitted: 2016-06-24 15:49 UTC Modified: 2016-09-17 20:58 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: s7g2vp2 at yahoo dot co dot uk Assigned: nikic
Status: Closed Package: MySQLi related
PHP Version: 7.0.8 OS: Windows Server 2012r2
Private report: No CVE-ID:
 [2016-06-24 15:49 UTC] s7g2vp2 at yahoo dot co dot uk
Description:
------------
We are testing our application in PHP 7 and are experiencing crashes. This occurs when PHP is running under 64 bit Apache 2.4 using mod_php. It also occurs when using PHP's built-in web server. 

I originally found the problem in 7.0.7 so upgraded to 7.0.8 to see if the problem was fixed. The same code runs okay on PHP 5.4, PHP 5.5 & PHP 5.6.

The crash seems to be triggered when I append an array to a second array (removing that line of code prevents the crash):
ie:
$resultArray[] = $itemArray;

$itemArray is an associative array that contains values fetched from a MySQL query.

Our app runs various Update & Select queries before it reaches this point so the crash could be the result of a problem that occurred earlier in our code.

Test script:
---------------
Unfortunately, after several hours of trying I have been unable to duplicate this problem outside of our application. I have provided a backtrace.

Actual result:
--------------
DebugDiag Analysis Report 

   Dumps: 
1/1 


   Rules: 
1/1 



Analysis Summary


 Error 


Description Recommendation 

In php__PID__14052__Date__06_24_2016__Time_03_47_12PM__902__Second_Chance_Exception_C0000005.dmp the assembly instruction at php7ts!_emalloc+a2 in C:\php708_debug\php7ts.dll from The PHP Group has caused an access violation exception (0xC0000005) when trying to read from memory location 0x00000000 on thread 0
 Please follow up with the vendor The PHP Group for C:\php708_debug\php7ts.dll
 

Report for php__PID__14052__Date__06_24_2016__Time_03_47_12PM__902__Second_Chance_Exception_C0000005.dmp



Type of Analysis Performed   Combined Crash/Hang Analysis 
Machine Name   xxxxx 
Operating System   Windows Server 2012 
Number Of Processors   2 
Process ID   14052 
Process Image   C:\php708_debug\php.exe 
Command Line   php -S 172.17.150.10:81 -t C:\webroot 
System Up-Time   14 day(s) 23:01:36 
Process Up-Time   00:01:48 
Processor Type   X64 
Process Bitness   64-Bit 

Top 5 Threads by CPU time


Note - Times include both user mode and kernel mode for each thread 
Thread ID: 0     Total CPU Time: 00:00:00.765     Entry Point for Thread: php!mainCRTStartup 
Thread ID: 1     Total CPU Time: 00:00:00.000     Entry Point for Thread: mswsock!SockAsyncThread 

CLR Information


Thread Report

Thread 0 - System ID 15772


Entry point   php!mainCRTStartup 
Create time   24/06/2016 15:45:29 
Time spent in user mode   0 Days 00:00:00.625 
Time spent in kernel mode   0 Days 00:00:00.140 

  Source

php7ts!_emalloc+a2 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_alloc.c @ 2450 + 5b]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_alloc.c @ 2450 + 5b 
php7ts!_mysqlnd_pemalloc+76 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_alloc.c @ 145]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_alloc.c @ 145 
php7ts!php_mysqlnd_rset_field_read+978 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_wireprotocol.c @ 1347 + e]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_wireprotocol.c @ 1347 + e 
php7ts!php_mysqlnd_res_meta_read_metadata_pub+1b6 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_result_meta.c @ 75 + 8]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_result_meta.c @ 75 + 8 
php7ts!php_mysqlnd_res_read_result_metadata_pub+163 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_result.c @ 380 + 8]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_result.c @ 380 + 8 
php7ts!php_mysqlnd_stmt_prepare_pub+3d7 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_ps.c @ 451 + 9]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqlnd\mysqlnd_ps.c @ 451 + 9 
php_mysqli!zif_mysqli_prepare+178 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqli\mysqli_api.c @ 1865 + 15]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\ext\mysqli\mysqli_api.c @ 1865 + 15 
php7ts!ZEND_DO_FCALL_SPEC_HANDLER+12b [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_vm_execute.h @ 854]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_vm_execute.h @ 854 
php7ts!execute_ex+44 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_vm_execute.h @ 417 + 5]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_vm_execute.h @ 417 + 5 
php7ts!zend_execute+1f7 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_vm_execute.h @ 459]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend_vm_execute.h @ 459 
php7ts!zend_execute_scripts+13e [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend.c @ 1428]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\zend\zend.c @ 1428 
php7ts!php_execute_script+4d9 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\main\main.c @ 2494 + 1b]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\main\main.c @ 2494 + 1b 
php!php_cli_server_dispatch_script+ea [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 1941]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 1941 
php!php_cli_server_dispatch+112 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2115 + b]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2115 + b 
php!php_cli_server_recv_event_read_request+98 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2329]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2329 
php!php_cli_server_do_event_for_each_fd_callback+170 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2415]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2415 
php!php_cli_server_poller_iter_on_active+db [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 822 + f]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 822 + f 
php!php_cli_server_do_event_loop+b0 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2441 + 35]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2441 + 35 
php!do_cli_server+1f1 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2543]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli_server.c @ 2543 
php!main+2394 [c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli.c @ 1347 + 5]   c:\php-sdk\php70dev\vc14\x64\php-7.0.8-ts\sapi\cli\php_cli.c @ 1347 + 5 
php!__scrt_common_main_seh+124 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 255 + 22]   f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 255 + 22 
kernel32!BaseThreadInitThunk+d    
ntdll!RtlUserThreadStart+34    




Thread 1 - System ID 15124

Entry point   mswsock!SockAsyncThread 
Create time   24/06/2016 15:45:30 
Time spent in user mode   0 Days 00:00:00.000 
Time spent in kernel mode   0 Days 00:00:00.000 

  Source

ntdll!NtRemoveIoCompletion+a    
mswsock!SockAsyncThread+79    
kernel32!BaseThreadInitThunk+d    
ntdll!RtlUserThreadStart+34    

Exception Information


PHP7TS!_EMALLOC+A2In php__PID__14052__Date__06_24_2016__Time_03_47_12PM__902__Second_Chance_Exception_C0000005.dmp the assembly instruction at php7ts!_emalloc+a2 in C:\php708_debug\php7ts.dll from The PHP Group has caused an access violation exception (0xC0000005) when trying to read from memory location 0x00000000 on thread 0

Module Information 

Image Name: C:\php708_debug\php7ts.dll   Symbol Type:  PDB 
Base address: 0x00000003`00905a4d   Time Stamp:  Tue Jun 21 23:57:34 2016  
Checksum: 0x00000000`00000000   Comments:   
COM DLL: False   Company Name:  The PHP Group 
ISAPIExtension: False   File Description:  PHP Script Interpreter 
ISAPIFilter: False   File Version:  7.0.8 
Managed DLL: False   Internal Name:  PHP Script Interpreter 
VB DLL: False   Legal Copyright:  Copyright © 1997-2016 The PHP Group 
Loaded Image Name:  php7ts.dll   Legal Trademarks:  PHP 
Mapped Image Name:     Original filename:  php7ts.dll 
Module name:  php7ts   Private Build:   
Single Threaded:  False   Product Name:  PHP 
Module Size:  8.27 MBytes   Product Version:  7.0.8 
Symbol File Name:  c:\php708_debug\ext\php7ts.pdb   Special Build:  & 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-01 11:17 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2016-07-01 11:17 UTC] ab@php.net
Were it possible you to provide a crash dump?

Thanks.
 [2016-07-01 13:44 UTC] s7g2vp2 at yahoo dot co dot uk
-Status: Feedback +Status: Open
 [2016-07-01 13:44 UTC] s7g2vp2 at yahoo dot co dot uk
Hi. I already included this information in my original post.

If you need me to do anything else can you provide some instructions on what I need to do.

Thanks.
 [2016-07-01 16:00 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2016-07-01 16:00 UTC] ab@php.net
With DebugDiag you usually also produce a crash dump. Or, you can use this technique https://msdn.microsoft.com/de-de/library/windows/desktop/bb787181(v=vs.85).aspx . Just be sure the dump doesn't include any sensitive data.

You also could still pursue a reproduce snippet. From the backtrace you've posted, it is something related to mysqli_prepare() usage.

Thanks.
 [2016-07-01 18:24 UTC] s7g2vp2 at yahoo dot co dot uk
-Status: Feedback +Status: Open
 [2016-07-01 18:24 UTC] s7g2vp2 at yahoo dot co dot uk
ok. I've created a full dump. It is 17MB zipped.
How do I get this to you as I cannot see any way to attach arbitrary files to the case.
 [2016-07-03 18:43 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2016-07-03 18:43 UTC] ab@php.net
Yeah, you can't attach files on this tracker. Please share it some other way.

Thanks.
 [2016-07-06 14:38 UTC] s7g2vp2 at yahoo dot co dot uk
-Status: Feedback +Status: Open
 [2016-07-06 14:38 UTC] s7g2vp2 at yahoo dot co dot uk
I've shared the file here:
https://www.dropbox.com/s/fxgve6bir4evyro/php.exe.11024.dmp.zip?dl=0
 [2016-07-15 08:32 UTC] s7g2vp2 at yahoo dot co dot uk
Hi.

Just checking in to see if you need any additional information?

Thanks.
 [2016-07-25 20:31 UTC] ab@php.net
Just came to it, thanks for sharing. I've loaded it, but it seems to be from some custom build, so it asks me for pdb i don't have. Were it possible to repeat with some official PHP binary, so the debug info were fetcheable as well? Or maybe, you were alternatively able to extract a reproduce snippet?

Thanks.
 [2016-07-26 08:16 UTC] s7g2vp2 at yahoo dot co dot uk
Hi.

I used the build available from windows.php.net

I'm sure I took the php 7.0.8 build and added the debug pack:
php-debug-pack-7.0.8-Win32-VC14-x64.zip
 [2016-07-28 10:53 UTC] ab@php.net
-Status: Open +Status: Feedback
 [2016-07-28 10:53 UTC] ab@php.net
Indeed, thanks for the hint. The symbols match now. Unfortunately it's still impossible to come to the crash cause :( Though, more info for you - the particular statement used for mysqli_prepare is

SELECT * FROM `METADATA` WHERE (`orderid` = ?) AND (`orderitemid` = ?) AND (`section` = ?) AND (`orderitemcomponentid` = ?)

The crash happens while preparing it. I would ask you to research the code around it to maybe extract a reproduce snippet.

Another chance, which could possibly bring more info, were to create a dump while USE_ZEND_ALLOC=0 is set in the environment. That way the PHP memory manager is turned off, so some useful info could be delivered from CRT.

Thanks.
 [2016-08-07 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2016-08-18 13:47 UTC] cmb@php.net
-Status: No Feedback +Status: Re-Opened
 [2016-08-18 13:47 UTC] cmb@php.net
Re-opened on OP request.
 [2016-08-18 14:18 UTC] s7g2vp2 at yahoo dot co dot uk
-Summary: PHP Crashes When Appending Array Containing MySQLi Result Data +Summary: PHP Crashes When Modifying Array Containing MySQLi Result Data
 [2016-08-18 14:18 UTC] s7g2vp2 at yahoo dot co dot uk
We have finally managed to reproduce the problem outside of our application. I have updated the case summary as the trigger turns out to be something different to what I originally thought.

There appears to be more than one version of the problem as different code can trigger a crash in different places. 

I have included a sample script below which should allow you to reproduce the problem (tested on MS-Windows and Mac OS X).




<?php

$dbHost = "127.0.0.1";
$dbUserName = "";
$dbPassword = "";
$dbDatabase = "";

$dbObj = new mysqli($dbHost, $dbUserName, $dbPassword, $dbDatabase);

$tableDropSQL = "DROP TABLE php7bug";

$dbObj->query($tableDropSQL);

$tableCreateSQL = "CREATE TABLE php7bug (id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, code VARCHAR(30) NOT NULL)";

if ($dbObj->query($tableCreateSQL) === TRUE)
{
    echo "Table MyGuests created successfully\n";

	$seedSQL = "INSERT INTO php7bug (`code`) VALUES ('code1');";
	$seedSQL .= "INSERT INTO php7bug (`code`) VALUES ('code2');";
	$seedSQL .= "INSERT INTO php7bug (`code`) VALUES ('code3');";

	if ($dbObj->multi_query($seedSQL) === TRUE)
	{
	    echo "New records created successfully\n";
	}
}


$dbObj = new mysqli($dbHost, $dbUserName, $dbPassword, $dbDatabase);

$expectedRecords = 3;

$id = 1;

$subRow = array();

if ($stmt2 = $dbObj->prepare("SELECT id, code FROM `php7bug`"))
{
	$stmt2->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY);

	if ($stmt2->execute())
	{
		$stmt2->bind_result($subRow['id'], $subRow['code']);

		$count = 1;

		while ($stmt2->fetch())
		{
			error_log("row: " . $count++ . " of " . $expectedRecords . "\n");

			// DOESN'T CAUSE SEGFAULT
			// $subRow['code'] = array();

			// DOESN'T CAUSE SEGFAULT
			// $subRow['code'] = array('id' => 1);

			// DOESN'T CAUSE SEGFAULT
			// $subRow['code'] = array('id' => $id);

			// CAUSES SEGFAULT - NEVER REACHES "Finished 1"
			$testArray = array('id' => $id);
			$subRow['code'] = $testArray;

			// CAUSES SEGFAULT - NEVER REACHES "Finished 2"
			// $subRow['code'] = array('id' => $id);
			// $testArray = array('id' => $id);
			// $subRow['code'] = $testArray;


			// CAUSES SEGFAULT - NEVER REACHES "Finished 1"
			// $metaData = array();
			// $metaData['id'] = $id;
			// $subRow['code'] = $metaData;

		}
	}
}

echo "Finished 1\n";

// this is the line which crashes the script	
$newArray = array();
	
echo "Finished 2\n";
	
?>
 [2016-08-29 18:12 UTC] s7g2vp2 at yahoo dot co dot uk
Hi.

Just checking to see if you now have everything to re-produce the bug.

Thanks.
 [2016-09-17 10:08 UTC] nikic@php.net
I wasn't able to reproduce the issue using the provided reproduce script on Ubuntu 16.04. I tried both current master and PHP 7.0.8 specifically.
 [2016-09-17 10:16 UTC] nikic@php.net
-Status: Re-Opened +Status: Verified
 [2016-09-17 10:16 UTC] nikic@php.net
Sorry, I made a mistake in the configuration. I was able to reproduce the issue on PHP 7.0 (including HEAD), but was *not* able to reproduce it on PHP 7.1.
 [2016-09-17 10:20 UTC] nikic@php.net
The offending line is https://github.com/php/php-src/blob/master/ext/mysqlnd/mysqlnd_ps.c#L817, which performs a zval_dtor instead of a zval_ptr_dtor.

Instead of fixing this particular case, I think we should apply https://github.com/php/php-src/commit/ded69ee6e6039d56ee7b65b1a578ed1e3d1859da to PHP-7.0 to avoid this class of problems with zval_dtor in general.
 [2016-09-17 20:58 UTC] nikic@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Feb 21 19:01:38 2017 UTC