From b7b8618123d559a7919ad7a353c9c7f0d36b3c25 Mon Sep 17 00:00:00 2001 From: Ricardo Dias Date: Mon, 10 Feb 2025 14:35:14 +0000 Subject: [PATCH] Use `DEEPBIND` flag when loading external modules using `dlopen` The current flags used in `dlopen` to load external modules don't allow modules to define symbols that are already defined by the valkey server binary because the symbol resolution first looks in the server memory and only if it does not find anything, it looks in the module (shared library) memory. This might become a problem if, for instance, we try to implement a new scripting engine based on a newer version of Lua. The Lua interpreter library shares many symbol names with the Lua interpreter included in the Valkey server binary. To fix the above problem, this PR adds the flag `RTLD_DEEPBIND` to the flags used in `dlopen`, which changes the symbol resolution strategy to look for the symbol in the module memory first, if the code executing is from the module. Signed-off-by: Ricardo Dias --- src/module.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/module.c b/src/module.c index d40b2ea01b..34f34b0f74 100644 --- a/src/module.c +++ b/src/module.c @@ -12274,7 +12274,16 @@ int moduleLoad(const char *path, void **module_argv, int module_argc, int is_loa } } - handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); + int dlopen_flags = RTLD_NOW | RTLD_LOCAL; +#ifndef __SANITIZE_ADDRESS__ + /* RTLD_DEEPBIND, which is required for loading modules that contains the + * same symbols, does not work with ASAN. Therefore, we exclude + * RTLD_DEEPBIND when doing test builds with ASAN. + * See https://github.com/google/sanitizers/issues/611 for more details.*/ + dlopen_flags |= RTLD_DEEPBIND; +#endif + + handle = dlopen(path, dlopen_flags); if (handle == NULL) { serverLog(LL_WARNING, "Module %s failed to load: %s", path, dlerror()); return C_ERR;