Bug 1200336: Apply fix for Chromium issue 482784 for sandbox bug when built with VS2015. r=tabraldes
authorBob Owen <bobowencode@gmail.com>
Thu, 10 Sep 2015 08:25:20 +0100
changeset 294355 da4d79a712c697a4aa1b671933648ef35ea310bb
parent 294354 d8f6186e342570f0853f537c398714be359cbc86
child 294356 e55283c9b6a08e788c5f58196cf551c6674a72be
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstabraldes
bugs1200336, 482784
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1200336: Apply fix for Chromium issue 482784 for sandbox bug when built with VS2015. r=tabraldes
security/sandbox/chromium/sandbox/win/src/target_services.cc
security/sandbox/chromium/sandbox/win/src/target_services.h
security/sandbox/moz-chromium-commit-status.txt
security/sandbox/win/src/sandboxtarget/sandboxTarget.h
--- a/security/sandbox/chromium/sandbox/win/src/target_services.cc
+++ b/security/sandbox/chromium/sandbox/win/src/target_services.cc
@@ -1,14 +1,16 @@
 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "sandbox/win/src/target_services.h"
 
+#include <new>
+
 #include <process.h>
 
 #include "base/basictypes.h"
 #include "sandbox/win/src/crosscall_client.h"
 #include "sandbox/win/src/handle_closer_agent.h"
 #include "sandbox/win/src/handle_interception.h"
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/process_mitigations.h"
@@ -51,16 +53,23 @@ bool CloseOpenHandles() {
     handle_closer.InitializeHandlesToClose();
     if (!handle_closer.CloseHandles())
       return false;
   }
 
   return true;
 }
 
+// Used as storage for g_target_services, because other allocation facilities
+// are not available early. We can't use a regular function static because on
+// VS2015, because the CRT tries to acquire a lock to guard initialization, but
+// this code runs before the CRT is initialized.
+char g_target_services_memory[sizeof(sandbox::TargetServicesBase)];
+sandbox::TargetServicesBase* g_target_services = nullptr;
+
 }  // namespace
 
 namespace sandbox {
 
 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level =
     INTEGRITY_LEVEL_LAST;
 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations = 0;
 
@@ -94,18 +103,20 @@ void TargetServicesBase::LowerToken() {
     ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_MITIGATION);
 }
 
 ProcessState* TargetServicesBase::GetState() {
   return &process_state_;
 }
 
 TargetServicesBase* TargetServicesBase::GetInstance() {
-  static TargetServicesBase instance;
-  return &instance;
+  // Leak on purpose TargetServicesBase.
+  if (!g_target_services)
+    g_target_services = new (g_target_services_memory) TargetServicesBase;
+  return g_target_services;
 }
 
 // The broker services a 'test' IPC service with the IPC_PING_TAG tag.
 bool TargetServicesBase::TestIPCPing(int version) {
   void* memory = GetGlobalIPCMemory();
   if (NULL == memory) {
     return false;
   }
@@ -150,25 +161,28 @@ bool TargetServicesBase::TestIPCPing(int
       return false;
     }
   } else {
     return false;
   }
   return true;
 }
 
-bool ProcessState::IsKernel32Loaded() {
+ProcessState::ProcessState() : process_state_(0) {
+}
+
+bool ProcessState::IsKernel32Loaded() const {
   return process_state_ != 0;
 }
 
-bool ProcessState::InitCalled() {
+bool ProcessState::InitCalled() const {
   return process_state_ > 1;
 }
 
-bool ProcessState::RevertedToSelf() {
+bool ProcessState::RevertedToSelf() const {
   return process_state_ > 2;
 }
 
 void ProcessState::SetKernel32Loaded() {
   if (!process_state_)
     process_state_ = 1;
 }
 
--- a/security/sandbox/chromium/sandbox/win/src/target_services.h
+++ b/security/sandbox/chromium/sandbox/win/src/target_services.h
@@ -8,33 +8,29 @@
 #include "base/basictypes.h"
 #include "sandbox/win/src/sandbox.h"
 #include "sandbox/win/src/win_utils.h"
 
 namespace sandbox {
 
 class ProcessState {
  public:
-  ProcessState() : process_state_(0) {}
-
+  ProcessState();
   // Returns true if kernel32.dll has been loaded.
-  bool IsKernel32Loaded();
-
+  bool IsKernel32Loaded() const;
   // Returns true if main has been called.
-  bool InitCalled();
-
+  bool InitCalled() const;
   // Returns true if LowerToken has been called.
-  bool RevertedToSelf();
-
+  bool RevertedToSelf() const;
   // Set the current state.
   void SetKernel32Loaded();
   void SetInitCalled();
   void SetRevertedToSelf();
 
- public:
+ private:
   int process_state_;
   DISALLOW_COPY_AND_ASSIGN(ProcessState);
 };
 
 // This class is an implementation of the  TargetServices.
 // Look in the documentation of sandbox::TargetServices for more info.
 // Do NOT add a destructor to this class without changing the implementation of
 // the factory method.
--- a/security/sandbox/moz-chromium-commit-status.txt
+++ b/security/sandbox/moz-chromium-commit-status.txt
@@ -1,5 +1,7 @@
 Chromium Commit                            Directory / File (relative to security/sandbox/)
 ----------------------------------------   ------------------------------------------------
 df7cc6c04725630dd4460f29d858a77507343b24   chromium
 b533d6533585377edd63ec6500469f6c4fba602a   chromium/sandbox/win/src/sharedmem_ipc_server.cc
 034bd64db1806d85b2ceacc736074ac07722af4a   chromium/sandbox/win/src/service_resolver_64.cc
+de2078cfbbb6770791d32575a1a72a288e6d66a6   chromium/sandbox/win/src/target_services.cc
+de2078cfbbb6770791d32575a1a72a288e6d66a6   chromium/sandbox/win/src/target_services.h
--- a/security/sandbox/win/src/sandboxtarget/sandboxTarget.h
+++ b/security/sandbox/win/src/sandboxtarget/sandboxTarget.h
@@ -40,19 +40,16 @@ public:
    *
    * @param aTargetServices The target services that will be used
    */
   void SetTargetServices(sandbox::TargetServices* aTargetServices)
   {
     MOZ_ASSERT(aTargetServices);
     MOZ_ASSERT(!mTargetServices,
                "Sandbox TargetServices must only be set once.");
-    // We use process_state_ instead of InitCalled() here due to linking issues.
-    MOZ_ASSERT(aTargetServices->GetState()->process_state_ > 1,
-               "Sandbox TargetServices must already be initialized.");
 
     mTargetServices = aTargetServices;
   }
 
   /**
    * Called by the library that wants to "start" the sandbox, i.e. change to the
    * more secure delayed / lockdown policy.
    */