From 154e8a8a5a088f661ee7de82e86f509be95d117a Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 3 Feb 2026 14:44:18 +0100 Subject: [PATCH] Fix borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization Fixes OSS-Fuzz #481014628 Introduced in GH-20628 --- Zend/Optimizer/block_pass.c | 4 +++- ext/opcache/tests/oss-fuzz-481014628.phpt | 27 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/oss-fuzz-481014628.phpt diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 7f97caa1fdab..2963e59485e5 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -176,7 +176,9 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array && zend_optimizer_update_op1_const(op_array, opline, &c)) { VAR_SOURCE(op1) = NULL; if (opline->opcode != ZEND_JMP_NULL - && !zend_bitset_in(used_ext, VAR_NUM(src->result.var))) { + && !zend_bitset_in(used_ext, VAR_NUM(src->result.var)) + /* FETCH_W with ZEND_FETCH_GLOBAL_LOCK does not free op1, which will be used again. */ + && (opline->opcode != ZEND_FETCH_W && (opline->extended_value & ZEND_FETCH_GLOBAL_LOCK))) { literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); } diff --git a/ext/opcache/tests/oss-fuzz-481014628.phpt b/ext/opcache/tests/oss-fuzz-481014628.phpt new file mode 100644 index 000000000000..8aa6cf3fe1fd --- /dev/null +++ b/ext/opcache/tests/oss-fuzz-481014628.phpt @@ -0,0 +1,27 @@ +--TEST-- +OSS-Fuzz #481014628: Borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--FILE-- + +--EXPECT-- +NULL +int(42)