From f5eb19febedf5663b3ba9617ecc03cdf94b6df9c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 16 Aug 2026 11:23:11 +0100 Subject: [PATCH 1/3] ext/opcache: opcache.interned_strings_buffer per FPM pool crashed on restart. Fix #23288 The directive was still accepted once the shared interned string table had been sized from the master php.ini, so a diverging pool value made the next restart run accel_interned_strings_restore_state() against a table that was never allocated. Reject post-startup changes like opcache.memory_consumption and gate the restore on the shared table state instead of the per-process directive. --- ext/opcache/ZendAccelerator.c | 2 +- ext/opcache/zend_accelerator_module.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index a2d964c15070..70f3d8313638 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2715,7 +2715,7 @@ ZEND_RINIT_FUNCTION(zend_accelerator) zend_reset_cache_vars(); zend_accel_hash_clean(&ZCSG(hash)); - if (ZCG(accel_directives).interned_strings_buffer) { + if (ZCSG(interned_strings).saved_top) { accel_interned_strings_restore_state(); } diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index ffa09aaf9e67..2fb7e775bb34 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -93,6 +93,11 @@ static ZEND_INI_MH(OnUpdateMemoryConsumption) static ZEND_INI_MH(OnUpdateInternedStringsBuffer) { + if (accel_startup_ok) { + zend_accel_error(ACCEL_LOG_WARNING, "opcache.interned_strings_buffer cannot be changed when OPcache is already set up."); + return FAILURE; + } + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); zend_long size = zend_ini_parse_quantity_warn(new_value, entry->name); From cede67419a61a39fbc1e4a0b5cba486f43e916a1 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 16 Aug 2026 12:13:13 +0100 Subject: [PATCH 2/3] add fpm test --- ...-opcache-interned-strings-buffer-pool.phpt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt diff --git a/sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt b/sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt new file mode 100644 index 000000000000..b64e919b105b --- /dev/null +++ b/sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt @@ -0,0 +1,53 @@ +--TEST-- +FPM: GH-23288 - opcache.interned_strings_buffer overridden per pool must not crash on restart +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- +start(iniEntries: [ + 'opcache.enable' => '1', + 'opcache.enable_cli' => '1', + 'opcache.interned_strings_buffer' => '0', +]); +$tester->expectLogStartNotices(); +$tester->request()->expectBody('ok'); +$tester->request()->expectBody('ok'); +$tester->request()->expectBody('ok'); +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- + From bfab8efe8d0c8acde9edf499bb3f3fcc9904e284 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 16 Aug 2026 12:37:04 +0100 Subject: [PATCH 3/3] fix test attempt --- .../gh23288-opcache-interned-strings-buffer-pool.phpt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt b/sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt index b64e919b105b..8f48b3a8c209 100644 --- a/sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt +++ b/sapi/fpm/tests/gh23288-opcache-interned-strings-buffer-pool.phpt @@ -16,8 +16,6 @@ error_log = {{FILE:LOG}} listen = {{ADDR}} pm = static pm.max_children = 1 -php_admin_value[opcache.enable] = 1 -php_admin_value[opcache.enable_cli] = 1 php_admin_value[opcache.interned_strings_buffer] = 8 EOT; @@ -28,12 +26,11 @@ opcache_reset(); echo "ok"; EOT; +$opcache = ini_get('extension_dir') . DIRECTORY_SEPARATOR . 'opcache.' . PHP_SHLIB_SUFFIX; +$extraArgs = is_file($opcache) ? ['-dzend_extension=' . $opcache] : []; + $tester = new FPM\Tester($cfg, $code); -$tester->start(iniEntries: [ - 'opcache.enable' => '1', - 'opcache.enable_cli' => '1', - 'opcache.interned_strings_buffer' => '0', -]); +$tester->start($extraArgs, iniEntries: ['opcache.interned_strings_buffer' => '0']); $tester->expectLogStartNotices(); $tester->request()->expectBody('ok'); $tester->request()->expectBody('ok');