php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61183 Firebird PDO memory corruption
Submitted: 2012-02-25 09:20 UTC Modified: 2014-01-01 12:40 UTC
Votes:5
Avg. Score:5.0 ± 0.0
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:3 (75.0%)
From: noxwizard at gmail dot com Assigned: mariuz
Status: Assigned Package: PDO Firebird
PHP Version: 5.3.10 OS: Windows Server 2008 x86
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2012-02-25 09:20 UTC] noxwizard at gmail dot com
Description:
------------
Running Firebird 2.5, and trying to use PDO to run a few queries, I ran into 
memory corruption. I've tested the same code on a few other DBMSs via PDO and they 
run fine, so it seems related to the Firebird PDO module. It also doesn't happen 
on every table structure. For example, I tried a table consisting of a single 
integer field and the error wasn't triggered. Playing with the script a bit, it 
eventually output: zend_mm_heap corrupted

The structure for the table in the example script can be found here: 
https://github.com/phpbb/phpbb3/blob/release-
3.0.10/phpBB/install/schemas/firebird_schema.sql#L1319

Test script:
---------------
<?php
try
{
	$dbh = new PDO('firebird:host=localhost;dbname=C:\\phpbb_test_data\\tests.fdb', 'SYSDBA', 'masterkey');
	for($i = 0; $i < 5000; $i++)
	{
		$statement = $dbh->prepare('INSERT INTO "PHPBB_USERS" ("USER_ID", "USERNAME", "USERNAME_CLEAN", "USER_PERMISSIONS", "USER_SIG", "USER_OCC", "USER_INTERESTS") VALUES (?, ?, ?, ?, ?, ?, ?)');
		$statement->execute(array (0 => '2', 1 => 'banned', 2 => 'banned', 3 => '', 4 => '', 5 => '', 6 => ''));
		echo 'Statement run: ' . $i . "\n";
	}
}
catch (PDOException $e)
{
	echo 'Exception: ' . $e->getMessage();
}

Expected result:
----------------
The script should run 5000 times and exit cleanly.

Actual result:
--------------
The script runs through a few iterations and PHP crashes. Altercations to the 
script can make it run longer or shorter (without trailing ?> crashes in 2 
iterations, with it, crashes after 1998 iterations).

This first backtrace is from a 32bit Windows Server 2008 install running in a 
VirtualBox VM:
Entry point   php!mainCRTStartup 
Create time   2/25/2012 2:40:53 AM 
Time spent in user mode   0 Days 0:0:0.15 
Time spent in kernel mode   0 Days 0:0:0.781 

Function     Arg 1     Arg 2     Arg 3   Source 
php5ts!zend_mm_set_custom_handlers+225     00000001     0212fa20     0212e7e0    
php5ts!_estrndup+35     02130770     00000000     02272f78    
php5ts!_zval_copy_ctor_func+42     0212e7e0     00000001     0212f490    
php5ts!pdo_stmt_describe_columns+701     00000001     02130810     00000000    
php5ts!execute+1130     02160080     02272f01     634b7838    
php5ts!execute+15ed     02272f78     0091f440     00000000    
php5ts!execute+2e8     0212e548     02272f00     02272f78    
php5ts!zend_execute_scripts+fe     00000008     02272f78     00000000    
php5ts!php_execute_script+24c     0091f6f0     02272f78     00ee742c    
php!main+b9b     00000002     02272f08     02271be0    
php!memcpy+160     7ffd7000     0091f830     777b1603    
kernel32!BaseThreadInitThunk+12     7ffd7000     75823a7e     00000000    
ntdll!RtlInitializeExceptionChain+63     00ee3002     7ffd7000     ffffffff    
ntdll!RtlInitializeExceptionChain+36     00ee3002     7ffd7000     00000000    

PHP5TS!ZEND_MM_SET_CUSTOM_HANDLERS+225In 
php__PID__4908__Date__02_25_2012__Time_02_41_07AM__420__Second_Chance_Exception_
C0000005.dmp the assembly instruction at 
php5ts!zend_mm_set_custom_handlers+225 in C:\php\php5ts.dll from The PHP Group 
has caused an access violation exception (0xC0000005) when trying to read from 
memory location 0x6e6e616a on thread 0

Module Information 
Image Name: C:\php\php5ts.dll   Symbol Type:  PDB 
Base address: 0x63490000   Time Stamp:  Thu Feb 02 13:36:49 2012  
Checksum: 0x005a3fb6   Comments:   
COM DLL: False   Company Name:  The PHP Group 
ISAPIExtension: False   File Description:  PHP Script Interpreter 
ISAPIFilter: False   File Version:  5.3.10 
Managed DLL: False   Internal Name:  PHP Script Interpreter 
VB DLL: False   Legal Copyright:  Copyright © 1997-2010 The PHP Group 
Loaded Image Name:  php5ts.dll   Legal Trademarks:  PHP 
Mapped Image Name:     Original filename:  php5ts.dll 
Module name:  php5ts   Private Build:   
Single Threaded:  False   Product Name:  PHP 
Module Size:  5.77 MBytes   Product Version:  5.3.10 
Symbol File Name:  C:\php_debug\php5ts.pdb   Special Build:  & 


Moving it to my main system, Windows 7 x64 (32bit Firebird 2.5 still), with 
Visual Studio 2010, I captured the following stack trace when it crashed:
php5ts.dll!_zend_mm_alloc_int(_zend_mm_heap * heap=0x6e6e6162, unsigned int 
size=1)  Line 1835
php5ts.dll!_estrndup(const char * s=0x02cb1308, unsigned int length=0)  Line 
2503 + 0x33 bytes
php5ts.dll!_zval_copy_ctor_func(_zval_struct * zvalue=0x02cb1d80)  Line 120 + 
0xc bytes
php5ts.dll!zim_PDOStatement_execute(int ht=1, _zval_struct * 
return_value=0x02cb1028, _zval_struct * * return_value_ptr=0x00000000, 
_zval_struct * 
this_ptr=0x02cb1088, int return_value_used=0, void * * * tsrm_ls=0x02c91ad0)  
Line 478 + 0x3f bytes
php5ts.dll!zend_do_fcall_common_helper_SPEC(_zend_execute_data * 
execute_data=0x02ce0080, void * * * tsrm_ls=0x02c91a01)  Line 320 + 0x41 bytes
php5ts.dll!ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(_zend_execute_data * 
execute_data=0x00000000, void * * * tsrm_ls=0x00000001)  Line 426
php5ts.dll!execute(_zend_op_array * op_array=0x02caee80, void * * * 
tsrm_ls=0x02c91a00)  Line 107 + 0xa bytes
php5ts.dll!zend_execute_scripts(int type=8, void * * * tsrm_ls=0x02c91ad0, 
_zval_struct * * retval=0x00000000, int file_count=3, ...)  Line 1237
php5ts.dll!php_execute_script(_zend_file_handle * primary_file=0x010afc84, void 
* * * tsrm_ls=0x02c91ad0)  Line 2308 + 0x12 bytes
php.exe!main(int argc=2, char * * argv=0x02c92fa8)  Line 1185
php.exe!__tmainCRTStartup()  Line 586 + 0x17 bytes
kernel32.dll!7646339a() 
[Frames below may be incorrect and/or missing, no symbols loaded for 
kernel32.dll]
ntdll.dll!770a9ef2()
ntdll.dll!770a9ec5()

Patches

Blob_Bind_Fix (last revision 2012-10-25 02:31 UTC) by james at kenjim dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-03-30 06:36 UTC] mariuz@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: mariuz
 [2012-10-04 08:30 UTC] james at kenjim dot com
This problem appears to comes from the handling of blobs.  In the function firebird_bind_blob in firebird_statement.c we pass param in and are destroying it with zval_dtor.  I think we should not be destroying it because it was provided by firebird_stmt_param_hook and no other path destroys this variable.  

Commenting out the zval_dtor(param) line fixes the crashing.

I also don't think we need to call SEPARATE_ZVAL(&param) or convert_to_string_ex(&param) as param appears to always be a string regardless of what we bind.
 [2012-10-05 08:25 UTC] james at kenjim dot com
After further testing I've found that NULL zval's may be passed into firebird_bind_blob so convert_to_string_ex needs to be called or a check for NULL param needs to be done before calling Z_STRLEN_P.
 [2012-10-16 03:08 UTC] paul dot ishenin at gmail dot com
I have a crash (0xc0000005 exception) when I execute a statement which inserts or 
updates blob and values are bind using bindValue(). But if I use bindParam() 
instead there is no crash. For example:

$q = Yii::app()->db->createCommand('INSERT INTO TEST (BL) VALUES (:bl)');
// this will crash $q->bindValue(':bl', bl, PDO::PARAM_LOB);
$q->bindParam(':bl', bl, PDO::PARAM_LOB); // this will not crash
$q->execute();
 [2014-01-01 12:40 UTC] felipe@php.net
-Package: PDO related +Package: PDO Firebird
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 09:02:29 2014 UTC