Skip to content

Commit 84bf6c3

Browse files
haoxian2pcolberg
authored andcommitted
Fixed coverity in acl_hal_mmd.cpp: Resource leak (RESOURCE_LEAK)
mmd_libraries were not closed after execution, which causes memory leaks. But mmd_libraries cannot be closed trivially since closing the library invalidates the symbol return by dlsym(), which means calling the function further down is undefined behaviour. To solve this issues, I added a `dl_wrapper_t` vector as a global initialized vector that would be deallocated when closing the runtime library. This vector would contain all the opened libraries that would be closed by the destructor of `dl_wrapper_t` once the vector deallocates.
1 parent 5a71e64 commit 84bf6c3

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

src/acl_hal_mmd.cpp

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,41 @@ unsigned acl_convert_mmd_capabilities(unsigned mmd_capabilities);
188188
const static size_t MIN_SOF_SIZE = 1;
189189
const static size_t MIN_PLL_CONFIG_SIZE = 1;
190190

191+
// Wrapper for dl libraries
192+
struct dl_wrapper_t {
193+
std::vector<void *> mmd_libs;
194+
dl_wrapper_t() { ; }
195+
~dl_wrapper_t() {
196+
for (void *mmd_lib : this->mmd_libs) {
197+
if (mmd_lib) {
198+
#ifdef _WIN32
199+
FreeLibrary((HMODULE)mmd_lib);
200+
#else
201+
dlclose(mmd_lib);
202+
#endif
203+
}
204+
}
205+
}
206+
207+
// destroy last element of mmd_libs
208+
void pop_back() {
209+
if (this->mmd_libs.back()) {
210+
#ifdef _WIN32
211+
FreeLibrary((HMODULE)this->mmd_libs.back());
212+
#else
213+
dlclose(this->mmd_libs.back());
214+
#endif
215+
}
216+
this->mmd_libs.pop_back();
217+
}
218+
219+
// prohibit copying to avoid double-close of handle
220+
dl_wrapper_t(const dl_wrapper_t &) = delete;
221+
dl_wrapper_t &operator=(const dl_wrapper_t &) = delete;
222+
};
223+
191224
std::vector<acl_mmd_dispatch_t> internal_mmd_dispatch;
225+
static dl_wrapper_t dl_wrapper;
192226

193227
// Dynamically load board mmd & symbols
194228
static size_t num_board_pkgs;
@@ -568,8 +602,9 @@ cl_bool l_load_single_board_library(const char *library_name,
568602
return CL_FALSE;
569603
}
570604
#endif
571-
auto *mmd_library = my_dlopen(library_name, &error_msg);
572-
if (!mmd_library) {
605+
dl_wrapper.mmd_libs.push_back(my_dlopen(library_name, &error_msg));
606+
if (!dl_wrapper.mmd_libs.back()) {
607+
dl_wrapper.pop_back();
573608
std::cout << "Error: Could not load board library " << library_name;
574609
if (error_msg && error_msg[0] != '\0') {
575610
std::cout << " (error_msg: " << error_msg << ")";
@@ -578,18 +613,19 @@ cl_bool l_load_single_board_library(const char *library_name,
578613
return CL_FALSE;
579614
}
580615

581-
auto *test_symbol =
582-
my_dlsym(mmd_library, "aocl_mmd_get_offline_info", &error_msg);
616+
auto *test_symbol = my_dlsym(dl_wrapper.mmd_libs.back(),
617+
"aocl_mmd_get_offline_info", &error_msg);
583618
if (!test_symbol) {
584619
// On Linux, for custom libraries close the library (which was opened
585620
// locally) and then reopen globally. For Windows, there is no option (i.e.
586621
// it is always global)
587622
#ifdef __linux__
588-
my_dlclose(mmd_library);
623+
my_dlclose(dl_wrapper.mmd_libs.back());
589624
ACL_HAL_DEBUG_MSG_VERBOSE(
590625
1, "This library is a custom library. Opening globally.\n");
591-
mmd_library = my_dlopen_global(library_name, &error_msg);
592-
if (!mmd_library) {
626+
dl_wrapper.mmd_libs.back() = my_dlopen_global(library_name, &error_msg);
627+
if (!dl_wrapper.mmd_libs.back()) {
628+
dl_wrapper.pop_back();
593629
std::cout << "Error: Could not load custom library " << library_name;
594630
if (error_msg && error_msg[0] != '\0') {
595631
std::cout << " (error_msg: " << error_msg << ")";
@@ -600,9 +636,9 @@ cl_bool l_load_single_board_library(const char *library_name,
600636
#endif
601637
} else {
602638
if (load_libraries) {
603-
auto result =
604-
l_load_board_functions(&(internal_mmd_dispatch[num_boards_found]),
605-
library_name, mmd_library, error_msg);
639+
auto result = l_load_board_functions(
640+
&(internal_mmd_dispatch[num_boards_found]), library_name,
641+
dl_wrapper.mmd_libs.back(), error_msg);
606642
if (result == CL_FALSE) {
607643
std::cout << "Error: Could not load board library " << library_name
608644
<< " due to failure to load symbols\n";
@@ -1155,9 +1191,10 @@ static acl_mmd_dispatch_t *get_msim_mmd_layer() {
11551191
ipa_simulator ? mmd_lib_name_ipa : mmd_lib_name_aoc;
11561192

11571193
char *error_msg = nullptr;
1158-
auto *mmd_lib = my_dlopen(mmd_lib_name, &error_msg);
1194+
dl_wrapper.mmd_libs.push_back(my_dlopen(mmd_lib_name, &error_msg));
11591195
typedef acl_mmd_dispatch_t *(*fcn_type)();
1160-
if (!mmd_lib) {
1196+
if (!dl_wrapper.mmd_libs.back()) {
1197+
dl_wrapper.pop_back();
11611198
std::cout << "Error: Could not load simulation MMD library "
11621199
<< mmd_lib_name;
11631200
if (error_msg && error_msg[0] != '\0') {
@@ -1166,8 +1203,9 @@ static acl_mmd_dispatch_t *get_msim_mmd_layer() {
11661203
std::cout << "\n";
11671204
return nullptr;
11681205
}
1169-
auto *sym = my_dlsym(mmd_lib, sym_name, &error_msg);
1206+
auto *sym = my_dlsym(dl_wrapper.mmd_libs.back(), sym_name, &error_msg);
11701207
if (!sym) {
1208+
dl_wrapper.pop_back();
11711209
std::cout << "Error: Symbol " << sym_name
11721210
<< " not found in simulation MMD library ";
11731211
if (error_msg && error_msg[0] != '\0') {

0 commit comments

Comments
 (0)