From 83a413334c65d3d00b37a6c230d0435dac1b51f6 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Sat, 6 Jun 2026 16:04:41 +0000 Subject: [PATCH] Fix dangling `suffix` pointer in tracked library info `record_library_load()` stored the autodetected `suffix` pointer directly, unlike `libname` which is deep-copied. This is only safe when `suffix` is a static string literal, but `autodetect_symbol_suffix()` checks the caller-supplied `suffix_hint` first and returns that pointer when it matches. In the `LBT_DEFAULT_LIBS` path that hint is a stack buffer in `init()`, so `lbt_config.loaded_libs[i]->suffix` would dangle after `init()` returns and a later `lbt_get_config()` read would be a use-after-return (triggered by e.g. `LBT_DEFAULT_LIBS="libopenblas64.so!64_"`). Deep-copy the suffix in `record_library_load()` and free it in `clear_loaded_libraries()`, matching the existing handling of `libname`. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/config.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index b558fc2..f16012f 100644 --- a/src/config.c +++ b/src/config.c @@ -43,6 +43,7 @@ void clear_loaded_libraries() { for (int idx=0; idxlibname); + free((void *)lbt_config.loaded_libs[idx]->suffix); free(lbt_config.loaded_libs[idx]->active_forwards); //close_library(lbt_config.loaded_libs[idx]->handle); free(lbt_config.loaded_libs[idx]); @@ -110,7 +111,12 @@ void record_library_load(const char * libname, void * handle, const char * suffi new_libinfo->libname = (char *) malloc(namelen); memcpy(new_libinfo->libname, libname, namelen); new_libinfo->handle = handle; - new_libinfo->suffix = suffix; + // Deep-copy the suffix: it may point to a caller-supplied `suffix_hint` (e.g. a stack + // buffer in `init()`), so we cannot retain the original pointer past this call. + size_t suffixlen = strlen(suffix) + 1; + char * suffix_copy = (char *) malloc(suffixlen); + memcpy(suffix_copy, suffix, suffixlen); + new_libinfo->suffix = suffix_copy; new_libinfo->active_forwards = (uint8_t *)malloc(sizeof(uint8_t)*(NUM_EXPORTED_FUNCS/8 + 1)); memcpy(new_libinfo->active_forwards, forwards, sizeof(uint8_t)*(NUM_EXPORTED_FUNCS/8 + 1)); new_libinfo->interface = interface;