Skip to content

Commit db9776c

Browse files
committed
Fixed bug #79151
Make sure we also NULL out next/prev of the removed element on pop/shift. This only matter is that element is still being referenced by an iterator.
1 parent dd3c664 commit db9776c

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ PHP NEWS
2525
. Fixed bug #79115 (ReflectionClass::isCloneable call reflected class
2626
__destruct). (Nikita)
2727

28+
- SPL:
29+
. Fixed bug #79151 (heap use after free caused by
30+
spl_dllist_it_helper_move_forward). (Nikita)
31+
2832
23 Jan 2020, PHP 7.3.14
2933

3034
- Core

ext/spl/spl_dllist.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ static void spl_ptr_llist_pop(spl_ptr_llist *llist, zval *ret) /* {{{ */
257257
llist->count--;
258258
ZVAL_COPY(ret, &tail->data);
259259

260+
tail->prev = NULL;
260261
if (llist->dtor) {
261262
llist->dtor(tail);
262263
}
@@ -310,6 +311,7 @@ static void spl_ptr_llist_shift(spl_ptr_llist *llist, zval *ret) /* {{{ */
310311
llist->count--;
311312
ZVAL_COPY(ret, &head->data);
312313

314+
head->next = NULL;
313315
if (llist->dtor) {
314316
llist->dtor(head);
315317
}

ext/spl/tests/bug79151.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Bug #79151: heap use after free caused by spl_dllist_it_helper_move_forward
3+
--FILE--
4+
<?php
5+
6+
$a = new SplDoublyLinkedList();
7+
$a->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_DELETE);
8+
$a->push(1);
9+
$a->rewind();
10+
$a->unshift(2);
11+
var_dump($a->pop());
12+
var_dump($a->next());
13+
14+
$a = new SplDoublyLinkedList();
15+
$a->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_DELETE);
16+
$a->unshift(1);
17+
$a->rewind();
18+
$a->push(2);
19+
var_dump($a->shift());
20+
var_dump($a->next());
21+
22+
?>
23+
--EXPECT--
24+
int(1)
25+
NULL
26+
int(1)
27+
NULL

0 commit comments

Comments
 (0)