зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
6cc3c72b79
Коммит
5dc4fae77b
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче