# refcount and hence double free issue

- Thread: https://externals.io/message/15845
- Original archive: https://news-web.php.net/php.internals/15845
- Started by Kamesh Jayachandran on 2005-04-06T07:13:53+00:00
- Messages: 4
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #15845 — Kamesh Jayachandran — 2005-04-06T07:13:53+00:00

URL: https://externals.io/message/15845#15845

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

---

## #15846 — Derick Rethans — 2005-04-06T07:16:34+00:00

URL: https://externals.io/message/15845#15846 · In reply to: #15845

> 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

---

## #15847 — Kamesh Jayachandran — 2005-04-06T07:18:35+00:00

URL: https://externals.io/message/15845#15847 · In reply to: #15846

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:
> 
> 
> > […]
> 
> 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

---

## #15953 — Kamesh Jayachandran — 2005-04-13T07:46:07+00:00

URL: https://externals.io/message/15845#15953 · In reply to: #15847

<?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
3)
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:
> > […]
