Commit fcff846a73d for php.net
commit fcff846a73de03fe02fc2fca2e212cbc12feb945
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date: Mon Feb 9 13:22:35 2026 +0100
Fix borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization (GH-21121)
Fixes OSS-Fuzz #481014628
Introduced in GH-20628
Co-authored-by: Arnaud Le Blanc <365207+arnaud-lb@users.noreply.github.com>
diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c
index 7f97caa1fda..5a0af263039 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 00000000000..8aa6cf3fe1f
--- /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--
+<?php
+
+function f() {
+ return 'foo';
+}
+
+function test() {
+ global ${f()};
+ var_dump($foo);
+}
+
+test();
+$foo = 42;
+test();
+
+?>
+--EXPECT--
+NULL
+int(42)