Skip to content

Commit 6b6e666

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 1cb38e4 commit 6b6e666

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
@@ -26,5 +26,4 @@ new Test();
2626
--EXPECTF--
2727
object(Test)#1 (0) {
2828
}
29-
object(Test)#2 (0) {
30-
}
29+
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)