Bug 1023239 - Block crashy builds of V-Bates. r=bsmedberg

--HG--
extra : rebase_source : 5b0d32f84ddcea375736777270f99af4e63a0513
This commit is contained in:
David Major 2014-07-01 09:33:43 +12:00
parent a510b05849
commit 1ebe57b5fe

View File

@ -47,12 +47,16 @@ struct DllBlockInfo {
// Note that the version is usually 4 components, which is A.B.C.D
// encoded as 0x AAAA BBBB CCCC DDDD ULL (spaces added for clarity),
// but it's not required to be of that format.
//
// If the USE_TIMESTAMP flag is set, then we use the timestamp from
// the IMAGE_FILE_HEADER in lieu of a version number.
unsigned long long maxVersion;
enum {
FLAGS_DEFAULT = 0,
BLOCK_WIN8PLUS_ONLY = 1,
BLOCK_XP_ONLY = 2
BLOCK_XP_ONLY = 2,
USE_TIMESTAMP = 4,
} flags;
};
@ -144,8 +148,10 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
// XP topcrash with F-Secure, bug 970362
{ "fs_ccf_ni_umh32.dll", MAKE_VERSION(1, 42, 101, 0), DllBlockInfo::BLOCK_XP_ONLY },
// Topcrash with V-bates, bug 1002748
// Topcrash with V-bates, bug 1002748 and bug 1023239
{ "libinject.dll", UNVERSIONED },
{ "libinject2.dll", 0x537DDC93, DllBlockInfo::USE_TIMESTAMP },
{ "libredir2.dll", 0x5385B7ED, DllBlockInfo::USE_TIMESTAMP },
// Crashes with RoboForm2Go written against old SDK, bug 988311
{ "rf-firefox-22.dll", ALL_VERSIONS },
@ -272,6 +278,33 @@ CheckASLR(const wchar_t* path)
return retval;
}
DWORD
GetTimestamp(const wchar_t* path)
{
DWORD timestamp = 0;
HANDLE file = ::CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
nullptr);
if (file != INVALID_HANDLE_VALUE) {
HANDLE map = ::CreateFileMappingW(file, nullptr, PAGE_READONLY, 0, 0,
nullptr);
if (map) {
RVAMap<IMAGE_DOS_HEADER> peHeader(map, 0);
if (peHeader) {
RVAMap<IMAGE_NT_HEADERS> ntHeader(map, peHeader->e_lfanew);
if (ntHeader) {
timestamp = ntHeader->FileHeader.TimeDateStamp;
}
}
::CloseHandle(map);
}
::CloseHandle(file);
}
return timestamp;
}
// This lock protects both the reentrancy sentinel and the crash reporter
// data structures.
static CRITICAL_SECTION sLock;
@ -571,27 +604,34 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
return STATUS_DLL_NOT_FOUND;
}
DWORD zero;
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
if (info->flags & DllBlockInfo::USE_TIMESTAMP) {
fVersion = GetTimestamp(full_fname);
if (fVersion > info->maxVersion) {
load_ok = true;
}
} else {
DWORD zero;
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
// If we failed to get the version information, we block.
// If we failed to get the version information, we block.
if (infoSize != 0) {
nsAutoArrayPtr<unsigned char> infoData(new unsigned char[infoSize]);
VS_FIXEDFILEINFO *vInfo;
UINT vInfoLen;
if (infoSize != 0) {
nsAutoArrayPtr<unsigned char> infoData(new unsigned char[infoSize]);
VS_FIXEDFILEINFO *vInfo;
UINT vInfoLen;
if (GetFileVersionInfoW(full_fname, 0, infoSize, infoData) &&
VerQueryValueW(infoData, L"\\", (LPVOID*) &vInfo, &vInfoLen))
{
fVersion =
((unsigned long long)vInfo->dwFileVersionMS) << 32 |
((unsigned long long)vInfo->dwFileVersionLS);
if (GetFileVersionInfoW(full_fname, 0, infoSize, infoData) &&
VerQueryValueW(infoData, L"\\", (LPVOID*) &vInfo, &vInfoLen))
{
fVersion =
((unsigned long long)vInfo->dwFileVersionMS) << 32 |
((unsigned long long)vInfo->dwFileVersionLS);
// finally do the version check, and if it's greater than our block
// version, keep loading
if (fVersion > info->maxVersion)
load_ok = true;
// finally do the version check, and if it's greater than our block
// version, keep loading
if (fVersion > info->maxVersion)
load_ok = true;
}
}
}
}