summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Xu <pengxu@google.com>2017-08-09 23:02:23 -0700
committerPeng Xu <pengxu@google.com>2017-08-10 22:31:50 +0000
commit2fd77c0fea82f6872a188dd63c164a385643e792 (patch)
tree0c0ff82186e44a9acff44e02379d0041100bfe97
parent8d9fa07fe1d5d160e6514e7ecf55157f69b091d8 (diff)
downloadlibhardware-2fd77c0fea82f6872a188dd63c164a385643e792.tar.gz
Fix potential memory leak in multihal
Bug: 64266341 Test: compile and pixel 2017 device sensor operate normally Change-Id: I879379106d038ce28937a28ab5863b4bea615bf0
-rw-r--r--modules/sensors/multihal.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/modules/sensors/multihal.cpp b/modules/sensors/multihal.cpp
index 1cea7aeb..b5360cc8 100644
--- a/modules/sensors/multihal.cpp
+++ b/modules/sensors/multihal.cpp
@@ -49,10 +49,11 @@ static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t data_available_cond = PTHREAD_COND_INITIALIZER;
bool waiting_for_data = false;
-/*
- * Vector of sub modules, whose indexes are referred to in this file as module_index.
- */
-static std::vector<hw_module_t *> *sub_hw_modules = NULL;
+// Vector of sub modules, whose indexes are referred to in this file as module_index.
+static std::vector<hw_module_t *> *sub_hw_modules = nullptr;
+
+// Vector of sub modules shared object handles
+static std::vector<void *> *so_handles = nullptr;
/*
* Comparable class that globally identifies a sensor, by module index and local handle.
@@ -509,11 +510,26 @@ int sensors_poll_context_t::close() {
static int device__close(struct hw_device_t *dev) {
+ pthread_mutex_lock(&init_modules_mutex);
sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
if (ctx != NULL) {
int retval = ctx->close();
delete ctx;
}
+
+ if (sub_hw_modules != nullptr) {
+ delete sub_hw_modules;
+ sub_hw_modules = nullptr;
+ }
+
+ if (so_handles != nullptr) {
+ for (auto handle : *so_handles) {
+ dlclose(handle);
+ }
+ delete so_handles;
+ so_handles = nullptr;
+ }
+ pthread_mutex_unlock(&init_modules_mutex);
return 0;
}
@@ -583,7 +599,9 @@ static bool starts_with(const char* s, const char* prefix) {
* Adds valid paths from the config file to the vector passed in.
* The vector must not be null.
*/
-static void get_so_paths(std::vector<std::string> *so_paths) {
+static std::vector<std::string> get_so_paths() {
+ std::vector<std::string> so_paths;
+
const std::vector<const char *> config_path_list(
{ MULTI_HAL_CONFIG_FILE_PATH, DEPRECATED_MULTI_HAL_CONFIG_FILE_PATH });
@@ -599,7 +617,7 @@ static void get_so_paths(std::vector<std::string> *so_paths) {
}
if(!stream) {
ALOGW("No multihal config file found");
- return;
+ return so_paths;
}
ALOGE_IF(strcmp(path, DEPRECATED_MULTI_HAL_CONFIG_FILE_PATH) == 0,
@@ -611,8 +629,9 @@ static void get_so_paths(std::vector<std::string> *so_paths) {
std::string line;
while (std::getline(stream, line)) {
ALOGV("config file line: '%s'", line.c_str());
- so_paths->push_back(line);
+ so_paths.push_back(line);
}
+ return so_paths;
}
/*
@@ -625,15 +644,15 @@ static void lazy_init_modules() {
pthread_mutex_unlock(&init_modules_mutex);
return;
}
- std::vector<std::string> *so_paths = new std::vector<std::string>();
- get_so_paths(so_paths);
+ std::vector<std::string> so_paths(get_so_paths());
// dlopen the module files and cache their module symbols in sub_hw_modules
sub_hw_modules = new std::vector<hw_module_t *>();
+ so_handles = new std::vector<void *>();
dlerror(); // clear any old errors
const char* sym = HAL_MODULE_INFO_SYM_AS_STR;
- for (std::vector<std::string>::iterator it = so_paths->begin(); it != so_paths->end(); it++) {
- const char* path = it->c_str();
+ for (const auto &s : so_paths) {
+ const char* path = s.c_str();
void* lib_handle = dlopen(path, RTLD_LAZY);
if (lib_handle == NULL) {
ALOGW("dlerror(): %s", dlerror());
@@ -651,8 +670,13 @@ static void lazy_init_modules() {
} else {
ALOGV("Loaded symbols from \"%s\"", sym);
sub_hw_modules->push_back(module);
+ so_handles->push_back(lib_handle);
+ lib_handle = nullptr;
}
}
+ if (lib_handle != nullptr) {
+ dlclose(lib_handle);
+ }
}
pthread_mutex_unlock(&init_modules_mutex);
}