Bug #81429 [Com]: SplFixedArray::setSize(0) called during offsetSet() causes segmentation fault

From: Date: Mon, 13 Sep 2021 00:41:25 +0000
Subject: Bug #81429 [Com]: SplFixedArray::setSize(0) called during offsetSet() causes segmentation fault
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-236553@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81429&edit=1

 ID:                 81429
 Comment by:         antonino dot spampinato86 at gmail dot com
 Reported by:        tandre@php.net
 Summary:            SplFixedArray::setSize(0) called during offsetSet()
                     causes segmentation fault
 Status:             Open
 Type:               Bug
 Package:            SPL related
 Operating System:   Any
 PHP Version:        8.1.0RC1
 Block user comment: N
 Private report:     N

 New Comment:

<?php
echo __LINE__,"\n";
$values = new SplFixedArray(1);
echo __LINE__,"\n";
$values->offsetSet(0, new HasDestructor());
global $values;
/*echo __LINE__,"\n";
$values->offsetSet(0, null);*/

class HasDestructor {
    public function __destruct() {
        global $values;
        if(isset($GLOBALS['values'])) {
        echo __LINE__,"\n";
        $values->setSize(0);
        var_dump('local second object scope ', $values);
        }
    }
}


Previous Comments:
------------------------------------------------------------------------
[2021-09-10 14:03:10] tandre@php.net

Description:
------------
offsetSet does not account for the fact that the array may no longer exist after the field is
overwritten.

This can be fixed by ZVAL_COPY_VALUE to copy the old value to a temporary location, then overwriting
the old address, then destructing the copy of the old value.

(I used this approach in a PECL I wrote when considering proposing data structures such as Vector in
core in the future - https://github.com/TysonAndre/pecl-teds/blob/0.1.0a1/teds_vector.c#L809-L820
)


Related to https://bugs.php.net/bug.php?id=80663


Test script:
---------------
<?php
echo __LINE__,"\n";
$values = new SplFixedArray(1);
echo __LINE__,"\n";
$values->offsetSet(0, new HasDestructor());
echo __LINE__,"\n";
$values->offsetSet(0, null);

class HasDestructor {
    public function __destruct() {
        echo __LINE__,"\n";
        $GLOBALS['values']->setSize(0);
    }
}


Expected result:
----------------
The size is set to 0 and there are no memory leaks

Actual result:
--------------
2
4
6
11
==8024== Invalid write of size 8
==8024==    at 0x79B888: spl_fixedarray_object_write_dimension_helper (spl_fixedarray.c:419)
==8024==    by 0x79CD70: zim_SplFixedArray_offsetSet (spl_fixedarray.c:762)
==8024==    by 0xA16344: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1761)
==8024==    by 0xA87C89: execute_ex (zend_vm_execute.h:54512)
==8024==    by 0xA8D429: zend_execute (zend_vm_execute.h:58843)
==8024==    by 0x9D96B8: zend_execute_scripts (zend.c:1755)
==8024==    by 0x936E36: php_execute_script (main.c:2519)
==8024==    by 0xB4947B: do_cli (php_cli.c:965)
==8024==    by 0xB4A583: main (php_cli.c:1367)
==8024==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==8024== 
==8024== 
==8024== Process terminating with default action of signal 11 (SIGSEGV)
==8024==  Access not within mapped region at address 0x0
==8024==    at 0x79B888: spl_fixedarray_object_write_dimension_helper (spl_fixedarray.c:419)
==8024==    by 0x79CD70: zim_SplFixedArray_offsetSet (spl_fixedarray.c:762)
==8024==    by 0xA16344: ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1761)
==8024==    by 0xA87C89: execute_ex (zend_vm_execute.h:54512)
==8024==    by 0xA8D429: zend_execute (zend_vm_execute.h:58843)
==8024==    by 0x9D96B8: zend_execute_scripts (zend.c:1755)
==8024==    by 0x936E36: php_execute_script (main.c:2519)
==8024==    by 0xB4947B: do_cli (php_cli.c:965)
==8024==    by 0xB4A583: main (php_cli.c:1367)
==8024==  If you believe this happened as a result of a stack
==8024==  overflow in your program's main thread (unlikely but
==8024==  possible), you can try to increase the size of the
==8024==  main thread stack using the --main-stacksize= flag.
==8024==  The main thread stack size used in this run was 8388608.



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=81429&edit=1


Thread (3 messages)

« previous php.bugs (#236553) next »