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

Fix GH-20856: heap-use-after-free in SplDoublyLinkedList iterator when modifying during iteration

The element may be still in use in other places, so the linking pointers
should be kept consistent. If not consistent, the "move forward" code in
the sample test will read a stale, dangling pointer.

Closes GH-20885.
This commit is contained in:
Niels Dossche
2026-01-09 17:14:11 +01:00
parent f61b1fc036
commit 2a2e0e8128
3 changed files with 35 additions and 2 deletions

4
NEWS
View File

@@ -20,6 +20,10 @@ PHP NEWS
. Fixed bug GH-18139 (Memory leak when overriding some settings
via readline_info()). (ndossche)
- SPL:
. Fixed bug GH-20856 (heap-use-after-free in SplDoublyLinkedList iterator
when modifying during iteration). (ndossche)
- Standard:
. Fixed bug #74357 (lchown fails to change ownership of symlink with ZTS)
(Jakub Zelenka)

View File

@@ -764,11 +764,10 @@ PHP_METHOD(SplDoublyLinkedList, offsetUnset)
element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);
if (element != NULL) {
/* connect the neightbors */
/* disconnect the neighbours */
if (element->prev) {
element->prev->next = element->next;
}
if (element->next) {
element->next->prev = element->prev;
}
@@ -782,6 +781,10 @@ PHP_METHOD(SplDoublyLinkedList, offsetUnset)
llist->tail = element->prev;
}
/* Keep consistency if element is kept alive. */
element->prev = NULL;
element->next = NULL;
/* finally, delete the element */
llist->count--;

View File

@@ -0,0 +1,26 @@
--TEST--
GH-20856 (heap-use-after-free in SplDoublyLinkedList iterator when modifying during iteration)
--CREDITS--
vi3tL0u1s
iluuu1994
--FILE--
<?php
$m = new SplStack;
$m[] = new stdClass;
$m[] = new stdClass;
foreach ($m as $l) {
unset($m[0]);
unset($m[0]);
}
var_dump($m);
?>
--EXPECTF--
object(SplStack)#%d (%d) {
["flags":"SplDoublyLinkedList":private]=>
int(6)
["dllist":"SplDoublyLinkedList":private]=>
array(0) {
}
}