mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 932100 - Part 2: Move DLL blocklist code to mozglue. r=bsmedberg, r=glandium
--HG-- rename : toolkit/xre/nsWindowsDllBlocklist.cpp => mozglue/build/WindowsDllBlocklist.cpp
This commit is contained in:
parent
0233f4ada7
commit
4a637bff20
@ -42,6 +42,7 @@
|
||||
#endif
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
||||
static void Output(const char *fmt, ... )
|
||||
{
|
||||
@ -92,9 +93,6 @@ public:
|
||||
XRE_GetFileFromPathType XRE_GetFileFromPath;
|
||||
XRE_CreateAppDataType XRE_CreateAppData;
|
||||
XRE_FreeAppDataType XRE_FreeAppData;
|
||||
#ifdef XRE_HAS_DLL_BLOCKLIST
|
||||
XRE_SetupDllBlocklistType XRE_SetupDllBlocklist;
|
||||
#endif
|
||||
XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
|
||||
XRE_mainType XRE_main;
|
||||
|
||||
@ -102,9 +100,6 @@ static const nsDynamicFunctionLoad kXULFuncs[] = {
|
||||
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
|
||||
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
|
||||
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
|
||||
#ifdef XRE_HAS_DLL_BLOCKLIST
|
||||
{ "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist },
|
||||
#endif
|
||||
{ "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
|
||||
{ "XRE_main", (NSFuncPtr*) &XRE_main },
|
||||
{ nullptr, nullptr }
|
||||
@ -210,6 +205,10 @@ int main(int argc, char* argv[])
|
||||
gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DLL_BLOCKLIST
|
||||
DllBlocklist_Initialize();
|
||||
#endif
|
||||
|
||||
// We do this because of data in bug 771745
|
||||
XPCOMGlueEnablePreload();
|
||||
|
||||
@ -227,10 +226,6 @@ int main(int argc, char* argv[])
|
||||
return 255;
|
||||
}
|
||||
|
||||
#ifdef XRE_HAS_DLL_BLOCKLIST
|
||||
XRE_SetupDllBlocklist();
|
||||
#endif
|
||||
|
||||
if (gotCounters) {
|
||||
#if defined(XP_WIN)
|
||||
XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -154,9 +155,6 @@ static void AttachToTestHarness()
|
||||
XRE_GetFileFromPathType XRE_GetFileFromPath;
|
||||
XRE_CreateAppDataType XRE_CreateAppData;
|
||||
XRE_FreeAppDataType XRE_FreeAppData;
|
||||
#ifdef XRE_HAS_DLL_BLOCKLIST
|
||||
XRE_SetupDllBlocklistType XRE_SetupDllBlocklist;
|
||||
#endif
|
||||
XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
|
||||
XRE_StartupTimelineRecordType XRE_StartupTimelineRecord;
|
||||
XRE_mainType XRE_main;
|
||||
@ -166,9 +164,6 @@ static const nsDynamicFunctionLoad kXULFuncs[] = {
|
||||
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
|
||||
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
|
||||
{ "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
|
||||
#ifdef XRE_HAS_DLL_BLOCKLIST
|
||||
{ "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist },
|
||||
#endif
|
||||
{ "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
|
||||
{ "XRE_StartupTimelineRecord", (NSFuncPtr*) &XRE_StartupTimelineRecord },
|
||||
{ "XRE_main", (NSFuncPtr*) &XRE_main },
|
||||
@ -607,6 +602,17 @@ int main(int argc, char* argv[])
|
||||
|
||||
nsIFile *xreDirectory;
|
||||
|
||||
#ifdef HAS_DLL_BLOCKLIST
|
||||
DllBlocklist_Initialize();
|
||||
|
||||
// In order to be effective against AppInit DLLs, the blocklist must be
|
||||
// initialized before user32.dll is loaded into the process. If this assert
|
||||
// ever fires, then the fix for bug 932100 has been defeated and the
|
||||
// blocklist will miss AppInit DLLs. You should use a delayload or reorder
|
||||
// the code to prevent user32.dll from loading during early startup.
|
||||
MOZ_ASSERT(!GetModuleHandleA("user32.dll"));
|
||||
#endif
|
||||
|
||||
nsresult rv = InitXPCOMGlue(argv[0], &xreDirectory);
|
||||
if (NS_FAILED(rv)) {
|
||||
return 255;
|
||||
@ -614,10 +620,6 @@ int main(int argc, char* argv[])
|
||||
|
||||
XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
|
||||
|
||||
#ifdef XRE_HAS_DLL_BLOCKLIST
|
||||
XRE_SetupDllBlocklist();
|
||||
#endif
|
||||
|
||||
if (gotCounters) {
|
||||
#if defined(XP_WIN)
|
||||
XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
#ifdef XP_MACOSX
|
||||
@ -38,8 +39,8 @@ main(int argc, char** argv, char** envp)
|
||||
setbuf(stdout, 0);
|
||||
#endif
|
||||
|
||||
#ifdef XRE_HAS_DLL_BLOCKLIST
|
||||
XRE_SetupDllBlocklist();
|
||||
#ifdef HAS_DLL_BLOCKLIST
|
||||
DllBlocklist_Initialize();
|
||||
#endif
|
||||
|
||||
int result = XRE_XPCShellMain(argc, argv, envp);
|
||||
|
@ -45,7 +45,14 @@ ifneq (,$(filter -DEFAULTLIB:mozcrt,$(MOZ_GLUE_LDFLAGS)))
|
||||
NO_INSTALL_IMPORT_LIBRARY = 1
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_ZLIB_LIBS)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(MOZ_ZLIB_LIBS) \
|
||||
version.lib \
|
||||
$(NULL)
|
||||
|
||||
STL_FLAGS=
|
||||
|
||||
endif
|
||||
|
||||
ifeq (Darwin_1,$(OS_TARGET)_$(MOZ_REPLACE_MALLOC))
|
||||
|
@ -5,18 +5,15 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4275 4530 ) // See msvc-stl-wrapper.template.h
|
||||
#include <map>
|
||||
#pragma warning( pop )
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#define MOZ_NO_MOZALLOC
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
@ -24,10 +21,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
#define ALL_VERSIONS ((unsigned long long)-1LL)
|
||||
|
||||
// DLLs sometimes ship without a version number, particularly early
|
||||
@ -153,7 +146,47 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
|
||||
// define this for very verbose dll load debug spew
|
||||
#undef DEBUG_very_verbose
|
||||
|
||||
extern bool gInXPCOMLoadOnMainThread;
|
||||
static const char kBlockedDllsParameter[] = "BlockedDllList=";
|
||||
static const int kBlockedDllsParameterLen =
|
||||
sizeof(kBlockedDllsParameter) - 1;
|
||||
|
||||
static const char kBlocklistInitFailedParameter[] = "BlocklistInitFailed=";
|
||||
static const int kBlocklistInitFailedParameterLen =
|
||||
sizeof(kBlocklistInitFailedParameter) - 1;
|
||||
|
||||
static const char kUser32BeforeBlocklistParameter[] = "User32BeforeBlocklist=";
|
||||
static const int kUser32BeforeBlocklistParameterLen =
|
||||
sizeof(kUser32BeforeBlocklistParameterLen) - 1;
|
||||
|
||||
static DWORD sThreadLoadingXPCOMModule;
|
||||
static bool sBlocklistInitFailed;
|
||||
static bool sUser32BeforeBlocklist;
|
||||
|
||||
// Duplicated from xpcom glue. Ideally this should be shared.
|
||||
static void
|
||||
printf_stderr(const char *fmt, ...)
|
||||
{
|
||||
if (IsDebuggerPresent()) {
|
||||
char buf[2048];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
va_end(args);
|
||||
OutputDebugStringA(buf);
|
||||
}
|
||||
|
||||
FILE *fp = _fdopen(_dup(2), "a");
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(fp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@ -170,7 +203,7 @@ struct RVAMap {
|
||||
DWORD alignedOffset = (offset / info.dwAllocationGranularity) *
|
||||
info.dwAllocationGranularity;
|
||||
|
||||
NS_ASSERTION(offset - alignedOffset < info.dwAllocationGranularity, "Wtf");
|
||||
MOZ_ASSERT(offset - alignedOffset < info.dwAllocationGranularity, "Wtf");
|
||||
|
||||
mRealView = ::MapViewOfFile(map, FILE_MAP_READ, 0, alignedOffset,
|
||||
sizeof(T) + (offset - alignedOffset));
|
||||
@ -544,7 +577,7 @@ continue_loading:
|
||||
printf_stderr("LdrLoadDll: continuing load... ('%S')\n", moduleFileName->Buffer);
|
||||
#endif
|
||||
|
||||
if (gInXPCOMLoadOnMainThread && NS_IsMainThread()) {
|
||||
if (GetCurrentThreadId() == sThreadLoadingXPCOMModule) {
|
||||
// Check to ensure that the DLL has ASLR.
|
||||
full_fname = getFullPath(filePath, fname);
|
||||
if (!full_fname) {
|
||||
@ -566,31 +599,56 @@ WindowsDllInterceptor NtDllIntercept;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
XRE_SetupDllBlocklist()
|
||||
NS_EXPORT void
|
||||
DllBlocklist_Initialize()
|
||||
{
|
||||
if (GetModuleHandleA("user32.dll")) {
|
||||
sUser32BeforeBlocklist = true;
|
||||
}
|
||||
|
||||
NtDllIntercept.Init("ntdll.dll");
|
||||
|
||||
ReentrancySentinel::InitializeStatics();
|
||||
|
||||
bool ok = NtDllIntercept.AddHook("LdrLoadDll", reinterpret_cast<intptr_t>(patched_LdrLoadDll), (void**) &stub_LdrLoadDll);
|
||||
|
||||
if (!ok) {
|
||||
sBlocklistInitFailed = true;
|
||||
#ifdef DEBUG
|
||||
if (!ok)
|
||||
printf_stderr ("LdrLoadDll hook failed, no dll blocklisting active\n");
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (!ok) {
|
||||
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DllBlockList Failed\n"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void
|
||||
CrashReporter::WriteBlockedDlls(HANDLE file)
|
||||
NS_EXPORT void
|
||||
DllBlocklist_SetInXPCOMLoadOnMainThread(bool inXPCOMLoadOnMainThread)
|
||||
{
|
||||
DllBlockSet::Write(file);
|
||||
if (inXPCOMLoadOnMainThread) {
|
||||
MOZ_ASSERT(sThreadLoadingXPCOMModule == 0, "Only one thread should be doing this");
|
||||
sThreadLoadingXPCOMModule = GetCurrentThreadId();
|
||||
} else {
|
||||
sThreadLoadingXPCOMModule = 0;
|
||||
}
|
||||
}
|
||||
|
||||
NS_EXPORT void
|
||||
DllBlocklist_WriteNotes(HANDLE file)
|
||||
{
|
||||
DWORD nBytes;
|
||||
|
||||
WriteFile(file, kBlockedDllsParameter, kBlockedDllsParameterLen, &nBytes, nullptr);
|
||||
DllBlockSet::Write(file);
|
||||
WriteFile(file, "\n", 1, &nBytes, nullptr);
|
||||
|
||||
if (sBlocklistInitFailed) {
|
||||
WriteFile(file, kBlocklistInitFailedParameter,
|
||||
kBlocklistInitFailedParameterLen, &nBytes, nullptr);
|
||||
WriteFile(file, "1\n", 2, &nBytes, nullptr);
|
||||
}
|
||||
|
||||
if (sUser32BeforeBlocklist) {
|
||||
WriteFile(file, kUser32BeforeBlocklistParameter,
|
||||
kUser32BeforeBlocklistParameterLen, &nBytes, nullptr);
|
||||
WriteFile(file, "1\n", 2, &nBytes, nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
38
mozglue/build/WindowsDllBlocklist.h
Normal file
38
mozglue/build/WindowsDllBlocklist.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_windowsdllblocklist_h
|
||||
#define mozilla_windowsdllblocklist_h
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||
|
||||
#include <windows.h>
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "nscore.h"
|
||||
|
||||
#define HAS_DLL_BLOCKLIST
|
||||
|
||||
NS_IMPORT void DllBlocklist_Initialize();
|
||||
NS_IMPORT void DllBlocklist_SetInXPCOMLoadOnMainThread(bool inXPCOMLoadOnMainThread);
|
||||
NS_IMPORT void DllBlocklist_WriteNotes(HANDLE file);
|
||||
|
||||
class AutoSetXPCOMLoadOnMainThread
|
||||
{
|
||||
public:
|
||||
AutoSetXPCOMLoadOnMainThread(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
DllBlocklist_SetInXPCOMLoadOnMainThread(true);
|
||||
}
|
||||
|
||||
~AutoSetXPCOMLoadOnMainThread() {
|
||||
DllBlocklist_SetInXPCOMLoadOnMainThread(false);
|
||||
}
|
||||
|
||||
private:
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
#endif // defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#endif // mozilla_windowsdllblocklist_h
|
@ -31,6 +31,11 @@ if CONFIG['OS_TARGET'] == 'Android':
|
||||
'BionicGlue.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'WindowsDllBlocklist.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_NUWA_PROCESS']:
|
||||
EXPORTS.ipc += [
|
||||
'Nuwa.h',
|
||||
@ -42,6 +47,7 @@ if CONFIG['MOZ_NUWA_PROCESS']:
|
||||
EXPORTS.mozilla += [
|
||||
'arm.h',
|
||||
'SSE.h',
|
||||
'WindowsDllBlocklist.h',
|
||||
]
|
||||
|
||||
if CONFIG['CPU_ARCH'].startswith('x86'):
|
||||
|
@ -83,6 +83,7 @@ using mozilla::InjectCrashRunnable;
|
||||
|
||||
#include "mozilla/mozalloc_oom.h"
|
||||
#include "mozilla/LateWriteChecks.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
CFStringRef reporterClientAppID = CFSTR("org.mozilla.crashreporter");
|
||||
@ -222,11 +223,6 @@ static const char kIsGarbageCollectingParameter[] = "IsGarbageCollecting=";
|
||||
static const int kIsGarbageCollectingParameterLen =
|
||||
sizeof(kIsGarbageCollectingParameter)-1;
|
||||
|
||||
#ifdef XP_WIN
|
||||
static const char kBlockedDllsParameter[] = "BlockedDllList=";
|
||||
static const int kBlockedDllsParameterLen = sizeof(kBlockedDllsParameter) - 1;
|
||||
#endif
|
||||
|
||||
// this holds additional data sent via the API
|
||||
static Mutex* crashReporterAPILock;
|
||||
static Mutex* notesFieldLock;
|
||||
@ -545,9 +541,10 @@ bool MinidumpCallback(
|
||||
WriteFile(hFile, isGarbageCollecting ? "1" : "0", 1, &nBytes, nullptr);
|
||||
WriteFile(hFile, "\n", 1, &nBytes, nullptr);
|
||||
}
|
||||
WriteFile(hFile, kBlockedDllsParameter, kBlockedDllsParameterLen, &nBytes, nullptr);
|
||||
WriteBlockedDlls(hFile);
|
||||
WriteFile(hFile, "\n", 1, &nBytes, nullptr);
|
||||
|
||||
#ifdef HAS_DLL_BLOCKLIST
|
||||
DllBlocklist_WriteNotes(hFile);
|
||||
#endif
|
||||
|
||||
// Try to get some information about memory.
|
||||
MEMORYSTATUSEX statex;
|
||||
|
@ -44,11 +44,6 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data);
|
||||
|
||||
nsresult SetGarbageCollecting(bool collecting);
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Implemented by the blocklist, this method writes the blocklist annotation
|
||||
void WriteBlockedDlls(HANDLE file);
|
||||
#endif
|
||||
|
||||
nsresult SetRestartArgs(int argc, char** argv);
|
||||
nsresult SetupExtraData(nsIFile* aAppDataDirectory,
|
||||
const nsACString& aBuildID);
|
||||
|
@ -24,7 +24,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
EXPORTS += ['nsWindowsDllInterceptor.h']
|
||||
SOURCES += [
|
||||
'nsNativeAppSupportWin.cpp',
|
||||
'nsWindowsDllBlocklist.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
EXPORTS += ['MacQuirks.h']
|
||||
|
@ -437,12 +437,6 @@ XRE_API(bool,
|
||||
XRE_API(void,
|
||||
XRE_InstallX11ErrorHandler, ())
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#define XRE_HAS_DLL_BLOCKLIST
|
||||
XRE_API(void,
|
||||
XRE_SetupDllBlocklist, ())
|
||||
#endif
|
||||
|
||||
XRE_API(void,
|
||||
XRE_TelemetryAccumulate, (int aID, uint32_t aSample))
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "nsTraceRefcntImpl.h"
|
||||
|
||||
#include "nsIFile.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
@ -61,8 +62,6 @@ GetNativeModuleLoaderLog()
|
||||
return sLog;
|
||||
}
|
||||
|
||||
bool gInXPCOMLoadOnMainThread = false;
|
||||
|
||||
#define LOG(level, args) PR_LOG(GetNativeModuleLoaderLog(), level, args)
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(nsNativeModuleLoader,
|
||||
@ -140,10 +139,12 @@ nsNativeModuleLoader::LoadModule(FileLocation &aFile)
|
||||
}
|
||||
|
||||
// We haven't loaded this module before
|
||||
|
||||
gInXPCOMLoadOnMainThread = true;
|
||||
rv = file->Load(&data.library);
|
||||
gInXPCOMLoadOnMainThread = false;
|
||||
{
|
||||
#ifdef HAS_DLL_BLOCKLIST
|
||||
AutoSetXPCOMLoadOnMainThread guard;
|
||||
#endif
|
||||
rv = file->Load(&data.library);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
char errorMsg[1024] = "<unknown; can't get error from NSPR>";
|
||||
|
Loading…
Reference in New Issue
Block a user