Skip to content

Commit

Permalink
Fix too aggressive DCE that leads to memory leak
Browse files Browse the repository at this point in the history
Fixes oss-fuzz #43738
  • Loading branch information
dstogov committed Jan 28, 2022
1 parent 464e725 commit 965dafe
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
28 changes: 19 additions & 9 deletions ext/opcache/Optimizer/sccp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2275,21 +2275,31 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
zend_optimizer_update_op1_const(ctx->scdf.op_array, opline, value);
}
return 0;
} else {
zend_ssa_remove_result_def(ssa, ssa_op);
if (opline->opcode == ZEND_DO_ICALL) {
removed_ops = remove_call(ctx, opline, ssa_op);
} else if (opline->opcode == ZEND_TYPE_CHECK
&& (opline->op1_type & (IS_VAR|IS_TMP_VAR))
&& (!value_known(&ctx->values[ssa_op->op1_use])
|| IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use])
|| IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) {
} else if ((opline->op2_type & (IS_VAR|IS_TMP_VAR))
&& (!value_known(&ctx->values[ssa_op->op2_use])
|| IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op2_use])
|| IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op2_use]))) {
return 0;
} else if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
&& (!value_known(&ctx->values[ssa_op->op1_use])
|| IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use])
|| IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) {
if (opline->opcode == ZEND_TYPE_CHECK
|| opline->opcode == ZEND_BOOL) {
zend_ssa_remove_result_def(ssa, ssa_op);
/* For TYPE_CHECK we may compute the result value without knowing the
* operand, based on type inference information. Make sure the operand is
* freed and leave further cleanup to DCE. */
opline->opcode = ZEND_FREE;
opline->result_type = IS_UNUSED;
removed_ops++;
} else {
return 0;
}
} else {
zend_ssa_remove_result_def(ssa, ssa_op);
if (opline->opcode == ZEND_DO_ICALL) {
removed_ops = remove_call(ctx, opline, ssa_op);
} else {
zend_ssa_remove_instr(ssa, opline, ssa_op);
removed_ops++;
Expand Down
13 changes: 13 additions & 0 deletions ext/opcache/tests/opt/sccp_037.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
SCCP 037: Memory leak
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
--FILE--
<?php
[!![[new ERROR]]];
?>
DONE
--EXPECT--
DONE

0 comments on commit 965dafe

Please sign in to comment.