OSDN Git Service

* loadlib.h: New header implementing safe LoadLibrary calls.
authorcorinna <corinna>
Sat, 28 Aug 2010 11:22:37 +0000 (11:22 +0000)
committercorinna <corinna>
Sat, 28 Aug 2010 11:22:37 +0000 (11:22 +0000)
Include throughout files using LoadLibrary function.
* cygcheck.cc (dump_sysinfo): Retrieve kernel32.dll handle via
GetModuleHandle, rather than using LoadLibrary.
* cygpath.cc (get_long_name): Ditto.
(do_sysfolders): Append .dll suffix in LoadLibrary call.
* ldh.cc (WinMain): Use LoadLibraryExW with DONT_RESOLVE_DLL_REFERENCES
to avoid loading malicious library code.
* locale.cc (print_locale_with_codeset): Change way to retrieve
kernel32.dll path.

13 files changed:
winsup/utils/ChangeLog
winsup/utils/cygcheck.cc
winsup/utils/cygpath.cc
winsup/utils/ldh.cc
winsup/utils/loadlib.h [new file with mode: 0644]
winsup/utils/locale.cc
winsup/utils/mkgroup.c
winsup/utils/mkpasswd.c
winsup/utils/module_info.cc
winsup/utils/path.cc
winsup/utils/ps.cc
winsup/utils/regtool.cc
winsup/utils/strace.cc

index 507ddd3..df6e183 100644 (file)
@@ -1,3 +1,16 @@
+2010-08-28  Corinna Vinschen  <corinna@vinschen.de>
+
+       * loadlib.h: New header implementing safe LoadLibrary calls.
+       Include throughout files using LoadLibrary function.
+       * cygcheck.cc (dump_sysinfo): Retrieve kernel32.dll handle via
+       GetModuleHandle, rather than using LoadLibrary.
+       * cygpath.cc (get_long_name): Ditto.
+       (do_sysfolders): Append .dll suffix in LoadLibrary call.
+       * ldh.cc (WinMain): Use LoadLibraryExW with DONT_RESOLVE_DLL_REFERENCES
+       to avoid loading malicious library code.
+       * locale.cc (print_locale_with_codeset): Change way to retrieve
+       kernel32.dll path.
+
 2010-08-26  Corinna Vinschen  <corinna@vinschen.de>
 
        * cygpath.cc (get_device_name): Prefer the \\.\X: DOS device for
index 5b15cdf..9eb8c56 100644 (file)
@@ -1,7 +1,7 @@
 /* cygcheck.cc
 
    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Red Hat, Inc.
+   2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
 
    This file is part of Cygwin.
 
@@ -26,6 +26,7 @@
 #include "cygwin/include/mntent.h"
 #include "cygwin/cygprops.h"
 #undef cygwin_internal
+#include "loadlib.h"
 
 #define alloca __builtin_alloca
 
@@ -1409,7 +1410,7 @@ dump_sysinfo ()
        display_error ("dump_sysinfo: GetVersionEx()");
     }
 
-  HMODULE k32 = LoadLibrary ("kernel32.dll");
+  HMODULE k32 = GetModuleHandleW (L"kernel32.dll");
 
   switch (osversion.dwPlatformId)
     {
@@ -1838,8 +1839,6 @@ dump_sysinfo ()
              name);
     }
 
-  if (!FreeLibrary (k32))
-    display_error ("dump_sysinfo: FreeLibrary()");
   SetErrorMode (prev_mode);
   if (givehelp)
     {
index 449c543..63606a9 100644 (file)
@@ -28,6 +28,7 @@ details. */
 #include <ddk/winddk.h>
 #include <ddk/ntifs.h>
 #include "wide_path.h"
+#include "loadlib.h"
 
 static const char version[] = "$Revision$";
 
@@ -452,7 +453,7 @@ get_long_name (const char *filename, DWORD& len)
 {
   char *sbuf;
   wchar_t buf[32768];
-  static HINSTANCE k32 = LoadLibrary ("kernel32.dll");
+  static HINSTANCE k32 = GetModuleHandleW (L"kernel32.dll");
   static DWORD (WINAPI *GetLongPathName) (LPCWSTR, LPWSTR, DWORD) =
     (DWORD (WINAPI *) (LPCWSTR, LPWSTR, DWORD)) GetProcAddress (k32, "GetLongPathNameW");
   if (!GetLongPathName)
@@ -610,7 +611,7 @@ do_sysfolders (char option)
       break;
 
     case 'H':
-      k32 = LoadLibrary ("userenv");
+      k32 = LoadLibrary ("userenv.dll");
       if (k32)
        GetProfilesDirectoryAPtrW = (BOOL (*) (LPWSTR, LPDWORD))
          GetProcAddress (k32, "GetProfilesDirectoryW");
index 7bea569..db0449f 100644 (file)
@@ -11,7 +11,7 @@ WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
        cmd += 4;
        break;
       }
-  if (!*cmd || !LoadLibraryW (cmd))
+  if (!*cmd || !LoadLibraryExW (cmd, NULL, DONT_RESOLVE_DLL_REFERENCES))
     ExitProcess (0x0100);
   ExitProcess (0x0000);
 }
diff --git a/winsup/utils/loadlib.h b/winsup/utils/loadlib.h
new file mode 100644 (file)
index 0000000..405b4b2
--- /dev/null
@@ -0,0 +1,59 @@
+/* loadlib.h
+
+   Copyright 2010 Red Hat, Inc.
+
+   This file is part of Cygwin.
+
+   This software is a copyrighted work licensed under the terms of the
+   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
+   details. */
+
+#ifndef _LOADLIB_H
+#define _LOADLIB_H
+
+#include <windows.h>
+#include <wchar.h>
+
+/* Load all system libs from the windows system directory by prepending the
+   full path.  This doesn't work for loadling cygwin1.dll.  For this case,
+   instead of prepending the path, make sure that the CWD is removed from
+   the DLL search path, if possible (XP SP1++, Vista++). */
+static HMODULE
+_load_sys_library (const wchar_t *dll)
+{
+  static BOOL (*set_dll_directory)(LPCWSTR);
+  static WCHAR sysdir[MAX_PATH];
+  static UINT sysdir_len;
+
+  WCHAR dllpath[MAX_PATH];
+
+  if (!sysdir_len)
+    {
+      sysdir_len = GetSystemDirectoryW (sysdir, MAX_PATH);
+      sysdir[sysdir_len++] = L'\\';
+      sysdir[sysdir_len] = L'\0';
+    }
+  if (!set_dll_directory)
+    {
+      HMODULE k32 = GetModuleHandleW (L"kernel32.dll");
+      if (k32)
+       set_dll_directory = (BOOL (*)(LPCWSTR))
+                    GetProcAddress (k32, "SetDllDirectoryW");
+      if (!set_dll_directory)
+       set_dll_directory = (BOOL (*)(LPCWSTR)) -1;
+      else
+       set_dll_directory (L"");
+    }
+
+  if (wcscmp (dll, L"cygwin1.dll") == 0)
+    return LoadLibraryExW (L"cygwin1.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+    
+  wcscpy (dllpath, sysdir);
+  wcscpy (dllpath + sysdir_len, dll);
+  return LoadLibraryExW (dllpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+}
+
+#define LoadLibraryW(d)        _load_sys_library(d)
+#define LoadLibraryA(d)        _load_sys_library(L##d)
+
+#endif /* _LOADLIB_H */
index 8dbfd9b..d6d1064 100644 (file)
@@ -126,9 +126,10 @@ print_locale_with_codeset (int verbose, loc_t *locale, bool utf8,
   if (!sysroot)
     {
       char sysbuf[PATH_MAX];
-      stpcpy (stpcpy (sysbuf, getenv ("SYSTEMROOT")),
-             "\\system32\\kernel32.dll");
-      sysroot = (const char *) cygwin_create_path (CCP_WIN_A_TO_POSIX, sysbuf);
+      HMODULE k32 = GetModuleHandleW (L"kernel32.dll");
+      if (GetModuleFileName (k32, sysbuf, PATH_MAX))
+       sysroot = (const char *) cygwin_create_path (CCP_WIN_A_TO_POSIX,
+                                                    sysbuf);
       if (!sysroot)
        sysroot = "kernel32.dll";
     }
index 19b679e..12fe7b9 100644 (file)
@@ -1,7 +1,7 @@
 /* mkgroup.c:
 
    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2007, 2008, 2009 Red Hat, Inc.
+   2007, 2008, 2009, 2010 Red Hat, Inc.
 
    This file is part of Cygwin.
 
@@ -28,6 +28,7 @@
 #include <ntsecapi.h>
 #include <dsgetdc.h>
 #include <ntdef.h>
+#include "loadlib.h"
 
 #define print_win_error(x) _print_win_error(x, __LINE__)
 
index 36c4622..9b0d362 100644 (file)
@@ -1,7 +1,7 @@
 /* mkpasswd.c:
 
    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
-   2008, 2009 Red Hat, Inc.
+   2008, 2009, 2010 Red Hat, Inc.
 
    This file is part of Cygwin.
 
@@ -28,6 +28,7 @@
 #include <ntsecapi.h>
 #include <dsgetdc.h>
 #include <ntdef.h>
+#include "loadlib.h"
 
 #define print_win_error(x) _print_win_error(x, __LINE__)
 
index c0e7079..1522b50 100644 (file)
@@ -1,6 +1,6 @@
 /* module_info.cc
 
-   Copyright 1999,2000,2001 Red Hat, Inc.
+   Copyright 1999,2000,2001,2010 Red Hat, Inc.
 
    Written by Egor Duda <deo@logos-m.ru>
 
@@ -13,6 +13,7 @@ details. */
 #include <stdlib.h>
 #include <windows.h>
 #include <psapi.h>
+#include "loadlib.h"
 
 static int psapi_loaded = 0;
 static HMODULE psapi_module_handle = NULL;
index da40b34..8178eb4 100644 (file)
@@ -29,6 +29,7 @@ details. */
 #ifdef FSTAB_ONLY
 #include <sys/cygwin.h>
 #endif
+#include "loadlib.h"
 
 #ifndef FSTAB_ONLY
 /* Used when treating / and \ as equivalent. */
index 0b317d2..30152eb 100644 (file)
@@ -1,7 +1,7 @@
 /* ps.cc
 
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2008, 2009 Red Hat, Inc.
+   2008, 2009, 2010 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -23,6 +23,7 @@ details. */
 #include <psapi.h>
 #include <ddk/ntapi.h>
 #include <ddk/winddk.h>
+#include "loadlib.h"
 
 /* Maximum possible path length under NT.  There's no official define
    for that value.  Note that PATH_MAX is only 4K. */
index d8a492c..c51479d 100644 (file)
@@ -1,7 +1,7 @@
 /* regtool.cc
 
    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009 Red Hat Inc.
+   2009, 2010 Red Hat Inc.
 
 This file is part of Cygwin.
 
@@ -19,6 +19,7 @@ details. */
 #define WINVER 0x0502
 #include <windows.h>
 #include <sys/cygwin.h>
+#include "loadlib.h"
 
 #define DEFAULT_KEY_SEPARATOR '\\'
 
index 607137e..2eb3b82 100644 (file)
@@ -26,6 +26,7 @@ details. */
 #include "cygwin/include/sys/cygwin.h"
 #include "path.h"
 #undef cygwin_internal
+#include "loadlib.h"
 
 /* we *know* we're being built with GCC */
 #define alloca __builtin_alloca