From a5c0031ec4ac648261553128894e157ee41889cb Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 23 May 2019 20:22:44 +0200 Subject: Correctly process and indicate error from LoadLibraryExA() function Function save_err_str() checks for error by GetLastError() call. Calling EnumProcessModules() may change or reset it. So call save_err_str() immediately after LoadLibraryExA(). --- dlfcn.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/dlfcn.c b/dlfcn.c index 993808d..c97a870 100644 --- a/dlfcn.c +++ b/dlfcn.c @@ -267,24 +267,33 @@ void *dlopen( const char *file, int mode ) hModule = LoadLibraryExA(lpFileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ); - if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 ) - dwProcModsAfter = 0; - - /* If the object was loaded with RTLD_LOCAL, add it to list of local - * objects, so that its symbols cannot be retrieved even if the handle for - * the original program file is passed. POSIX says that if the same - * file is specified in multiple invocations, and any of them are - * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the - * symbols will remain global. If number of loaded modules was not - * changed after calling LoadLibraryEx(), it means that library was - * already loaded. - */ if( !hModule ) + { save_err_str( lpFileName ); - else if( (mode & RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter ) - local_add( hModule ); - else if( !(mode & RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter ) - local_rem( hModule ); + } + else + { + if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 ) + dwProcModsAfter = 0; + + /* If the object was loaded with RTLD_LOCAL, add it to list of local + * objects, so that its symbols cannot be retrieved even if the handle for + * the original program file is passed. POSIX says that if the same + * file is specified in multiple invocations, and any of them are + * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the + * symbols will remain global. If number of loaded modules was not + * changed after calling LoadLibraryEx(), it means that library was + * already loaded. + */ + if( (mode & RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter ) + { + local_add( hModule ); + } + else if( !(mode & RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter ) + { + local_rem( hModule ); + } + } } /* Return to previous state of the error-mode bit flags. */ -- cgit v1.2.3-55-g6feb