summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch')
-rw-r--r--security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch99
1 files changed, 99 insertions, 0 deletions
diff --git a/security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch b/security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch
new file mode 100644
index 0000000000..4d1817db17
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/after_update/arm64_set_LoaderThreads.patch
@@ -0,0 +1,99 @@
+# 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/security/sandbox/chromium/sandbox/win/src/win_utils.cc b/security/sandbox/chromium/sandbox/win/src/win_utils.cc
+--- a/security/sandbox/chromium/sandbox/win/src/win_utils.cc
++++ b/security/sandbox/chromium/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/security/sandbox/chromium/sandbox/win/src/win_utils.h b/security/sandbox/chromium/sandbox/win/src/win_utils.h
+--- a/security/sandbox/chromium/sandbox/win/src/win_utils.h
++++ b/security/sandbox/chromium/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,