mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 06:56:14 +01:00
Recuce DLL hijack risk on Windows
Don't call LoadLibrary() on shell32.dll or kernel32.dll. kernel32.dll is always loaded. Shell32.dll is also already loaded as glib links to functions in it. So just call GetModuleHandle() on them. For mlang.dll in win_iconv.c and winhttp.dll in gwinhttpvfs.c, always try loading them from a complete path, from the Windows system directory. Use the "tool help" API to enumerate modules in gmodule-win32.c. It is present in all Windows versions since Windows 2000, which is all we support anyway. Thus no need to look that API up dynamically. Just link to it normally. We can bin the fallback code that attempts to use the psapi API.
This commit is contained in:
parent
54c51c73c6
commit
6ddef375c8
@ -40,12 +40,23 @@ static GWinHttpDllFuncs funcs;
|
|||||||
static void
|
static void
|
||||||
lookup_funcs (void)
|
lookup_funcs (void)
|
||||||
{
|
{
|
||||||
HMODULE winhttp;
|
HMODULE winhttp = NULL;
|
||||||
|
char winhttp_dll[MAX_PATH + 100];
|
||||||
|
int n;
|
||||||
|
|
||||||
if (lookup_done)
|
if (lookup_done)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
winhttp = LoadLibrary ("winhttp.dll");
|
n = GetSystemDirectory (winhttp_dll, MAX_PATH);
|
||||||
|
if (n > 0 && n < MAX_PATH)
|
||||||
|
{
|
||||||
|
if (winhttp_dll[n-1] != '\\' &&
|
||||||
|
winhttp_dll[n-1] != '/')
|
||||||
|
strcat (winhttp_dll, "\\");
|
||||||
|
strcat (winhttp_dll, "winhttp.dll");
|
||||||
|
winhttp = LoadLibrary (winhttp_dll);
|
||||||
|
}
|
||||||
|
|
||||||
if (winhttp != NULL)
|
if (winhttp != NULL)
|
||||||
{
|
{
|
||||||
funcs.pWinHttpCloseHandle = (BOOL (WINAPI *) (HINTERNET)) GetProcAddress (winhttp, "WinHttpCloseHandle");
|
funcs.pWinHttpCloseHandle = (BOOL (WINAPI *) (HINTERNET)) GetProcAddress (winhttp, "WinHttpCloseHandle");
|
||||||
|
@ -2277,13 +2277,15 @@ load_user_special_dirs (void)
|
|||||||
HANDLE hToken,
|
HANDLE hToken,
|
||||||
PWSTR *ppszPath);
|
PWSTR *ppszPath);
|
||||||
t_SHGetKnownFolderPath p_SHGetKnownFolderPath;
|
t_SHGetKnownFolderPath p_SHGetKnownFolderPath;
|
||||||
|
|
||||||
static const GUID FOLDERID_Downloads =
|
static const GUID FOLDERID_Downloads =
|
||||||
{ 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
|
{ 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
|
||||||
static const GUID FOLDERID_Public =
|
static const GUID FOLDERID_Public =
|
||||||
{ 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } };
|
{ 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } };
|
||||||
|
|
||||||
wchar_t *wcp;
|
wchar_t *wcp;
|
||||||
|
|
||||||
p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (LoadLibrary ("shell32.dll"),
|
p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandle ("shell32.dll"),
|
||||||
"SHGetKnownFolderPath");
|
"SHGetKnownFolderPath");
|
||||||
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
|
g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
|
||||||
@ -2609,7 +2611,7 @@ get_module_for_address (gconstpointer address)
|
|||||||
if (!beenhere)
|
if (!beenhere)
|
||||||
{
|
{
|
||||||
p_GetModuleHandleExA =
|
p_GetModuleHandleExA =
|
||||||
(t_GetModuleHandleExA) GetProcAddress (LoadLibrary ("kernel32.dll"),
|
(t_GetModuleHandleExA) GetProcAddress (GetModuleHandle ("kernel32.dll"),
|
||||||
"GetModuleHandleExA");
|
"GetModuleHandleExA");
|
||||||
beenhere = TRUE;
|
beenhere = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -706,10 +706,20 @@ static RFC1766TOLCIDA Rfc1766ToLcidA;
|
|||||||
static int
|
static int
|
||||||
load_mlang()
|
load_mlang()
|
||||||
{
|
{
|
||||||
HMODULE h;
|
HMODULE h = NULL;
|
||||||
|
char mlang_dll[MAX_PATH + 100];
|
||||||
|
int n;
|
||||||
if (ConvertINetString != NULL)
|
if (ConvertINetString != NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
h = LoadLibrary("mlang.dll");
|
n = GetSystemDirectory(mlang_dll, MAX_PATH);
|
||||||
|
if (n > 0 && n < MAX_PATH)
|
||||||
|
{
|
||||||
|
if (mlang_dll[n-1] != '\\' &&
|
||||||
|
mlang_dll[n-1] != '/')
|
||||||
|
strcat(mlang_dll, "\\");
|
||||||
|
strcat(mlang_dll, "mlang.dll");
|
||||||
|
h = LoadLibrary(mlang_dll);
|
||||||
|
}
|
||||||
if (!h)
|
if (!h)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ConvertINetString = (CONVERTINETSTRING)GetProcAddress(h, "ConvertINetString");
|
ConvertINetString = (CONVERTINETSTRING)GetProcAddress(h, "ConvertINetString");
|
||||||
|
@ -110,45 +110,22 @@ _g_module_close (gpointer handle,
|
|||||||
static gpointer
|
static gpointer
|
||||||
find_in_any_module_using_toolhelp (const gchar *symbol_name)
|
find_in_any_module_using_toolhelp (const gchar *symbol_name)
|
||||||
{
|
{
|
||||||
typedef HANDLE (WINAPI *PFNCREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
|
|
||||||
static PFNCREATETOOLHELP32SNAPSHOT pfnCreateToolhelp32Snapshot = NULL;
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI *PFNMODULE32FIRST)(HANDLE, MODULEENTRY32*);
|
|
||||||
static PFNMODULE32FIRST pfnModule32First= NULL;
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI *PFNMODULE32NEXT)(HANDLE, MODULEENTRY32*);
|
|
||||||
static PFNMODULE32NEXT pfnModule32Next = NULL;
|
|
||||||
|
|
||||||
static HMODULE kernel32;
|
|
||||||
|
|
||||||
HANDLE snapshot;
|
HANDLE snapshot;
|
||||||
MODULEENTRY32 me32;
|
MODULEENTRY32 me32;
|
||||||
|
|
||||||
gpointer p;
|
gpointer p;
|
||||||
|
|
||||||
if (!pfnCreateToolhelp32Snapshot || !pfnModule32First || !pfnModule32Next)
|
if ((snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0)) == (HANDLE) -1)
|
||||||
{
|
|
||||||
if (!kernel32)
|
|
||||||
if (!(kernel32 = GetModuleHandle ("kernel32.dll")))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!(pfnCreateToolhelp32Snapshot = (PFNCREATETOOLHELP32SNAPSHOT) GetProcAddress (kernel32, "CreateToolhelp32Snapshot"))
|
|
||||||
|| !(pfnModule32First = (PFNMODULE32FIRST) GetProcAddress (kernel32, "Module32First"))
|
|
||||||
|| !(pfnModule32Next = (PFNMODULE32NEXT) GetProcAddress (kernel32, "Module32Next")))
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((snapshot = (*pfnCreateToolhelp32Snapshot) (TH32CS_SNAPMODULE, 0)) == (HANDLE) -1)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
me32.dwSize = sizeof (me32);
|
me32.dwSize = sizeof (me32);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
if ((*pfnModule32First) (snapshot, &me32))
|
if (Module32First (snapshot, &me32))
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
if ((p = GetProcAddress (me32.hModule, symbol_name)) != NULL)
|
if ((p = GetProcAddress (me32.hModule, symbol_name)) != NULL)
|
||||||
break;
|
break;
|
||||||
} while ((*pfnModule32Next) (snapshot, &me32));
|
} while (Module32Next (snapshot, &me32));
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle (snapshot);
|
CloseHandle (snapshot);
|
||||||
@ -156,63 +133,12 @@ find_in_any_module_using_toolhelp (const gchar *symbol_name)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
|
||||||
find_in_any_module_using_psapi (const gchar *symbol_name)
|
|
||||||
{
|
|
||||||
static HMODULE psapi = NULL;
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI *PFNENUMPROCESSMODULES) (HANDLE, HMODULE *, DWORD, LPDWORD) ;
|
|
||||||
static PFNENUMPROCESSMODULES pfnEnumProcessModules = NULL;
|
|
||||||
|
|
||||||
HMODULE *modules;
|
|
||||||
HMODULE dummy;
|
|
||||||
gint i, size;
|
|
||||||
DWORD needed;
|
|
||||||
|
|
||||||
gpointer p;
|
|
||||||
|
|
||||||
if (!pfnEnumProcessModules)
|
|
||||||
{
|
|
||||||
if (!psapi)
|
|
||||||
if ((psapi = LoadLibrary ("psapi.dll")) == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!(pfnEnumProcessModules = (PFNENUMPROCESSMODULES) GetProcAddress (psapi, "EnumProcessModules")))
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(*pfnEnumProcessModules) (GetCurrentProcess (), &dummy,
|
|
||||||
sizeof (HMODULE), &needed))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
size = needed + 10 * sizeof (HMODULE);
|
|
||||||
modules = g_malloc (size);
|
|
||||||
|
|
||||||
if (!(*pfnEnumProcessModules) (GetCurrentProcess (), modules,
|
|
||||||
size, &needed)
|
|
||||||
|| needed > size)
|
|
||||||
{
|
|
||||||
g_free (modules);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = NULL;
|
|
||||||
for (i = 0; i < needed / sizeof (HMODULE); i++)
|
|
||||||
if ((p = GetProcAddress (modules[i], symbol_name)) != NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
g_free (modules);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
find_in_any_module (const gchar *symbol_name)
|
find_in_any_module (const gchar *symbol_name)
|
||||||
{
|
{
|
||||||
gpointer result;
|
gpointer result;
|
||||||
|
|
||||||
if ((result = find_in_any_module_using_toolhelp (symbol_name)) == NULL
|
if ((result = find_in_any_module_using_toolhelp (symbol_name)) == NULL)
|
||||||
&& (result = find_in_any_module_using_psapi (symbol_name)) == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
Reference in New Issue
Block a user