tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

38_arm64_set_LoaderThreads.patch (2564B)


      1 # HG changeset patch
      2 # User Bob Owen <bobowencode@gmail.com>
      3 # Date 1549645620 0
      4 #      Fri Feb 08 17:07:00 2019 +0000
      5 # Node ID fb5e7c1090a7ddfde22fd2fb5f8a957ccc61fa64
      6 # Parent  5ef34aa8c8918649528048dd60907862a4355e29
      7 Bug 1515088 Part 2: Set LoaderThreads to 1 in the RTL_USER_PROCESS_PARAMETERS structure on child process start-up. r=aklotz
      8 
      9 diff --git a/sandbox/win/src/win_utils.cc b/sandbox/win/src/win_utils.cc
     10 --- a/sandbox/win/src/win_utils.cc
     11 +++ b/sandbox/win/src/win_utils.cc
     12 @@ -170,16 +170,50 @@ void* GetProcessBaseAddress(HANDLE proce
     13                            &bytes_read) ||
     14       (sizeof(magic) != bytes_read)) {
     15     return nullptr;
     16   }
     17 
     18   if (magic[0] != 'M' || magic[1] != 'Z')
     19     return nullptr;
     20 
     21 +#if defined(_M_ARM64)
     22 +  // Windows 10 on ARM64 has multi-threaded DLL loading that does not work with
     23 +  // the sandbox. (On x86 this gets disabled by hook detection code that was not
     24 +  // ported to ARM64). This overwrites the LoaderThreads value in the process
     25 +  // parameters part of the PEB, if it is set to the default of 0 (which
     26 +  // actually means it defaults to 4 loading threads). This is an undocumented
     27 +  // field so there is a, probably small, risk that it might change or move in
     28 +  // the future. In order to slightly guard against that we only update if the
     29 +  // value is currently 0.
     30 +  auto processParameters = reinterpret_cast<uint8_t*>(peb.ProcessParameters);
     31 +  const uint32_t loaderThreadsOffset = 0x40c;
     32 +  uint32_t maxLoaderThreads = 0;
     33 +  BOOL memoryRead = ::ReadProcessMemory(
     34 +      process, processParameters + loaderThreadsOffset, &maxLoaderThreads,
     35 +      sizeof(maxLoaderThreads), &bytes_read);
     36 +  if (memoryRead && (sizeof(maxLoaderThreads) == bytes_read) &&
     37 +      (maxLoaderThreads == 0)) {
     38 +    maxLoaderThreads = 1;
     39 +    auto address = processParameters + loaderThreadsOffset;
     40 +    auto length = sizeof(maxLoaderThreads);
     41 +
     42 +    // First, remove the protection.
     43 +    DWORD old_protection;
     44 +    if (::VirtualProtectEx(process, address, length, PAGE_READWRITE,
     45 +                           &old_protection)) {
     46 +      ::WriteProcessMemory(process, address, &maxLoaderThreads, length, NULL);
     47 +
     48 +      // Attempt to restore the original protection.
     49 +      ::VirtualProtectEx(process, address, length, old_protection,
     50 +                         &old_protection);
     51 +    }
     52 +  }
     53 +#endif
     54 +
     55   return base_address;
     56 }
     57 
     58 absl::optional<ProcessHandleMap> GetCurrentProcessHandles() {
     59   DWORD handle_count;
     60   if (!::GetProcessHandleCount(::GetCurrentProcess(), &handle_count))
     61     return absl::nullopt;