[php-src] Issue #24252: Opcache: SCCP turns `$c::$m()` into CONST/CONST INIT_STATIC_METHOD_CALL with one cache slot, heap-buffer-overflow

From: Date: Sun, 11 Oct 2026 02:48:08 +0000
Subject: [php-src] Issue #24252: Opcache: SCCP turns `$c::$m()` into CONST/CONST INIT_STATIC_METHOD_CALL with one cache slot, heap-buffer-overflow
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-252968@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/24252 Author: waroad > With SCCP enabled and the compact-literals pass off, a dynamic static call whose class and > method names are both constant-propagated reads past the function's runtime cache in > ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER, and a release > build segfaults. ```php <?php class Foo { static function bar() { return "sb"; } } function f() { $c = "Foo"; $m = "bar"; return $c::$m(); } echo f(), "\n"; ``` ``` php -n -d opcache.enable_cli=1 -d opcache.file_update_protection=0 -d opcache.optimization_level=0xA0 static_call.php ``` > opcache.optimization_level=0x7FFEBBFF (the default minus pass > 11, 0x400) fails the same way. On an ASan build (run with > USE_ZEND_ALLOC=0): ``` ==282==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000003ed8 at pc 0x55a8609a58e4 bp 0x7ffe492d9390 sp 0x7ffe492d9380 READ of size 8 at 0x502000003ed8 thread T0 #0 0x55a8609a58e3 in ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER Zend/zend_vm_execute.h:7558 #1 0x55a860c28b6f in execute_ex Zend/zend_vm_execute.h:111556 #2 0x55a860c71830 in zend_execute Zend/zend_vm_execute.h:116021 0x502000003ed8 is located 0 bytes to the right of 8-byte region [0x502000003ed0,0x502000003ed8) allocated by thread T0 here: #4 0x55a86091962d in init_func_run_time_cache_i Zend/zend_execute.c:4511 #6 0x55a86097b67f in ZEND_INIT_FCALL_SPEC_CONST_HANDLER Zend/zend_vm_execute.h:4194 ``` > Expected sb, which is what the script prints with opcache off > and at the default optimization level. > Found at commit b527e1b34ee97f4ea402e36a641509af7436759d and still reproduces at > 12df76792026cd62dbbfdf78a426919afe3e0011. A release build segfaults (exit 139, no output) at both > optimization levels above. > Looks like SCCP replaces the two operands one at a time: > zend_optimizer_update_op1_const() > (Zend/Optimizer/zend_optimizer.c:318-326) sees op2 still a CV and allocates one slot, then > zend_optimizer_update_op2_const() (zend_optimizer.c:508-514) sees > op1 already CONST and allocates nothing, while the CONST/CONST handler uses two slots (class and > function). The default level hides it because pass 11 reallocates all cache slots. I can send a patch if that helps. Found with an LLM-based testing tool. As CONTRIBUTING.md asks, the paragraphs in > quotes were written with Claude; I ran every command myself.

« previous php.bugs (#252968) next »