Backed out 5 changesets (bug 1284897) for mozilla::SandboxPermissions::RemovePermissionsForProcess crashes

Backed out changeset 19b2fcee13a9 (bug 1284897)
Backed out changeset a5171791437f (bug 1284897)
Backed out changeset 3ea8b8a18515 (bug 1284897)
Backed out changeset 21497a4e3bde (bug 1284897)
Backed out changeset 12e17d5f0fa9 (bug 1284897)
This commit is contained in:
Phil Ringnalda 2017-02-16 22:14:15 -08:00
Родитель ebddba2ae4
Коммит 87ae1a50e4
25 изменённых файлов: 195 добавлений и 1266 удалений

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

@ -217,8 +217,6 @@ static int do_main(int argc, char* argv[], char* envp[])
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
sandbox::BrokerServices* brokerServices =
sandboxing::GetInitializedBrokerServices();
sandboxing::PermissionsService* permissionsService =
sandboxing::GetPermissionsService();
#if defined(MOZ_CONTENT_SANDBOX)
if (!brokerServices) {
Output("Couldn't initialize the broker services.\n");
@ -226,7 +224,6 @@ static int do_main(int argc, char* argv[], char* envp[])
}
#endif
config.sandboxBrokerServices = brokerServices;
config.sandboxPermissionsService = permissionsService;
#endif
#ifdef LIBFUZZER

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

@ -14,9 +14,6 @@ using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
using class mac_plugin_interposing::NSCursorInfo from "mozilla/plugins/PluginMessageUtils.h";
using struct nsID from "nsID.h";
using struct mozilla::plugins::NPAudioDeviceChangeDetailsIPC from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::GetFileNameFunc from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::OpenFileNameIPC from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::OpenFileNameRetIPC from "mozilla/plugins/PluginMessageUtils.h";
namespace mozilla {
namespace plugins {
@ -166,10 +163,6 @@ parent:
intr NPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(bool shouldRegister)
returns (NPError result);
// Used to broker the GetOpenFileName/GetSaveFileName file pickers on Windows.
intr GetFileName(GetFileNameFunc aFunc, OpenFileNameIPC aOfnIn)
returns (OpenFileNameRetIPC aOfnOut, bool aResult);
};
} // namespace plugins

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

@ -151,192 +151,5 @@ void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v)
VOID_TO_NPVARIANT(*v);
}
#ifdef XP_WIN
void
OpenFileNameIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn)
{
mHwndOwner = nullptr;
// Filter is double-NULL terminated. mFilter should include the double-NULL.
mHasFilter = aLpofn->lpstrFilter != nullptr;
if (mHasFilter) {
uint32_t dNullIdx = 0;
while (aLpofn->lpstrFilter[dNullIdx] != L'\0' ||
aLpofn->lpstrFilter[dNullIdx+1] != L'\0') {
dNullIdx++;
}
mFilter.assign(aLpofn->lpstrFilter, dNullIdx+2);
}
mHasCustomFilter = aLpofn->lpstrCustomFilter != nullptr;
if (mHasCustomFilter) {
mCustomFilterIn = std::wstring(aLpofn->lpstrCustomFilter);
mNMaxCustFilterOut =
aLpofn->nMaxCustFilter - (wcslen(aLpofn->lpstrCustomFilter) + 1);
}
else {
mNMaxCustFilterOut = 0;
}
mFilterIndex = aLpofn->nFilterIndex;
mFile = std::wstring(aLpofn->lpstrFile);
mNMaxFile = aLpofn->nMaxFile;
mNMaxFileTitle =
aLpofn->lpstrFileTitle != nullptr ? aLpofn->nMaxFileTitle : 0;
mHasInitialDir = aLpofn->lpstrInitialDir != nullptr;
if (mHasInitialDir) {
mInitialDir = std::wstring(aLpofn->lpstrInitialDir);
}
mHasTitle = aLpofn->lpstrTitle != nullptr;
if (mHasTitle) {
mTitle = std::wstring(aLpofn->lpstrTitle);
}
mHasDefExt = aLpofn->lpstrDefExt != nullptr;
if (mHasDefExt) {
mDefExt = std::wstring(aLpofn->lpstrDefExt);
}
mFlags = aLpofn->Flags;
// If the user sets OFN_ALLOWMULTISELECT then we require OFN_EXPLORER
// as well. Without OFN_EXPLORER, the method has ancient legacy
// behavior that we don't support.
MOZ_ASSERT((mFlags & OFN_EXPLORER) || !(mFlags & OFN_ALLOWMULTISELECT));
// We ignore any visual customization and callbacks that the user set.
mFlags &= ~(OFN_ENABLEHOOK | OFN_ENABLETEMPLATEHANDLE | OFN_ENABLETEMPLATE);
mFlagsEx = aLpofn->FlagsEx;
}
void
OpenFileNameIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const
{
aLpofn->lStructSize = sizeof(OPENFILENAMEW);
aLpofn->hwndOwner = mHwndOwner;
if (mHasFilter) {
memcpy(const_cast<LPWSTR>(aLpofn->lpstrFilter),
mFilter.data(), mFilter.size() * sizeof(wchar_t));
}
if (mHasCustomFilter) {
aLpofn->nMaxCustFilter = mCustomFilterIn.size() + 1 + mNMaxCustFilterOut;
wcscpy(aLpofn->lpstrCustomFilter, mCustomFilterIn.c_str());
memset(aLpofn->lpstrCustomFilter + mCustomFilterIn.size() + 1, 0,
mNMaxCustFilterOut * sizeof(wchar_t));
}
else {
aLpofn->nMaxCustFilter = 0;
}
aLpofn->nFilterIndex = mFilterIndex;
wcscpy(aLpofn->lpstrFile, mFile.c_str());
aLpofn->nMaxFile = mNMaxFile;
aLpofn->nMaxFileTitle = mNMaxFileTitle;
if (mHasInitialDir) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrInitialDir), mInitialDir.c_str());
}
if (mHasTitle) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrTitle), mTitle.c_str());
}
aLpofn->Flags = mFlags; /* TODO: Consider adding OFN_NOCHANGEDIR */
if (mHasDefExt) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrDefExt), mDefExt.c_str());
}
aLpofn->FlagsEx = mFlagsEx;
}
void
OpenFileNameIPC::AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const
{
if (mHasFilter) {
// mFilter is double-NULL terminated and it includes the double-NULL in its length.
aLpofn->lpstrFilter =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mFilter.size())));
}
if (mHasCustomFilter) {
aLpofn->lpstrCustomFilter =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * (mCustomFilterIn.size() + 1) + mNMaxCustFilterOut));
}
aLpofn->lpstrFile =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFile));
if (mNMaxFileTitle > 0) {
aLpofn->lpstrFileTitle =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFileTitle));
}
if (mHasInitialDir) {
aLpofn->lpstrInitialDir =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mInitialDir.size() + 1)));
}
if (mHasTitle) {
aLpofn->lpstrTitle =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mTitle.size() + 1)));
}
if (mHasDefExt) {
aLpofn->lpstrDefExt =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mDefExt.size() + 1)));
}
}
void
OpenFileNameIPC::FreeOfnStrings(LPOPENFILENAMEW aLpofn) const
{
if (aLpofn->lpstrFilter) {
free(const_cast<LPWSTR>(aLpofn->lpstrFilter));
}
if (aLpofn->lpstrCustomFilter) {
free(aLpofn->lpstrCustomFilter);
}
if (aLpofn->lpstrFile) {
free(aLpofn->lpstrFile);
}
if (aLpofn->lpstrFileTitle) {
free(aLpofn->lpstrFileTitle);
}
if (aLpofn->lpstrInitialDir) {
free(const_cast<LPWSTR>(aLpofn->lpstrInitialDir));
}
if (aLpofn->lpstrTitle) {
free(const_cast<LPWSTR>(aLpofn->lpstrTitle));
}
if (aLpofn->lpstrDefExt) {
free(const_cast<LPWSTR>(aLpofn->lpstrDefExt));
}
}
void
OpenFileNameRetIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn)
{
if (aLpofn->lpstrCustomFilter != nullptr) {
mCustomFilterOut =
std::wstring(aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1);
}
mFile.assign(aLpofn->lpstrFile, aLpofn->nMaxFile);
if (aLpofn->lpstrFileTitle != nullptr) {
mFileTitle.assign(aLpofn->lpstrFileTitle, wcslen(aLpofn->lpstrFileTitle) + 1);
}
mFileOffset = aLpofn->nFileOffset;
mFileExtension = aLpofn->nFileExtension;
}
void
OpenFileNameRetIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const
{
if (aLpofn->lpstrCustomFilter) {
LPWSTR secondString =
aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1;
const wchar_t* customFilterOut = mCustomFilterOut.c_str();
MOZ_ASSERT(wcslen(aLpofn->lpstrCustomFilter) + 1 +
wcslen(customFilterOut) + 1 + 1 <= aLpofn->nMaxCustFilter);
wcscpy(secondString, customFilterOut);
secondString[wcslen(customFilterOut) + 1] = L'\0'; // terminated with two NULLs
}
MOZ_ASSERT(mFile.size() <= aLpofn->nMaxFile);
memcpy(aLpofn->lpstrFile,
mFile.data(), mFile.size() * sizeof(wchar_t));
if (aLpofn->lpstrFileTitle != nullptr) {
MOZ_ASSERT(mFileTitle.size() + 1 < aLpofn->nMaxFileTitle);
wcscpy(aLpofn->lpstrFileTitle, mFileTitle.c_str());
}
aLpofn->nFileOffset = mFileOffset;
aLpofn->nFileExtension = mFileExtension;
}
#endif // XP_WIN
} // namespace plugins
} // namespace mozilla

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

@ -32,9 +32,6 @@
namespace mac_plugin_interposing { class NSCursorInfo { }; }
#endif
using mac_plugin_interposing::NSCursorInfo;
#ifdef XP_WIN
#include "commdlg.h"
#endif
namespace mozilla {
namespace plugins {
@ -126,59 +123,9 @@ typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
#ifdef XP_WIN
typedef base::SharedMemoryHandle WindowsSharedMemoryHandle;
typedef HANDLE DXGISharedSurfaceHandle;
// Values indicate GetOpenFileNameW and GetSaveFileNameW.
enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC };
// IPC-capable version of the Windows OPENFILENAMEW struct.
typedef struct _OpenFileNameIPC
{
// Allocates memory for the strings in this object. This should usually
// be used with a zeroed out OPENFILENAMEW structure.
void AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const;
void FreeOfnStrings(LPOPENFILENAMEW aLpofn) const;
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
NativeWindowHandle mHwndOwner;
std::wstring mFilter; // Double-NULL terminated (i.e. L"\0\0") if mHasFilter is true
bool mHasFilter;
std::wstring mCustomFilterIn;
bool mHasCustomFilter;
uint32_t mNMaxCustFilterOut;
uint32_t mFilterIndex;
std::wstring mFile;
uint32_t mNMaxFile;
uint32_t mNMaxFileTitle;
std::wstring mInitialDir;
bool mHasInitialDir;
std::wstring mTitle;
bool mHasTitle;
uint32_t mFlags;
std::wstring mDefExt;
bool mHasDefExt;
uint32_t mFlagsEx;
} OpenFileNameIPC;
// GetOpenFileNameW and GetSaveFileNameW overwrite fields of their OPENFILENAMEW
// parameter. This represents those values so that they can be returned via IPC.
typedef struct _OpenFileNameRetIPC
{
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
std::wstring mCustomFilterOut;
std::wstring mFile; // Double-NULL terminated (i.e. L"\0\0")
std::wstring mFileTitle;
uint16_t mFileOffset;
uint16_t mFileExtension;
} OpenFileNameRetIPC;
#else // XP_WIN
#else
typedef mozilla::null_t WindowsSharedMemoryHandle;
typedef mozilla::null_t DXGISharedSurfaceHandle;
typedef mozilla::null_t GetFileNameFunc;
typedef mozilla::null_t OpenFileNameIPC;
typedef mozilla::null_t OpenFileNameRetIPC;
#endif
// XXX maybe not the best place for these. better one?
@ -776,129 +723,6 @@ struct ParamTraits<mozilla::plugins::NPAudioDeviceChangeDetailsIPC>
}
};
#ifdef XP_WIN
template <>
struct ParamTraits<mozilla::plugins::_OpenFileNameIPC>
{
typedef mozilla::plugins::_OpenFileNameIPC paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mHwndOwner);
WriteParam(aMsg, aParam.mFilter);
WriteParam(aMsg, aParam.mHasFilter);
WriteParam(aMsg, aParam.mCustomFilterIn);
WriteParam(aMsg, aParam.mHasCustomFilter);
WriteParam(aMsg, aParam.mNMaxCustFilterOut);
WriteParam(aMsg, aParam.mFilterIndex);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mNMaxFile);
WriteParam(aMsg, aParam.mNMaxFileTitle);
WriteParam(aMsg, aParam.mInitialDir);
WriteParam(aMsg, aParam.mHasInitialDir);
WriteParam(aMsg, aParam.mTitle);
WriteParam(aMsg, aParam.mHasTitle);
WriteParam(aMsg, aParam.mFlags);
WriteParam(aMsg, aParam.mDefExt);
WriteParam(aMsg, aParam.mHasDefExt);
WriteParam(aMsg, aParam.mFlagsEx);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->mHwndOwner) &&
ReadParam(aMsg, aIter, &aResult->mFilter) &&
ReadParam(aMsg, aIter, &aResult->mHasFilter) &&
ReadParam(aMsg, aIter, &aResult->mCustomFilterIn) &&
ReadParam(aMsg, aIter, &aResult->mHasCustomFilter) &&
ReadParam(aMsg, aIter, &aResult->mNMaxCustFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFilterIndex) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mHasInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mTitle) &&
ReadParam(aMsg, aIter, &aResult->mHasTitle) &&
ReadParam(aMsg, aIter, &aResult->mFlags) &&
ReadParam(aMsg, aIter, &aResult->mDefExt) &&
ReadParam(aMsg, aIter, &aResult->mHasDefExt) &&
ReadParam(aMsg, aIter, &aResult->mFlagsEx)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%S, %S, %S, %S]", aParam.mFilter.c_str(),
aParam.mCustomFilterIn.c_str(), aParam.mFile.c_str(),
aParam.mTitle.c_str()));
}
};
template <>
struct ParamTraits<mozilla::plugins::_OpenFileNameRetIPC>
{
typedef mozilla::plugins::_OpenFileNameRetIPC paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mCustomFilterOut);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mFileTitle);
WriteParam(aMsg, aParam.mFileOffset);
WriteParam(aMsg, aParam.mFileExtension);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->mCustomFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mFileOffset) &&
ReadParam(aMsg, aIter, &aResult->mFileExtension)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%S, %S, %S, %d, %d]", aParam.mCustomFilterOut.c_str(),
aParam.mFile.c_str(), aParam.mFileTitle.c_str(),
aParam.mFileOffset, aParam.mFileExtension));
}
};
template <>
struct ParamTraits<mozilla::plugins::GetFileNameFunc>
{
typedef mozilla::plugins::GetFileNameFunc paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, static_cast<uint32_t>(aParam));
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
uint32_t result;
if (ReadParam(aMsg, aIter, &result)) {
*aResult = static_cast<paramType>(result);
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
aLog->append(StringPrintf(L"[%S]",
aParam == mozilla::plugins::OPEN_FUNC ? "GetOpenFileName" : "GetSaveFileName"));
}
};
#endif // XP_WIN
} /* namespace IPC */

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

@ -97,17 +97,6 @@ static HWND sBrowserHwnd = nullptr;
// sandbox process doesn't get current key states. So we need get it on chrome.
typedef SHORT (WINAPI *GetKeyStatePtr)(int);
static GetKeyStatePtr sGetKeyStatePtrStub = nullptr;
static WindowsDllInterceptor sComDlg32Intercept;
// proxy GetSaveFileName/GetOpenFileName on chrome so that we can know which
// files the user has given permission to access
// We count on GetOpenFileNameA/GetSaveFileNameA calling
// GetOpenFileNameW/GetSaveFileNameW so we don't proxy them explicitly.
typedef BOOL (WINAPI *GetOpenFileNameWPtr)(LPOPENFILENAMEW lpofn);
static GetOpenFileNameWPtr sGetOpenFileNameWPtrStub = nullptr;
typedef BOOL (WINAPI *GetSaveFileNameWPtr)(LPOPENFILENAMEW lpofn);
static GetSaveFileNameWPtr sGetSaveFileNameWPtrStub = nullptr;
#endif
/* static */
@ -2123,124 +2112,6 @@ PMCGetKeyState(int aVirtKey)
}
return sGetKeyStatePtrStub(aVirtKey);
}
BOOL WINAPI PMCGetSaveFileNameW(LPOPENFILENAMEW lpofn);
BOOL WINAPI PMCGetOpenFileNameW(LPOPENFILENAMEW lpofn);
// Runnable that performs GetOpenFileNameW and GetSaveFileNameW
// on the main thread so that the call can be
// synchronously run on the PluginModuleParent via IPC.
// The task alerts the given semaphore when it is finished.
class GetFileNameTask : public Runnable
{
BOOL* mReturnValue;
void* mLpOpenFileName;
HANDLE mSemaphore;
GetFileNameFunc mFunc;
public:
explicit GetFileNameTask(GetFileNameFunc func, void* aLpOpenFileName,
HANDLE aSemaphore, BOOL* aReturnValue) :
mLpOpenFileName(aLpOpenFileName), mSemaphore(aSemaphore),
mReturnValue(aReturnValue), mFunc(func)
{}
NS_IMETHOD Run() override
{
PLUGIN_LOG_DEBUG_METHOD;
AssertPluginThread();
switch (mFunc) {
case OPEN_FUNC:
*mReturnValue =
PMCGetOpenFileNameW(static_cast<LPOPENFILENAMEW>(mLpOpenFileName));
break;
case SAVE_FUNC:
*mReturnValue =
PMCGetSaveFileNameW(static_cast<LPOPENFILENAMEW>(mLpOpenFileName));
break;
}
if (!ReleaseSemaphore(mSemaphore, 1, nullptr)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
};
// static
BOOL
PostToPluginThread(GetFileNameFunc aFunc, void* aLpofn)
{
MOZ_ASSERT(!IsPluginThread());
// Synchronously run GetFileNameTask from the main thread.
// Start a semaphore at 0. We release the semaphore (bringing its
// count to 1) when the synchronous call is done.
nsAutoHandle semaphore(CreateSemaphore(NULL, 0, 1, NULL));
if (semaphore == nullptr) {
MOZ_ASSERT(semaphore != nullptr);
return FALSE;
}
BOOL returnValue = FALSE;
RefPtr<GetFileNameTask> task =
new GetFileNameTask(aFunc, aLpofn, semaphore, &returnValue);
ProcessChild::message_loop()->PostTask(task.forget());
DWORD err = WaitForSingleObject(semaphore, INFINITE);
if (err != WAIT_FAILED) {
return returnValue;
}
PLUGIN_LOG_DEBUG(("Error while waiting for semaphore: %d",
GetLastError()));
MOZ_ASSERT(err != WAIT_FAILED);
return FALSE;
}
// static
BOOL WINAPI
PMCGetFileNameW(GetFileNameFunc aFunc, LPOPENFILENAMEW aLpofn)
{
if (!IsPluginThread()) {
return PostToPluginThread(aFunc, aLpofn);
}
PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome();
if (chromeInstance) {
bool ret = FALSE;
OpenFileNameIPC inputOfn;
inputOfn.CopyFromOfn(aLpofn);
OpenFileNameRetIPC outputOfn;
if (chromeInstance->CallGetFileName(aFunc, inputOfn,
&outputOfn, &ret)) {
if (ret) {
outputOfn.AddToOfn(aLpofn);
}
}
return ret;
}
switch (aFunc) {
case OPEN_FUNC:
return sGetOpenFileNameWPtrStub(aLpofn);
case SAVE_FUNC:
return sGetSaveFileNameWPtrStub(aLpofn);
}
MOZ_ASSERT_UNREACHABLE("Illegal GetFileNameFunc value");
return FALSE;
}
// static
BOOL WINAPI
PMCGetSaveFileNameW(LPOPENFILENAMEW aLpofn)
{
return PMCGetFileNameW(SAVE_FUNC, aLpofn);
}
// static
BOOL WINAPI
PMCGetOpenFileNameW(LPOPENFILENAMEW aLpofn)
{
return PMCGetFileNameW(OPEN_FUNC, aLpofn);
}
#endif
PPluginInstanceChild*
@ -2273,17 +2144,6 @@ PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType,
sUser32Intercept.AddHook("GetKeyState", reinterpret_cast<intptr_t>(PMCGetKeyState),
(void**) &sGetKeyStatePtrStub);
}
sComDlg32Intercept.Init("comdlg32.dll");
if (!sGetSaveFileNameWPtrStub) {
sComDlg32Intercept.AddHook("GetSaveFileNameW", reinterpret_cast<intptr_t>(PMCGetSaveFileNameW),
(void**) &sGetSaveFileNameWPtrStub);
}
if (!sGetOpenFileNameWPtrStub) {
sComDlg32Intercept.AddHook("GetOpenFileNameW", reinterpret_cast<intptr_t>(PMCGetOpenFileNameW),
(void**) &sGetOpenFileNameWPtrStub);
}
#endif
return new PluginInstanceChild(&mFunctions, aMimeType, aMode, aNames,

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

@ -810,10 +810,6 @@ PluginModuleChromeParent::~PluginModuleChromeParent()
false);
#endif
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mSandboxPermissions.RemovePermissionsForProcess(OtherPid());
#endif
if (!mShutdown) {
NS_WARNING("Plugin host deleted the module without shutting down.");
NPError err;
@ -3407,69 +3403,3 @@ PluginModuleChromeParent::AnswerGetKeyState(const int32_t& aVirtKey,
return PluginModuleParent::AnswerGetKeyState(aVirtKey, aRet);
#endif
}
mozilla::ipc::IPCResult
PluginModuleChromeParent::AnswerGetFileName(const GetFileNameFunc& aFunc,
const OpenFileNameIPC& aOfnIn,
OpenFileNameRetIPC* aOfnOut,
bool* aResult)
{
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
OPENFILENAMEW ofn;
memset(&ofn, 0, sizeof(ofn));
aOfnIn.AllocateOfnStrings(&ofn);
aOfnIn.AddToOfn(&ofn);
switch (aFunc) {
case OPEN_FUNC:
*aResult = GetOpenFileName(&ofn);
break;
case SAVE_FUNC:
*aResult = GetSaveFileName(&ofn);
break;
}
if (*aResult) {
if (ofn.Flags & OFN_ALLOWMULTISELECT) {
// We only support multiselect with the OFN_EXPLORER flag.
// This guarantees that ofn.lpstrFile follows the pattern below.
MOZ_ASSERT(ofn.Flags & OFN_EXPLORER);
// lpstrFile is one of two things:
// 1. A null terminated full path to a file, or
// 2. A path to a folder, followed by a NULL, followed by a
// list of file names, each NULL terminated, followed by an
// additional NULL (so it is also double-NULL terminated).
std::wstring path = std::wstring(ofn.lpstrFile);
MOZ_ASSERT(ofn.nFileOffset > 0);
// For condition #1, nFileOffset points to the file name in the path.
// It will be preceeded by a non-NULL character from the path.
if (ofn.lpstrFile[ofn.nFileOffset-1] != L'\0') {
mSandboxPermissions.GrantFileAccess(OtherPid(), path.c_str(),
aFunc == SAVE_FUNC);
}
else {
// This is condition #2
wchar_t* nextFile = ofn.lpstrFile + path.size() + 1;
while (*nextFile != L'\0') {
std::wstring nextFileStr(nextFile);
std::wstring fullPath =
path + std::wstring(L"\\") + nextFileStr;
mSandboxPermissions.GrantFileAccess(OtherPid(), fullPath.c_str(),
aFunc == SAVE_FUNC);
nextFile += nextFileStr.size() + 1;
}
}
}
else {
mSandboxPermissions.GrantFileAccess(OtherPid(), ofn.lpstrFile,
aFunc == SAVE_FUNC);
}
aOfnOut->CopyFromOfn(&ofn);
}
aOfnIn.FreeOfnStrings(&ofn);
return IPC_OK();
#else
MOZ_ASSERT_UNREACHABLE("GetFileName IPC message is only available on "
"Windows builds with sandbox.");
return IPC_FAIL_NO_REASON(this);
#endif
}

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

@ -24,7 +24,6 @@
#include "nsIObserver.h"
#ifdef XP_WIN
#include "nsWindowsHelpers.h"
#include "sandboxPermissions.h"
#endif
#ifdef MOZ_CRASHREPORTER
@ -195,14 +194,6 @@ protected:
const bool& shouldRegister,
NPError* result) override;
virtual mozilla::ipc::IPCResult
AnswerGetFileName(const GetFileNameFunc& aFunc,
const OpenFileNameIPC& aOfnIn,
OpenFileNameRetIPC* aOfnOut, bool* aResult) override
{
return IPC_FAIL_NO_REASON(this);
}
protected:
void SetChildTimeout(const int32_t aChildTimeout);
static void TimeoutChanged(const char* aPref, void* aModule);
@ -518,12 +509,6 @@ class PluginModuleChromeParent
virtual mozilla::ipc::IPCResult
AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override;
// Proxy GetOpenFileName/GetSaveFileName on Windows.
virtual mozilla::ipc::IPCResult
AnswerGetFileName(const GetFileNameFunc& aFunc,
const OpenFileNameIPC& aOfnIn,
OpenFileNameRetIPC* aOfnOut, bool* aResult) override;
private:
virtual void
EnteredCxxStack() override;
@ -677,9 +662,6 @@ private:
nsCString mProfile;
bool mIsBlocklisted;
static bool sInstantiated;
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mozilla::SandboxPermissions mSandboxPermissions;
#endif
};
} // namespace plugins

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

@ -97,6 +97,13 @@ AddSandboxAllowedFiles(int32_t aSandboxLevel,
return;
}
// Higher than level 2 currently removes the users own rights.
if (aSandboxLevel > 2) {
AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR);
AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR,
NS_LITERAL_STRING("\\*"));
}
// Level 2 and above is now using low integrity, so we need to give write
// access to the Flash directories.
// This should be made Flash specific (Bug 1171396).

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

@ -129,7 +129,6 @@ if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
LOCAL_INCLUDES += [
'/security/sandbox/chromium',
'/security/sandbox/chromium-shim',
'/security/sandbox/win/src/sandboxpermissions',
]
DEFINES['FORCE_PR_LOG'] = True

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

@ -1,136 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
/* SandboxPermissions.cpp - Special permissions granted to sandboxed processes */
#include "permissionsService.h"
#include <algorithm>
#include <winternl.h>
namespace mozilla {
namespace sandboxing {
static const std::wstring ZONE_IDENTIFIER_STR(L":ZONE.IDENTIFIER");
static const std::wstring ZONE_ID_DATA_STR(L":ZONE.IDENTIFIER:$DATA");
bool
StringEndsWith(const std::wstring& str, const std::wstring& strEnding)
{
if (strEnding.size() > str.size()) {
return false;
}
return std::equal(strEnding.rbegin(), strEnding.rend(), str.rbegin());
}
// Converts NT device internal filenames to normal user-space by stripping
// the prefixes and suffixes from the file name.
std::wstring
GetPlainFileName(const wchar_t* aNTFileName)
{
while (*aNTFileName == L'\\' || *aNTFileName == L'.' ||
*aNTFileName == L'?' || *aNTFileName == L':' ) {
++aNTFileName;
}
std::wstring nameCopy(aNTFileName);
std::transform(nameCopy.begin(), nameCopy.end(), nameCopy.begin(), towupper);
if (StringEndsWith(nameCopy, ZONE_ID_DATA_STR)) {
nameCopy = nameCopy.substr(0, nameCopy.size() - ZONE_ID_DATA_STR.size());
} else if (StringEndsWith(nameCopy, ZONE_IDENTIFIER_STR)) {
nameCopy = nameCopy.substr(0, nameCopy.size() - ZONE_IDENTIFIER_STR.size());
}
return nameCopy;
}
/* static */ PermissionsService*
PermissionsService::GetInstance()
{
static PermissionsService sPermissionsService;
return &sPermissionsService;
}
PermissionsService::PermissionsService() :
mFileAccessViolationFunc(nullptr)
{
}
void
PermissionsService::GrantFileAccess(uint32_t aProcessId,
const wchar_t* aFilename,
bool aPermitWrite)
{
FilePermissionMap& permissions = mProcessFilePermissions[aProcessId];
std::wstring filename = GetPlainFileName(aFilename);
permissions[filename] |= aPermitWrite;
}
void
PermissionsService::SetFileAccessViolationFunc(FileAccessViolationFunc aFavFunc)
{
mFileAccessViolationFunc = aFavFunc;
}
void
PermissionsService::ReportBlockedFile(bool aNeedsWrite)
{
if (mFileAccessViolationFunc) {
mFileAccessViolationFunc(aNeedsWrite);
}
}
bool
PermissionsService::UserGrantedFileAccess(uint32_t aProcessId,
const wchar_t* aFilename,
uint32_t aAccess,
uint32_t aDisposition)
{
// There are 3 types of permissions:
// * Those available w/ read-only permission
// * Those available w/ read-only AND read-write permission
// * Those always forbidden.
const uint32_t FORBIDDEN_FLAGS =
FILE_EXECUTE | FILE_LIST_DIRECTORY | FILE_TRAVERSE | STANDARD_RIGHTS_EXECUTE;
const uint32_t NEEDS_WRITE_FLAGS =
FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA |
DELETE | STANDARD_RIGHTS_WRITE;
bool needsWrite =
(aAccess & NEEDS_WRITE_FLAGS) || (aDisposition != FILE_OPEN);
if (aAccess & FORBIDDEN_FLAGS) {
ReportBlockedFile(needsWrite);
return false;
}
auto permissions = mProcessFilePermissions.find(aProcessId);
if (permissions == mProcessFilePermissions.end()) {
ReportBlockedFile(needsWrite);
return false; // process has no special file access at all
}
std::wstring filename = GetPlainFileName(aFilename);
auto itPermission = permissions->second.find(filename);
if (itPermission == permissions->second.end()) {
ReportBlockedFile(needsWrite);
return false; // process has no access to this file
}
// We have read permission. Check for write permission if requested.
if (!needsWrite || itPermission->second) {
return true;
}
// We needed write access but didn't have it.
ReportBlockedFile(needsWrite);
return false;
}
void
PermissionsService::RemovePermissionsForProcess(uint32_t aProcessId)
{
mProcessFilePermissions.erase(aProcessId);
}
} // namespace sandboxing
} // namespace mozilla

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

@ -1,78 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_sandboxing_permissionsService_h
#define mozilla_sandboxing_permissionsService_h
#include <unordered_map>
namespace mozilla {
namespace sandboxing {
/*
* Represents additional permissions granted to sandboxed processes.
* The members are virtual so that the object can be created in any
* library that links with libsandbox_s and then shared with and used
* by libXUL, which does not link with libsandbox_s.
*/
class PermissionsService
{
public:
static PermissionsService* GetInstance();
/*
* Allow future access to aFilename by the plugin process.
*/
virtual void GrantFileAccess(uint32_t aProcessId, const wchar_t* aFilename,
bool aPermitWrite);
/*
* Type of callback function that the sandbox uses to report file
* accesses that were denied.
* Parameter is a boolean indicating the access request was read-only
* (false) or read-write (true)
*/
typedef void (*FileAccessViolationFunc)(bool);
/*
* Sets the callback function that is called whenever a file access is
* denied by the sandbox.
*/
virtual void SetFileAccessViolationFunc(FileAccessViolationFunc aFavFunc);
/*
* Returns true if the user has granted the sandboxed plugin process the
* requested permission to open the file.
* Calls aFavFunc with file info if the file access was blocked.
*/
virtual bool UserGrantedFileAccess(uint32_t aProcessId, const wchar_t* aFilename,
uint32_t aAccess, uint32_t aDisposition);
/*
* Clears all special file access for the given plugin process.
*/
virtual void RemovePermissionsForProcess(uint32_t aProcessId);
private:
PermissionsService();
void ReportBlockedFile(bool aNeedsWrite);
// Maps from filenames to a boolean indicating read-only permission (false) or
// read-write permission (true).
typedef std::unordered_map<std::wstring, bool> FilePermissionMap;
// Maps from process ID to map of user-granted file permissions for
// that process.
typedef std::unordered_map<uint32_t, FilePermissionMap> ProcessFilePermissionMap;
ProcessFilePermissionMap mProcessFilePermissions;
FileAccessViolationFunc mFileAccessViolationFunc;
};
} // namespace sandboxing
} // namespace mozilla
#endif // mozilla_sandboxing_permissionsService_h

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

@ -17,8 +17,6 @@
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_nt_util.h"
#include "mozilla/sandboxing/permissionsService.h"
namespace sandbox {
FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
@ -117,16 +115,6 @@ bool FilesystemDispatcher::NtCreateFile(IPCInfo* ipc,
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
params.GetBase());
// If the policies forbid access (any result other than ASK_BROKER),
// then check for user-granted access to file.
if (ASK_BROKER != result &&
mozilla::sandboxing::PermissionsService::GetInstance()->
UserGrantedFileAccess(ipc->client_info->process_id, filename,
desired_access, create_disposition)) {
result = ASK_BROKER;
}
HANDLE handle;
ULONG_PTR io_information = 0;
NTSTATUS nt_status;
@ -174,16 +162,6 @@ bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc,
// knows what to do.
EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
params.GetBase());
// If the policies forbid access (any result other than ASK_BROKER),
// then check for user-granted access to file.
if (ASK_BROKER != result &&
mozilla::sandboxing::PermissionsService::GetInstance()->UserGrantedFileAccess(
ipc->client_info->process_id, filename,
desired_access, create_disposition)) {
result = ASK_BROKER;
}
HANDLE handle;
ULONG_PTR io_information = 0;
NTSTATUS nt_status;

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

@ -70,6 +70,9 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
break;
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
// The following call must match in the parameters with
@ -150,6 +153,9 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
params[OpenFile::BROKER] = ParamPickerMake(broker);
if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
break;
SharedMemIPCClient ipc(memory);
CrossCallReturn answer = {0};
ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,

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

@ -19,7 +19,6 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
DIRS += [
'win/src/sandboxbroker',
'win/src/sandboxpermissions',
'win/src/sandboxtarget',
]
@ -30,7 +29,6 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
EXPORTS.mozilla.sandboxing += [
'chromium-shim/sandbox/win/loggingCallbacks.h',
'chromium-shim/sandbox/win/loggingTypes.h',
'chromium-shim/sandbox/win/permissionsService.h',
'chromium-shim/sandbox/win/sandboxLogging.h',
'win/SandboxInitialization.h',
]
@ -38,7 +36,6 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'chromium-shim/base/files/file_path.cpp',
'chromium-shim/base/logging.cpp',
'chromium-shim/sandbox/win/permissionsService.cpp',
'chromium-shim/sandbox/win/sandboxLogging.cpp',
'chromium/base/at_exit.cc',
'chromium/base/base_switches.cc',

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

@ -7,7 +7,6 @@
#include "SandboxInitialization.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "mozilla/sandboxing/permissionsService.h"
namespace mozilla {
namespace sandboxing {
@ -78,10 +77,5 @@ GetInitializedBrokerServices()
return sInitializedBrokerServices;
}
PermissionsService* GetPermissionsService()
{
return PermissionsService::GetInstance();
}
} // sandboxing
} // mozilla

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

@ -21,8 +21,6 @@ namespace mozilla {
// sandbox for our namespace painful.
namespace sandboxing {
class PermissionsService;
/**
* Initializes (if required) and returns the Chromium sandbox TargetServices.
*
@ -43,8 +41,6 @@ void LowerSandbox();
*/
sandbox::BrokerServices* GetInitializedBrokerServices();
PermissionsService* GetPermissionsService();
} // sandboxing
} // mozilla

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

@ -1,22 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
SOURCES += [
'sandboxPermissions.cpp',
]
EXPORTS += [
'sandboxPermissions.h',
]
for var in ('UNICODE', '_UNICODE'):
DEFINES[var] = True
LOCAL_INCLUDES += [
'/security/sandbox/win',
]
FINAL_LIBRARY = 'xul'

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

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#include "sandboxPermissions.h"
#include "mozilla/Assertions.h"
#include "mozilla/sandboxing/permissionsService.h"
namespace mozilla
{
sandboxing::PermissionsService* SandboxPermissions::sPermissionsService = nullptr;
void
SandboxPermissions::Initialize(sandboxing::PermissionsService* aPermissionsService,
FileAccessViolationFunc aFileAccessViolationFunc)
{
sPermissionsService = aPermissionsService;
sPermissionsService->SetFileAccessViolationFunc(aFileAccessViolationFunc);
}
void
SandboxPermissions::GrantFileAccess(uint32_t aProcessId, const wchar_t* aFilename,
bool aPermitWrite)
{
MOZ_ASSERT(sPermissionsService, "Must initialize sandbox PermissionsService");
sPermissionsService->GrantFileAccess(aProcessId, aFilename, aPermitWrite);
}
void
SandboxPermissions::RemovePermissionsForProcess(uint32_t aProcessId)
{
MOZ_ASSERT(sPermissionsService, "Must initialize sandbox PermissionsService");
sPermissionsService->RemovePermissionsForProcess(aProcessId);
}
} // namespace mozilla

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

@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_sandboxing_sandboxPermissions_h
#define mozilla_sandboxing_sandboxPermissions_h
#include <stdint.h>
#include <windows.h>
namespace mozilla {
namespace sandboxing {
class PermissionsService;
}
/*
* This object wraps a PermissionsService object. This object is available
* in libXUL but PermissionsService is not.
*/
class SandboxPermissions
{
public:
/*
* Type of callback function that the sandbox uses to report file
* accesses that were denied.
* Parameter is a boolean indicating the access request was read-only
* (false) or read-write (true)
*/
typedef void (*FileAccessViolationFunc)(bool);
/*
* Prepare this object by providing it with the internal permissions service.
*/
static void Initialize(sandboxing::PermissionsService* aPermissionsService,
FileAccessViolationFunc aFileAccessViolationFunc);
/*
* Allow future access to aFilename by the process with the given ID.
*/
void GrantFileAccess(uint32_t aProcessId, const wchar_t* aFilename,
bool aPermitWrite);
/*
* Clears all special file access for the given process.
*/
void RemovePermissionsForProcess(uint32_t aProcessId);
private:
static sandboxing::PermissionsService* sPermissionsService;
};
} // mozilla
#endif // mozilla_sandboxing_sandboxPermissions_h

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

@ -31,18 +31,11 @@ class BrokerServices;
namespace mozilla {
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
namespace sandboxing {
class PermissionsService;
}
#endif
struct BootstrapConfig
{
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
/* Chromium sandbox BrokerServices. */
sandbox::BrokerServices* sandboxBrokerServices;
sandboxing::PermissionsService* sandboxPermissionsService;
#endif
/* Pointer to static XRE AppData from application.ini.h */
const StaticXREAppData* appData;

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

@ -214,7 +214,6 @@
#include "mozilla/SandboxInfo.h"
#elif defined(XP_WIN)
#include "SandboxBroker.h"
#include "SandboxPermissions.h"
#endif
#endif
@ -3319,10 +3318,6 @@ XREMain::XRE_mainInit(bool* aExitFlag)
NS_WARNING("Failed to initialize broker services, sandboxed processes will "
"fail to start.");
}
if (mAppData->sandboxPermissionsService) {
SandboxPermissions::Initialize(mAppData->sandboxPermissionsService,
nullptr);
}
#endif
#ifdef XP_MACOSX
@ -4611,7 +4606,6 @@ XREMain::XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig)
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mAppData->sandboxBrokerServices = aConfig.sandboxBrokerServices;
mAppData->sandboxPermissionsService = aConfig.sandboxPermissionsService;
#endif
mozilla::IOInterposerInit ioInterposerGuard;

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

@ -209,20 +209,15 @@ int main()
TestHook("kernel32.dll", "VirtualAlloc") &&
TestHook("kernel32.dll", "MapViewOfFile") &&
TestHook("gdi32.dll", "CreateDIBSection") &&
TestHook("kernel32.dll", "CreateFileW") && // see Bug 1316415
TestHook("kernel32.dll", "CreateFileW") &&
#endif
TestHook("kernel32.dll", "CreateFileA") &&
TestDetour("user32.dll", "CreateWindowExW") &&
TestHook("user32.dll", "InSendMessageEx") &&
TestHook("imm32.dll", "ImmGetContext") &&
// TestHook("imm32.dll", "ImmReleaseContext") && // see Bug 1316415
TestHook("imm32.dll", "ImmGetCompositionStringW") &&
TestHook("imm32.dll", "ImmSetCandidateWindow") &&
TestHook("imm32.dll", "ImmNotifyIME") &&
TestHook("comdlg32.dll", "GetSaveFileNameW") &&
TestHook("comdlg32.dll", "GetOpenFileNameW") &&
#ifdef _M_X64
TestHook("user32.dll", "GetKeyState") && // see Bug 1316415
TestHook("user32.dll", "GetKeyState") &&
#endif
MaybeTestHook(ShouldTestTipTsf(), "tiptsf.dll", "ProcessCaretEvents") &&
#ifdef _M_IX86

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

@ -17,11 +17,6 @@
namespace sandbox {
class BrokerServices;
}
namespace mozilla {
namespace sandboxing {
class PermissionsService;
}
}
#endif
namespace mozilla {
@ -199,7 +194,6 @@ public:
* Chromium sandbox BrokerServices.
*/
sandbox::BrokerServices* sandboxBrokerServices = nullptr;
mozilla::sandboxing::PermissionsService* sandboxPermissionsService;
#endif
};

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

@ -70,12 +70,6 @@
#include <stdint.h>
#define COPY_CODES(NBYTES) do { \
memcpy(&tramp[nTrampBytes], &origBytes[nOrigBytes], NBYTES); \
nOrigBytes += NBYTES; \
nTrampBytes += NBYTES; \
} while (0)
namespace mozilla {
namespace internal {
@ -549,8 +543,7 @@ protected:
enum JumpType {
Je,
Jmp,
Call
Jmp
};
struct JumpPatch {
@ -564,6 +557,14 @@ protected:
{
}
void AddJumpPatch(size_t aHookOffset, intptr_t aAbsJumpAddress,
JumpType aType = JumpType::Jmp)
{
mHookOffset = aHookOffset;
mJumpAddress = aAbsJumpAddress;
mType = aType;
}
size_t GenerateJump(uint8_t* aCode)
{
size_t offset = mHookOffset;
@ -574,26 +575,20 @@ protected:
offset += 2;
}
// Near call/jmp, absolute indirect, address given in r/m32
if (mType == JumpType::Call) {
// CALL [RIP+0]
aCode[offset] = 0xff;
aCode[offset + 1] = 0x15;
// The offset to jump destination -- ie it is placed 2 bytes after the offset.
*reinterpret_cast<int32_t*>(aCode + offset + 2) = 2;
aCode[offset + 2 + 4] = 0xeb; // JMP +8 (jump over mJumpAddress)
aCode[offset + 2 + 4 + 1] = 8;
*reinterpret_cast<int64_t*>(aCode + offset + 2 + 4 + 2) = mJumpAddress;
return offset + 2 + 4 + 2 + 8;
} else {
// JMP [RIP+0]
aCode[offset] = 0xff;
aCode[offset + 1] = 0x25;
// The offset to jump destination is 0
*reinterpret_cast<int32_t*>(aCode + offset + 2) = 0;
*reinterpret_cast<int64_t*>(aCode + offset + 2 + 4) = mJumpAddress;
return offset + 2 + 4 + 8;
}
// JMP [RIP+0]
aCode[offset] = 0xff;
aCode[offset + 1] = 0x25;
*reinterpret_cast<int32_t*>(aCode + offset + 2) = 0;
// Jump table
*reinterpret_cast<int64_t*>(aCode + offset + 2 + 4) = mJumpAddress;
return offset + 2 + 4 + 8;
}
bool HasJumpPatch() const
{
return !!mJumpAddress;
}
size_t mHookOffset;
@ -677,359 +672,283 @@ protected:
return;
}
// We keep the address of the original function in the first bytes of
// the trampoline buffer
*((void**)tramp) = aOrigFunction;
tramp += sizeof(void*);
byteptr_t origBytes = (byteptr_t)aOrigFunction;
// # of bytes of the original function that we can overwrite.
int nOrigBytes = 0;
int nBytes = 0;
#if defined(_M_IX86)
int pJmp32 = -1;
while (nOrigBytes < 5) {
while (nBytes < 5) {
// Understand some simple instructions that might be found in a
// prologue; we might need to extend this as necessary.
//
// Note! If we ever need to understand jump instructions, we'll
// need to rewrite the displacement argument.
unsigned char prefixGroups;
int numPrefixBytes = CountPrefixBytes(origBytes, nOrigBytes, &prefixGroups);
int numPrefixBytes = CountPrefixBytes(origBytes, nBytes, &prefixGroups);
if (numPrefixBytes < 0 || (prefixGroups & (ePrefixGroup3 | ePrefixGroup4))) {
// Either the prefix sequence was bad, or there are prefixes that
// we don't currently support (groups 3 and 4)
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
nOrigBytes += numPrefixBytes;
if (origBytes[nOrigBytes] >= 0x88 &&
origBytes[nOrigBytes] <= 0x8B) {
nBytes += numPrefixBytes;
if (origBytes[nBytes] >= 0x88 && origBytes[nBytes] <= 0x8B) {
// various MOVs
++nOrigBytes;
int len = CountModRmSib(origBytes + nOrigBytes);
++nBytes;
int len = CountModRmSib(origBytes + nBytes);
if (len < 0) {
MOZ_ASSERT_UNREACHABLE("Unrecognized MOV opcode sequence");
return;
}
nOrigBytes += len;
} else if (origBytes[nOrigBytes] == 0xA1) {
nBytes += len;
} else if (origBytes[nBytes] == 0xA1) {
// MOV eax, [seg:offset]
nOrigBytes += 5;
} else if (origBytes[nOrigBytes] == 0xB8) {
nBytes += 5;
} else if (origBytes[nBytes] == 0xB8) {
// MOV 0xB8: http://ref.x86asm.net/coder32.html#xB8
nOrigBytes += 5;
} else if (origBytes[nOrigBytes] == 0x33 &&
(origBytes[nOrigBytes+1] & kMaskMod) == kModReg) {
// XOR r32, r32
nOrigBytes += 2;
} else if ((origBytes[nOrigBytes] & 0xf8) == 0x40) {
// INC r32
nOrigBytes += 1;
} else if (origBytes[nOrigBytes] == 0x83) {
nBytes += 5;
} else if (origBytes[nBytes] == 0x83) {
// ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r/m, imm8
unsigned char b = origBytes[nOrigBytes + 1];
unsigned char b = origBytes[nBytes + 1];
if ((b & 0xc0) == 0xc0) {
// ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r, imm8
nOrigBytes += 3;
nBytes += 3;
} else {
// bail
MOZ_ASSERT_UNREACHABLE("Unrecognized bit opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x68) {
} else if (origBytes[nBytes] == 0x68) {
// PUSH with 4-byte operand
nOrigBytes += 5;
} else if ((origBytes[nOrigBytes] & 0xf0) == 0x50) {
nBytes += 5;
} else if ((origBytes[nBytes] & 0xf0) == 0x50) {
// 1-byte PUSH/POP
nOrigBytes++;
} else if (origBytes[nOrigBytes] == 0x6A) {
nBytes++;
} else if (origBytes[nBytes] == 0x6A) {
// PUSH imm8
nOrigBytes += 2;
} else if (origBytes[nOrigBytes] == 0xe9) {
pJmp32 = nOrigBytes;
nBytes += 2;
} else if (origBytes[nBytes] == 0xe9) {
pJmp32 = nBytes;
// jmp 32bit offset
nOrigBytes += 5;
} else if (origBytes[nOrigBytes] == 0xff &&
origBytes[nOrigBytes + 1] == 0x25) {
nBytes += 5;
} else if (origBytes[nBytes] == 0xff && origBytes[nBytes + 1] == 0x25) {
// jmp [disp32]
nOrigBytes += 6;
} else if (origBytes[nOrigBytes] == 0xc2) {
// ret imm16. We can't handle this but it happens. We don't ASSERT but we do fail to hook.
#if defined(MOZILLA_INTERNAL_API)
NS_WARNING("Cannot hook method -- RET opcode found");
#endif
return;
nBytes += 6;
} else {
//printf ("Unknown x86 instruction byte 0x%02x, aborting trampoline\n", origBytes[nOrigBytes]);
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
//printf ("Unknown x86 instruction byte 0x%02x, aborting trampoline\n", origBytes[nBytes]);
return;
}
}
// The trampoline is a copy of the instructions that we just traced,
// followed by a jump that we add below.
memcpy(tramp, aOrigFunction, nOrigBytes);
#elif defined(_M_X64)
// The number of bytes used by the trampoline.
int nTrampBytes = 0;
bool foundJmp = false;
JumpPatch jump;
while (nOrigBytes < 13) {
// If we found JMP 32bit offset, we require that the next bytes must
// be NOP or INT3. There is no reason to copy them.
// TODO: This used to trigger for Je as well. Now that I allow
// instructions after CALL and JE, I don't think I need that.
// The only real value of this condition is that if code follows a JMP
// then its _probably_ the target of a JMP somewhere else and we
// will be overwriting it, which would be tragic. This seems
// highly unlikely.
if (foundJmp) {
if (origBytes[nOrigBytes] == 0x90 || origBytes[nOrigBytes] == 0xcc) {
nOrigBytes++;
while (nBytes < 13) {
// if found JMP 32bit offset, next bytes must be NOP or INT3
if (jump.HasJumpPatch()) {
if (origBytes[nBytes] == 0x90 || origBytes[nBytes] == 0xcc) {
nBytes++;
continue;
}
MOZ_ASSERT_UNREACHABLE("Opcode sequence includes commands after JMP");
return;
}
if (origBytes[nOrigBytes] == 0x0f) {
COPY_CODES(1);
if (origBytes[nOrigBytes] == 0x1f) {
if (origBytes[nBytes] == 0x0f) {
nBytes++;
if (origBytes[nBytes] == 0x1f) {
// nop (multibyte)
COPY_CODES(1);
if ((origBytes[nOrigBytes] & 0xc0) == 0x40 &&
(origBytes[nOrigBytes] & 0x7) == 0x04) {
COPY_CODES(3);
nBytes++;
if ((origBytes[nBytes] & 0xc0) == 0x40 &&
(origBytes[nBytes] & 0x7) == 0x04) {
nBytes += 3;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x05) {
} else if (origBytes[nBytes] == 0x05) {
// syscall
COPY_CODES(1);
} else if (origBytes[nOrigBytes] == 0x84) {
nBytes++;
} else if (origBytes[nBytes] == 0x84) {
// je rel32
JumpPatch jump(nTrampBytes - 1, // overwrite the 0x0f we copied above
(intptr_t)(origBytes + nOrigBytes + 5 +
*(reinterpret_cast<int32_t*>(origBytes + nOrigBytes + 1))),
JumpType::Je);
nTrampBytes = jump.GenerateJump(tramp);
nOrigBytes += 5;
jump.AddJumpPatch(nBytes - 1,
(intptr_t)
origBytes + nBytes + 5 +
*(reinterpret_cast<int32_t*>(origBytes +
nBytes + 1)),
JumpType::Je);
nBytes += 5;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x40 ||
origBytes[nOrigBytes] == 0x41) {
} else if (origBytes[nBytes] == 0x40 ||
origBytes[nBytes] == 0x41) {
// Plain REX or REX.B
COPY_CODES(1);
if ((origBytes[nOrigBytes] & 0xf0) == 0x50) {
nBytes++;
if ((origBytes[nBytes] & 0xf0) == 0x50) {
// push/pop with Rx register
COPY_CODES(1);
} else if (origBytes[nOrigBytes] >= 0xb8 && origBytes[nOrigBytes] <= 0xbf) {
nBytes++;
} else if (origBytes[nBytes] >= 0xb8 && origBytes[nBytes] <= 0xbf) {
// mov r32, imm32
COPY_CODES(5);
nBytes += 5;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x45) {
} else if (origBytes[nBytes] == 0x45) {
// REX.R & REX.B
COPY_CODES(1);
nBytes++;
if (origBytes[nOrigBytes] == 0x33) {
if (origBytes[nBytes] == 0x33) {
// xor r32, r32
COPY_CODES(2);
nBytes += 2;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if ((origBytes[nOrigBytes] & 0xfb) == 0x48) {
} else if ((origBytes[nBytes] & 0xfb) == 0x48) {
// REX.W | REX.WR
COPY_CODES(1);
nBytes++;
if (origBytes[nOrigBytes] == 0x81 &&
(origBytes[nOrigBytes + 1] & 0xf8) == 0xe8) {
if (origBytes[nBytes] == 0x81 &&
(origBytes[nBytes + 1] & 0xf8) == 0xe8) {
// sub r, dword
COPY_CODES(6);
} else if (origBytes[nOrigBytes] == 0x83 &&
(origBytes[nOrigBytes + 1] & 0xf8) == 0xe8) {
nBytes += 6;
} else if (origBytes[nBytes] == 0x83 &&
(origBytes[nBytes + 1] & 0xf8) == 0xe8) {
// sub r, byte
COPY_CODES(3);
} else if (origBytes[nOrigBytes] == 0x83 &&
(origBytes[nOrigBytes + 1] & (kMaskMod|kMaskReg)) == kModReg) {
// add r, byte
COPY_CODES(3);
} else if (origBytes[nOrigBytes] == 0x83 &&
(origBytes[nOrigBytes + 1] & 0xf8) == 0x60) {
nBytes += 3;
} else if (origBytes[nBytes] == 0x83 &&
(origBytes[nBytes + 1] & 0xf8) == 0x60) {
// and [r+d], imm8
COPY_CODES(5);
} else if (origBytes[nOrigBytes] == 0x2b &&
(origBytes[nOrigBytes + 1] & kMaskMod) == kModReg) {
// sub r64, r64
COPY_CODES(2);
} else if (origBytes[nOrigBytes] == 0x85) {
nBytes += 5;
} else if (origBytes[nBytes] == 0x85) {
// 85 /r => TEST r/m32, r32
if ((origBytes[nOrigBytes + 1] & 0xc0) == 0xc0) {
COPY_CODES(2);
if ((origBytes[nBytes + 1] & 0xc0) == 0xc0) {
nBytes += 2;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if ((origBytes[nOrigBytes] & 0xfd) == 0x89) {
COPY_CODES(1);
} else if ((origBytes[nBytes] & 0xfd) == 0x89) {
++nBytes;
// MOV r/m64, r64 | MOV r64, r/m64
int len = CountModRmSib(origBytes + nOrigBytes);
int len = CountModRmSib(origBytes + nBytes);
if (len < 0) {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
COPY_CODES(len);
} else if (origBytes[nOrigBytes] == 0xc7) {
nBytes += len;
} else if (origBytes[nBytes] == 0xc7) {
// MOV r/m64, imm32
if (origBytes[nOrigBytes + 1] == 0x44) {
if (origBytes[nBytes + 1] == 0x44) {
// MOV [r64+disp8], imm32
// ModR/W + SIB + disp8 + imm32
COPY_CODES(8);
nBytes += 8;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0xff) {
} else if (origBytes[nBytes] == 0xff) {
// JMP /4
if ((origBytes[nOrigBytes + 1] & 0xc0) == 0x0 &&
(origBytes[nOrigBytes + 1] & 0x07) == 0x5) {
if ((origBytes[nBytes + 1] & 0xc0) == 0x0 &&
(origBytes[nBytes + 1] & 0x07) == 0x5) {
// [rip+disp32]
// convert JMP 32bit offset to JMP 64bit direct
JumpPatch jump(nTrampBytes - 1, // overwrite the REX.W/REX.WR we copied above
*reinterpret_cast<intptr_t*>(origBytes + nOrigBytes + 6 +
*reinterpret_cast<int32_t*>(origBytes + nOrigBytes + 2)),
JumpType::Jmp);
nTrampBytes = jump.GenerateJump(tramp);
nOrigBytes += 6;
foundJmp = true;
jump.AddJumpPatch(nBytes - 1,
*reinterpret_cast<intptr_t*>(
origBytes + nBytes + 6 +
*reinterpret_cast<int32_t*>(origBytes + nBytes +
2)));
nBytes += 6;
} else {
// not support yet!
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else {
// not support yet!
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x66) {
} else if (origBytes[nBytes] == 0x66) {
// operand override prefix
COPY_CODES(1);
nBytes += 1;
// This is the same as the x86 version
if (origBytes[nOrigBytes] >= 0x88 && origBytes[nOrigBytes] <= 0x8B) {
if (origBytes[nBytes] >= 0x88 && origBytes[nBytes] <= 0x8B) {
// various MOVs
unsigned char b = origBytes[nOrigBytes + 1];
unsigned char b = origBytes[nBytes + 1];
if (((b & 0xc0) == 0xc0) ||
(((b & 0xc0) == 0x00) &&
((b & 0x07) != 0x04) && ((b & 0x07) != 0x05))) {
// REG=r, R/M=r or REG=r, R/M=[r]
COPY_CODES(2);
nBytes += 2;
} else if ((b & 0xc0) == 0x40) {
if ((b & 0x07) == 0x04) {
// REG=r, R/M=[SIB + disp8]
COPY_CODES(4);
nBytes += 4;
} else {
// REG=r, R/M=[r + disp8]
COPY_CODES(3);
nBytes += 3;
}
} else {
// complex MOV, bail
MOZ_ASSERT_UNREACHABLE("Unrecognized MOV opcode sequence");
return;
}
}
} else if ((origBytes[nOrigBytes] & 0xf0) == 0x50) {
} else if ((origBytes[nBytes] & 0xf0) == 0x50) {
// 1-byte push/pop
COPY_CODES(1);
} else if (origBytes[nOrigBytes] == 0x65) {
nBytes++;
} else if (origBytes[nBytes] == 0x65) {
// GS prefix
//
// The entry of GetKeyState on Windows 10 has the following code.
// 65 48 8b 04 25 30 00 00 00 mov rax,qword ptr gs:[30h]
// (GS prefix + REX + MOV (0x8b) ...)
if (origBytes[nOrigBytes + 1] == 0x48 &&
(origBytes[nOrigBytes + 2] >= 0x88 && origBytes[nOrigBytes + 2] <= 0x8b)) {
COPY_CODES(3);
int len = CountModRmSib(origBytes + nOrigBytes);
if (origBytes[nBytes + 1] == 0x48 &&
(origBytes[nBytes + 2] >= 0x88 && origBytes[nBytes + 2] <= 0x8b)) {
nBytes += 3;
int len = CountModRmSib(origBytes + nBytes);
if (len < 0) {
// no way to support this yet.
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
COPY_CODES(len);
nBytes += len;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else if (origBytes[nOrigBytes] == 0x90) {
} else if (origBytes[nBytes] == 0x90) {
// nop
COPY_CODES(1);
} else if (origBytes[nOrigBytes] == 0xb8) {
nBytes++;
} else if (origBytes[nBytes] == 0xb8) {
// MOV 0xB8: http://ref.x86asm.net/coder32.html#xB8
COPY_CODES(5);
} else if (origBytes[nOrigBytes] == 0x33) {
nBytes += 5;
} else if (origBytes[nBytes] == 0x33) {
// xor r32, r/m32
COPY_CODES(2);
} else if (origBytes[nOrigBytes] == 0xf6) {
nBytes += 2;
} else if (origBytes[nBytes] == 0xf6) {
// test r/m8, imm8 (used by ntdll on Windows 10 x64)
// (no flags are affected by near jmp since there is no task switch,
// so it is ok for a jmp to be written immediately after a test)
BYTE subOpcode = 0;
int nModRmSibBytes = CountModRmSib(&origBytes[nOrigBytes + 1], &subOpcode);
int nModRmSibBytes = CountModRmSib(&origBytes[nBytes + 1], &subOpcode);
if (nModRmSibBytes < 0 || subOpcode != 0) {
// Unsupported
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
COPY_CODES(2 + nModRmSibBytes);
} else if (origBytes[nOrigBytes] == 0xd1 &&
(origBytes[nOrigBytes+1] & kMaskMod) == kModReg) {
// bit shifts/rotates : (SA|SH|RO|RC)(R|L) r32
// (e.g. 0xd1 0xe0 is SAL, 0xd1 0xc8 is ROR)
COPY_CODES(2);
} else if (origBytes[nOrigBytes] == 0xc3) {
nBytes += 2 + nModRmSibBytes;
} else if (origBytes[nBytes] == 0xc3) {
// ret
COPY_CODES(1);
} else if (origBytes[nOrigBytes] == 0xcc) {
nBytes++;
} else if (origBytes[nBytes] == 0xcc) {
// int 3
COPY_CODES(1);
} else if (origBytes[nOrigBytes] == 0xe8 ||
origBytes[nOrigBytes] == 0xe9) {
// CALL (0xe8) or JMP (0xe9) 32bit offset
foundJmp = origBytes[nOrigBytes] == 0xe9;
JumpPatch jump(nTrampBytes,
(intptr_t)(origBytes + nOrigBytes + 5 +
*(reinterpret_cast<int32_t*>(origBytes + nOrigBytes + 1))),
origBytes[nOrigBytes] == 0xe8 ? JumpType::Call : JumpType::Jmp);
nTrampBytes = jump.GenerateJump(tramp);
nOrigBytes += 5;
} else if (origBytes[nOrigBytes] == 0xff) {
COPY_CODES(1);
if ((origBytes[nOrigBytes] & (kMaskMod|kMaskReg)) == 0xf0) {
nBytes++;
} else if (origBytes[nBytes] == 0xe9) {
// jmp 32bit offset
jump.AddJumpPatch(nBytes,
// convert JMP 32bit offset to JMP 64bit direct
(intptr_t)
origBytes + nBytes + 5 +
*(reinterpret_cast<int32_t*>(origBytes + nBytes + 1)));
nBytes += 5;
} else if (origBytes[nBytes] == 0xff) {
nBytes++;
if ((origBytes[nBytes] & 0xf8) == 0xf0) {
// push r64
COPY_CODES(1);
} else if (origBytes[nOrigBytes] == 0x25) {
// jmp absolute indirect m32
foundJmp = true;
int32_t offset = *(reinterpret_cast<int32_t*>(origBytes + nOrigBytes + 1));
int64_t* ptrToJmpDest = reinterpret_cast<int64_t*>(origBytes + nOrigBytes + 5 + offset);
intptr_t jmpDest = static_cast<intptr_t>(*ptrToJmpDest);
JumpPatch jump(nTrampBytes, jmpDest, JumpType::Jmp);
nTrampBytes = jump.GenerateJump(tramp);
nOrigBytes += 5;
nBytes++;
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
} else {
MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence");
return;
}
}
@ -1037,13 +956,20 @@ protected:
#error "Unknown processor type"
#endif
if (nOrigBytes > 100) {
if (nBytes > 100) {
//printf ("Too big!");
return;
}
// target address of the final jmp instruction in the trampoline
byteptr_t trampDest = origBytes + nOrigBytes;
// We keep the address of the original function in the first bytes of
// the trampoline buffer
*((void**)tramp) = aOrigFunction;
tramp += sizeof(void*);
memcpy(tramp, aOrigFunction, nBytes);
// OrigFunction+N, the target of the trampoline
byteptr_t trampDest = origBytes + nBytes;
#if defined(_M_IX86)
if (pJmp32 >= 0) {
@ -1052,16 +978,20 @@ protected:
// Adjust jump target displacement to jump location in the trampoline.
*((intptr_t*)(tramp + pJmp32 + 1)) += origBytes - tramp;
} else {
tramp[nOrigBytes] = 0xE9; // jmp
*((intptr_t*)(tramp + nOrigBytes + 1)) =
(intptr_t)trampDest - (intptr_t)(tramp + nOrigBytes + 5); // target displacement
tramp[nBytes] = 0xE9; // jmp
*((intptr_t*)(tramp + nBytes + 1)) =
(intptr_t)trampDest - (intptr_t)(tramp + nBytes + 5); // target displacement
}
#elif defined(_M_X64)
// If the we found a Jmp, we don't need to add another instruction. However,
// if we found a _conditional_ jump or a CALL (or no control operations
// at all) then we still need to run the rest of aOriginalFunction.
if (!foundJmp) {
JumpPatch patch(nTrampBytes, reinterpret_cast<intptr_t>(trampDest));
// If JMP/JE opcode found, we don't insert to trampoline jump
if (jump.HasJumpPatch()) {
size_t offset = jump.GenerateJump(tramp);
if (jump.mType != JumpType::Jmp) {
JumpPatch patch(offset, reinterpret_cast<intptr_t>(trampDest));
patch.GenerateJump(tramp);
}
} else {
JumpPatch patch(nBytes, reinterpret_cast<intptr_t>(trampDest));
patch.GenerateJump(tramp);
}
#endif
@ -1070,7 +1000,7 @@ protected:
*aOutTramp = tramp;
// ensure we can modify the original code
AutoVirtualProtect protect(aOrigFunction, nOrigBytes, PAGE_EXECUTE_READWRITE);
AutoVirtualProtect protect(aOrigFunction, nBytes, PAGE_EXECUTE_READWRITE);
if (!protect.Protect()) {
//printf ("VirtualProtectEx failed! %d\n", GetLastError());
return;
@ -1165,16 +1095,6 @@ public:
}
}
/**
* Hook/detour the method aName from the DLL we set in Init so that it calls
* aHookDest instead. Returns the original method pointer in aOrigFunc
* and returns true if successful.
*
* IMPORTANT: If you use this method, please add your case to the
* TestDllInterceptor in order to detect future failures. Even if this
* succeeds now, updates to the hooked DLL could cause it to fail in
* the future.
*/
bool AddHook(const char* aName, intptr_t aHookDest, void** aOrigFunc)
{
// Use a nop space patch if possible, otherwise fall back to a detour.
@ -1191,16 +1111,6 @@ public:
return AddDetour(aName, aHookDest, aOrigFunc);
}
/**
* Detour the method aName from the DLL we set in Init so that it calls
* aHookDest instead. Returns the original method pointer in aOrigFunc
* and returns true if successful.
*
* IMPORTANT: If you use this method, please add your case to the
* TestDllInterceptor in order to detect future failures. Even if this
* succeeds now, updates to the detoured DLL could cause it to fail in
* the future.
*/
bool AddDetour(const char* aName, intptr_t aHookDest, void** aOrigFunc)
{
// Generally, code should not call this method directly. Use AddHook unless

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

@ -49,7 +49,6 @@ XREAppData::operator=(const XREAppData& aOther)
UAName = aOther.UAName;
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
sandboxBrokerServices = aOther.sandboxBrokerServices;
sandboxPermissionsService = aOther.sandboxPermissionsService;
#endif
return *this;
}