Bug 1094370: Use the USER_LOCKDOWN access token for GMP processes. r=aklotz
--- 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);