Bug 1035125 Part 8: Pass sandboxing pointers through XRE_InitChildProcess instead of linking to more functions in xul. r=aklotz,glandium

MozReview-Commit-ID: 5AiktOArpfU

--HG--
extra : rebase_source : 1ba3be949e2bfeb3b67687ab05d43342852ab764
This commit is contained in:
Bob Owen 2016-05-15 16:35:22 +01:00
Родитель 209b6e6e18
Коммит c43bf02cda
15 изменённых файлов: 182 добавлений и 84 удалений

Просмотреть файл

@ -7,11 +7,9 @@
#include "GMPLoader.h" #include "GMPLoader.h"
#include <stdio.h> #include <stdio.h>
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/UniquePtr.h"
#include "gmp-entrypoints.h" #include "gmp-entrypoints.h"
#include "prlink.h" #include "prlink.h"
#include "prenv.h" #include "prenv.h"
#include "nsAutoPtr.h"
#include <string> #include <string>
@ -79,8 +77,8 @@ private:
UniquePtr<GMPAdapter> mAdapter; UniquePtr<GMPAdapter> mAdapter;
}; };
GMPLoader* CreateGMPLoader(SandboxStarter* aStarter) { UniquePtr<GMPLoader> CreateGMPLoader(SandboxStarter* aStarter) {
return static_cast<GMPLoader*>(new GMPLoaderImpl(aStarter)); return MakeUnique<GMPLoaderImpl>(aStarter);
} }
class PassThroughGMPAdapter : public GMPAdapter { class PassThroughGMPAdapter : public GMPAdapter {

Просмотреть файл

@ -10,6 +10,7 @@
#include <stdint.h> #include <stdint.h>
#include "prlink.h" #include "prlink.h"
#include "gmp-entrypoints.h" #include "gmp-entrypoints.h"
#include "mozilla/UniquePtr.h"
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
#include "mozilla/Sandbox.h" #include "mozilla/Sandbox.h"
@ -98,7 +99,7 @@ public:
// On Desktop, this function resides in plugin-container. // On Desktop, this function resides in plugin-container.
// On Mobile, this function resides in XUL. // On Mobile, this function resides in XUL.
GMPLoader* CreateGMPLoader(SandboxStarter* aStarter); UniquePtr<GMPLoader> CreateGMPLoader(SandboxStarter* aStarter);
} // namespace gmp } // namespace gmp
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -25,9 +25,8 @@
#include "GMPLoader.h" #include "GMPLoader.h"
#if defined(XP_WIN) && defined(MOZ_SANDBOX) #if defined(XP_WIN) && defined(MOZ_SANDBOX)
#include "mozilla/sandboxTarget.h" #include "mozilla/sandboxing/SandboxInitialization.h"
#include "mozilla/sandboxing/loggingCallbacks.h" #include "mozilla/sandboxing/sandboxLogging.h"
#include "sandbox/win/src/sandbox_factory.h"
#endif #endif
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
@ -86,7 +85,7 @@ class WinSandboxStarter : public mozilla::gmp::SandboxStarter {
public: public:
virtual bool Start(const char *aLibPath) override { virtual bool Start(const char *aLibPath) override {
if (gIsSandboxEnabled) { if (gIsSandboxEnabled) {
sandbox::SandboxFactory::GetTargetServices()->LowerToken(); mozilla::sandboxing::LowerSandbox();
} }
return true; return true;
} }
@ -163,21 +162,17 @@ content_process_main(int argc, char* argv[])
#endif #endif
} }
XREChildData childData;
#if defined(XP_WIN) && defined(MOZ_SANDBOX) #if defined(XP_WIN) && defined(MOZ_SANDBOX)
if (gIsSandboxEnabled) { if (gIsSandboxEnabled) {
sandbox::TargetServices* target_service = childData.sandboxTargetServices =
sandbox::SandboxFactory::GetTargetServices(); mozilla::sandboxing::GetInitializedTargetServices();
if (!target_service) { if (!childData.sandboxTargetServices) {
return 1; return 1;
} }
sandbox::ResultCode result = target_service->Init(); childData.ProvideLogFunction = mozilla::sandboxing::ProvideLogFunction;
if (result != sandbox::SBOX_ALL_OK) {
return 2;
}
mozilla::SandboxTarget::Instance()->SetTargetServices(target_service);
mozilla::sandboxing::PrepareForLogging();
} }
#endif #endif
@ -225,16 +220,15 @@ content_process_main(int argc, char* argv[])
SetDllDirectory(L""); SetDllDirectory(L"");
} }
#endif #endif
nsAutoPtr<mozilla::gmp::GMPLoader> loader;
#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK) #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
// On desktop, the GMPLoader lives in plugin-container, so that its // On desktop, the GMPLoader lives in plugin-container, so that its
// code can be covered by an EME/GMP vendor's voucher. // code can be covered by an EME/GMP vendor's voucher.
nsAutoPtr<mozilla::gmp::SandboxStarter> starter(MakeSandboxStarter()); nsAutoPtr<mozilla::gmp::SandboxStarter> starter(MakeSandboxStarter());
if (XRE_GetProcessType() == GeckoProcessType_GMPlugin) { if (XRE_GetProcessType() == GeckoProcessType_GMPlugin) {
loader = mozilla::gmp::CreateGMPLoader(starter); childData.gmpLoader = mozilla::gmp::CreateGMPLoader(starter);
} }
#endif #endif
nsresult rv = XRE_InitChildProcess(argc, argv, loader); nsresult rv = XRE_InitChildProcess(argc, argv, &childData);
NS_ENSURE_SUCCESS(rv, 1); NS_ENSURE_SUCCESS(rv, 1);
return 0; return 0;

Просмотреть файл

@ -35,6 +35,7 @@
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "XREChildData.h"
/* Android headers don't define RUSAGE_THREAD */ /* Android headers don't define RUSAGE_THREAD */
#ifndef RUSAGE_THREAD #ifndef RUSAGE_THREAD
@ -421,6 +422,7 @@ ChildProcessInit(int argc, char* argv[])
fXRE_SetProcessType(argv[--argc]); fXRE_SetProcessType(argv[--argc]);
return fXRE_InitChildProcess(argc, argv, nullptr); XREChildData childData;
return fXRE_InitChildProcess(argc, argv, &childData);
} }

Просмотреть файл

@ -7,53 +7,20 @@
#ifndef security_sandbox_loggingCallbacks_h__ #ifndef security_sandbox_loggingCallbacks_h__
#define security_sandbox_loggingCallbacks_h__ #define security_sandbox_loggingCallbacks_h__
#include "mozilla/sandboxing/loggingTypes.h"
#include "mozilla/sandboxing/sandboxLogging.h"
#ifdef TARGET_SANDBOX_EXPORTS
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/sandboxing/loggingTypes.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#ifdef MOZ_STACKWALKING #ifdef MOZ_STACKWALKING
#include "mozilla/StackWalk.h" #include "mozilla/StackWalk.h"
#endif #endif
#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
#else
#define TARGET_SANDBOX_EXPORT __declspec(dllimport)
#endif
namespace mozilla { namespace mozilla {
namespace sandboxing { namespace sandboxing {
// We need to use a callback to work around the fact that sandbox_s lib is
// linked into plugin-container.exe directly and also via xul.dll via
// sandboxbroker.dll. This causes problems with holding the state required to
// implement sandbox logging.
// So, we provide a callback from plugin-container.exe that the code in xul.dll
// can call to make sure we hit the right version of the code.
void TARGET_SANDBOX_EXPORT
SetProvideLogFunctionCb(ProvideLogFunctionCb aProvideLogFunctionCb);
// Provide a call back so a pointer to a logging function can be passed later.
static void
PrepareForLogging()
{
SetProvideLogFunctionCb(ProvideLogFunction);
}
#ifdef TARGET_SANDBOX_EXPORTS
static ProvideLogFunctionCb sProvideLogFunctionCb = nullptr;
void
SetProvideLogFunctionCb(ProvideLogFunctionCb aProvideLogFunctionCb)
{
sProvideLogFunctionCb = aProvideLogFunctionCb;
}
#ifdef MOZ_STACKWALKING #ifdef MOZ_STACKWALKING
static uint32_t sStackTraceDepth = 0; static uint32_t sStackTraceDepth = 0;
@ -110,15 +77,15 @@ Log(const char* aMessageType,
// Initialize sandbox logging if required. // Initialize sandbox logging if required.
static void static void
InitLoggingIfRequired() InitLoggingIfRequired(ProvideLogFunctionCb aProvideLogFunctionCb)
{ {
if (!sProvideLogFunctionCb) { if (!aProvideLogFunctionCb) {
return; return;
} }
if (Preferences::GetBool("security.sandbox.windows.log") || if (Preferences::GetBool("security.sandbox.windows.log") ||
PR_GetEnv("MOZ_WIN_SANDBOX_LOGGING")) { PR_GetEnv("MOZ_WIN_SANDBOX_LOGGING")) {
sProvideLogFunctionCb(Log); aProvideLogFunctionCb(Log);
#if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_STACKWALKING) #if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_STACKWALKING)
// We can only log the stack trace on process types where we know that the // We can only log the stack trace on process types where we know that the
@ -130,8 +97,8 @@ InitLoggingIfRequired()
#endif #endif
} }
} }
#endif
} // sandboxing } // sandboxing
} // mozilla } // mozilla
#endif // security_sandbox_loggingCallbacks_h__ #endif // security_sandbox_loggingCallbacks_h__

Просмотреть файл

@ -13,12 +13,6 @@
#include "loggingTypes.h" #include "loggingTypes.h"
#ifdef SANDBOX_EXPORTS
#define SANDBOX_EXPORT __declspec(dllexport)
#else
#define SANDBOX_EXPORT __declspec(dllimport)
#endif
namespace sandbox { namespace sandbox {
class TargetPolicy; class TargetPolicy;
} }
@ -28,7 +22,7 @@ namespace sandboxing {
// This is used to pass a LogCallback to the sandboxing code, as the logging // This is used to pass a LogCallback to the sandboxing code, as the logging
// requires code to which we cannot link directly. // requires code to which we cannot link directly.
void SANDBOX_EXPORT ProvideLogFunction(LogFunction aLogFunction); void ProvideLogFunction(LogFunction aLogFunction);
// Set up dummy interceptions via the broker, so we can log calls. // Set up dummy interceptions via the broker, so we can log calls.
void ApplyLoggingPolicy(sandbox::TargetPolicy& aPolicy); void ApplyLoggingPolicy(sandbox::TargetPolicy& aPolicy);

Просмотреть файл

@ -28,6 +28,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
'chromium-shim/sandbox/win/loggingCallbacks.h', 'chromium-shim/sandbox/win/loggingCallbacks.h',
'chromium-shim/sandbox/win/loggingTypes.h', 'chromium-shim/sandbox/win/loggingTypes.h',
'chromium-shim/sandbox/win/sandboxLogging.h', 'chromium-shim/sandbox/win/sandboxLogging.h',
'win/SandboxInitialization.h',
] ]
SOURCES += [ SOURCES += [
@ -128,6 +129,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
'chromium/sandbox/win/src/win2k_threadpool.cc', 'chromium/sandbox/win/src/win2k_threadpool.cc',
'chromium/sandbox/win/src/win_utils.cc', 'chromium/sandbox/win/src/win_utils.cc',
'chromium/sandbox/win/src/window.cc', 'chromium/sandbox/win/src/window.cc',
'win/SandboxInitialization.cpp',
] ]
if CONFIG['CPU_ARCH'] == 'x86_64': if CONFIG['CPU_ARCH'] == 'x86_64':

Просмотреть файл

@ -0,0 +1,46 @@
/* -*- 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/. */
#include "SandboxInitialization.h"
#include "sandbox/win/src/sandbox_factory.h"
namespace mozilla {
namespace sandboxing {
static sandbox::TargetServices*
InitializeTargetServices()
{
sandbox::TargetServices* targetServices =
sandbox::SandboxFactory::GetTargetServices();
if (!targetServices) {
return nullptr;
}
if (targetServices->Init() != sandbox::SBOX_ALL_OK) {
return nullptr;
}
return targetServices;
}
sandbox::TargetServices*
GetInitializedTargetServices()
{
static sandbox::TargetServices* sInitializedTargetServices =
InitializeTargetServices();
return sInitializedTargetServices;
}
void
LowerSandbox()
{
GetInitializedTargetServices()->LowerToken();
}
} // sandboxing
} // mozilla

Просмотреть файл

@ -0,0 +1,35 @@
/* -*- 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 mozilla_sandboxing_SandboxInitialization_h
#define mozilla_sandboxing_SandboxInitialization_h
namespace sandbox {
class TargetServices;
}
namespace mozilla {
// Note the Chromium code just uses a bare sandbox namespace, which makes using
// sandbox for our namespace painful.
namespace sandboxing {
/**
* Initializes (if required) and returns the Chromium sandbox TargetServices.
*
* @return the TargetServices or null if the creation or initialization failed.
*/
sandbox::TargetServices* GetInitializedTargetServices();
/**
* Lowers the permissions on the process sandbox.
* Provided because the GMP sandbox needs to be lowered from the executable.
*/
void LowerSandbox();
} // sandboxing
} // mozilla
#endif // mozilla_sandboxing_SandboxInitialization_h

Просмотреть файл

@ -12,17 +12,10 @@
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "base/MissingBasicTypes.h" #include "base/MissingBasicTypes.h"
#include "sandbox/win/src/sandbox.h" #include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/target_services.h"
#ifdef TARGET_SANDBOX_EXPORTS
#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
#else
#define TARGET_SANDBOX_EXPORT __declspec(dllimport)
#endif
namespace mozilla { namespace mozilla {
class SandboxTarget
class TARGET_SANDBOX_EXPORT SandboxTarget
{ {
public: public:
/** /**

Просмотреть файл

@ -159,6 +159,12 @@ LOCAL_INCLUDES += [
'/xpcom/build', '/xpcom/build',
] ]
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
LOCAL_INCLUDES += [
'/security/sandbox/chromium',
'/security/sandbox/chromium-shim',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [
'/widget', '/widget',

Просмотреть файл

@ -79,7 +79,7 @@
#include "base/histogram.h" #include "base/histogram.h"
#if defined(MOZ_SANDBOX) && defined(XP_WIN) #if defined(MOZ_SANDBOX) && defined(XP_WIN)
#define TARGET_SANDBOX_EXPORTS #include "mozilla/sandboxTarget.h"
#include "mozilla/sandboxing/loggingCallbacks.h" #include "mozilla/sandboxing/loggingCallbacks.h"
#endif #endif
@ -297,11 +297,12 @@ SetTaskbarGroupId(const nsString& aId)
nsresult nsresult
XRE_InitChildProcess(int aArgc, XRE_InitChildProcess(int aArgc,
char* aArgv[], char* aArgv[],
GMPLoader* aGMPLoader) const XREChildData* aChildData)
{ {
NS_ENSURE_ARG_MIN(aArgc, 2); NS_ENSURE_ARG_MIN(aArgc, 2);
NS_ENSURE_ARG_POINTER(aArgv); NS_ENSURE_ARG_POINTER(aArgv);
NS_ENSURE_ARG_POINTER(aArgv[0]); NS_ENSURE_ARG_POINTER(aArgv[0]);
MOZ_ASSERT(aChildData);
#ifdef HAS_DLL_BLOCKLIST #ifdef HAS_DLL_BLOCKLIST
DllBlocklist_Initialize(); DllBlocklist_Initialize();
@ -314,13 +315,13 @@ XRE_InitChildProcess(int aArgc,
#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK) #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
// On non-Fennec Gecko, the GMPLoader code resides in plugin-container, // On non-Fennec Gecko, the GMPLoader code resides in plugin-container,
// and we must forward it through to the GMP code here. // and we must forward it through to the GMP code here.
GMPProcessChild::SetGMPLoader(aGMPLoader); GMPProcessChild::SetGMPLoader(aChildData->gmpLoader.get());
#else #else
// On Fennec, the GMPLoader's code resides inside XUL (because for the time // On Fennec, the GMPLoader's code resides inside XUL (because for the time
// being GMPLoader relies upon NSPR, which we can't use in plugin-container // being GMPLoader relies upon NSPR, which we can't use in plugin-container
// on Android), so we create it here inside XUL and pass it to the GMP code. // on Android), so we create it here inside XUL and pass it to the GMP code.
nsAutoPtr<GMPLoader> loader(CreateGMPLoader(nullptr)); UniquePtr<GMPLoader> loader = CreateGMPLoader(nullptr);
GMPProcessChild::SetGMPLoader(loader); GMPProcessChild::SetGMPLoader(loader.get());
#endif #endif
#if defined(XP_WIN) #if defined(XP_WIN)
@ -345,6 +346,12 @@ XRE_InitChildProcess(int aArgc,
if (_fileno(stdin) == -1 || _get_osfhandle(fileno(stdin)) == -1) if (_fileno(stdin) == -1 || _get_osfhandle(fileno(stdin)) == -1)
freopen("CONIN$", "r", stdin); freopen("CONIN$", "r", stdin);
} }
#if defined(MOZ_SANDBOX)
if (aChildData->sandboxTargetServices) {
SandboxTarget::Instance()->SetTargetServices(aChildData->sandboxTargetServices);
}
#endif
#endif #endif
// NB: This must be called before profiler_init // NB: This must be called before profiler_init
@ -628,7 +635,7 @@ XRE_InitChildProcess(int aArgc,
#if defined(MOZ_SANDBOX) && defined(XP_WIN) #if defined(MOZ_SANDBOX) && defined(XP_WIN)
// We need to do this after the process has been initialised, as // We need to do this after the process has been initialised, as
// InitLoggingIfRequired may need access to prefs. // InitLoggingIfRequired may need access to prefs.
mozilla::sandboxing::InitLoggingIfRequired(); mozilla::sandboxing::InitLoggingIfRequired(aChildData->ProvideLogFunction);
#endif #endif
OverrideDefaultLocaleIfNeeded(); OverrideDefaultLocaleIfNeeded();

Просмотреть файл

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 XREChildData_h
#define XREChildData_h
#include "mozilla/UniquePtr.h"
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
#include "mozilla/sandboxing/loggingTypes.h"
namespace sandbox {
class TargetServices;
}
#endif
namespace mozilla {
namespace gmp {
class GMPLoader;
}
}
/**
* Data needed to start a child process.
*/
struct XREChildData
{
#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
/**
* Used to load the GMP binary.
*/
mozilla::UniquePtr<mozilla::gmp::GMPLoader> gmpLoader;
#endif
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
/**
* Chromium sandbox TargetServices.
*/
sandbox::TargetServices* sandboxTargetServices = nullptr;
/**
* Function to provide a logging function to the chromium sandbox code.
*/
mozilla::sandboxing::ProvideLogFunctionCb ProvideLogFunction = nullptr;
#endif
};
#endif // XREChildData_h

Просмотреть файл

@ -10,6 +10,7 @@ EXPORTS += [
'nsXPCOMCIDInternal.h', 'nsXPCOMCIDInternal.h',
'nsXREAppData.h', 'nsXREAppData.h',
'nsXULAppAPI.h', 'nsXULAppAPI.h',
'XREChildData.h',
'xrecore.h', 'xrecore.h',
] ]

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/Vector.h" #include "mozilla/Vector.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "XREChildData.h"
/** /**
* A directory service key which provides the platform-correct "application * A directory service key which provides the platform-correct "application
@ -411,7 +412,7 @@ class GMPLoader;
XRE_API(nsresult, XRE_API(nsresult,
XRE_InitChildProcess, (int aArgc, XRE_InitChildProcess, (int aArgc,
char* aArgv[], char* aArgv[],
mozilla::gmp::GMPLoader* aGMPLoader)) const XREChildData* aChildData))
XRE_API(GeckoProcessType, XRE_API(GeckoProcessType,
XRE_GetProcessType, ()) XRE_GetProcessType, ())