Bug 1546545: Part 2 - Create empty TrampolineCollection if the process sandbox forbids dynamic code r=aklotz

TrampolineCollection iterates over an array of Trampolines that it has set 'write' permissions for.  If this happens in a process whose sandbox forbids dynamic code then these permissions cannot be set.  This patch detects that condition and returns an empty TrampolineCollection in that case.  We ASSERT if we fail to set permissions for any other reason.

Differential Revision: https://phabricator.services.mozilla.com/D28613

--HG--
extra : moz-landing-system : lando
This commit is contained in:
David Parks 2019-04-29 21:07:20 +00:00
Родитель 9d48e224c0
Коммит 406cc6afbf
3 изменённых файлов: 39 добавлений и 5 удалений

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

@ -17,11 +17,18 @@ BOOL WINAPI GetProcessMitigationPolicy(
namespace mozilla {
MFBT_API bool IsWin32kLockedDown() {
static const DynamicallyLinkedFunctionPtr<
decltype(&::GetProcessMitigationPolicy)>&
FetchGetProcessMitigationPolicyFunc() {
static const DynamicallyLinkedFunctionPtr<decltype(
&::GetProcessMitigationPolicy)>
pGetProcessMitigationPolicy(L"kernel32.dll",
"GetProcessMitigationPolicy");
return pGetProcessMitigationPolicy;
}
MFBT_API bool IsWin32kLockedDown() {
auto& pGetProcessMitigationPolicy = FetchGetProcessMitigationPolicyFunc();
if (!pGetProcessMitigationPolicy) {
return false;
}
@ -36,4 +43,20 @@ MFBT_API bool IsWin32kLockedDown() {
return polInfo.DisallowWin32kSystemCalls;
}
MFBT_API bool IsDynamicCodeDisabled() {
auto& pGetProcessMitigationPolicy = FetchGetProcessMitigationPolicyFunc();
if (!pGetProcessMitigationPolicy) {
return false;
}
PROCESS_MITIGATION_DYNAMIC_CODE_POLICY polInfo;
if (!pGetProcessMitigationPolicy(::GetCurrentProcess(),
ProcessDynamicCodePolicy, &polInfo,
sizeof(polInfo))) {
return false;
}
return polInfo.ProhibitDynamicCode;
}
} // namespace mozilla

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

@ -12,6 +12,7 @@
namespace mozilla {
MFBT_API bool IsWin32kLockedDown();
MFBT_API bool IsDynamicCodeDisabled();
} // namespace mozilla

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

@ -12,6 +12,7 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/Maybe.h"
#include "mozilla/Types.h"
#include "mozilla/WindowsProcessMitigations.h"
namespace mozilla {
namespace interceptor {
@ -345,9 +346,18 @@ class MOZ_STACK_CLASS TrampolineCollection final {
return;
}
DebugOnly<BOOL> ok = mMMPolicy.Protect(aLocalBase, aNumTramps * aTrampSize,
PAGE_EXECUTE_READWRITE, &mPrevProt);
MOZ_ASSERT(ok);
BOOL ok = mMMPolicy.Protect(aLocalBase, aNumTramps * aTrampSize,
PAGE_EXECUTE_READWRITE, &mPrevProt);
if (!ok) {
// When destroying a sandboxed process that uses
// MITIGATION_DYNAMIC_CODE_DISABLE, we won't be allowed to write to our
// executable memory so we just do nothing. If we fail to get access
// to memory for any other reason, we still don't want to crash but we
// do assert.
MOZ_ASSERT(IsDynamicCodeDisabled());
mNumTramps = 0;
mPrevProt = 0;
}
}
~TrampolineCollection() {
@ -405,7 +415,7 @@ class MOZ_STACK_CLASS TrampolineCollection final {
uint8_t* const mLocalBase;
const uintptr_t mRemoteBase;
const uint32_t mTrampSize;
const uint32_t mNumTramps;
uint32_t mNumTramps;
uint32_t mPrevProt;
CRITICAL_SECTION* mCS;