From 34f07c5cbc088f45d7c1fd5e4df03033d83513f9 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 14 Jun 2025 17:53:36 +0200 Subject: [PATCH] Fix use-after-free of object through __isset() and globals Fixes GH-18845 --- Zend/tests/gh18845.phpt | 18 ++++++++++++++++++ Zend/zend_object_handlers.c | 6 ++++++ 2 files changed, 24 insertions(+) create mode 100644 Zend/tests/gh18845.phpt diff --git a/Zend/tests/gh18845.phpt b/Zend/tests/gh18845.phpt new file mode 100644 index 000000000000..1a6ca6913fda --- /dev/null +++ b/Zend/tests/gh18845.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-18845: Use-after-free of object through __isset() and globals +--FILE-- +prop ?? 1); + +?> +--EXPECT-- +int(1) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 7b804e7afe95..9421867c8fb4 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -905,7 +905,13 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int if (zobj->ce->__get && !((*guard) & IN_GET)) { goto call_getter; } + + bool obj_is_freed = GC_REFCOUNT(zobj) == 1; OBJ_RELEASE(zobj); + if (UNEXPECTED(obj_is_freed)) { + retval = &EG(uninitialized_zval); + goto exit; + } } else if (zobj->ce->__get && !((*guard) & IN_GET)) { goto call_getter_addref; }