Fix use-after-free with delayed interned memoized const operand

We should addref CONST operands during memoization, as they might
be destroyed by later compilation, e.g. through interning.
This commit is contained in:
Nikita Popov 2019-10-04 10:38:11 +02:00
parent f26b60a583
commit 9659562cb5
2 changed files with 20 additions and 1 deletions

View File

@ -0,0 +1,12 @@
--TEST--
Null coalesce assign with memoized constant operand that is later interned (OSS-Fuzz #17903)
--FILE--
<?php
$foo[__DIR__] ??= 42;
var_dump($foo);
?>
--EXPECTF--
array(1) {
["%s"]=>
int(42)
}

View File

@ -2054,6 +2054,9 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */
} else if (result->op_type == IS_TMP_VAR) {
zend_emit_op_tmp(&memoized_result, ZEND_COPY_TMP, result, NULL);
} else {
if (result->op_type == IS_CONST) {
Z_TRY_ADDREF(result->u.constant);
}
memoized_result = *result;
}
@ -7540,7 +7543,11 @@ void zend_compile_coalesce(znode *result, zend_ast *ast) /* {{{ */
/* }}} */
static void znode_dtor(zval *zv) {
efree(Z_PTR_P(zv));
znode *node = Z_PTR_P(zv);
if (node->op_type == IS_CONST) {
zval_ptr_dtor_nogc(&node->u.constant);
}
efree(node);
}
void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */