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

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

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

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

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

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

@ -35,6 +35,7 @@
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "XREChildData.h"
/* Android headers don't define RUSAGE_THREAD */
#ifndef RUSAGE_THREAD
@ -421,6 +422,7 @@ ChildProcessInit(int argc, char* argv[])
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__
#define security_sandbox_loggingCallbacks_h__
#include "mozilla/sandboxing/loggingTypes.h"
#include "mozilla/sandboxing/sandboxLogging.h"
#ifdef TARGET_SANDBOX_EXPORTS
#include <sstream>
#include <iostream>
#include "mozilla/Preferences.h"
#include "mozilla/sandboxing/loggingTypes.h"
#include "nsContentUtils.h"
#ifdef MOZ_STACKWALKING
#include "mozilla/StackWalk.h"
#endif
#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
#else
#define TARGET_SANDBOX_EXPORT __declspec(dllimport)
#endif
namespace mozilla {
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
static uint32_t sStackTraceDepth = 0;
@ -110,15 +77,15 @@ Log(const char* aMessageType,
// Initialize sandbox logging if required.
static void
InitLoggingIfRequired()
InitLoggingIfRequired(ProvideLogFunctionCb aProvideLogFunctionCb)
{
if (!sProvideLogFunctionCb) {
if (!aProvideLogFunctionCb) {
return;
}
if (Preferences::GetBool("security.sandbox.windows.log") ||
PR_GetEnv("MOZ_WIN_SANDBOX_LOGGING")) {
sProvideLogFunctionCb(Log);
aProvideLogFunctionCb(Log);
#if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_STACKWALKING)
// We can only log the stack trace on process types where we know that the
@ -130,8 +97,8 @@ InitLoggingIfRequired()
#endif
}
}
#endif
} // sandboxing
} // mozilla
#endif // security_sandbox_loggingCallbacks_h__
#endif // security_sandbox_loggingCallbacks_h__

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

@ -13,12 +13,6 @@
#include "loggingTypes.h"
#ifdef SANDBOX_EXPORTS
#define SANDBOX_EXPORT __declspec(dllexport)
#else
#define SANDBOX_EXPORT __declspec(dllimport)
#endif
namespace sandbox {
class TargetPolicy;
}
@ -28,7 +22,7 @@ namespace sandboxing {
// This is used to pass a LogCallback to the sandboxing code, as the logging
// 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.
void ApplyLoggingPolicy(sandbox::TargetPolicy& aPolicy);

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

@ -28,6 +28,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
'chromium-shim/sandbox/win/loggingCallbacks.h',
'chromium-shim/sandbox/win/loggingTypes.h',
'chromium-shim/sandbox/win/sandboxLogging.h',
'win/SandboxInitialization.h',
]
SOURCES += [
@ -128,6 +129,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
'chromium/sandbox/win/src/win2k_threadpool.cc',
'chromium/sandbox/win/src/win_utils.cc',
'chromium/sandbox/win/src/window.cc',
'win/SandboxInitialization.cpp',
]
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 "base/MissingBasicTypes.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 {
class TARGET_SANDBOX_EXPORT SandboxTarget
class SandboxTarget
{
public:
/**

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

@ -159,6 +159,12 @@ LOCAL_INCLUDES += [
'/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':
LOCAL_INCLUDES += [
'/widget',

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

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

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

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