mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
For RAR load, check LD_LIBRARY_PATH before checking install path
ClamAV initalization's rarload() function tries to load libclamunrar_iface from the install path before checking under LD_LIBRARY_PATH. This means the unit tests will use the wrong unrar library if testing on a system where ClamAV is already installed. In the event there is an ABI break between versions, this will cause a bunch of tests to fail. This commit fixes the issue by checking for libclamunrar_iface under LD_LIBRARY_PATH *first* before checking in the install lib directory. Note in the previous version we were also checking LD_LIBRARY_PATH on Windows, which is not a thing. I removed this. Fixes: https://github.com/Cisco-Talos/clamav/issues/1249 Also removed check for WARN_DLOPEN_FAIL define, which was not used, and mistakenly set for the unrar library build target.
This commit is contained in:
parent
3809b2a518
commit
93699dfb8f
2 changed files with 103 additions and 107 deletions
|
@ -92,106 +92,27 @@ static int is_rar_inited = 0;
|
|||
#define PASTE2(a, b) a #b
|
||||
#define PASTE(a, b) PASTE2(a, b)
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static void *load_module(const char *name, const char *featurename)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
static const char *suffixes[] = {LT_MODULE_EXT};
|
||||
#else
|
||||
static const char *suffixes[] = {
|
||||
LT_MODULE_EXT "." LIBCLAMAV_FULLVER,
|
||||
PASTE(LT_MODULE_EXT ".", LIBCLAMAV_MAJORVER),
|
||||
LT_MODULE_EXT,
|
||||
"." LT_LIBEXT};
|
||||
#endif
|
||||
|
||||
const char *searchpath;
|
||||
HMODULE rhandle = NULL;
|
||||
char modulename[128];
|
||||
size_t i;
|
||||
#ifdef _WIN32
|
||||
HMODULE rhandle = NULL;
|
||||
#else
|
||||
void *rhandle;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* First try a standard LoadLibraryA() without specifying a full path.
|
||||
* For Windows, just try a standard LoadLibraryA() with each of the different possible suffixes.
|
||||
* For more information on the DLL search order, see:
|
||||
* https://docs.microsoft.com/en-us/windows/desktop/Dlls/dynamic-link-library-search-order
|
||||
* https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
|
||||
*/
|
||||
cli_dbgmsg("searching for %s\n", featurename);
|
||||
#else
|
||||
/*
|
||||
* First search using the provided SEARCH_LIBDIR (e.g. "<prefix>/lib")
|
||||
* Known issue: If an older clamav version is already installed, the clamav
|
||||
* unit tests using this function will load the older library version from
|
||||
* the install path first.
|
||||
*/
|
||||
searchpath = SEARCH_LIBDIR;
|
||||
cli_dbgmsg("searching for %s, user-searchpath: %s\n", featurename, searchpath);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) {
|
||||
#ifdef _WIN32
|
||||
snprintf(modulename, sizeof(modulename), "%s%s", name, suffixes[i]);
|
||||
rhandle = LoadLibraryA(modulename);
|
||||
#else // !_WIN32
|
||||
snprintf(modulename, sizeof(modulename), "%s" PATHSEP "%s%s", searchpath, name, suffixes[i]);
|
||||
rhandle = dlopen(modulename, RTLD_NOW);
|
||||
#endif // !_WIN32
|
||||
if (rhandle) {
|
||||
break;
|
||||
}
|
||||
|
||||
cli_dbgmsg("searching for %s: %s not found\n", featurename, modulename);
|
||||
}
|
||||
snprintf(modulename, sizeof(modulename), "%s%s", name, LT_MODULE_EXT);
|
||||
|
||||
rhandle = LoadLibraryA(modulename);
|
||||
if (NULL == rhandle) {
|
||||
char *ld_library_path = NULL;
|
||||
/*
|
||||
* library not found.
|
||||
* Try again using LD_LIBRARY_PATH environment variable for the path.
|
||||
*/
|
||||
ld_library_path = getenv("LD_LIBRARY_PATH");
|
||||
if (NULL != ld_library_path) {
|
||||
#define MAX_LIBRARY_PATHS 10
|
||||
size_t token_index;
|
||||
size_t tokens_count;
|
||||
const char *tokens[MAX_LIBRARY_PATHS];
|
||||
char *err = NULL;
|
||||
|
||||
char *tokenized_library_path = NULL;
|
||||
|
||||
tokenized_library_path = strdup(ld_library_path);
|
||||
tokens_count = cli_strtokenize(tokenized_library_path, ':', MAX_LIBRARY_PATHS, tokens);
|
||||
|
||||
for (token_index = 0; token_index < tokens_count; token_index++) {
|
||||
cli_dbgmsg("searching for %s, LD_LIBRARY_PATH: %s\n", featurename, tokens[token_index]);
|
||||
|
||||
for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) {
|
||||
snprintf(modulename, sizeof(modulename), "%s" PATHSEP "%s%s", tokens[token_index], name, suffixes[i]);
|
||||
#ifdef _WIN32
|
||||
rhandle = LoadLibraryA(modulename);
|
||||
#else // !_WIN32
|
||||
rhandle = dlopen(modulename, RTLD_NOW);
|
||||
#endif // !_WIN32
|
||||
if (rhandle) {
|
||||
break;
|
||||
}
|
||||
|
||||
cli_dbgmsg("searching for %s: %s not found\n", featurename, modulename);
|
||||
}
|
||||
|
||||
if (rhandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(tokenized_library_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == rhandle) {
|
||||
#ifdef _WIN32
|
||||
char *err = NULL;
|
||||
DWORD lasterr = GetLastError();
|
||||
if (0 < lasterr) {
|
||||
FormatMessageA(
|
||||
|
@ -203,36 +124,112 @@ static void *load_module(const char *name, const char *featurename)
|
|||
0,
|
||||
NULL);
|
||||
}
|
||||
#else // !_WIN32
|
||||
const char *err = dlerror();
|
||||
#endif // !_WIN32
|
||||
|
||||
#ifdef WARN_DLOPEN_FAIL
|
||||
if (NULL == err) {
|
||||
cli_warnmsg("Cannot dlopen %s: Unknown error - %s support unavailable\n", name, featurename);
|
||||
cli_dbgmsg("Cannot LoadLibraryA %s: Unknown error - %s support unavailable\n", name, featurename);
|
||||
} else {
|
||||
cli_warnmsg("Cannot dlopen %s: %s - %s support unavailable\n", name, err, featurename);
|
||||
}
|
||||
#else
|
||||
if (NULL == err) {
|
||||
cli_dbgmsg("Cannot dlopen %s: Unknown error - %s support unavailable\n", name, featurename);
|
||||
} else {
|
||||
cli_dbgmsg("Cannot dlopen %s: %s - %s support unavailable\n", name, err, featurename);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if (NULL != err) {
|
||||
cli_dbgmsg("Cannot LoadLibraryA %s: %s - %s support unavailable\n", name, err, featurename);
|
||||
LocalFree(err);
|
||||
}
|
||||
#endif
|
||||
return rhandle;
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
cli_dbgmsg("%s support loaded from %s\n", featurename, modulename);
|
||||
|
||||
done:
|
||||
|
||||
return (void *)rhandle;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void *load_module(const char *name, const char *featurename)
|
||||
{
|
||||
static const char *suffixes[] = {
|
||||
LT_MODULE_EXT "." LIBCLAMAV_FULLVER,
|
||||
PASTE(LT_MODULE_EXT ".", LIBCLAMAV_MAJORVER),
|
||||
LT_MODULE_EXT,
|
||||
"." LT_LIBEXT};
|
||||
void *rhandle = NULL;
|
||||
char *tokenized_library_path = NULL;
|
||||
char *ld_library_path = NULL;
|
||||
const char *err;
|
||||
|
||||
char modulename[128];
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* First try using LD_LIBRARY_PATH environment variable for the path.
|
||||
* We do this first because LD_LIBRARY_PATH is intended as an option to override the installed library path.
|
||||
*
|
||||
* We don't do this for Windows because Windows doesn't have an equivalent to LD_LIBRARY_PATH
|
||||
* and because LoadLibraryA() will search the executable's folder, which works for the unit tests.
|
||||
*/
|
||||
ld_library_path = getenv("LD_LIBRARY_PATH");
|
||||
if (NULL != ld_library_path && strlen(ld_library_path) > 0) {
|
||||
#define MAX_LIBRARY_PATHS 10
|
||||
size_t token_index;
|
||||
size_t tokens_count;
|
||||
const char *tokens[MAX_LIBRARY_PATHS];
|
||||
|
||||
/*
|
||||
* LD_LIBRARY_PATH may be a colon-separated list of directories.
|
||||
* Tokenize the list and try to load the library from each directory.
|
||||
*/
|
||||
tokenized_library_path = strdup(ld_library_path);
|
||||
tokens_count = cli_strtokenize(tokenized_library_path, ':', MAX_LIBRARY_PATHS, tokens);
|
||||
|
||||
for (token_index = 0; token_index < tokens_count; token_index++) {
|
||||
cli_dbgmsg("searching for %s, LD_LIBRARY_PATH: %s\n", featurename, tokens[token_index]);
|
||||
|
||||
for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) {
|
||||
snprintf(modulename, sizeof(modulename), "%s" PATHSEP "%s%s", tokens[token_index], name, suffixes[i]);
|
||||
|
||||
rhandle = dlopen(modulename, RTLD_NOW);
|
||||
if (NULL != rhandle) {
|
||||
cli_dbgmsg("%s support loaded from %s\n", featurename, modulename);
|
||||
goto done;
|
||||
}
|
||||
|
||||
cli_dbgmsg("searching for %s: %s not found\n", featurename, modulename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Search in "<prefix>/lib" checking with each of the different possible suffixes.
|
||||
*/
|
||||
cli_dbgmsg("searching for %s, user-searchpath: %s\n", featurename, SEARCH_LIBDIR);
|
||||
|
||||
for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) {
|
||||
snprintf(modulename, sizeof(modulename), "%s" PATHSEP "%s%s", SEARCH_LIBDIR, name, suffixes[i]);
|
||||
|
||||
rhandle = dlopen(modulename, RTLD_NOW);
|
||||
if (NULL != rhandle) {
|
||||
cli_dbgmsg("%s support loaded from %s\n", featurename, modulename);
|
||||
goto done;
|
||||
}
|
||||
|
||||
cli_dbgmsg("searching for %s: %s not found\n", featurename, modulename);
|
||||
}
|
||||
|
||||
err = dlerror();
|
||||
if (NULL == err) {
|
||||
cli_dbgmsg("Cannot dlopen %s: Unknown error - %s support unavailable\n", name, featurename);
|
||||
} else {
|
||||
cli_dbgmsg("Cannot dlopen %s: %s - %s support unavailable\n", name, err, featurename);
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
free(tokenized_library_path);
|
||||
|
||||
return (void *)rhandle;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static void *get_module_function(HMODULE handle, const char *name)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2019-2024 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||
|
||||
add_compile_definitions(RARDLL)
|
||||
add_compile_definitions(WARN_DLOPEN_FAIL)
|
||||
add_compile_definitions(_FILE_OFFSET_BITS=64)
|
||||
|
||||
if(WIN32)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue