ID: 49937
Updated by: [email protected]
Reported By: [email protected]
Status: Open
Bug Type: PDO related
Operating System: Linux
PHP Version: 5.2.11
New Comment:
Here is the patch which fixes the race condition in pdo :
Patch is generated against PHP_5_2 svn branch.
Index: ext/pdo/pdo_stmt.c
===================================================================
--- ext/pdo/pdo_stmt.c (revision 289806)
+++ ext/pdo/pdo_stmt.c (working copy)
@@ -2325,7 +2325,7 @@
stmt->refcount = 1;
ALLOC_HASHTABLE(stmt->properties);
zend_hash_init(stmt->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_copy(stmt->properties, &stmt->ce->default_properties,
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+ zend_hash_copy(stmt->properties, &stmt->ce->default_properties,
(copy_ctor_func_t) zval_add_ref_atomic, (void *) &tmp, sizeof(zval *));
old_stmt = (pdo_stmt_t *)zend_object_store_get_object(zobject
TSRMLS_CC);
@@ -2454,7 +2454,7 @@
stmt->refcount = 1;
ALLOC_HASHTABLE(stmt->properties);
zend_hash_init(stmt->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_copy(stmt->properties, &ce->default_properties,
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+ zend_hash_copy(stmt->properties, &ce->default_properties,
(copy_ctor_func_t) zval_add_ref_atomic, (void *) &tmp, sizeof(zval *));
retval.handle = zend_objects_store_put(stmt,
(zend_objects_store_dtor_t)zend_objects_destroy_object,
(zend_objects_free_object_storage_t)pdo_dbstmt_free_storage,
(zend_objects_store_clone_t)dbstmt_clone_obj TSRMLS_CC);
retval.handlers = &pdo_dbstmt_object_handlers;
Index: TSRM/TSRM.c
===================================================================
--- TSRM/TSRM.c (revision 289806)
+++ TSRM/TSRM.c (working copy)
@@ -714,6 +714,12 @@
return retval;
}
+TSRM_API void *tsrm_atomic_incr(volatile unsigned int* val)
+{
+ tsrm_mutex_lock(tsmm_mutex);
+ ++*val;
+ tsrm_mutex_unlock(tsmm_mutex);
+}
/*
Index: TSRM/TSRM.h
===================================================================
--- TSRM/TSRM.h (revision 289806)
+++ TSRM/TSRM.h (working copy)
@@ -139,6 +139,7 @@
TSRM_API void
*tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t
new_thread_begin_handler);
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t
new_thread_end_handler);
+TSRM_API void *tsrm_atomic_incr(volatile unsigned int* val);
/* these 3 APIs should only be used by people that fully understand
the threading model
* used by PHP/Zend and the selected SAPI. */
Index: Zend/zend_variables.c
===================================================================
--- Zend/zend_variables.c (revision 289806)
+++ Zend/zend_variables.c (working copy)
@@ -100,6 +100,17 @@
}
/* }}} */
+
+ZEND_API void zval_add_ref_atomic(zval **p) /* {{{ */
+{
+#ifdef ZTS
+ tsrm_atomic_incr(&(*p)->refcount);
+#else
+ (*p)->refcount++;
+#endif
+}
+/* }}} */
+
ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC) /*
{{{ */
{
switch (zvalue->type) {
Index: Zend/zend_variables.h
===================================================================
--- Zend/zend_variables.h (revision 289806)
+++ Zend/zend_variables.h (working copy)
@@ -76,6 +76,7 @@
#endif
ZEND_API void zval_add_ref(zval **p);
+ZEND_API void zval_add_ref_atomic(zval **p);
END_EXTERN_C()
Previous Comments:
------------------------------------------------------------------------
[2009-10-20 22:43:54] [email protected]
Description:
------------
There is a race condition in pdo's stmt PDOStatement class.
This class is dynamically created and it adds a member named
queryString
(inside pdo_stmt_init).
zend_declare_property_null allocates property using malloc.
Later pdo_dbstmt_ce is copied to other hashes in pdo_dbstmt_new.
zend_hash_copy increments refcount of pdo_dbstmt_ce->queryString
property. In
multithreaded php refcount increment was not atomic. It was causing
refcount
to become 0 and hence efree was trying to delete something which was
allocated
from malloc.
There is a php benchmark kit named olio and can be downloaded from :
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_SMI-Site/en_US/-/USD/viewproductdetail-start?productref=olio-php-1.0-a-...@cds-cds_smi
The bug is easily reproducible with olio php benchmark inside Sun Web
Server.
Expected result:
----------------
Correct functionality
Actual result:
--------------
Stack trace :
--------------
Program terminated with signal 11, Segmentation fault.
#0 0x00002ba1630451e0 in _zend_mm_free_int ()
from /home/sun/webserver7/bin/libphp5.so
#1 0x00002ba163084aa0 in zend_std_write_property ()
from /home/sun/webserver7/bin/libphp5.so
#2 0x00002ba162ebfc4a in pdo_stmt_construct ()
from /home/sun/webserver7/bin/libphp5.so
#3 0x00002ba162ec0073 in zim_PDO_query ()
from /home/sun/webserver7/bin/libphp5.so
#4 0x00002ba1630999f9 in zend_do_fcall_common_helper_SPEC ()
from /home/sun/webserver7/bin/libphp5.so
#5 0x00002ba16308705f in execute () from
/home/sun/webserver7/bin/libphp5.so
#6 0x00002ba1630993d8 in zend_do_fcall_common_helper_SPEC ()
from /home/sun/webserver7/bin/libphp5.so
#7 0x00002ba16308705f in execute () from
/home/sun/webserver7/bin/libphp5.so
#8 0x00002ba1630630fa in zend_execute_scripts ()
from /home/sun/webserver7/bin/libphp5.so
#9 0x00002ba1630188bb in php_execute_script ()
from /home/sun/webserver7/bin/libphp5.so
#10 0x00002ba1630ee465 in php5_execute ()
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=49937&edit=1