fix(php): 修复PHP嵌入模式下的模块注册和字符串释放问题

- 在模块注册失败时返回错误码255而不是继续执行
- 在模块启动失败时返回错误码255而不是继续执行
- 添加注释解释PHP内部字符串处理的bug
- 在请求关闭时手动从模块表中删除内部字符串以防止重复释放
- 防止use-after-free内存安全问题的发生
pull/1/head
韩天峰 7 months ago
parent 0d5d91ec02
commit 3931d77ceb
  1. 7
      src/cpp/main.cc

@ -22,10 +22,12 @@ int main(int cpp_argc, char **cpp_argv) {
if (zend_register_module_ex(module, MODULE_PERSISTENT) == NULL) { if (zend_register_module_ex(module, MODULE_PERSISTENT) == NULL) {
zend_error(E_ERROR, "Failed to register module [%s]", module->name); zend_error(E_ERROR, "Failed to register module [%s]", module->name);
return 255;
} }
if (zend_startup_module_ex(module) == FAILURE) { if (zend_startup_module_ex(module) == FAILURE) {
zend_error(E_ERROR, "Failed to startup module [%s]", module->name); zend_error(E_ERROR, "Failed to startup module [%s]", module->name);
return 255;
} }
int rc = 0; int rc = 0;
@ -50,6 +52,11 @@ int main(int cpp_argc, char **cpp_argv) {
php_app_clean(); php_app_clean();
php::request_shutdown(); php::request_shutdown();
/**
* There is a bug in PHP's handling of internal strings. All interned strings are released in the request shutdown
* function, but then released again in the php_embed_shutdown function, resulting in a use-after-free issue. These
* must be manually removed from the module table to prevent double release.
*/
auto name_len = strlen(module->name); auto name_len = strlen(module->name);
auto lcname = zend_string_alloc(name_len, module->type == MODULE_PERSISTENT); auto lcname = zend_string_alloc(name_len, module->type == MODULE_PERSISTENT);
zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len); zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len);

Loading…
Cancel
Save