From ab9d121f483ceb3c465f233f872d4d54840caaf7 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Mon, 6 Oct 2025 18:25:40 +0200 Subject: [PATCH] Fix access to uninitialized variables in preload_load() preload_load() reads EG(class_table) and EG(function_table), but these may not be initialized. Move these accesses out of preload_load(). Closes GH-20081 --- NEWS | 4 ++++ ext/opcache/ZendAccelerator.c | 15 ++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index b4b0521051f..a897bf0b733 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ PHP NEWS . Fixed bug GH-19974 (fpm_status_export_to_zval segfault for parallel execution). (Jakub Zelenka, txuna) +- Opcache: + . Fixed bug GH-20081 (access to uninitialized vars in preload_load()). + (Arnaud) + - Random: . Fix Randomizer::__serialize() w.r.t. INDIRECTs. (nielsdos) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 1b0101dbfd6..f8564999eef 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -4345,15 +4345,6 @@ static void preload_load(void) } } - if (EG(zend_constants)) { - EG(persistent_constants_count) = EG(zend_constants)->nNumUsed; - } - if (EG(function_table)) { - EG(persistent_functions_count) = EG(function_table)->nNumUsed; - } - if (EG(class_table)) { - EG(persistent_classes_count) = EG(class_table)->nNumUsed; - } if (CG(map_ptr_last) != ZCSG(map_ptr_last)) { size_t old_map_ptr_last = CG(map_ptr_last); CG(map_ptr_last) = ZCSG(map_ptr_last); @@ -4589,6 +4580,12 @@ static zend_result accel_preload(const char *config, bool in_child) preload_load(); + /* Update persistent counts, as shutdown will discard anything past + * that, and these tables are aliases to global ones at this point. */ + EG(persistent_functions_count) = EG(function_table)->nNumUsed; + EG(persistent_classes_count) = EG(class_table)->nNumUsed; + EG(persistent_constants_count) = EG(zend_constants)->nNumUsed; + /* Store individual scripts with unlinked classes */ HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT();