Bug 1119878 Part 1: Change SandboxTarget to hold sandbox target services to provide functions. r=aklotz, r=glandium, r=cpearce
authorBob Owen <bobowencode@gmail.com>
Wed, 01 Apr 2015 09:40:35 +0100
changeset 266833 6790a442f39a529638c2db31786cabf8ee313751
parent 266832 43f8e1806067ed293e709197eb8c2ac53fe88ab4
child 266834 aee0f61516c53778dba9c97c6cbd5c35750902e3
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz, glandium, cpearce
bugs1119878
milestone40.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 1119878 Part 1: Change SandboxTarget to hold sandbox target services to provide functions. r=aklotz, r=glandium, r=cpearce
dom/ipc/moz.build
dom/media/gmp/GMPChild.cpp
dom/media/gmp/GMPLoader.cpp
dom/plugins/ipc/moz.build
ipc/app/moz.build
ipc/contentproc/moz.build
ipc/contentproc/plugin-container.cpp
security/sandbox/chromium-shim/base/MissingBasicTypes.h
security/sandbox/win/src/sandboxtarget/sandboxTarget.h
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -135,16 +135,22 @@ LOCAL_INCLUDES += [
     '/netwerk/base',
     '/toolkit/xre',
     '/uriloader/exthandler',
     '/widget',
     '/xpcom/base',
     '/xpcom/threads',
 ]
 
+if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
+    LOCAL_INCLUDES += [
+        '/security/sandbox/chromium',
+        '/security/sandbox/chromium-shim',
+    ]
+
 DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gonk', 'qt'):
     DEFINES['MOZ_ENABLE_FREETYPE'] = True
 
 if CONFIG['MOZ_TOOLKIT_SEARCH']:
     DEFINES['MOZ_TOOLKIT_SEARCH'] = True
 
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -29,20 +29,17 @@ static const int MAX_VOUCHER_LENGTH = 50
 
 #ifdef XP_WIN
 #include <stdlib.h> // for _exit()
 #else
 #include <unistd.h> // for _exit()
 #endif
 
 #if defined(MOZ_GMP_SANDBOX)
-#if defined(XP_WIN)
-#define TARGET_SANDBOX_EXPORTS
-#include "mozilla/sandboxTarget.h"
-#elif defined(XP_MACOSX)
+#if defined(XP_MACOSX)
 #include "mozilla/Sandbox.h"
 #endif
 #endif
 
 namespace mozilla {
 
 #undef LOG
 #undef LOGD
--- a/dom/media/gmp/GMPLoader.cpp
+++ b/dom/media/gmp/GMPLoader.cpp
@@ -8,17 +8,16 @@
 #include <stdio.h>
 #include "mozilla/Attributes.h"
 #include "gmp-entrypoints.h"
 #include "prlink.h"
 
 #include <string>
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
-#include "mozilla/sandboxTarget.h"
 #include "mozilla/Scoped.h"
 #include "windows.h"
 #include <intrin.h>
 #include <assert.h>
 #endif
 
 #if defined(HASH_NODE_ID_WITH_DEVICE_ID)
 // In order to provide EME plugins with a "device binding" capability,
--- a/dom/plugins/ipc/moz.build
+++ b/dom/plugins/ipc/moz.build
@@ -124,16 +124,22 @@ FAIL_ON_WARNINGS = True
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '../base',
     '/xpcom/base/',
 ]
 
+if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
+    LOCAL_INCLUDES += [
+        '/security/sandbox/chromium',
+        '/security/sandbox/chromium-shim',
+    ]
+
 DEFINES['FORCE_PR_LOG'] = True
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gtk3':
     CXXFLAGS += CONFIG['TK_CFLAGS']
 else:
     # Force build against gtk+2 for struct offsets and such.
     CXXFLAGS += CONFIG['MOZ_GTK2_CFLAGS']
 
--- a/ipc/app/moz.build
+++ b/ipc/app/moz.build
@@ -41,18 +41,18 @@ LOCAL_INCLUDES += [
 if CONFIG['OS_TARGET'] != 'Android':
     SOURCES += [
         '../../dom/media/gmp/GMPLoader.cpp',
     ]
 
 if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     # For sandbox includes and the include dependencies those have
     LOCAL_INCLUDES += [
-        '/security',
         '/security/sandbox/chromium',
+        '/security/sandbox/chromium-shim',
     ]
     USE_LIBS += [
         'rlz',
         'sandbox_staticruntime_s',
     ]
     DELAYLOAD_DLLS += [
         'nss3.dll',
         'xul.dll'
--- a/ipc/contentproc/moz.build
+++ b/ipc/contentproc/moz.build
@@ -15,14 +15,14 @@ SOURCES += [
 include('/ipc/chromium/chromium-config.mozbuild')
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     LOCAL_INCLUDES += [
         '/toolkit/xre',
         '/xpcom/base',
     ]
 
-if CONFIG['OS_ARCH'] == 'WINNT':
-    # For sandbox includes and the include dependencies those have
+
+if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     LOCAL_INCLUDES += [
-        '/security',
         '/security/sandbox/chromium',
+        '/security/sandbox/chromium-shim',
     ]
--- a/ipc/contentproc/plugin-container.cpp
+++ b/ipc/contentproc/plugin-container.cpp
@@ -20,21 +20,19 @@
 #define XRE_DONT_PROTECT_DLL_LOAD
 #include "nsWindowsWMain.cpp"
 #include "nsSetDllDirectory.h"
 #endif
 
 #include "GMPLoader.h"
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
-#include "sandbox/chromium/base/basictypes.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
 #include "mozilla/sandboxTarget.h"
 #include "mozilla/sandboxing/loggingCallbacks.h"
+#include "sandbox/win/src/sandbox_factory.h"
 #endif
 
 #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
 #include "mozilla/Sandbox.h"
 #include "mozilla/SandboxInfo.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
@@ -74,29 +72,23 @@ InitializeBinder(void *aDummy) {
     LOGE_IF(err, "setpriority failed. Current process needs root permission.");
     android::ProcessState::self()->startThreadPool();
     setpriority(PRIO_PROCESS, 0, curPrio);
 }
 #endif
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
 static bool gIsSandboxEnabled = false;
-void StartSandboxCallback()
-{
-    if (gIsSandboxEnabled) {
-        sandbox::TargetServices* target_service =
-            sandbox::SandboxFactory::GetTargetServices();
-        target_service->LowerToken();
-    }
-}
 
 class WinSandboxStarter : public mozilla::gmp::SandboxStarter {
 public:
     virtual void Start(const char *aLibPath) override {
-        StartSandboxCallback();
+        if (gIsSandboxEnabled) {
+            sandbox::SandboxFactory::GetTargetServices()->LowerToken();
+        }
     }
 };
 #endif
 
 #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
 class LinuxSandboxStarter : public mozilla::gmp::SandboxStarter {
     LinuxSandboxStarter() { }
 public:
@@ -184,21 +176,21 @@ content_process_main(int argc, char* arg
 #ifdef MOZ_SANDBOX
     if (gIsSandboxEnabled) {
         sandbox::TargetServices* target_service =
             sandbox::SandboxFactory::GetTargetServices();
         if (!target_service) {
             return 1;
         }
 
-        sandbox::ResultCode result = target_service->Init();
+        sandbox::ResultCode result =
+            mozilla::SandboxTarget::Instance()->InitTargetServices(target_service);
         if (result != sandbox::SBOX_ALL_OK) {
            return 2;
         }
-        mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback);
 
         mozilla::sandboxing::PrepareForLogging();
     }
 #endif
 #endif
     nsAutoPtr<mozilla::gmp::GMPLoader> loader;
 #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
     // On desktop, the GMPLoader lives in plugin-container, so that its
new file mode 100644
--- /dev/null
+++ b/security/sandbox/chromium-shim/base/MissingBasicTypes.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef security_sandbox_MissingBasicTypes_h__
+#define security_sandbox_MissingBasicTypes_h__
+
+#include <stdint.h>
+
+// These types are still used by the Chromium sandbox code. When referencing
+// Chromium sandbox code from Gecko we can't use the normal base/basictypes.h as
+// it clashes with the one from ipc/chromium/src/base/. These types have been
+// removed from the one in ipc/chromium/src/base/.
+typedef int8_t int8;
+typedef uint8_t uint8;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+
+#endif  // security_sandbox_MissingBasicTypes_h__
--- a/security/sandbox/win/src/sandboxtarget/sandboxTarget.h
+++ b/security/sandbox/win/src/sandboxtarget/sandboxTarget.h
@@ -2,64 +2,96 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __SECURITY_SANDBOX_SANDBOXTARGET_H__
 #define __SECURITY_SANDBOX_SANDBOXTARGET_H__
 
+#include <windows.h>
+
+#include "base/MissingBasicTypes.h"
+#include "sandbox/win/src/sandbox.h"
+
 #ifdef TARGET_SANDBOX_EXPORTS
 #define TARGET_SANDBOX_EXPORT __declspec(dllexport)
 #else
 #define TARGET_SANDBOX_EXPORT __declspec(dllimport)
 #endif
 namespace mozilla {
 
 
 class TARGET_SANDBOX_EXPORT SandboxTarget
 {
 public:
-  typedef void (*StartSandboxPtr)();
-
   /**
    * Obtains a pointer to the singleton instance
    */
   static SandboxTarget* Instance()
   {
     static SandboxTarget sb;
     return &sb;
   }
 
   /**
-   * Called by the application that will lower the sandbox token
+   * Used by the application to pass in the target services that provide certain
+   * functions to the sandboxed code.
    *
-   * @param aStartSandboxCallback A callback function which will lower privs
+   * @param aTargetServices The target services that will be initialized and used
    */
-  void SetStartSandboxCallback(StartSandboxPtr aStartSandboxCallback)
+  sandbox::ResultCode
+  InitTargetServices(sandbox::TargetServices* aTargetServices)
   {
-    mStartSandboxCallback = aStartSandboxCallback;
+    MOZ_ASSERT(aTargetServices);
+    MOZ_ASSERT(!mTargetServices,
+               "Sandbox TargetServices must only be initialized once.");
+
+    sandbox::ResultCode result = aTargetServices->Init();
+    if (sandbox::SBOX_ALL_OK == result) {
+      mTargetServices = aTargetServices;
+    }
+
+    return result;
   }
 
   /**
-   * Called by the library that wants to start the sandbox, which in turn
-   * calls into the previously set StartSandboxCallback.
+   * Called by the library that wants to "start" the sandbox, i.e. change to the
+   * more secure delayed / lockdown policy.
    */
   void StartSandbox()
   {
-    if (mStartSandboxCallback) {
-      mStartSandboxCallback();
+    if (mTargetServices) {
+      mTargetServices->LowerToken();
     }
   }
 
+  /**
+   * Used to duplicate handles via the broker process. The permission for the
+   * handle type and target process has to have been set on the sandbox policy.
+   */
+  bool BrokerDuplicateHandle(HANDLE aSourceHandle, DWORD aTargetProcessId,
+                             HANDLE* aTargetHandle, DWORD aDesiredAccess,
+                             DWORD aOptions)
+  {
+    if (!mTargetServices) {
+      return false;
+    }
+
+    sandbox::ResultCode result =
+      mTargetServices->DuplicateHandle(aSourceHandle, aTargetProcessId,
+                                       aTargetHandle, aDesiredAccess, aOptions);
+    return (sandbox::SBOX_ALL_OK == result);
+  }
+
 protected:
   SandboxTarget() :
-    mStartSandboxCallback(nullptr)
+    mTargetServices(nullptr)
   {
   }
 
-  StartSandboxPtr mStartSandboxCallback;
+  sandbox::TargetServices* mTargetServices;
 };
 
 
 } // mozilla
 
 #endif