[php-src] Issue #9396: PHP-FPM segfaults with Opcache enabled with Late Static Binding
| From: | vityank | Date: | Mon, 22 Aug 2022 11:08:12 +0000 |
| Subject: | [php-src] Issue #9396: PHP-FPM segfaults with Opcache enabled with Late Static Binding | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242277@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/9396
Author: vityank
### Description
PHP-FPM crashes then OPCache enabled(Even if I disable all low 16bits of optimization flags in
opcache.optimization_level) with some pattern of Late static binding involved.
* Only PHP-FPM is affected. Main PHP binary works fine(With opcache.enable_cli=1)
* PHP-FPM works fine if OPCache is completely disabled(opcache.enable=0)
* PHP-FPM 7.3 with OPCache works fine - 8.0 Crashes.
* Specific case in dev crashes in ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER , but
coredumps from our production shown other handlers from Zend/zend_vm_execute.h crashing the same
way.
Unfortunately I can't create minimal working test case(I tried my best).
The only thing I know is that pattern like this causes it in the end(Note the constant having
initial value via 'self' and later used as LSB via 'static'):
class TestClass
{
const PHOENIX = '/usr/local/bin/grep';
const CON1 = 'propose';
const CON2 = self::CON1;
const CON3 = 'r2';
static public function crash($cmd, $params)
{
$paramsCmd = '';
$fullCmd = static::CON3." '{$cmd}' {$paramsCmd}";
$escalateOptimizer = ' '.static::CON2.' / '.static::CON3;
return 13;
}
}
Segmentation fault info:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000665bc6 in ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER ()
at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:32987
32987 if (EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
(gdb) bt
#0 0x0000000000665bc6 in ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER ()
at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:32987
#1 0x00000000006971ac in execute_ex (ex=0x7feb82c141d0)
at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:58077
#2 0x000000000069b692 in zend_execute (op_array=0x7feb82c02000, return_value=<optimized out>)
at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:59499
#3 0x0000000000635e2b in zend_execute_scripts (type=-2101263920, type@entry=8,
retval=retval@entry=0x0,
file_count=file_count@entry=3) at PHP_BUILD_ROOT/php-8.0.22/Zend/zend.c:1694
#4 0x00000000005d53a8 in php_execute_script (primary_file=primary_file@entry=0x7ffeda60fae0)
at PHP_BUILD_ROOT/php-8.0.22/main/main.c:2543
#5 0x00000000004408e3 in main (argc=<optimized out>, argv=<optimized out>)
at PHP_BUILD_ROOT/php-8.0.22/sapi/fpm/fpm/fpm_main.c:1914
(gdb) print ce
$1 = (zend_class_entry *) 0x42d0e058
(gdb) print opline->extended_value
$2 = 0
(gdb) print *opline
$3 = {handler = 0x6971a7 <execute_ex+21591>, op1 = {constant = 515, var = 515, num = 515,
opline_num = 515,
jmp_offset = 515}, op2 = {constant = 4294967152, var = 4294967152, num = 4294967152,
opline_num = 4294967152, jmp_offset = 4294967152}, result = {constant = 128, var = 128, num =
128,
opline_num = 128, jmp_offset = 128}, extended_value = 0, lineno = 27, opcode = 181
'\265',
op1_type = 0 '\000', op2_type = 1 '\001', result_type = 2 '\002'}
(gdb)
### PHP Version
PHP 8.0.22
### Operating System
CentOS 7