Hi All,
I have come across a double free because of improper refcount
manipulation.
<?php
class MyTextSanitizer
{
var $smileys=array()
function MyTextSanitizer() {}
function getSmileys()
{
return $this->smileys;
}
}
$myts = new MyTextSanitizer();
$smiles =& $myts->getSmileys(); //calling by ref alone causes improper
refcount
$smiles = $myts->getSmileys(); //this does not cause improper refcount
?>
What is happening is class_entry->default_properties and
object->properties are sharing the same zval** as the data($smileys)
against their keys with incrementing the refcount.
In the execution of the script refcount of $smileys is changing from
1->2,
2->3,
3->2,
2->3,
3->2,
2->1, --->when it is 1 zend_objects_free_object_storage calls
zend_hash_destroy of object->properties which calls _zval_ptr_dtor on
each of its data($smiley) frees it if the refcount ==1
1->0 --destroy_zend_class also calls
zend_hash_destroy(&ce->default_properties) by the time
$smiley->refcount=0 and storage is already freed which is accessed by
_zval_ptr_dtor to decrement the refcount which causes a segfault with a
huge script.
Anyway will see who and all increment/decrement the refcount and see
where to increment it or not to decrement it.
With regards
Kamesh Jayachandran
Hi All,
I have come across a double free because of improper refcount
manipulation.
<?php
class MyTextSanitizer
{
var $smileys=array()
function MyTextSanitizer() {}
function getSmileys()
{
return $this->smileys;
}
}
$myts = new MyTextSanitizer();
$smiles =& $myts->getSmileys(); //calling by ref alone causes improper
refcount
$smiles = $myts->getSmileys(); //this does not cause improper refcount
?>
This fact is known, Marcus and I have a working patch for this - but
it'll break binairy compat for PHP 4.4 - stay tuned for this.
regards,
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
It happens in php-5.0.4 also.
With regards
Kamesh Jayachandran
On Wed, 6 Apr 2005 09:16:34 +0200 (CEST), "Derick Rethans"
derick@php.net said:
Hi All,
I have come across a double free because of improper refcount
manipulation.
<?php
class MyTextSanitizer
{
var $smileys=array()
function MyTextSanitizer() {}
function getSmileys()
{
return $this->smileys;
}
}
$myts = new MyTextSanitizer();
$smiles =& $myts->getSmileys(); //calling by ref alone causes improper
refcount
$smiles = $myts->getSmileys(); //this does not cause improper refcount
?>This fact is known, Marcus and I have a working patch for this - but
it'll break binairy compat for PHP 4.4 - stay tuned for this.regards,
Derick--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
<?php
class MyTextSanitizer
{
var $smileys=array()
function MyTextSanitizer() {}
function getSmileys()
{
return $this->smileys;
}
}
$myts = new MyTextSanitizer();
$smiles =& $myts->getSmileys(); //calling by ref alone causes improper
?>
The opcodes for the above script
ZEND_FETCH_CLASS
ZEND_NEW (Increases the refcount of smileys array from 1 to 2.
zend_declare class made it 1 from 0)
ZEND_JMP_NO_CTOR (Not executed)
ZEND_INIT_CTOR_CALL (No change in smileys refcount)
ZEND_DO_FCALL_BY_NAME(No change in smileys refcount)
ZEND_FETCH_W(No change in smileys refcount)
ZEND_ASSIGN(No change in smileys refcount)
ZEND_FETCH_R(No change in smileys refcount)
ZEND_INIT_METHOD_CALL(No change in smileys refcount)
ZEND_DO_FCALL_BY_NAME(Increases the refcount of smileys array from 2 to
ZEND_FETCH_W(No change in smileys refcount)
ZEND_ASSIGN_REF(Increases the refcount of smileys array from 3 to 1.
_get_zval_ptr_ptr on &opline->op2 makes it 3 to 2.
zend_assign_to_variable_reference(&opline->result,
get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W), value_ptr_ptr, EX(Ts)
TSRMLS_CC); decreases it from 2 to 1)
ZEND_RETURN
ZEND_HANDLE_EXCEPTION
object destructor reduces the refcount from 1 to 0 and destroys the
$smileys. zend_destroy_class now attempts to destroy it again. This
causes a segfault.
With regards
Kamesh Jayachandran
On Wed, 06 Apr 2005 00:18:35 -0700, "Kamesh Jayachandran"
kameshj@fastmail.fm said:
It happens in php-5.0.4 also.
With regards
Kamesh Jayachandran
On Wed, 6 Apr 2005 09:16:34 +0200 (CEST), "Derick Rethans"
derick@php.net said:Hi All,
I have come across a double free because of improper refcount
manipulation.
<?php
class MyTextSanitizer
{
var $smileys=array()
function MyTextSanitizer() {}
function getSmileys()
{
return $this->smileys;
}
}
$myts = new MyTextSanitizer();
$smiles =& $myts->getSmileys(); //calling by ref alone causes improper
refcount
$smiles = $myts->getSmileys(); //this does not cause improper refcount
?>This fact is known, Marcus and I have a working patch for this - but
it'll break binairy compat for PHP 4.4 - stay tuned for this.regards,
Derick--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org