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] <https://github.com/php/php-src/issues/9589#issuecomment-1263718701>

Closes GH-9689.
This commit is contained in:
Christoph M. Becker 2022-10-07 16:51:01 +02:00
parent 8e146c8806
commit 6e0505bf27
No known key found for this signature in database
GPG Key ID: D66C9593118BCCB6
3 changed files with 17 additions and 0 deletions

2
NEWS
View File

@ -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

View File

@ -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"

View File

@ -0,0 +1,10 @@
--TEST--
dl() segfaults when module is already loaded
--EXTENSIONS--
dl_test
--FILE--
<?php
dl("dl_test");
?>
--EXPECT--
Warning: Module "dl_test" is already loaded in Unknown on line 0