Bug 1094370: Use the USER_LOCKDOWN access token for GMP processes. r=aklotz
authorBob Owen <bobowencode@gmail.com>
Mon, 26 Jan 2015 10:14:39 +0000
changeset 225765 02cac0756bc1042a958248bf9b462620bcf42fad
parent 225764 a0db598f71a5b9a2c63430f6cf064f88c247409b
child 225766 48171dc1a53572825f050cc8f82a1975930fb2be
push id28175
push userryanvm@gmail.com
push dateMon, 26 Jan 2015 21:33:41 +0000
treeherdermozilla-central@a6f037b538ed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1094370
milestone38.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 1094370: Use the USER_LOCKDOWN access token for GMP processes. r=aklotz
dom/media/gmp/GMPLoader.cpp
security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
--- a/dom/media/gmp/GMPLoader.cpp
+++ b/dom/media/gmp/GMPLoader.cpp
@@ -9,16 +9,17 @@
 #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,
 // in the parent we generate and store some random bytes as salt for every
@@ -28,16 +29,41 @@
 // device specific data and munges that with the salt to create the
 // "node id" that we expose to EME plugins. It then overwrites the device
 // specific data, and activates the sandbox.
 #include "rlz/lib/machine_id.h"
 #include "rlz/lib/string_utils.h"
 #include "sha256.h"
 #endif
 
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+namespace {
+
+// Scoped type used by Load
+struct ScopedActCtxHandleTraits
+{
+  typedef HANDLE type;
+
+  static type empty()
+  {
+    return INVALID_HANDLE_VALUE;
+  }
+
+  static void release(type aActCtxHandle)
+  {
+    if (aActCtxHandle != INVALID_HANDLE_VALUE) {
+      ReleaseActCtx(aActCtxHandle);
+    }
+  }
+};
+typedef mozilla::Scoped<ScopedActCtxHandleTraits> ScopedActCtxHandle;
+
+} // anonymous namespace
+#endif
+
 namespace mozilla {
 namespace gmp {
 
 class GMPLoaderImpl : public GMPLoader {
 public:
   explicit GMPLoaderImpl(SandboxStarter* aStarter)
     : mSandboxStarter(aStarter)
   {}
@@ -163,16 +189,40 @@ GMPLoaderImpl::Load(const char* aLibPath
       *p = 0;
     }
   } else
 #endif
   {
     nodeId = std::string(aOriginSalt, aOriginSalt + aOriginSaltLen);
   }
 
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+  // If the GMP DLL is a side-by-side assembly with static imports then the DLL
+  // loader will attempt to create an activation context which will fail because
+  // of the sandbox. If we create an activation context before we start the
+  // sandbox then this one will get picked up by the DLL loader.
+  int pathLen = MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, nullptr, 0);
+  if (pathLen == 0) {
+    return false;
+  }
+
+  wchar_t* widePath = new wchar_t[pathLen];
+  if (MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, widePath, pathLen) == 0) {
+    delete[] widePath;
+    return false;
+  }
+
+  ACTCTX actCtx = { sizeof(actCtx) };
+  actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
+  actCtx.lpSource = widePath;
+  actCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
+  ScopedActCtxHandle actCtxHandle(CreateActCtx(&actCtx));
+  delete[] widePath;
+#endif
+
   // Start the sandbox now that we've generated the device bound node id.
   // This must happen after the node id is bound to the device id, as
   // generating the device id requires privileges.
   if (mSandboxStarter) {
     mSandboxStarter->Start(aLibPath);
   }
 
   // Load the GMP.
--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
+++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
@@ -167,17 +167,17 @@ SandboxBroker::SetSecurityLevelForGMPlug
   if (!mPolicy) {
     return false;
   }
 
   auto result = mPolicy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
   bool ret = (sandbox::SBOX_ALL_OK == result);
   result =
     mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
-                           sandbox::USER_RESTRICTED);
+                           sandbox::USER_LOCKDOWN);
   ret = ret && (sandbox::SBOX_ALL_OK == result);
 
   result = mPolicy->SetAlternateDesktop(true);
   ret = ret && (sandbox::SBOX_ALL_OK == result);
 
   result = mPolicy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
   ret = ret && (sandbox::SBOX_ALL_OK == result);