From eb2b0f1606f22815d792d30e8761e45585b02a43 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:56:39 +0100 Subject: [PATCH] Fix GH-17941: Stack-use-after-return with lazy objects and hooks zend_std_write_property() can return the variable pointer, but the code was using a local variable, and so a pointer to a local variable could be returned. Fix this by using the value pointer instead of the backup value was written. This can be more efficient on master by using the safe_assign helper. --- Zend/tests/lazy_objects/gh17941.phpt | 26 ++++++++++++++++++++++++++ Zend/zend_object_handlers.c | 5 +++++ 2 files changed, 31 insertions(+) create mode 100644 Zend/tests/lazy_objects/gh17941.phpt diff --git a/Zend/tests/lazy_objects/gh17941.phpt b/Zend/tests/lazy_objects/gh17941.phpt new file mode 100644 index 0000000000000..6af6355b99573 --- /dev/null +++ b/Zend/tests/lazy_objects/gh17941.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-17941 (Stack-use-after-return with lazy objects and hooks) +--FILE-- + $this->prop; set($x) => $this->prop = $x;} +} + +$rc = new ReflectionClass(SubClass::class); +$obj = $rc->newLazyProxy(function ($object) { + echo "init\n"; + return new SubClass; +}); + +function foo(SubClass $x) { + $x->prop = 1; + var_dump($x->prop); +} + +foo($obj); + +?> +--EXPECT-- +init +int(1) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 5a4e4b3ea3a1c..bba40c6bd41ec 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1198,6 +1198,11 @@ lazy_init:; variable_ptr = zend_std_write_property(zobj, name, &backup, cache_slot); zval_ptr_dtor(&backup); + + if (variable_ptr == &backup) { + variable_ptr = value; + } + return variable_ptr; } /* }}} */