]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Lock down the search path for Windows DLL loading.
authorSimon Tatham <anakin@pobox.com>
Mon, 18 Jul 2016 19:02:32 +0000 (20:02 +0100)
committerSimon Tatham <anakin@pobox.com>
Mon, 18 Jul 2016 19:02:32 +0000 (20:02 +0100)
At least on systems providing SetDefaultDllDirectories, this should
stop PuTTY from being willing to load DLLs from its containing
directory - which makes no difference when it's been properly
installed (in which case the application dir contains no DLLs anyway),
but does if it's being run from somewhere uncontrolled like a browser
downloads directory.

Preliminary testing suggests that this shouldn't break any existing
deliberate use of DLLs, including GSSAPI providers.

windows/window.c
windows/winmisc.c
windows/winpgen.c
windows/winpgnt.c
windows/winplink.c
windows/winsftp.c
windows/winstuff.h

index 290e6a31cf513da6803b294c61b8e58f09e69d89..115464105d8e9fea88cfc9253a2c05c5b151b5e1 100644 (file)
@@ -347,6 +347,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     HRESULT hr;
     int guess_width, guess_height;
 
+    dll_hijacking_protection();
+
     hinst = inst;
     hwnd = NULL;
     flags = FLAG_VERBOSE | FLAG_INTERACTIVE;
index f2e4f223595b4b73d642df1648223f282583d85a..11e2ca0f7d1353b46db523ca2d66f48b8ba85ad6 100644 (file)
@@ -149,6 +149,38 @@ char *get_username(void)
     return got_username ? user : NULL;
 }
 
+void dll_hijacking_protection(void)
+{
+    /*
+     * If the OS provides it, call SetDefaultDllDirectories() to
+     * prevent DLLs from being loaded from the directory containing
+     * our own binary, and instead only load from system32.
+     *
+     * This is a protection against hijacking attacks, if someone runs
+     * PuTTY directly from their web browser's download directory
+     * having previously been enticed into clicking on an unwise link
+     * that downloaded a malicious DLL to the same directory under one
+     * of various magic names that seem to be things that standard
+     * Windows DLLs delegate to.
+     *
+     * It shouldn't break deliberate loading of user-provided DLLs
+     * such as GSSAPI providers, because those are specified by their
+     * full pathname by the user-provided configuration.
+     */
+    static HMODULE kernel32_module;
+    DECL_WINDOWS_FUNCTION(static, BOOL, SetDefaultDllDirectories, (DWORD));
+
+    if (!kernel32_module) {
+        kernel32_module = load_system32_dll("kernel32.dll");
+        GET_WINDOWS_FUNCTION(kernel32_module, SetDefaultDllDirectories);
+    }
+
+    if (p_SetDefaultDllDirectories) {
+        /* LOAD_LIBRARY_SEARCH_SYSTEM32 only */
+        p_SetDefaultDllDirectories(0x800);
+    }
+}
+
 BOOL init_winver(void)
 {
     ZeroMemory(&osVersion, sizeof(osVersion));
index 98319608c3ca1f562b57c95fa83b9e276e9c754d..8468f805b4d7fef9d822410e5e02f979c41b61c0 100644 (file)
@@ -1519,6 +1519,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     char **argv;
     int ret;
 
+    dll_hijacking_protection();
+
     InitCommonControls();
     hinst = inst;
     hwnd = NULL;
index 86998a2bb49127c90e04ce8ce75c435335a23d5f..06c5fac15d8316a92a475852033d88ed0e30c4c8 100644 (file)
@@ -1072,6 +1072,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
     int argc, i;
     char **argv, **argstart;
 
+    dll_hijacking_protection();
+
     hinst = inst;
     hwnd = NULL;
 
index 99e269fdc106687e7edff5c51fb778ee22d545b7..3b20a0ab36de378124a46b1e6cfdc28339704a06 100644 (file)
@@ -312,6 +312,8 @@ int main(int argc, char **argv)
     int just_test_share_exists = FALSE;
     unsigned long now, next, then;
 
+    dll_hijacking_protection();
+
     sklist = NULL;
     skcount = sksize = 0;
     /*
index c786f7a65d686d65d165391674e878ed42fd7e91..7b08970f62ca3e16c54f2a1b02742e4042c9057f 100644 (file)
@@ -773,6 +773,8 @@ int main(int argc, char *argv[])
 {
     int ret;
 
+    dll_hijacking_protection();
+
     ret = psftp_main(argc, argv);
 
     return ret;
index 4f2b4e887184b50dd766ca55178662c57a50aa51..c57ce6ea9d73debbb5a1857279f0785e9f68ea6b 100644 (file)
@@ -478,6 +478,7 @@ void show_help(HWND hwnd);
  * Exports from winmisc.c.
  */
 extern OSVERSIONINFO osVersion;
+void dll_hijacking_protection(void);
 BOOL init_winver(void);
 HMODULE load_system32_dll(const char *libname);
 const char *win_strerror(int error);