Skip to content

Commit

Permalink
Don't use incompatible LOAD_LIBRARY_SEARCH flags when using LOAD_WITH…
Browse files Browse the repository at this point in the history
…_ALTERED_SEARCH_PATH
  • Loading branch information
elinor-fung committed Jan 30, 2025
1 parent ca8698d commit d86cd4d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ internal static IntPtr LoadBySearch(Assembly callingAssembly, bool searchAssembl
IntPtr ret;

int loadWithAlteredPathFlags = LoadWithAlteredSearchPathFlag;
const int loadLibrarySearchFlags = (int)DllImportSearchPath.UseDllDirectoryForDependencies
| (int)DllImportSearchPath.ApplicationDirectory
| (int)DllImportSearchPath.UserDirectories
| (int)DllImportSearchPath.System32
| (int)DllImportSearchPath.SafeDirectories;
bool libNameIsRelativePath = !Path.IsPathFullyQualified(libraryName);

// P/Invokes are often declared with variations on the actual library name.
Expand All @@ -80,14 +85,8 @@ internal static IntPtr LoadBySearch(Assembly callingAssembly, bool searchAssembl

if (!libNameIsRelativePath)
{
int flags = loadWithAlteredPathFlags;
if ((dllImportSearchPathFlags & (int)DllImportSearchPath.UseDllDirectoryForDependencies) != 0)
{
// LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR is the only flag affecting absolute path. Don't OR the flags
// unconditionally as all absolute path P/Invokes could then lose LOAD_WITH_ALTERED_SEARCH_PATH.
flags |= dllImportSearchPathFlags;
}

// LOAD_WITH_ALTERED_SEARCH_PATH is incompatible with LOAD_LIBRARY_SEARCH flags. Remove those flags if they are set.
int flags = loadWithAlteredPathFlags | (dllImportSearchPathFlags & ~loadLibrarySearchFlags);
ret = LoadLibraryHelper(currLibNameVariation, flags, ref errorTracker);
if (ret != IntPtr.Zero)
{
Expand All @@ -96,9 +95,12 @@ internal static IntPtr LoadBySearch(Assembly callingAssembly, bool searchAssembl
}
else if ((callingAssembly != null) && searchAssemblyDirectory)
{
// LOAD_WITH_ALTERED_SEARCH_PATH is incompatible with LOAD_LIBRARY_SEARCH flags. Remove those flags if they are set.
int flags = loadWithAlteredPathFlags | (dllImportSearchPathFlags & ~loadLibrarySearchFlags);

// Try to load the module alongside the assembly where the PInvoke was declared.
// For PInvokes where the DllImportSearchPath.AssemblyDirectory is specified, look next to the application.
ret = LoadLibraryHelper(Path.Combine(AppContext.BaseDirectory, currLibNameVariation), loadWithAlteredPathFlags | dllImportSearchPathFlags, ref errorTracker);
ret = LoadLibraryHelper(Path.Combine(AppContext.BaseDirectory, currLibNameVariation), flags, ref errorTracker);
if (ret != IntPtr.Zero)
{
return ret;
Expand Down
23 changes: 14 additions & 9 deletions src/coreclr/vm/nativelibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ namespace
NATIVE_LIBRARY_HANDLE hmod = NULL;

SString path{ pAssembly->GetPEAssembly()->GetPath() };
_ASSERTE(!Path::IsRelative(path));

SString::Iterator lastPathSeparatorIter = path.End();
if (PEAssembly::FindLastPathSeparator(path, lastPathSeparatorIter))
Expand Down Expand Up @@ -656,6 +657,14 @@ namespace

AppDomain* pDomain = GetAppDomain();
DWORD loadWithAlteredPathFlags = GetLoadWithAlteredSearchPathFlag();
DWORD loadLibrarySearchFlags = 0;
#ifdef TARGET_WINDOWS
loadLibrarySearchFlags = LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
| LOAD_LIBRARY_SEARCH_APPLICATION_DIR
| LOAD_LIBRARY_SEARCH_USER_DIRS
| LOAD_LIBRARY_SEARCH_SYSTEM32
| LOAD_LIBRARY_SEARCH_DEFAULT_DIRS;
#endif
bool libNameIsRelativePath = Path::IsRelative(wszLibName);

// P/Invokes are often declared with variations on the actual library name.
Expand Down Expand Up @@ -689,14 +698,8 @@ namespace

if (!libNameIsRelativePath)
{
DWORD flags = loadWithAlteredPathFlags;
if ((dllImportSearchPathFlags & LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR) != 0)
{
// LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR is the only flag affecting absolute path. Don't OR the flags
// unconditionally as all absolute path P/Invokes could then lose LOAD_WITH_ALTERED_SEARCH_PATH.
flags |= dllImportSearchPathFlags;
}

// LOAD_WITH_ALTERED_SEARCH_PATH is incompatible with LOAD_LIBRARY_SEARCH flags. Remove those flags if they are set.
DWORD flags = loadWithAlteredPathFlags | (dllImportSearchPathFlags & ~loadLibrarySearchFlags);
hmod = LocalLoadLibraryHelper(currLibNameVariation, flags, pErrorTracker);
if (hmod != NULL)
{
Expand All @@ -705,7 +708,9 @@ namespace
}
else if ((callingAssembly != nullptr) && searchAssemblyDirectory)
{
hmod = LoadFromPInvokeAssemblyDirectory(callingAssembly, currLibNameVariation, loadWithAlteredPathFlags | dllImportSearchPathFlags, pErrorTracker);
// LOAD_WITH_ALTERED_SEARCH_PATH is incompatible with LOAD_LIBRARY_SEARCH flags. Remove those flags if they are set.
DWORD flags = loadWithAlteredPathFlags | (dllImportSearchPathFlags & ~loadLibrarySearchFlags);
hmod = LoadFromPInvokeAssemblyDirectory(callingAssembly, currLibNameVariation, flags, pErrorTracker);
if (hmod != NULL)
{
return hmod;
Expand Down

0 comments on commit d86cd4d

Please sign in to comment.