php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81429 SplFixedArray::setSize(0) called during offsetSet() causes segmentation fault
Submitted: 2021-09-10 14:03 UTC Modified: -
From: tandre@php.net Assigned:
Status: Closed Package: SPL related
PHP Version: 8.1.0RC1 OS: Any
Private report: No CVE-ID: None
 [2021-09-10 14:03 UTC] 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.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-09-13 00:41 UTC] antonino dot spampinato86 at gmail dot com
<?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);
        }
    }
}
 [2021-09-14 01:32 UTC] git@php.net
Automatic comment on behalf of TysonAndre (author) and web-flow (committer)
Revision: https://github.com/php/php-src/commit/b053192a03e662205e6b9f65cba3eb64e229e4f2
Log: Fix #81429: Handle resizing in SplFixedArray::offsetSet (#7487)
 [2021-09-14 01:32 UTC] git@php.net
-Status: Open +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 10 08:01:27 2024 UTC