Commit e50a55e8 authored by Richard Pospesel's avatar Richard Pospesel Committed by Georg Koppen
Browse files

Bug 25112: Tor Browser 7.5 is not working on Windows Vista 64bit

With sandboxing enabled on Vista, 32-bit Firefox uses another 64-bit
process (wow_helper.exe) to patch functions in the loaded ntdll.dll
in the child content process.  However, we are not building
wow_helper.exe and it is not present, so the content process
creation method silently fails.

We 'could' go in and properly update the build system to build
wow_helper.exe with 64-bit mingw.  However, Vista support is going
away very soon for Tor Browser once we update to a newer Firefox ESR.
Therefore, the more prudent fix is to simply disable sandboxing when
running on Vista or lower in this WOW64 scenario, rather than to do
the work to get wow_helper.exe building only to have to rip it all
out in a few months when we rebase with latest Firefox ESR.  This
logic is ifdef'd out for 64-bit builds.

Verified the Tor Browser works as expected in following scenarios:
  32-bit Firefox on 32-bit Windows Vista -> Sandbox enabled
  32-bit Firefox on 64-bit Windows Vista -> Sandbox disabled
  32-bit Firefox on 64-bit Windows 7 -> Sandbox enabled
parent 45149725
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <sys/stat.h>

#ifdef XP_WIN
#include "mozilla/WindowsVersion.h"
#include "nsIWinTaskbar.h"
#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"

@@ -304,6 +305,55 @@ GeckoChildProcessHost::GetUniqueID()
  return sNextUniqueID++;
}

// pospeselr: This is a temporary workaround for TBB 25112
// Once we're off of ESR 52 TweakSandboxLevel() should be removed
#ifdef XP_WIN

// reduces sandbox level to 0 when running WOW64 on Vista and lower
// for 64-bit windows builds all this logic is unnecessary so we just
// pass-through
static int32_t
TweakSandboxLevel(int32_t sandboxLevel)
{
#ifdef _WIN64
  // we can't be running WOW64 if this is built as a 64-bit binary
  return sandboxLevel;
#else
  // 0 is as low as you can go, early out
  if (sandboxLevel == 0) {
    return 0;
  }

  // Win7 and later can be sandboxed without issue
  if (mozilla::IsWin7OrLater()) {
    return sandboxLevel;
  }

  // determine if we're 32-bit firefox on 64-bit windows (ie WOW64)
  typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
  IsWow64ProcessFunc IsWow64Process = reinterpret_cast<IsWow64ProcessFunc>(
      GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));

  // according to the MSDN, older versions of windows may not have this function
  // assume that this function missing indicates we cannot sandbox
  if (IsWow64Process == nullptr) {
    return 0;
  }

  // this function is non-zero on success, assume a failure means we
  // cannot sandbox
  BOOL isWow64 = FALSE;
  if (!IsWow64Process(GetCurrentProcess(), &isWow64)) {
    return 0;
  }

  // finally, this BOOL indicate whether we're WOW64
  return isWow64 ? 0 : sandboxLevel;
#endif  // _WIN64
}

#endif // XP_WIN

void
GeckoChildProcessHost::PrepareLaunch()
{
@@ -322,6 +372,7 @@ GeckoChildProcessHost::PrepareLaunch()
  // We need to get the pref here as the process is launched off main thread.
  if (mProcessType == GeckoProcessType_Content) {
    mSandboxLevel = Preferences::GetInt("security.sandbox.content.level");
    mSandboxLevel = TweakSandboxLevel(mSandboxLevel);
    mEnableSandboxLogging =
      Preferences::GetBool("security.sandbox.windows.log");
  }