Bug #81429 [Opn->Csd]: SplFixedArray::setSize(0) called during offsetSet() causes segmentation fault

From: Date: Tue, 14 Sep 2021 01:32:33 +0000
Subject: Bug #81429 [Opn->Csd]: SplFixedArray::setSize(0) called during offsetSet() causes segmentation fault
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-236575@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 Updated by: git@php.net Reported by: tandre@php.net Summary: SplFixedArray::setSize(0) called during offsetSet() causes segmentation fault -Status: Open +Status: Closed Type: Bug Package: SPL related Operating System: Any PHP Version: 8.1.0RC1 Block user comment: N Private report: N New Comment: 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) Previous Comments: ------------------------------------------------------------------------ [2021-09-13 00:41:25] 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-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

« previous php.bugs (#236575) next »