[php-src] Issue #9164: Segfault in zend_accel_class_hash_copy

From: Date: Wed, 27 Jul 2022 04:13:24 +0000
Subject: [php-src] Issue #9164: Segfault in zend_accel_class_hash_copy
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-242034@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/9164 Author: turchanov ### Description We use php-fpm with opcache with filecache, no JIT. On deployment of a newer version of php application codebase (that is opcache filecache is empty at the moment) we experience a spike of segfaults in php-fpm workers. This bug seems to be relevant to https://bugs.php.net/bug.php?id=81607 as we see that ce->name->gc->refcount / 8 is beyond the limits of CG(map_ptr_last) ``` #0 0x00007fd7b8a9e67a in zend_accel_class_hash_copy (target=0x26aa520, source=0x47dc6cf0) at /usr/src/debug/php-8.1.8-debug/ext/opcache/zend_accelerator_util_funcs.c:210 #1 0x00007fd7b8a9e870 in zend_accel_load_script (persistent_script=0x47dc6bc0, from_shared_memory=1) at /usr/src/debug/php-8.1.8-debug/ext/opcache/zend_accelerator_util_funcs.c:230 #2 0x00007fd7b8a6a2d8 in persistent_compile_file (file_handle=0x7ffd3264a1b0, type=2) at /usr/src/debug/php-8.1.8-debug/ext/opcache/ZendAccelerator.c:2240 #3 0x000000000099e6bf in compile_filename (type=2, filename=0x426aac80) at /usr/src/debug/php-8.1.8-debug/Zend/zend_language_scanner.c:707 #4 0x0000000000a7886c in zend_include_or_eval (inc_filename_zv=0x7fd7b4015ac0, type=2) at /usr/src/debug/php-8.1.8-debug/Zend/zend_execute.c:4617 ``` ``` (gdb) fr 0 |204 } else { |205 zend_class_entry *ce = Z_PTR(p->val); |206 t = _zend_hash_append_ptr_ex(target, p->key, Z_PTR(p->val), 1); |207 if ((ce->ce_flags & ZEND_ACC_LINKED) |208 && ZSTR_HAS_CE_CACHE(ce->name) |209 && ZSTR_VAL(p->key)[0]) { >|210 ZSTR_SET_CE_CACHE_EX(ce->name, ce, 0); <---- |211 } |212 } (gdb) print compiler_globals->map_ptr_base $1 = (void *) 0x7fd7a7a6000f (gdb) print compiler_globals->map_ptr_last $2 = 57332 (gdb) print ce->name->gc->refcount $3 = 472001 (gdb) print ce->name->gc->refcount / 8 $4 = 59000 ``` We implemented a work-around by reverting ZSTR_SET_CE_CACHE_EX(ce->name, ce, 0) to ZSTR_SET_CE_CACHE(ce->name, ce) in zend_accel_class_hash_copy (and in zend_accel_inheritance_cache_get and zend_persist_class_entry just in case) as it appears that invalid cache pointers do exists at this point. With this fix segfauls do not happen anymore. opcache settings: ``` zend_extension=opcache.so opcache.enable = 1 opcache.max_accelerated_files = 50000 opcache.interned_strings_buffer = 50 opcache.memory_consumption = 320 opcache.revalidate_freq = 15 opcache.enable_file_override = 1 opcache.file_cache = "..." ``` ### PHP Version PHP 8.1.8 ### Operating System CentOS 7.7

« previous php.bugs (#242034) next »