Specify version.dll and add notification hook for delay load (#24449)
authorElinor Fung <47805090+elinor-fung@users.noreply.github.com>
Wed, 8 May 2019 21:28:45 +0000 (14:28 -0700)
committerGitHub <noreply@github.com>
Wed, 8 May 2019 21:28:45 +0000 (14:28 -0700)
Mitigates an issue with hijacking of version.dll.
This is particularly an issue for self-contained and single-file-exe apps, as the hijacking in those cases does not require access to a machine-wide .NET Core install.

src/dlls/mscoree/CMakeLists.txt
src/dlls/mscoree/coreclr/CMakeLists.txt
src/dlls/mscoree/delayloadhook.cpp [new file with mode: 0644]

index 8fc3ebf..36f6c98 100644 (file)
@@ -12,6 +12,7 @@ set(CLR_SOURCES
 if(WIN32)
 list(APPEND CLR_SOURCES
     comcallunmarshal.cpp
+    delayloadhook.cpp
     Native.rc
 )
 
index a04ef21..fd7853c 100644 (file)
@@ -15,6 +15,9 @@ if (WIN32)
     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DELAYLOAD:api-ms-win-core-winrt-roparameterizediid-l1-1-0.dll")
     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DELAYLOAD:api-ms-win-ro-typeresolution-l1-1-0.dll")
 
+    # Delay load version.dll so that we can specify how to search when loading it as it is not part of Windows' known DLLs
+    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DELAYLOAD:version.dll")
+
     # No library groups for Win32
     set(START_LIBRARY_GROUP)
     set(END_LIBRARY_GROUP)
diff --git a/src/dlls/mscoree/delayloadhook.cpp b/src/dlls/mscoree/delayloadhook.cpp
new file mode 100644 (file)
index 0000000..2c9051e
--- /dev/null
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+// File: delayloadhook.cpp
+//
+
+#include "stdafx.h"
+
+#include <delayimp.h>
+
+FARPROC WINAPI secureDelayHook(unsigned dliNotify, PDelayLoadInfo pdli)
+{
+    if (dliNotify == dliNotePreLoadLibrary)
+    {
+        // Use a safe search path to avoid delay load dll hijacking
+        return (FARPROC)::LoadLibraryExA(pdli->szDll, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+    }
+
+    return nullptr;
+}
+
+// See https://docs.microsoft.com/en-us/cpp/build/reference/notification-hooks
+// This global hook is called prior to all the delay load LoadLibrary/GetProcAddress/etc. calls
+// Hooking this callback allows us to ensure that delay load LoadLibrary calls 
+// specify the LOAD_LIBRARY_SEARCH_SYSTEM32 search path
+const PfnDliHook __pfnDliNotifyHook2 = secureDelayHook;
\ No newline at end of file