Use atomic flag to prevent any recursion during dlopen. Refs #1120

This commit is contained in:
baldurk
2018-10-08 10:52:42 +01:00
parent b39c59f612
commit b39fa104cc
+12
View File
@@ -45,6 +45,8 @@ void plthook_lib(void *handle);
typedef void *(*DLOPENPROC)(const char *, int);
DLOPENPROC realdlopen = NULL;
static volatile int32_t tlsbusyflag = 0;
__attribute__((visibility("default"))) void *dlopen(const char *filename, int flag)
{
if(!realdlopen)
@@ -59,7 +61,10 @@ __attribute__((visibility("default"))) void *dlopen(const char *filename, int fl
return ret;
}
// don't do any hook processing inside here even if we call dlopen again
Atomic::Inc32(&tlsbusyflag);
void *ret = realdlopen(filename, flag);
Atomic::Dec32(&tlsbusyflag);
if(filename && ret)
{
@@ -85,6 +90,10 @@ void plthook_lib(void *handle)
static void CheckLoadedLibraries()
{
// don't process anything if the busy flag was set, otherwise set it ourselves
if(Atomic::CmpExch32(&tlsbusyflag, 0, 1) != 0)
return;
// iterate over the libraries and see which ones are already loaded, process function hooks for
// them and call callbacks.
for(auto it = libraryHooks.begin(); it != libraryHooks.end(); ++it)
@@ -110,6 +119,9 @@ static void CheckLoadedLibraries()
cb(handle);
}
}
// decrement the flag counter
Atomic::Dec32(&tlsbusyflag);
}
void *intercept_dlopen(const char *filename, int flag, void *ret)