Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For RAR load, check LD_LIBRARY_PATH before checking install path #1258

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ jobs:
- uses: actions/checkout@v1

- name: Install Build Tools
run: brew install bison flex
run: brew install bison flex pipx

- name: Install Dependencies
run: brew install bzip2 check curl-openssl json-c libxml2 ncurses openssl@1.1 pcre2 zlib
run: brew install bzip2 check curl json-c libxml2 ncurses openssl@3 pcre2 zlib

- name: Install pytest for easier to read test results
run: python3 -m pip install pytest
run: pipx install pytest

- uses: lukka/[email protected]

Expand All @@ -119,9 +119,9 @@ jobs:
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
run:
cmake ${{runner.workspace}}/clamav -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
-DOPENSSL_ROOT_DIR=/usr/local/opt/[email protected]/
-DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/[email protected]/lib/libcrypto.1.1.dylib
-DOPENSSL_SSL_LIBRARY=/usr/local/opt/[email protected]/lib/libssl.1.1.dylib
-DOPENSSL_ROOT_DIR=/opt/homebrew/include/
-DOPENSSL_CRYPTO_LIBRARY=/opt/homebrew/lib/libcrypto.3.dylib
-DOPENSSL_SSL_LIBRARY=/opt/homebrew/lib/libssl.3.dylib
-DENABLE_STATIC_LIB=ON
-DENABLE_EXAMPLES=ON

Expand All @@ -148,13 +148,13 @@ jobs:
run: sudo apt-get update

- name: Install Build Tools
run: sudo apt-get install -y bison flex valgrind
run: sudo apt-get install -y bison flex valgrind pipx

- name: Install Dependencies
run: sudo apt-get install -y check libbz2-dev libcurl4-openssl-dev libjson-c-dev libmilter-dev libncurses5-dev libpcre3-dev libssl-dev libxml2-dev zlib1g-dev

- name: Install pytest for easier to read test results
run: python3 -m pip install pytest
run: pipx install pytest

- uses: lukka/[email protected]

Expand Down
205 changes: 101 additions & 104 deletions libclamav/others.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,106 +92,27 @@ static int is_rar_inited = 0;
#define PASTE2(a, b) a #b
#define PASTE(a, b) PASTE2(a, b)

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;
static void *load_module(const char *name, const char *featurename)
{
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 *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);
}
char *err = NULL;

if (rhandle) {
break;
}
}
free(tokenized_library_path);
}
}

if (NULL == rhandle) {
#ifdef _WIN32
char *err = NULL;
DWORD lasterr = GetLastError();
if (0 < lasterr) {
FormatMessageA(
Expand All @@ -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);
cli_dbgmsg("Cannot LoadLibraryA %s: %s - %s support unavailable\n", name, err, featurename);
LocalFree(err);
}

goto done;
}

cli_dbgmsg("%s support loaded from %s\n", featurename, modulename);

done:

return (void *)rhandle;
}

#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);

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);
}
}
#endif
}

#ifdef _WIN32
if (NULL != err) {
LocalFree(err);
/*
* 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;
}
#endif
return rhandle;

cli_dbgmsg("searching for %s: %s not found\n", featurename, modulename);
}

cli_dbgmsg("%s support loaded from %s\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)
Expand Down
1 change: 0 additions & 1 deletion libclamunrar/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
Loading