[php-src] Issue #11734: Crash in zend_objects_store_free_object_storage due to uninitialised handlers
| From: | tstarling | Date: | Tue, 18 Jul 2023 00:44:05 +0000 |
| Subject: | [php-src] Issue #11734: Crash in zend_objects_store_free_object_storage due to uninitialised handlers | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-244989@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/11734
Author: tstarling
### Description
```php
<?php
ini_set('memory_limit', '2M');
$objs = [];
while (true) {
$objs[] = new SplPriorityQueue;
}
```
This crashes on shutdown:
```
Program received signal SIGSEGV, Segmentation fault.
0x00005555558e4187 in zend_objects_store_free_object_storage (objects=objects@entry=0x555555ad71a8
<executor_globals+840>, fast_shutdown=fast_shutdown@entry=true) at
./Zend/zend_objects_API.c:107
...
(gdb) print obj->handlers
$2 = (const zend_object_handlers *) 0x0
```
When an object is created, there is a critical section between zend_object_std_init() and the
assignment to handlers during which time it is unsafe to call the built-in allocator.
This was reported in LuaSandbox ([T322748](https://phabricator.wikimedia.org/T322748)) but a quick
review suggests that many other extensions have the same issue. In the PHP 8.1 tree, there is:
* dom_nodemap_or_nodelist_objects_new
* pdo_dbh_new
* spl_dllist_object_new_ex
* spl_heap_object_new_ex
* spl_object_storage_new_ex
* spl_array_object_new_ex
* tidy_object_new
* xsl_objects_new
My test case above uses the bug in spl_heap_object_new_ex().
Potential rectification options:
1. In zend_objects_store_free_object_storage, guard against !obj->handlers. I think this is a
good solution since it should fix the issue in all extensions. obj->handlers is set to NULL in
zend_object_alloc(). There are not many ways to access an object when there was a fatal error before
a reference was taken. Maybe a guard in zend_objects_store_call_destructors() would also be wise.
2. Fix all extensions. Update the comment on zend_object_alloc() to indicate that, in addition to
the other requirements, handlers must be set before any allocation is done.
### PHP Version
PHP 8.1.20
### Operating System
_No response_