Merge branch 'PHP-8.4'

* PHP-8.4:
  Fix uaf in SplDoublyLinkedList::offsetSet()
This commit is contained in:
Ilija Tovilo 2024-10-16 23:05:55 +02:00
commit 1a2b370ad6
No known key found for this signature in database
GPG key ID: 5050C66BFCD1015A
2 changed files with 32 additions and 1 deletions

View file

@ -726,8 +726,10 @@ PHP_METHOD(SplDoublyLinkedList, offsetSet)
if (element != NULL) { if (element != NULL) {
/* the element is replaced, delref the old one as in /* the element is replaced, delref the old one as in
* SplDoublyLinkedList::pop() */ * SplDoublyLinkedList::pop() */
zval_ptr_dtor(&element->data); zval garbage;
ZVAL_COPY_VALUE(&garbage, &element->data);
ZVAL_COPY(&element->data, value); ZVAL_COPY(&element->data, value);
zval_ptr_dtor(&garbage);
} else { } else {
zval_ptr_dtor(value); zval_ptr_dtor(value);
zend_argument_error(spl_ce_OutOfRangeException, 1, "is an invalid offset"); zend_argument_error(spl_ce_OutOfRangeException, 1, "is an invalid offset");

View file

@ -0,0 +1,29 @@
--TEST--
GH-16464: Use-after-free in SplDoublyLinkedList::offsetSet() when modifying list in destructor of overwritten object
--FILE--
<?php
class C {
public $a;
function __destruct() {
global $list;
var_dump($list->pop());
}
}
$list = new SplDoublyLinkedList;
$list->add(0, new C);
$list[0] = 42;
var_dump($list);
?>
--EXPECTF--
int(42)
object(SplDoublyLinkedList)#%d (2) {
["flags":"SplDoublyLinkedList":private]=>
int(0)
["dllist":"SplDoublyLinkedList":private]=>
array(0) {
}
}