Skip to content

Commit f0e1e01

Browse files
committed
Fix another use-after-free with static properties/destructors
Also make expression result of assignments consistent, containing the value of the variable from after the destructor has been executed. See GH-10168
1 parent 641fe23 commit f0e1e01

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

Zend/tests/gh10168_3.phpt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,4 @@ new Test();
2525
--EXPECTF--
2626
object(Test)#1 (0) {
2727
}
28-
object(Test)#2 (0) {
29-
}
28+
NULL

Zend/zend_execute.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3602,8 +3602,13 @@ ZEND_API zval* zend_assign_to_typed_ref_and_result(zval *variable_ptr, zval *ori
36023602
ret = zend_verify_ref_assignable_zval(Z_REF_P(variable_ptr), &value, strict);
36033603
variable_ptr = Z_REFVAL_P(variable_ptr);
36043604
if (EXPECTED(ret)) {
3605-
i_zval_ptr_dtor_noref(variable_ptr);
3605+
// The destructor must run after the variable has already been reassigned
3606+
// Otherwise, assigning to the variable again can cause a double free
3607+
// Thus we need to store the old value in a temporary slot
3608+
zval garbage;
3609+
ZVAL_COPY_VALUE(&garbage, variable_ptr);
36063610
ZVAL_COPY_VALUE(variable_ptr, &value);
3611+
i_zval_ptr_dtor_noref(&garbage);
36073612
} else {
36083613
zval_ptr_dtor_nogc(&value);
36093614
}

0 commit comments

Comments
 (0)