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:
4
NEWS
4
NEWS
@@ -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)
|
||||
|
||||
@@ -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--;
|
||||
|
||||
|
||||
26
ext/spl/tests/gh20856.phpt
Normal file
26
ext/spl/tests/gh20856.phpt
Normal 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) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user