99 lines
4.3 KiB
Diff
99 lines
4.3 KiB
Diff
# HG changeset patch
|
|
# User Bob Owen <bobowencode@gmail.com>
|
|
# Date 1549645620 0
|
|
# Fri Feb 08 17:07:00 2019 +0000
|
|
# Node ID fb5e7c1090a7ddfde22fd2fb5f8a957ccc61fa64
|
|
# Parent 5ef34aa8c8918649528048dd60907862a4355e29
|
|
Bug 1515088 Part 2: Set LoaderThreads to 1 in the RTL_USER_PROCESS_PARAMETERS structure on child process start-up. r=aklotz
|
|
|
|
diff --git a/sandbox/win/src/win_utils.cc b/sandbox/win/src/win_utils.cc
|
|
--- a/sandbox/win/src/win_utils.cc
|
|
+++ b/sandbox/win/src/win_utils.cc
|
|
@@ -456,20 +456,21 @@ bool GetNtPathFromWin32Path(const std::w
|
|
bool rv = GetPathFromHandle(file, nt_path);
|
|
::CloseHandle(file);
|
|
return rv;
|
|
}
|
|
|
|
bool WriteProtectedChildMemory(HANDLE child_process,
|
|
void* address,
|
|
const void* buffer,
|
|
- size_t length) {
|
|
+ size_t length,
|
|
+ DWORD writeProtection) {
|
|
// First, remove the protections.
|
|
DWORD old_protection;
|
|
- if (!::VirtualProtectEx(child_process, address, length, PAGE_WRITECOPY,
|
|
+ if (!::VirtualProtectEx(child_process, address, length, writeProtection,
|
|
&old_protection))
|
|
return false;
|
|
|
|
SIZE_T written;
|
|
bool ok =
|
|
::WriteProcessMemory(child_process, address, buffer, length, &written) &&
|
|
(length == written);
|
|
|
|
@@ -544,16 +545,40 @@ void* GetProcessBaseAddress(HANDLE proce
|
|
&bytes_read) ||
|
|
(sizeof(magic) != bytes_read)) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (magic[0] != 'M' || magic[1] != 'Z')
|
|
return nullptr;
|
|
|
|
+#if defined(_M_ARM64)
|
|
+ // Windows 10 on ARM64 has multi-threaded DLL loading that does not work with
|
|
+ // the sandbox. (On x86 this gets disabled by hook detection code that was not
|
|
+ // ported to ARM64). This overwrites the LoaderThreads value in the process
|
|
+ // parameters part of the PEB, if it is set to the default of 0 (which
|
|
+ // actually means it defaults to 4 loading threads). This is an undocumented
|
|
+ // field so there is a, probably small, risk that it might change or move in
|
|
+ // the future. In order to slightly guard against that we only update if the
|
|
+ // value is currently 0.
|
|
+ auto processParameters = reinterpret_cast<uint8_t*>(peb.ProcessParameters);
|
|
+ const uint32_t loaderThreadsOffset = 0x40c;
|
|
+ uint32_t maxLoaderThreads = 0;
|
|
+ BOOL memoryRead = ::ReadProcessMemory(
|
|
+ process, processParameters + loaderThreadsOffset, &maxLoaderThreads,
|
|
+ sizeof(maxLoaderThreads), &bytes_read);
|
|
+ if (memoryRead && (sizeof(maxLoaderThreads) == bytes_read) &&
|
|
+ (maxLoaderThreads == 0)) {
|
|
+ maxLoaderThreads = 1;
|
|
+ WriteProtectedChildMemory(process, processParameters + loaderThreadsOffset,
|
|
+ &maxLoaderThreads, sizeof(maxLoaderThreads),
|
|
+ PAGE_READWRITE);
|
|
+ }
|
|
+#endif
|
|
+
|
|
return base_address;
|
|
}
|
|
|
|
DWORD GetTokenInformation(HANDLE token,
|
|
TOKEN_INFORMATION_CLASS info_class,
|
|
std::unique_ptr<BYTE[]>* buffer) {
|
|
// Get the required buffer size.
|
|
DWORD size = 0;
|
|
diff --git a/sandbox/win/src/win_utils.h b/sandbox/win/src/win_utils.h
|
|
--- a/sandbox/win/src/win_utils.h
|
|
+++ b/sandbox/win/src/win_utils.h
|
|
@@ -111,17 +111,18 @@ HKEY GetReservedKeyFromName(const std::w
|
|
bool ResolveRegistryName(std::wstring name, std::wstring* resolved_name);
|
|
|
|
// Writes |length| bytes from the provided |buffer| into the address space of
|
|
// |child_process|, at the specified |address|, preserving the original write
|
|
// protection attributes. Returns true on success.
|
|
bool WriteProtectedChildMemory(HANDLE child_process,
|
|
void* address,
|
|
const void* buffer,
|
|
- size_t length);
|
|
+ size_t length,
|
|
+ DWORD writeProtection = PAGE_WRITECOPY);
|
|
|
|
// Allocates |buffer_bytes| in child (PAGE_READWRITE) and copies data
|
|
// from |local_buffer| in this process into |child|. |remote_buffer|
|
|
// contains the address in the chile. If a zero byte copy is
|
|
// requested |true| is returned and no allocation or copying is
|
|
// attempted. Returns false if allocation or copying fails. If
|
|
// copying fails, the allocation will be reversed.
|
|
bool CopyToChildMemory(HANDLE child,
|