From d5efa71dfa5c5d309ad9dbcbaebf4bea8361ea28 Mon Sep 17 00:00:00 2001 From: Nicholas Sielicki Date: Wed, 29 Oct 2025 16:41:28 -0500 Subject: [PATCH] prov/util: memhooks: avoid RTLD_NEXT usage dlsym(RTLD_NEXT, ...) may legally return any entrypoint which eventually finds its way into the requested symbol, in any library appearing in load-order after the current library. Load order can be messy in HPC runtime environments, or due to inconsistencies introduced by vendor toolchains and vendor packaging mechanisms. All current intercepts are expected to resolve to libc, so just do an explicit search inside libc to prevent accidentally resolving eg: PLT stubs. Fixes: #11451 Signed-off-by: Nicholas Sielicki --- prov/util/src/util_mem_hooks.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/prov/util/src/util_mem_hooks.c b/prov/util/src/util_mem_hooks.c index b0e9d7363ae..b11116ef6b4 100644 --- a/prov/util/src/util_mem_hooks.c +++ b/prov/util/src/util_mem_hooks.c @@ -480,6 +480,29 @@ static bool ofi_is_function_patched(struct ofi_intercept *intercept) } #endif +static void *ofi_find_libc_symbol(const char *symbol) +{ + void *handle; + void *addr; + + handle = dlopen("libc.so.6", RTLD_LAZY | RTLD_NOLOAD); + if (!handle) { + FI_DBG(&core_prov, FI_LOG_MR, + "could not open libc.so.6\n"); + return NULL; + } + + addr = dlsym(handle, symbol); + dlclose(handle); + + if (!addr) { + FI_DBG(&core_prov, FI_LOG_MR, + "could not find symbol %s in libc.so.6\n", symbol); + } + + return addr; +} + /* * This implementation intercepts syscalls by overwriting the beginning of * glibc's functions with a jump to our intercept function. After notifying the @@ -494,14 +517,13 @@ static int ofi_intercept_symbol(struct ofi_intercept *intercept) FI_DBG(&core_prov, FI_LOG_MR, "overwriting function %s\n", intercept->symbol); - func_addr = dlsym(RTLD_NEXT, intercept->symbol); + func_addr = ofi_find_libc_symbol(intercept->symbol); if (!func_addr) { func_addr = dlsym(RTLD_DEFAULT, intercept->symbol); if (!func_addr) { FI_DBG(&core_prov, FI_LOG_MR, - "could not find symbol %s\n", intercept->symbol); - ret = -FI_ENOMEM; - return ret; + "could not find symbol %s in any library\n", intercept->symbol); + return -FI_ENOENT; } }