From 12c987fae28d4d0ac247094b1242f0edad5fe644 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 17 Oct 2024 16:12:35 +0200 Subject: [PATCH] Fix use-after-free in SplObjectStorage::setInfo() Fixes GH-16479 Closes GH-16482 --- NEWS | 1 + ext/spl/spl_observer.c | 4 +++- ext/spl/tests/gh16479.phpt | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 ext/spl/tests/gh16479.phpt diff --git a/NEWS b/NEWS index 217b7e07be3..d173e4c1418 100644 --- a/NEWS +++ b/NEWS @@ -70,6 +70,7 @@ PHP NEWS . Fixed bug GH-16337 (Use-after-free in SplHeap). (nielsdos) . Fixed bug GH-16464 (Use-after-free in SplDoublyLinkedList::offsetSet()). (ilutov) + . Fixed bug GH-16479 (Use-after-free in SplObjectStorage::setInfo()). (ilutov) - Standard: . Fixed bug GH-16293 (Failed assertion when throwing in assert() callback with diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 21b19cffa38..cc2956ccc27 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -746,8 +746,10 @@ PHP_METHOD(SplObjectStorage, setInfo) if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) { RETURN_NULL(); } - zval_ptr_dtor(&element->inf); + zval garbage; + ZVAL_COPY_VALUE(&garbage, &element->inf); ZVAL_COPY(&element->inf, inf); + zval_ptr_dtor(&garbage); } /* }}} */ /* {{{ Moves position forward */ diff --git a/ext/spl/tests/gh16479.phpt b/ext/spl/tests/gh16479.phpt new file mode 100644 index 00000000000..5309a450b9d --- /dev/null +++ b/ext/spl/tests/gh16479.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-16479: Use-after-free in SplObjectStorage::setInfo() +--FILE-- +removeAll($store); + } +} + +$o = new stdClass; +$store = new SplObjectStorage; +$store[$o] = new C; +$store->setInfo(1); +var_dump($store); + +?> +--EXPECT-- +object(SplObjectStorage)#2 (1) { + ["storage":"SplObjectStorage":private]=> + array(0) { + } +}