Skip to content

Commit 4fbcebc

Browse files
committed
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 71d527e commit 4fbcebc

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

include/acl_hal_mmd.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,38 @@ typedef struct {
151151
int handle, const std::string &signal_name, unsigned int &finish_counter);
152152
} acl_mmd_dispatch_t;
153153

154+
// Helper function needed for dl libraries wrapper
155+
void *my_dlopen(const char *library_name, char **error_msg);
156+
void *my_dlsym(void *library, const char *function_name, char **error_msg);
157+
158+
// Wrapper for dl libraries
159+
struct dl_wrapper_t {
160+
void *mmd_lib;
161+
dl_wrapper_t(const char *library_name, char **error_msg) {
162+
this->mmd_lib = my_dlopen(library_name, error_msg);
163+
}
164+
~dl_wrapper_t() {
165+
if (this->mmd_lib) {
166+
#ifdef _WIN32
167+
FreeLibrary((HMODULE)this->mmd_lib);
168+
#else
169+
dlclose(this->mmd_lib);
170+
#endif
171+
}
172+
}
173+
// prohibit copying to avoid double-close of handle
174+
dl_wrapper_t(const dl_wrapper_t &) = delete;
175+
dl_wrapper_t &operator=(const dl_wrapper_t &) = delete;
176+
177+
// enable move for vector operations
178+
dl_wrapper_t(dl_wrapper_t &&) noexcept {};
179+
180+
// return symbol
181+
void *sym(const char *function_name, char **error_msg) {
182+
return my_dlsym(this->mmd_lib, function_name, error_msg);
183+
}
184+
};
185+
154186
typedef struct {
155187
int handle;
156188
std::string name;

src/acl_hal_mmd.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ const static size_t MIN_SOF_SIZE = 1;
189189
const static size_t MIN_PLL_CONFIG_SIZE = 1;
190190

191191
std::vector<acl_mmd_dispatch_t> internal_mmd_dispatch;
192+
std::vector<dl_wrapper_t> dl_wrapper_list;
192193

193194
// Dynamically load board mmd & symbols
194195
static size_t num_board_pkgs;
@@ -568,8 +569,9 @@ cl_bool l_load_single_board_library(const char *library_name,
568569
return CL_FALSE;
569570
}
570571
#endif
571-
auto *mmd_library = my_dlopen(library_name, &error_msg);
572-
if (!mmd_library) {
572+
dl_wrapper_list.emplace_back(library_name, &error_msg);
573+
if (!dl_wrapper_list.back().mmd_lib) {
574+
dl_wrapper_list.pop_back();
573575
std::cout << "Error: Could not load board library " << library_name;
574576
if (error_msg && error_msg[0] != '\0') {
575577
std::cout << " (error_msg: " << error_msg << ")";
@@ -579,17 +581,18 @@ cl_bool l_load_single_board_library(const char *library_name,
579581
}
580582

581583
auto *test_symbol =
582-
my_dlsym(mmd_library, "aocl_mmd_get_offline_info", &error_msg);
584+
dl_wrapper_list.back().sym("aocl_mmd_get_offline_info", &error_msg);
583585
if (!test_symbol) {
584586
// On Linux, for custom libraries close the library (which was opened
585587
// locally) and then reopen globally. For Windows, there is no option (i.e.
586588
// it is always global)
587589
#ifdef __linux__
588-
my_dlclose(mmd_library);
590+
my_dlclose(dl_wrapper_list.back().mmd_lib);
589591
ACL_HAL_DEBUG_MSG_VERBOSE(
590592
1, "This library is a custom library. Opening globally.\n");
591-
mmd_library = my_dlopen_global(library_name, &error_msg);
592-
if (!mmd_library) {
593+
dl_wrapper_list.back().mmd_lib = my_dlopen_global(library_name, &error_msg);
594+
if (!dl_wrapper_list.back().mmd_lib) {
595+
dl_wrapper_list.pop_back();
593596
std::cout << "Error: Could not load custom library " << library_name;
594597
if (error_msg && error_msg[0] != '\0') {
595598
std::cout << " (error_msg: " << error_msg << ")";
@@ -600,9 +603,9 @@ cl_bool l_load_single_board_library(const char *library_name,
600603
#endif
601604
} else {
602605
if (load_libraries) {
603-
auto result =
604-
l_load_board_functions(&(internal_mmd_dispatch[num_boards_found]),
605-
library_name, mmd_library, error_msg);
606+
auto result = l_load_board_functions(
607+
&(internal_mmd_dispatch[num_boards_found]), library_name,
608+
dl_wrapper_list.back().mmd_lib, error_msg);
606609
if (result == CL_FALSE) {
607610
std::cout << "Error: Could not load board library " << library_name
608611
<< " due to failure to load symbols\n";
@@ -611,7 +614,7 @@ cl_bool l_load_single_board_library(const char *library_name,
611614
}
612615
++num_boards_found;
613616
}
614-
617+
615618
return CL_TRUE;
616619
}
617620

@@ -855,6 +858,7 @@ cl_bool l_load_board_libraries(cl_bool load_libraries) {
855858
}
856859
fin.close();
857860
}
861+
closedir(dir);
858862
}
859863

860864
if (num_vendor_files_found == 0) {
@@ -876,8 +880,6 @@ cl_bool l_load_board_libraries(cl_bool load_libraries) {
876880
}
877881
}
878882

879-
if (dir)
880-
closedir(dir);
881883
return num_boards_found == 0 ? CL_FALSE : CL_TRUE;
882884
}
883885
#endif
@@ -1156,9 +1158,10 @@ static acl_mmd_dispatch_t *get_msim_mmd_layer() {
11561158
ipa_simulator ? mmd_lib_name_ipa : mmd_lib_name_aoc;
11571159

11581160
char *error_msg = nullptr;
1159-
auto *mmd_lib = my_dlopen(mmd_lib_name, &error_msg);
1161+
dl_wrapper_list.emplace_back(mmd_lib_name, &error_msg);
11601162
typedef acl_mmd_dispatch_t *(*fcn_type)();
1161-
if (!mmd_lib) {
1163+
if (!dl_wrapper_list.back().mmd_lib) {
1164+
dl_wrapper_list.pop_back();
11621165
std::cout << "Error: Could not load simulation MMD library "
11631166
<< mmd_lib_name;
11641167
if (error_msg && error_msg[0] != '\0') {
@@ -1167,8 +1170,9 @@ static acl_mmd_dispatch_t *get_msim_mmd_layer() {
11671170
std::cout << "\n";
11681171
return nullptr;
11691172
}
1170-
auto *sym = my_dlsym(mmd_lib, sym_name, &error_msg);
1173+
auto *sym = dl_wrapper_list.back().sym(sym_name, &error_msg);
11711174
if (!sym) {
1175+
dl_wrapper_list.pop_back();
11721176
std::cout << "Error: Symbol " << sym_name
11731177
<< " not found in simulation MMD library ";
11741178
if (error_msg && error_msg[0] != '\0') {

0 commit comments

Comments
 (0)