Skip to content

Commit 8f2383a

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. This can be more efficient on master by using the safe_assign helper.
1 parent 2e999ba commit 8f2383a

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

Zend/tests/lazy_objects/gh17941.phpt

Lines changed: 26 additions & 0 deletions
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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,9 +1196,10 @@ lazy_init:;
11961196
goto exit;
11971197
}
11981198

1199-
variable_ptr = zend_std_write_property(zobj, name, &backup, cache_slot);
1200-
zval_ptr_dtor(&backup);
1201-
return variable_ptr;
1199+
/* TODO: use zend_safe_assign_to_variable_noref() on master */
1200+
zval_ptr_dtor(value);
1201+
ZVAL_COPY_VALUE(value, &backup);
1202+
return zend_std_write_property(zobj, name, value, cache_slot);
12021203
}
12031204
/* }}} */
12041205

0 commit comments

Comments
 (0)