From 6e0505bf27bcdbbbf8733337a39b660a07cd2590 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 7 Oct 2022 16:51:01 +0200 Subject: [PATCH] Fix GH-9589: dl() segfaults when module is already loaded As of PHP 8.2.0, `zend_module_entry` structures are no longer copied, so when a module is permanently loaded, and users try to dynamically load that module again, the structure is corrupted[1], causing a segfault on shutdown. We catch that by checking whether any dynamically loaded module is already loaded, and bailing out in that case without modifying the `zend_module_entry` structure. [1] Closes GH-9689. --- NEWS | 2 ++ ext/standard/dl.c | 5 +++++ ext/standard/tests/general_functions/gh9589.phpt | 10 ++++++++++ 3 files changed, 17 insertions(+) create mode 100644 ext/standard/tests/general_functions/gh9589.phpt diff --git a/NEWS b/NEWS index b14555b348b..62b82f32fdd 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed bug GH-9655 (Pure intersection types cannot be implicitly nullable) (Girgias) + . Fixed bug GH-9589 (dl() segfaults when module is already loaded). (cmb, + Arnaud) - Streams: . Fixed bug GH-9590 (stream_select does not abort upon exception or empty diff --git a/ext/standard/dl.c b/ext/standard/dl.c index aae09963845..7b47c4726d1 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -205,6 +205,11 @@ PHPAPI int php_load_extension(const char *filename, int type, int start_now) return FAILURE; } module_entry = get_module(); + if (zend_hash_str_exists(&module_registry, module_entry->name, strlen(module_entry->name))) { + DL_UNLOAD(handle); + zend_error(E_CORE_WARNING, "Module \"%s\" is already loaded", module_entry->name); + return FAILURE; + } if (module_entry->zend_api != ZEND_MODULE_API_NO) { php_error_docref(NULL, error_type, "%s: Unable to initialize module\n" diff --git a/ext/standard/tests/general_functions/gh9589.phpt b/ext/standard/tests/general_functions/gh9589.phpt new file mode 100644 index 00000000000..a26f052debe --- /dev/null +++ b/ext/standard/tests/general_functions/gh9589.phpt @@ -0,0 +1,10 @@ +--TEST-- +dl() segfaults when module is already loaded +--EXTENSIONS-- +dl_test +--FILE-- + +--EXPECT-- +Warning: Module "dl_test" is already loaded in Unknown on line 0