Backout bug 677797 while preserving the fix from bug 694432 to see whether it helps with the crashes seen in bug 694432

This commit is contained in:
Ehsan Akhgari 2011-10-25 11:34:41 -04:00
Родитель 6cc3c72b79
Коммит 5dc4fae77b
1 изменённых файлов: 25 добавлений и 78 удалений

Просмотреть файл

@ -148,59 +148,6 @@ typedef NTSTATUS (NTAPI *LdrLoadDll_func) (PWCHAR filePath, PULONG flags, PUNICO
static LdrLoadDll_func stub_LdrLoadDll = 0; static LdrLoadDll_func stub_LdrLoadDll = 0;
namespace {
template <class T>
struct RVAMap {
RVAMap(HANDLE map, unsigned offset) {
mMappedView = reinterpret_cast<T*>
(::MapViewOfFile(map, FILE_MAP_READ, 0, offset, sizeof(T)));
}
~RVAMap() {
if (mMappedView) {
::UnmapViewOfFile(mMappedView);
}
}
operator const T*() const { return mMappedView; }
const T* operator->() const { return mMappedView; }
private:
const T* mMappedView;
};
void
ForceASLR(const wchar_t* path)
{
HANDLE file = ::CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
if (file != INVALID_HANDLE_VALUE) {
HANDLE map = ::CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (map) {
RVAMap<IMAGE_DOS_HEADER> peHeader(map, 0);
if (peHeader) {
RVAMap<IMAGE_NT_HEADERS> ntHeader(map, peHeader->e_lfanew);
if (ntHeader) {
// If we're dealing with a DLL which has code inside it, but does not have the
// ASLR bit set, allocate a page at its base address.
if (((ntHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0) &&
(ntHeader->OptionalHeader.SizeOfCode > 0)) {
void* page = ::VirtualAlloc((LPVOID)ntHeader->OptionalHeader.ImageBase, 1,
MEM_RESERVE, PAGE_NOACCESS);
// Note that we will leak this page, but it's ok since it's just one page in
// the virtual address space, with no physical page backing it.
// We're done at this point!
}
}
}
::CloseHandle(map);
}
::CloseHandle(file);
}
}
}
static NTSTATUS NTAPI static NTSTATUS NTAPI
patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle) patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileName, PHANDLE handle)
{ {
@ -210,32 +157,9 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
wchar_t *dll_part; wchar_t *dll_part;
DllBlockInfo *info; DllBlockInfo *info;
// 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;
int len = moduleFileName->Length / 2; int len = moduleFileName->Length / 2;
wchar_t *fname = moduleFileName->Buffer; wchar_t *fname = moduleFileName->Buffer;
// 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);
// The filename isn't guaranteed to be null terminated, but in practice // 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. // it always will be; ensure that this is so, and bail if not.
// This is done instead of the more robust approach because of bug 527122, // This is done instead of the more robust approach because of bug 527122,
@ -311,6 +235,29 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
#endif #endif
if (info->maxVersion != ALL_VERSIONS) { if (info->maxVersion != ALL_VERSIONS) {
// 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;
}
wchar_t *full_fname = (wchar_t*) malloc(sizeof(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);
DWORD zero; DWORD zero;
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero); DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
@ -334,6 +281,8 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
load_ok = true; load_ok = true;
} }
} }
free(full_fname);
} }
if (!load_ok) { if (!load_ok) {
@ -349,8 +298,6 @@ continue_loading:
NS_SetHasLoadedNewDLLs(); NS_SetHasLoadedNewDLLs();
ForceASLR(full_fname);
return stub_LdrLoadDll(filePath, flags, moduleFileName, handle); return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
} }