1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.5'

* PHP-8.5:
  Fix GH-20286: use-after-destroy during userland stream_close()
This commit is contained in:
Niels Dossche
2025-11-23 17:52:50 +01:00
2 changed files with 57 additions and 1 deletions

View File

@@ -214,21 +214,34 @@ void zend_init_rsrc_plist(void)
void zend_close_rsrc_list(HashTable *ht)
{
/* Reload ht->arData on each iteration, as it may be reallocated. */
uint32_t i = ht->nNumUsed;
uint32_t num = ht->nNumUsed;
retry:
zend_try {
while (i-- > 0) {
/* Reload ht->arData on each iteration, as it may be reallocated. */
zval *p = ZEND_HASH_ELEMENT(ht, i);
if (Z_TYPE_P(p) != IS_UNDEF) {
zend_resource *res = Z_PTR_P(p);
if (res->type >= 0) {
zend_resource_dtor(res);
if (UNEXPECTED(ht->nNumUsed != num)) {
/* New resources were added, reloop from the start.
* We need to keep the top->down order to avoid freeing resources
* in use by the newly created resources. */
i = num = ht->nNumUsed;
}
}
}
}
} zend_catch {
if (UNEXPECTED(ht->nNumUsed != num)) {
/* See above */
i = num = ht->nNumUsed;
}
/* If we have bailed, we probably executed user code (e.g. user stream
* API). Keep closing resources so they don't leak. User handlers must be
* called now so they aren't called in zend_deactivate() on

View File

@@ -0,0 +1,43 @@
--TEST--
GH-20286 use after destroy on userland stream_close
--CREDITS--
vi3tL0u1s
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) == 'WIN') die('skip Aborts with STATUS_BAD_FUNCTION_TABLE on Windows');
?>
--FILE--
<?php
class lib {
public $context;
function stream_set() {}
function stream_set_option() {}
function stream_stat() {
return true;
}
function stream_open() {
return true;
}
function stream_read($count) {
function a() {}
include('lib://');
}
function stream_close() {
static $count = 0;
if ($count++ < 3) // Prevent infinite loop
include('lib://');
}
}
stream_wrapper_register('lib', lib::class);
include('lib://test.php');
?>
--EXPECTF--
Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d
Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d
Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d
Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d