Bug 730051: Don't use SearchPathW to look for the DLL unless we're actually doing a load. r=bsmedberg

This commit is contained in:
Kyle Huey 2012-03-01 11:07:11 -08:00
parent b3cc90d0c1
commit 40f28e56a6

View File

@ -278,6 +278,32 @@ private:
CRITICAL_SECTION ReentrancySentinel::sLock;
std::map<DWORD, const char*>* ReentrancySentinel::sThreadMap;
static
wchar_t* getFullPath (PWCHAR filePath, wchar_t* fname)
{
// In Windows 8, the first parameter seems to be used for more than just the
// path name. For example, its numerical value can be 1. Passing a non-valid
// pointer to SearchPathW will cause a crash, so we need to check to see if we
// are handed a valid pointer, and otherwise just pass NULL to SearchPathW.
PWCHAR sanitizedFilePath = (intptr_t(filePath) < 1024) ? NULL : filePath;
// figure out the length of the string that we need
DWORD pathlen = SearchPathW(sanitizedFilePath, fname, L".dll", 0, NULL, NULL);
if (pathlen == 0) {
return nsnull;
}
wchar_t* full_fname = new wchar_t[pathlen+1];
if (!full_fname) {
// couldn't allocate memory?
return nsnull;
}
// now actually grab it
SearchPathW(sanitizedFilePath, fname, L".dll", pathlen+1, full_fname, NULL);
return full_fname;
}
static NTSTATUS NTAPI
patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle)
{
@ -289,29 +315,7 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
int len = moduleFileName->Length / 2;
wchar_t *fname = moduleFileName->Buffer;
// In Windows 8, the first parameter seems to be used for more than just the
// path name. For example, its numerical value can be 1. Passing a non-valid
// pointer to SearchPathW will cause a crash, so we need to check to see if we
// are handed a valid pointer, and otherwise just pass NULL to SearchPathW.
PWCHAR sanitizedFilePath = (intptr_t(filePath) < 1024) ? NULL : filePath;
// figure out the length of the string that we need
DWORD pathlen = SearchPathW(sanitizedFilePath, fname, L".dll", 0, NULL, NULL);
if (pathlen == 0) {
// uh, we couldn't find the DLL at all, so...
printf_stderr("LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find it?)\n", dllName);
return STATUS_DLL_NOT_FOUND;
}
nsAutoArrayPtr<wchar_t> full_fname(new wchar_t[pathlen+1]);
if (!full_fname) {
// couldn't allocate memory?
return STATUS_DLL_NOT_FOUND;
}
// now actually grab it
SearchPathW(sanitizedFilePath, fname, L".dll", pathlen+1, full_fname, NULL);
nsAutoArrayPtr<wchar_t> full_fname;
// The filename isn't guaranteed to be null terminated, but in practice
// it always will be; ensure that this is so, and bail if not.
@ -393,6 +397,13 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
goto continue_loading;
}
full_fname = getFullPath(filePath, fname);
if (!full_fname) {
// uh, we couldn't find the DLL at all, so...
printf_stderr("LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find it?)\n", dllName);
return STATUS_DLL_NOT_FOUND;
}
DWORD zero;
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
@ -433,6 +444,13 @@ continue_loading:
if (gInXPCOMLoadOnMainThread && NS_IsMainThread()) {
// Check to ensure that the DLL has ASLR.
full_fname = getFullPath(filePath, fname);
if (!full_fname) {
// uh, we couldn't find the DLL at all, so...
printf_stderr("LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find it?)\n", dllName);
return STATUS_DLL_NOT_FOUND;
}
if (!CheckASLR(full_fname)) {
printf_stderr("LdrLoadDll: Blocking load of '%s'. XPCOM components must support ASLR.\n", dllName);
return STATUS_DLL_NOT_FOUND;