* 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.
This commit is contained in:
Corinna Vinschen 2010-08-28 11:22:37 +00:00
parent 893a8b78fc
commit 71d8f118da
13 changed files with 95 additions and 15 deletions

View 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> 2010-08-26 Corinna Vinschen <corinna@vinschen.de>
* cygpath.cc (get_device_name): Prefer the \\.\X: DOS device for * cygpath.cc (get_device_name): Prefer the \\.\X: DOS device for

View File

@ -1,7 +1,7 @@
/* cygcheck.cc /* cygcheck.cc
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 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. This file is part of Cygwin.
@ -26,6 +26,7 @@
#include "cygwin/include/mntent.h" #include "cygwin/include/mntent.h"
#include "cygwin/cygprops.h" #include "cygwin/cygprops.h"
#undef cygwin_internal #undef cygwin_internal
#include "loadlib.h"
#define alloca __builtin_alloca #define alloca __builtin_alloca
@ -1409,7 +1410,7 @@ dump_sysinfo ()
display_error ("dump_sysinfo: GetVersionEx()"); display_error ("dump_sysinfo: GetVersionEx()");
} }
HMODULE k32 = LoadLibrary ("kernel32.dll"); HMODULE k32 = GetModuleHandleW (L"kernel32.dll");
switch (osversion.dwPlatformId) switch (osversion.dwPlatformId)
{ {
@ -1838,8 +1839,6 @@ dump_sysinfo ()
name); name);
} }
if (!FreeLibrary (k32))
display_error ("dump_sysinfo: FreeLibrary()");
SetErrorMode (prev_mode); SetErrorMode (prev_mode);
if (givehelp) if (givehelp)
{ {

View File

@ -28,6 +28,7 @@ details. */
#include <ddk/winddk.h> #include <ddk/winddk.h>
#include <ddk/ntifs.h> #include <ddk/ntifs.h>
#include "wide_path.h" #include "wide_path.h"
#include "loadlib.h"
static const char version[] = "$Revision$"; static const char version[] = "$Revision$";
@ -452,7 +453,7 @@ get_long_name (const char *filename, DWORD& len)
{ {
char *sbuf; char *sbuf;
wchar_t buf[32768]; wchar_t buf[32768];
static HINSTANCE k32 = LoadLibrary ("kernel32.dll"); static HINSTANCE k32 = GetModuleHandleW (L"kernel32.dll");
static DWORD (WINAPI *GetLongPathName) (LPCWSTR, LPWSTR, DWORD) = static DWORD (WINAPI *GetLongPathName) (LPCWSTR, LPWSTR, DWORD) =
(DWORD (WINAPI *) (LPCWSTR, LPWSTR, DWORD)) GetProcAddress (k32, "GetLongPathNameW"); (DWORD (WINAPI *) (LPCWSTR, LPWSTR, DWORD)) GetProcAddress (k32, "GetLongPathNameW");
if (!GetLongPathName) if (!GetLongPathName)
@ -610,7 +611,7 @@ do_sysfolders (char option)
break; break;
case 'H': case 'H':
k32 = LoadLibrary ("userenv"); k32 = LoadLibrary ("userenv.dll");
if (k32) if (k32)
GetProfilesDirectoryAPtrW = (BOOL (*) (LPWSTR, LPDWORD)) GetProfilesDirectoryAPtrW = (BOOL (*) (LPWSTR, LPDWORD))
GetProcAddress (k32, "GetProfilesDirectoryW"); GetProcAddress (k32, "GetProfilesDirectoryW");

View File

@ -11,7 +11,7 @@ WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
cmd += 4; cmd += 4;
break; break;
} }
if (!*cmd || !LoadLibraryW (cmd)) if (!*cmd || !LoadLibraryExW (cmd, NULL, DONT_RESOLVE_DLL_REFERENCES))
ExitProcess (0x0100); ExitProcess (0x0100);
ExitProcess (0x0000); ExitProcess (0x0000);
} }

59
winsup/utils/loadlib.h Normal file
View File

@ -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 */

View File

@ -126,9 +126,10 @@ print_locale_with_codeset (int verbose, loc_t *locale, bool utf8,
if (!sysroot) if (!sysroot)
{ {
char sysbuf[PATH_MAX]; char sysbuf[PATH_MAX];
stpcpy (stpcpy (sysbuf, getenv ("SYSTEMROOT")), HMODULE k32 = GetModuleHandleW (L"kernel32.dll");
"\\system32\\kernel32.dll"); if (GetModuleFileName (k32, sysbuf, PATH_MAX))
sysroot = (const char *) cygwin_create_path (CCP_WIN_A_TO_POSIX, sysbuf); sysroot = (const char *) cygwin_create_path (CCP_WIN_A_TO_POSIX,
sysbuf);
if (!sysroot) if (!sysroot)
sysroot = "kernel32.dll"; sysroot = "kernel32.dll";
} }

View File

@ -1,7 +1,7 @@
/* mkgroup.c: /* mkgroup.c:
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 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. This file is part of Cygwin.
@ -28,6 +28,7 @@
#include <ntsecapi.h> #include <ntsecapi.h>
#include <dsgetdc.h> #include <dsgetdc.h>
#include <ntdef.h> #include <ntdef.h>
#include "loadlib.h"
#define print_win_error(x) _print_win_error(x, __LINE__) #define print_win_error(x) _print_win_error(x, __LINE__)

View File

@ -1,7 +1,7 @@
/* mkpasswd.c: /* mkpasswd.c:
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 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. This file is part of Cygwin.
@ -28,6 +28,7 @@
#include <ntsecapi.h> #include <ntsecapi.h>
#include <dsgetdc.h> #include <dsgetdc.h>
#include <ntdef.h> #include <ntdef.h>
#include "loadlib.h"
#define print_win_error(x) _print_win_error(x, __LINE__) #define print_win_error(x) _print_win_error(x, __LINE__)

View File

@ -1,6 +1,6 @@
/* module_info.cc /* 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> Written by Egor Duda <deo@logos-m.ru>
@ -13,6 +13,7 @@ details. */
#include <stdlib.h> #include <stdlib.h>
#include <windows.h> #include <windows.h>
#include <psapi.h> #include <psapi.h>
#include "loadlib.h"
static int psapi_loaded = 0; static int psapi_loaded = 0;
static HMODULE psapi_module_handle = NULL; static HMODULE psapi_module_handle = NULL;

View File

@ -29,6 +29,7 @@ details. */
#ifdef FSTAB_ONLY #ifdef FSTAB_ONLY
#include <sys/cygwin.h> #include <sys/cygwin.h>
#endif #endif
#include "loadlib.h"
#ifndef FSTAB_ONLY #ifndef FSTAB_ONLY
/* Used when treating / and \ as equivalent. */ /* Used when treating / and \ as equivalent. */

View File

@ -1,7 +1,7 @@
/* ps.cc /* ps.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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. This file is part of Cygwin.
@ -23,6 +23,7 @@ details. */
#include <psapi.h> #include <psapi.h>
#include <ddk/ntapi.h> #include <ddk/ntapi.h>
#include <ddk/winddk.h> #include <ddk/winddk.h>
#include "loadlib.h"
/* Maximum possible path length under NT. There's no official define /* Maximum possible path length under NT. There's no official define
for that value. Note that PATH_MAX is only 4K. */ for that value. Note that PATH_MAX is only 4K. */

View File

@ -1,7 +1,7 @@
/* regtool.cc /* regtool.cc
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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. This file is part of Cygwin.
@ -19,6 +19,7 @@ details. */
#define WINVER 0x0502 #define WINVER 0x0502
#include <windows.h> #include <windows.h>
#include <sys/cygwin.h> #include <sys/cygwin.h>
#include "loadlib.h"
#define DEFAULT_KEY_SEPARATOR '\\' #define DEFAULT_KEY_SEPARATOR '\\'

View File

@ -26,6 +26,7 @@ details. */
#include "cygwin/include/sys/cygwin.h" #include "cygwin/include/sys/cygwin.h"
#include "path.h" #include "path.h"
#undef cygwin_internal #undef cygwin_internal
#include "loadlib.h"
/* we *know* we're being built with GCC */ /* we *know* we're being built with GCC */
#define alloca __builtin_alloca #define alloca __builtin_alloca