From d554124d3d87ef8d29e5a71a12eda37a6053fa76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Mon, 17 Apr 2023 17:28:41 +0200 Subject: [PATCH] Add zend.dlopen_deepbind php.ini directive Add a runtime configuration option to control whether loading shared libraries via dlopen(3) uses the GNU extension flag RTLD_DEEPBIND, if available. The flag ensures symbol lookup will prefer symbols from the shared object itself over global ones, which can resolve symbol namespace collisions in third party dependencies, see 601140cbe9a ("New versions of glibc support a RTLD_DEEPBIND flag to dlopen. The"). However using this flag symbols from preloaded libraries might be de- prioritized, e.g. free(3) from a preloaded allocator by the standard libc. This results in one allocator allocating memory and another one deallocating it, triggering double/invalid-free assertions. Closes: #10670 --- Zend/zend.c | 1 + Zend/zend_globals.h | 2 ++ Zend/zend_portability.h | 2 +- php.ini-development | 6 ++++++ php.ini-production | 6 ++++++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Zend/zend.c b/Zend/zend.c index 141d9bb4ad419..9bc01a7d8c714 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -241,6 +241,7 @@ static ZEND_INI_MH(OnUpdateFiberStackSize) /* {{{ */ ZEND_INI_BEGIN() ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) STD_ZEND_INI_ENTRY("zend.assertions", "1", ZEND_INI_ALL, OnUpdateAssertions, assertions, zend_executor_globals, executor_globals) + STD_ZEND_INI_BOOLEAN("zend.dlopen_deepbind", "1", ZEND_INI_SYSTEM, OnUpdateBool, dlopen_deepbind, zend_compiler_globals, compiler_globals) ZEND_INI_ENTRY3_EX("zend.enable_gc", "1", ZEND_INI_ALL, OnUpdateGCEnabled, NULL, NULL, NULL, zend_gc_enabled_displayer_cb) STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte, zend_compiler_globals, compiler_globals) ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding) diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 8900a5f416f53..f04c3561b85f6 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -104,6 +104,8 @@ struct _zend_compiler_globals { bool ini_parser_unbuffered_errors; + bool dlopen_deepbind; + zend_llist open_files; struct _zend_ini_parser_param *ini_parser_param; diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index c098d29d51842..60c19e25e1349 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -156,7 +156,7 @@ # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT) # define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT) # elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__) && !__has_feature(memory_sanitizer) -# define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_DEEPBIND) +# define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | (CG(dlopen_deepbind) ? RTLD_DEEPBIND : 0)) # else # define DL_LOAD(libname) dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL) # endif diff --git a/php.ini-development b/php.ini-development index d6bc11ae17e41..013b9f4e225c4 100644 --- a/php.ini-development +++ b/php.ini-development @@ -396,6 +396,12 @@ zend.exception_ignore_args = Off ; Production Value: 0 zend.exception_string_param_max_len = 15 +; Decides whether to use the dlopen(3) flag RTLD_DEEPBIND, if available, when +; loading shared libraries. This ensures symbol lookup will prefer symbols from +; the shared object itself over global ones. Conflicts with the use of custom +; memory allocators. +zend.dlopen_deepbind = On + ;;;;;;;;;;;;;;;;; ; Miscellaneous ; ;;;;;;;;;;;;;;;;; diff --git a/php.ini-production b/php.ini-production index 0d6ca0f144482..a32e11fedfb17 100644 --- a/php.ini-production +++ b/php.ini-production @@ -398,6 +398,12 @@ zend.exception_ignore_args = On ; of sensitive information in stack traces. zend.exception_string_param_max_len = 0 +; Decides whether to use the dlopen(3) flag RTLD_DEEPBIND, if available, when +; loading shared libraries. This ensures symbol lookup will prefer symbols from +; the shared object itself over global ones. Conflicts with the use of custom +; memory allocators. +zend.dlopen_deepbind = On + ;;;;;;;;;;;;;;;;; ; Miscellaneous ; ;;;;;;;;;;;;;;;;;