Skip to content

Commit eb2b0f1

Browse files
committed
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.
1 parent 2e999ba commit eb2b0f1

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

Zend/tests/lazy_objects/gh17941.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GH-17941 (Stack-use-after-return with lazy objects and hooks)
3+
--FILE--
4+
<?php
5+
6+
class SubClass {
7+
public $prop {get => $this->prop; set($x) => $this->prop = $x;}
8+
}
9+
10+
$rc = new ReflectionClass(SubClass::class);
11+
$obj = $rc->newLazyProxy(function ($object) {
12+
echo "init\n";
13+
return new SubClass;
14+
});
15+
16+
function foo(SubClass $x) {
17+
$x->prop = 1;
18+
var_dump($x->prop);
19+
}
20+
21+
foo($obj);
22+
23+
?>
24+
--EXPECT--
25+
init
26+
int(1)

Zend/zend_object_handlers.c

+5
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,11 @@ lazy_init:;
11981198

11991199
variable_ptr = zend_std_write_property(zobj, name, &backup, cache_slot);
12001200
zval_ptr_dtor(&backup);
1201+
1202+
if (variable_ptr == &backup) {
1203+
variable_ptr = value;
1204+
}
1205+
12011206
return variable_ptr;
12021207
}
12031208
/* }}} */

0 commit comments

Comments
 (0)