mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 1530245 - Launch sandbox from new remote sandbox broker process. r=jld,bobowen
Depends on D22051 Differential Revision: https://phabricator.services.mozilla.com/D22052 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
f4c9b88845
commit
de686d23c1
@ -46,6 +46,13 @@ int content_process_main(mozilla::Bootstrap* bootstrap, int argc,
|
||||
|
||||
bootstrap->XRE_SetProcessType(argv[--argc]);
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
if (bootstrap->XRE_GetProcessType() == GeckoProcessType_RemoteSandboxBroker) {
|
||||
childData.sandboxBrokerServices =
|
||||
mozilla::sandboxing::GetInitializedBrokerServices();
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult rv = bootstrap->XRE_InitChildProcess(argc, argv, &childData);
|
||||
return NS_FAILED(rv);
|
||||
}
|
||||
|
@ -44,9 +44,12 @@ static_assert(nsICrashService::PROCESS_TYPE_RDD == (int)GeckoProcessType_RDD,
|
||||
static_assert(nsICrashService::PROCESS_TYPE_SOCKET ==
|
||||
(int)GeckoProcessType_Socket,
|
||||
"GeckoProcessType enum is out of sync with nsICrashService!");
|
||||
static_assert(nsICrashService::PROCESS_TYPE_SANDBOX_BROKER ==
|
||||
(int)GeckoProcessType_RemoteSandboxBroker,
|
||||
"GeckoProcessType enum is out of sync with nsICrashService!");
|
||||
// Add new static asserts here if you add more process types.
|
||||
// Update this static assert as well.
|
||||
static_assert(nsICrashService::PROCESS_TYPE_SOCKET + 1 ==
|
||||
static_assert(nsICrashService::PROCESS_TYPE_SANDBOX_BROKER + 1 ==
|
||||
(int)GeckoProcessType_End,
|
||||
"GeckoProcessType enum is out of sync with nsICrashService!");
|
||||
|
||||
|
@ -56,6 +56,9 @@
|
||||
# include "mozilla/Preferences.h"
|
||||
# include "mozilla/sandboxing/sandboxLogging.h"
|
||||
# include "WinUtils.h"
|
||||
# if defined(_ARM64_)
|
||||
# include "mozilla/remoteSandboxBroker.h"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -103,7 +106,6 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
|
||||
mGroupId(u"-"),
|
||||
#endif
|
||||
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
|
||||
mSandboxBroker(new SandboxBroker()),
|
||||
mEnableSandboxLogging(false),
|
||||
mSandboxLevel(0),
|
||||
#endif
|
||||
@ -151,6 +153,12 @@ GeckoChildProcessHost::~GeckoChildProcessHost()
|
||||
mChildProcessHandle);
|
||||
#endif
|
||||
}
|
||||
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
|
||||
if (mSandboxBroker) {
|
||||
mSandboxBroker->Shutdown();
|
||||
mSandboxBroker = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeckoChildProcessHost::Destroy() {
|
||||
@ -1020,19 +1028,22 @@ bool GeckoChildProcessHost::PerformAsyncLaunch(
|
||||
FilePath exePath;
|
||||
BinaryPathType pathType = GetPathToBinary(exePath, mProcessType);
|
||||
|
||||
# if defined(MOZ_SANDBOX) || (defined(_ARM64_) && defined(XP_WIN))
|
||||
# if defined(MOZ_SANDBOX) || defined(_ARM64_)
|
||||
const bool isGMP = mProcessType == GeckoProcessType_GMPlugin;
|
||||
const bool isWidevine = isGMP && Contains(aExtraOpts, "gmp-widevinecdm");
|
||||
# if defined(_ARM64_) && defined(XP_WIN)
|
||||
# if defined(_ARM64_)
|
||||
const bool isClearKey = isGMP && Contains(aExtraOpts, "gmp-clearkey");
|
||||
if (isGMP && (isClearKey || isWidevine)) {
|
||||
// On Windows on ARM64 for ClearKey and Widevine, we want to run the
|
||||
// x86 plugin-container.exe in the "i686" subdirectory, instead of the
|
||||
// aarch64 plugin-container.exe. So insert "i686" into the exePath.
|
||||
const bool isSandboxBroker =
|
||||
mProcessType == GeckoProcessType_RemoteSandboxBroker;
|
||||
if (isClearKey || isWidevine || isSandboxBroker) {
|
||||
// On Windows on ARM64 for ClearKey and Widevine, and for the sandbox
|
||||
// launcher process, we want to run the x86 plugin-container.exe in
|
||||
// the "i686" subdirectory, instead of the aarch64 plugin-container.exe.
|
||||
// So insert "i686" into the exePath.
|
||||
exePath = exePath.DirName().AppendASCII("i686").Append(exePath.BaseName());
|
||||
}
|
||||
# endif
|
||||
# endif // defined(MOZ_SANDBOX) || (defined(_ARM64_) && defined(XP_WIN))
|
||||
# endif // if defined(_ARM64_)
|
||||
# endif // defined(MOZ_SANDBOX) || defined(_ARM64_)
|
||||
|
||||
CommandLine cmdLine(exePath.ToWStringHack());
|
||||
|
||||
@ -1064,6 +1075,13 @@ bool GeckoChildProcessHost::PerformAsyncLaunch(
|
||||
}
|
||||
|
||||
# if defined(MOZ_SANDBOX)
|
||||
# if defined(_ARM64_)
|
||||
if (isClearKey || isWidevine)
|
||||
mSandboxBroker = new RemoteSandboxBroker();
|
||||
else
|
||||
# endif // if defined(_ARM64_)
|
||||
mSandboxBroker = new SandboxBroker();
|
||||
|
||||
bool shouldSandboxCurrentProcess = false;
|
||||
|
||||
// XXX: Bug 1124167: We should get rid of the process specific logic for
|
||||
@ -1136,6 +1154,9 @@ bool GeckoChildProcessHost::PerformAsyncLaunch(
|
||||
case GeckoProcessType_Socket:
|
||||
// TODO - setup sandboxing for the socket process.
|
||||
break;
|
||||
case GeckoProcessType_RemoteSandboxBroker:
|
||||
// We don't sandbox the sandbox launcher...
|
||||
break;
|
||||
case GeckoProcessType_Default:
|
||||
default:
|
||||
MOZ_CRASH("Bad process type in GeckoChildProcessHost");
|
||||
@ -1208,7 +1229,7 @@ bool GeckoChildProcessHost::PerformAsyncLaunch(
|
||||
// No handle duplication necessary.
|
||||
break;
|
||||
default:
|
||||
if (!mSandboxBroker->AddTargetPeer(process)) {
|
||||
if (!SandboxBroker::AddTargetPeer(process)) {
|
||||
NS_WARNING("Failed to add child process as target peer.");
|
||||
}
|
||||
break;
|
||||
|
@ -1059,3 +1059,5 @@ description =
|
||||
description = bug 1363126
|
||||
[PClientSource::WorkerSyncPing]
|
||||
description = Synchronous ping allowing worker thread to confirm actor is created. Necessary to avoid racing with ClientHandle actors on main thread.
|
||||
[PRemoteSandboxBroker::LaunchApp]
|
||||
description = Synchronous launch of a child process that in turn launches and sandboxes another process. Called on a dedicated thread and targets a dedicated process, so this shouldn't block anything.
|
||||
|
@ -20,6 +20,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
|
||||
FORCE_STATIC_LIB = True
|
||||
|
||||
DIRS += [
|
||||
'win/src/remotesandboxbroker',
|
||||
'win/src/sandboxbroker',
|
||||
'win/src/sandboxpermissions',
|
||||
'win/src/sandboxtarget',
|
||||
|
@ -0,0 +1,35 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct EnvVar {
|
||||
nsString name;
|
||||
nsString value;
|
||||
};
|
||||
|
||||
struct LaunchParameters {
|
||||
nsString path;
|
||||
nsString args;
|
||||
EnvVar[] env;
|
||||
uint32_t processType;
|
||||
uint32_t sandboxLevel;
|
||||
nsString[] allowedReadFiles;
|
||||
uint64_t[] shareHandles;
|
||||
bool enableLogging;
|
||||
};
|
||||
|
||||
intr protocol PRemoteSandboxBroker
|
||||
{
|
||||
parent:
|
||||
async InitCrashReporter(Shmem shmem, NativeThreadId threadId);
|
||||
child:
|
||||
intr LaunchApp(LaunchParameters params)
|
||||
returns (bool ok, uint64_t handle);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
@ -0,0 +1,86 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RemoteSandboxBrokerChild.h"
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#include "nsDebugImpl.h"
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#include "RemoteSandboxBrokerProcessChild.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
RemoteSandboxBrokerChild::RemoteSandboxBrokerChild() {
|
||||
nsDebugImpl::SetMultiprocessMode("RemoteSandboxBroker");
|
||||
}
|
||||
|
||||
RemoteSandboxBrokerChild::~RemoteSandboxBrokerChild() {}
|
||||
|
||||
bool RemoteSandboxBrokerChild::Init(base::ProcessId aParentPid,
|
||||
MessageLoop* aIOLoop,
|
||||
IPC::Channel* aChannel) {
|
||||
if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
|
||||
return false;
|
||||
}
|
||||
CrashReporterClient::InitSingleton(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteSandboxBrokerChild::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
if (AbnormalShutdown == aWhy) {
|
||||
NS_WARNING("Abnormal shutdown of GMP process!");
|
||||
ipc::ProcessChild::QuickExit();
|
||||
}
|
||||
CrashReporterClient::DestroySingleton();
|
||||
XRE_ShutdownChildProcess();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult RemoteSandboxBrokerChild::AnswerLaunchApp(
|
||||
LaunchParameters&& aParams, bool* aOutOk, uint64_t* aOutHandle) {
|
||||
auto towstring = [](const nsString& s) {
|
||||
return std::wstring(s.get(), s.Length());
|
||||
};
|
||||
|
||||
base::EnvironmentMap envmap;
|
||||
for (const EnvVar& env : aParams.env()) {
|
||||
envmap[towstring(env.name())] = towstring(env.value());
|
||||
}
|
||||
|
||||
if (!mSandboxBroker.SetSecurityLevelForGMPlugin(
|
||||
AbstractSandboxBroker::SandboxLevel(aParams.sandboxLevel()))) {
|
||||
*aOutOk = false;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
for (const auto& path : aParams.allowedReadFiles()) {
|
||||
if (!mSandboxBroker.AllowReadFile(path.get())) {
|
||||
*aOutOk = false;
|
||||
return IPC_OK();
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& handle : aParams.shareHandles()) {
|
||||
mSandboxBroker.AddHandleToShare(HANDLE(handle));
|
||||
}
|
||||
|
||||
HANDLE p;
|
||||
*aOutOk =
|
||||
mSandboxBroker.LaunchApp(aParams.path().get(), aParams.args().get(),
|
||||
envmap, GeckoProcessType(aParams.processType()),
|
||||
aParams.enableLogging(), (void**)&p);
|
||||
if (*aOutOk) {
|
||||
*aOutHandle = uint64_t(p);
|
||||
}
|
||||
|
||||
for (const auto& handle : aParams.shareHandles()) {
|
||||
CloseHandle(HANDLE(handle));
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -0,0 +1,34 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef RemoteSandboxBrokerChild_h_
|
||||
#define RemoteSandboxBrokerChild_h_
|
||||
|
||||
#include "mozilla/PRemoteSandboxBrokerChild.h"
|
||||
#include "sandboxBroker.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class RemoteSandboxBrokerChild : public PRemoteSandboxBrokerChild {
|
||||
friend class PRemoteSandboxBrokerChild;
|
||||
|
||||
public:
|
||||
RemoteSandboxBrokerChild();
|
||||
virtual ~RemoteSandboxBrokerChild();
|
||||
bool Init(base::ProcessId aParentPid, MessageLoop* aIOLoop,
|
||||
IPC::Channel* aChannel);
|
||||
|
||||
private:
|
||||
mozilla::ipc::IPCResult AnswerLaunchApp(LaunchParameters&& aParams,
|
||||
bool* aOutOk, uint64_t* aOutHandle);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy);
|
||||
SandboxBroker mSandboxBroker;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -0,0 +1,91 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RemoteSandboxBrokerParent.h"
|
||||
#include "RemoteSandboxBrokerProcessParent.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include <windows.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
RefPtr<GenericPromise> RemoteSandboxBrokerParent::Launch(
|
||||
const nsTArray<uint64_t>& aHandlesToShare) {
|
||||
MOZ_ASSERT(!mProcess);
|
||||
if (mProcess) {
|
||||
// Don't re-init.
|
||||
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
|
||||
mProcess = new RemoteSandboxBrokerProcessParent();
|
||||
for (uint64_t handle : aHandlesToShare) {
|
||||
mProcess->AddHandleToShare(HANDLE(handle));
|
||||
}
|
||||
|
||||
// Note: we rely on the caller to keep this instance alive while we launch
|
||||
// the process, so that these closures point to valid memory.
|
||||
auto resolve = [this](base::ProcessHandle handle) {
|
||||
mOpened = Open(mProcess->GetChannel(), base::GetProcId(handle));
|
||||
if (!mOpened) {
|
||||
mProcess->Destroy();
|
||||
mProcess = nullptr;
|
||||
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
return GenericPromise::CreateAndResolve(true, __func__);
|
||||
};
|
||||
|
||||
auto reject = [this]() {
|
||||
NS_ERROR("failed to launch child in the parent");
|
||||
if (mProcess) {
|
||||
mProcess->Destroy();
|
||||
mProcess = nullptr;
|
||||
}
|
||||
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
};
|
||||
|
||||
return mProcess->AsyncLaunch()->Then(GetCurrentThreadSerialEventTarget(),
|
||||
__func__, std::move(resolve),
|
||||
std::move(reject));
|
||||
}
|
||||
|
||||
bool RemoteSandboxBrokerParent::DuplicateFromLauncher(HANDLE aLauncherHandle,
|
||||
LPHANDLE aOurHandle) {
|
||||
return ::DuplicateHandle(mProcess->GetChildProcessHandle(), aLauncherHandle,
|
||||
::GetCurrentProcess(), aOurHandle, 0, false,
|
||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
|
||||
}
|
||||
|
||||
void RemoteSandboxBrokerParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
if (AbnormalShutdown == aWhy) {
|
||||
Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
|
||||
NS_LITERAL_CSTRING("sandboxbroker"), 1);
|
||||
if (mCrashReporter) {
|
||||
mCrashReporter->GenerateCrashReport(OtherPid());
|
||||
mCrashReporter = nullptr;
|
||||
}
|
||||
}
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RemoteSandboxBrokerParent::Shutdown() {
|
||||
if (mOpened) {
|
||||
mOpened = false;
|
||||
Close();
|
||||
}
|
||||
if (mProcess) {
|
||||
mProcess->Destroy();
|
||||
mProcess = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult RemoteSandboxBrokerParent::RecvInitCrashReporter(
|
||||
Shmem&& aShmem, const NativeThreadId& aThreadId) {
|
||||
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(
|
||||
GeckoProcessType_RemoteSandboxBroker, aShmem, aThreadId);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -0,0 +1,43 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef RemoteSandboxBrokerParent_h_
|
||||
#define RemoteSandboxBrokerParent_h_
|
||||
|
||||
#include "mozilla/PRemoteSandboxBrokerParent.h"
|
||||
#include "RemoteSandboxBrokerProcessParent.h"
|
||||
#include "mozilla/ipc/CrashReporterHost.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class RemoteSandboxBrokerParent : public PRemoteSandboxBrokerParent {
|
||||
friend class PRemoteSandboxBrokerParent;
|
||||
|
||||
public:
|
||||
bool DuplicateFromLauncher(HANDLE aLauncherHandle, LPHANDLE aOurHandle);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
// Asynchronously launches the launcher process.
|
||||
// Note: we rely on the caller to keep this instance alive
|
||||
// until this promise resolves.
|
||||
RefPtr<GenericPromise> Launch(const nsTArray<uint64_t>& aHandlesToShare);
|
||||
|
||||
private:
|
||||
mozilla::ipc::IPCResult RecvInitCrashReporter(
|
||||
Shmem&& aShmem, const NativeThreadId& aThreadId);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
RemoteSandboxBrokerProcessParent* mProcess = nullptr;
|
||||
|
||||
bool mOpened = false;
|
||||
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // RemoteSandboxBrokerParent_h_
|
@ -0,0 +1,32 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RemoteSandboxBrokerProcessChild.h"
|
||||
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/BackgroundHangMonitor.h"
|
||||
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
RemoteSandboxBrokerProcessChild::RemoteSandboxBrokerProcessChild(
|
||||
ProcessId aParentPid)
|
||||
: ProcessChild(aParentPid) {}
|
||||
|
||||
RemoteSandboxBrokerProcessChild::~RemoteSandboxBrokerProcessChild() {}
|
||||
|
||||
bool RemoteSandboxBrokerProcessChild::Init(int aArgc, char* aArgv[]) {
|
||||
BackgroundHangMonitor::Startup();
|
||||
return mSandboxBrokerChild.Init(ParentPid(), IOThreadChild::message_loop(),
|
||||
IOThreadChild::channel());
|
||||
}
|
||||
|
||||
void RemoteSandboxBrokerProcessChild::CleanUp() {
|
||||
BackgroundHangMonitor::Shutdown();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -0,0 +1,33 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 RemoteSandboxBrokerProcessChild_h_
|
||||
#define RemoteSandboxBrokerProcessChild_h_
|
||||
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
#include "RemoteSandboxBrokerChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class RemoteSandboxBrokerProcessChild final
|
||||
: public mozilla::ipc::ProcessChild {
|
||||
protected:
|
||||
typedef mozilla::ipc::ProcessChild ProcessChild;
|
||||
|
||||
public:
|
||||
explicit RemoteSandboxBrokerProcessChild(ProcessId aParentPid);
|
||||
~RemoteSandboxBrokerProcessChild();
|
||||
|
||||
bool Init(int aArgc, char* aArgv[]) override;
|
||||
void CleanUp() override;
|
||||
|
||||
private:
|
||||
RemoteSandboxBrokerChild mSandboxBrokerChild;
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteSandboxBrokerProcessChild);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPProcessChild_h_
|
@ -0,0 +1,33 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RemoteSandboxBrokerProcessParent.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include <windows.h>
|
||||
|
||||
using mozilla::ipc::GeckoChildProcessHost;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
RemoteSandboxBrokerProcessParent::RemoteSandboxBrokerProcessParent()
|
||||
: GeckoChildProcessHost(GeckoProcessType_RemoteSandboxBroker) {
|
||||
MOZ_COUNT_CTOR(RemoteSandboxBrokerProcessParent);
|
||||
}
|
||||
|
||||
RemoteSandboxBrokerProcessParent::~RemoteSandboxBrokerProcessParent() {
|
||||
MOZ_COUNT_DTOR(RemoteSandboxBrokerProcessParent);
|
||||
}
|
||||
|
||||
RefPtr<RemoteSandboxBrokerProcessParent::HandlePromise>
|
||||
RemoteSandboxBrokerProcessParent::AsyncLaunch() {
|
||||
if (!GeckoChildProcessHost::AsyncLaunch()) {
|
||||
return HandlePromise::CreateAndReject(GeckoChildProcessHost::LaunchError{},
|
||||
__func__);
|
||||
}
|
||||
return WhenProcessHandleReady();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -0,0 +1,46 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=4 et :
|
||||
* 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 RemoteSandboxBrokerProcessParent_h_
|
||||
#define RemoteSandboxBrokerProcessParent_h_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "base/basictypes.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/thread.h"
|
||||
#include "chrome/common/child_process_host.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
|
||||
class nsIRunnable;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class RemoteSandboxBrokerProcessParent final
|
||||
: public mozilla::ipc::GeckoChildProcessHost {
|
||||
public:
|
||||
using LaunchError = GeckoChildProcessHost::LaunchError;
|
||||
using LaunchPromise = GeckoChildProcessHost::LaunchPromise<bool>;
|
||||
|
||||
RemoteSandboxBrokerProcessParent();
|
||||
|
||||
using GeckoChildProcessHost::HandlePromise;
|
||||
|
||||
RefPtr<HandlePromise> AsyncLaunch();
|
||||
|
||||
bool CanShutdown() override { return true; }
|
||||
|
||||
using mozilla::ipc::GeckoChildProcessHost::GetChannel;
|
||||
using mozilla::ipc::GeckoChildProcessHost::GetChildProcessHandle;
|
||||
|
||||
private:
|
||||
~RemoteSandboxBrokerProcessParent();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RemoteSandboxBrokerProcessParent);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // ifndef GMPProcessParent_h
|
35
security/sandbox/win/src/remotesandboxbroker/moz.build
Normal file
35
security/sandbox/win/src/remotesandboxbroker/moz.build
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
SOURCES += [
|
||||
'remoteSandboxBroker.cpp',
|
||||
'RemoteSandboxBrokerChild.cpp',
|
||||
'RemoteSandboxBrokerParent.cpp',
|
||||
'RemoteSandboxBrokerProcessChild.cpp',
|
||||
'RemoteSandboxBrokerProcessParent.cpp',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'remoteSandboxBroker.h',
|
||||
'RemoteSandboxBrokerChild.h',
|
||||
'RemoteSandboxBrokerParent.h',
|
||||
'RemoteSandboxBrokerProcessChild.h',
|
||||
'RemoteSandboxBrokerProcessParent.h',
|
||||
]
|
||||
|
||||
for var in ('UNICODE', '_UNICODE'):
|
||||
DEFINES[var] = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['CC_TYPE'] == 'clang-cl':
|
||||
AllowCompilerWarnings() # workaround for bug 1090497
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PRemoteSandboxBroker.ipdl'
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
@ -0,0 +1,159 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "remoteSandboxBroker.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
RemoteSandboxBroker::RemoteSandboxBroker() {}
|
||||
|
||||
RemoteSandboxBroker::~RemoteSandboxBroker() {
|
||||
MOZ_ASSERT(
|
||||
mShutdown,
|
||||
"Shutdown must be called on RemoteSandboxBroker before destruction!");
|
||||
}
|
||||
|
||||
void RemoteSandboxBroker::Shutdown() {
|
||||
MOZ_ASSERT(!mShutdown, "Don't call Shutdown() twice!");
|
||||
mShutdown = true;
|
||||
|
||||
if (!mIPCLaunchThread) {
|
||||
// Can't have launched child process, nothing to shutdown.
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<RemoteSandboxBroker> self = this;
|
||||
mIPCLaunchThread->Dispatch(
|
||||
NS_NewRunnableFunction("Remote Sandbox Launch", [self, this]() {
|
||||
// Note: `self` here should be the last reference to this instance.
|
||||
mParent.Shutdown();
|
||||
mIPCLaunchThread = nullptr;
|
||||
}));
|
||||
}
|
||||
|
||||
bool RemoteSandboxBroker::LaunchApp(const wchar_t *aPath,
|
||||
const wchar_t *aArguments,
|
||||
base::EnvironmentMap &aEnvironment,
|
||||
GeckoProcessType aProcessType,
|
||||
const bool aEnableLogging,
|
||||
void **aProcessHandle) {
|
||||
// Note: we expect to be called on the IPC launch thread from
|
||||
// GeckoChildProcesHost while it's launching a child process. We can't
|
||||
// run a synchronous launch here as that blocks the calling thread while
|
||||
// it dispatches a task to the IPC launch thread to spawn the process.
|
||||
// Since our calling thread is the IPC launch thread, we'd then be
|
||||
// deadlocked. So instead we do an async launch, and spin the event
|
||||
// loop until the process launch succeeds.
|
||||
|
||||
// We should be on the IPC launch thread. We're shutdown on the IO thread,
|
||||
// so save a ref to the IPC launch thread here, so we can close the channel
|
||||
// on the IPC launch thread on shutdown.
|
||||
mIPCLaunchThread = GetCurrentThreadEventTarget();
|
||||
|
||||
mParameters.path() = nsDependentString(aPath);
|
||||
mParameters.args() = nsDependentString(aArguments);
|
||||
|
||||
auto toNsString = [](const std::wstring &s) {
|
||||
return nsDependentString(s.c_str());
|
||||
};
|
||||
for (auto itr : aEnvironment) {
|
||||
mParameters.env().AppendElement(
|
||||
EnvVar(toNsString(itr.first), toNsString(itr.second)));
|
||||
}
|
||||
|
||||
mParameters.processType() = uint32_t(aProcessType);
|
||||
mParameters.enableLogging() = aEnableLogging;
|
||||
|
||||
enum Result { Pending, Succeeded, Failed };
|
||||
Result res = Pending;
|
||||
auto resolve = [&](bool ok) {
|
||||
res = Succeeded;
|
||||
return GenericPromise::CreateAndResolve(ok, __func__);
|
||||
};
|
||||
|
||||
auto reject = [&](nsresult) {
|
||||
res = Failed;
|
||||
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
};
|
||||
|
||||
mParent.Launch(mParameters.shareHandles())
|
||||
->Then(GetCurrentThreadSerialEventTarget(), __func__, std::move(resolve),
|
||||
std::move(reject));
|
||||
|
||||
// Spin the event loop while the sandbox launcher process launches.
|
||||
SpinEventLoopUntil([&]() { return res != Pending; });
|
||||
|
||||
if (res == Failed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t handle = 0;
|
||||
bool ok = false;
|
||||
bool rv = mParent.CallLaunchApp(std::move(mParameters), &ok, &handle) && ok;
|
||||
mParameters.shareHandles().Clear();
|
||||
if (!rv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Duplicate the handle of the child process that the launcher launched from
|
||||
// the launcher process's space into this process' space.
|
||||
HANDLE ourChildHandle = 0;
|
||||
bool dh = mParent.DuplicateFromLauncher((HANDLE)handle, &ourChildHandle);
|
||||
if (!dh) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aProcessHandle = (void **)(ourChildHandle);
|
||||
|
||||
base::ProcessHandle process = *aProcessHandle;
|
||||
SandboxBroker::AddTargetPeer(process);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoteSandboxBroker::SetSecurityLevelForGMPlugin(SandboxLevel aLevel) {
|
||||
mParameters.sandboxLevel() = uint32_t(aLevel);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoteSandboxBroker::AllowReadFile(wchar_t const *aFile) {
|
||||
mParameters.allowedReadFiles().AppendElement(nsDependentString(aFile));
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteSandboxBroker::AddHandleToShare(HANDLE aHandle) {
|
||||
mParameters.shareHandles().AppendElement(uint64_t(aHandle));
|
||||
}
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
void RemoteSandboxBroker::SetSecurityLevelForContentProcess(
|
||||
int32_t aSandboxLevel, bool aIsFileProcess) {
|
||||
MOZ_CRASH(
|
||||
"RemoteSandboxBroker::SetSecurityLevelForContentProcess not Implemented");
|
||||
}
|
||||
#endif
|
||||
|
||||
void RemoteSandboxBroker::SetSecurityLevelForGPUProcess(int32_t aSandboxLevel) {
|
||||
MOZ_CRASH(
|
||||
"RemoteSandboxBroker::SetSecurityLevelForGPUProcess not Implemented");
|
||||
}
|
||||
|
||||
bool RemoteSandboxBroker::SetSecurityLevelForRDDProcess() {
|
||||
MOZ_CRASH(
|
||||
"RemoteSandboxBroker::SetSecurityLevelForRDDProcess not Implemented");
|
||||
}
|
||||
|
||||
bool RemoteSandboxBroker::SetSecurityLevelForPluginProcess(
|
||||
int32_t aSandboxLevel) {
|
||||
MOZ_CRASH(
|
||||
"RemoteSandboxBroker::SetSecurityLevelForPluginProcess not Implemented");
|
||||
}
|
||||
|
||||
AbstractSandboxBroker *CreateRemoteSandboxBroker() {
|
||||
return new RemoteSandboxBroker();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -0,0 +1,66 @@
|
||||
/* -*- 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __REMOTE_SANDBOXBROKER_H__
|
||||
#define __REMOTE_SANDBOXBROKER_H__
|
||||
|
||||
#include "sandboxBroker.h"
|
||||
#include "RemoteSandboxBrokerParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// To make sandboxing an x86 plugin-container process on Windows on ARM64,
|
||||
// we launch an x86 child process which in turn launches and sandboxes the x86
|
||||
// plugin-container child. This means the sandbox broker (in the remote
|
||||
// x86 sandbox launcher process) can be same-arch with the process that it's
|
||||
// sandboxing, which means all the sandbox's assumptions about things being
|
||||
// same arch still hold.
|
||||
class RemoteSandboxBroker : public AbstractSandboxBroker {
|
||||
public:
|
||||
RemoteSandboxBroker();
|
||||
|
||||
void Shutdown() override;
|
||||
|
||||
// Note: This should be called on the IPC launch thread, and this spins
|
||||
// the event loop. So this means potentially another IPC launch could occur
|
||||
// re-entrantly while calling this.
|
||||
bool LaunchApp(const wchar_t *aPath, const wchar_t *aArguments,
|
||||
base::EnvironmentMap &aEnvironment,
|
||||
GeckoProcessType aProcessType, const bool aEnableLogging,
|
||||
void **aProcessHandle) override;
|
||||
|
||||
// Security levels for different types of processes
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
void SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
|
||||
bool aIsFileProcess) override;
|
||||
#endif
|
||||
void SetSecurityLevelForGPUProcess(int32_t aSandboxLevel) override;
|
||||
bool SetSecurityLevelForRDDProcess() override;
|
||||
bool SetSecurityLevelForPluginProcess(int32_t aSandboxLevel) override;
|
||||
bool SetSecurityLevelForGMPlugin(SandboxLevel aLevel) override;
|
||||
bool AllowReadFile(wchar_t const *file) override;
|
||||
void AddHandleToShare(HANDLE aHandle) override;
|
||||
|
||||
private:
|
||||
virtual ~RemoteSandboxBroker();
|
||||
|
||||
// Parameters that we use to launch the child process.
|
||||
LaunchParameters mParameters;
|
||||
|
||||
RemoteSandboxBrokerParent mParent;
|
||||
|
||||
// We bind the RemoteSandboxBrokerParent to the IPC launch thread.
|
||||
// As such, we must close its channel on the same thread. So we save
|
||||
// a reference to the IPC launch thread here.
|
||||
nsCOMPtr<nsIEventTarget> mIPCLaunchThread;
|
||||
|
||||
// True if we've been shutdown.
|
||||
bool mShutdown = false;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // __REMOTE_SANDBOXBROKER_H__
|
@ -97,43 +97,54 @@ static void CacheDirAndAutoClear(nsIProperties* aDirSvc, const char* aDirKey,
|
||||
void SandboxBroker::GeckoDependentInitialize() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Cache directory paths for use in policy rules, because the directory
|
||||
// service must be called on the main thread.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> dirSvc =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(
|
||||
false,
|
||||
"Failed to get directory service, cannot cache directories for rules.");
|
||||
LOG_E(
|
||||
"Failed to get directory service, cannot cache directories for rules.");
|
||||
return;
|
||||
}
|
||||
bool haveXPCOM = XRE_GetProcessType() != GeckoProcessType_RemoteSandboxBroker;
|
||||
if (haveXPCOM) {
|
||||
// Cache directory paths for use in policy rules, because the directory
|
||||
// service must be called on the main thread.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> dirSvc =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(false,
|
||||
"Failed to get directory service, cannot cache directories "
|
||||
"for rules.");
|
||||
LOG_E(
|
||||
"Failed to get directory service, cannot cache directories for "
|
||||
"rules.");
|
||||
return;
|
||||
}
|
||||
|
||||
CacheDirAndAutoClear(dirSvc, NS_GRE_DIR, &sBinDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_APP_USER_PROFILE_50_DIR, &sProfileDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
&sContentTempDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_APP_PLUGIN_PROCESS_TEMP_DIR, &sPluginTempDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_WIN_APPDATA_DIR, &sRoamingAppDataDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_WIN_LOCAL_APPDATA_DIR, &sLocalAppDataDir);
|
||||
CacheDirAndAutoClear(dirSvc, XRE_USER_SYS_EXTENSION_DEV_DIR,
|
||||
&sUserExtensionsDevDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_GRE_DIR, &sBinDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_APP_USER_PROFILE_50_DIR, &sProfileDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
&sContentTempDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_APP_PLUGIN_PROCESS_TEMP_DIR,
|
||||
&sPluginTempDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_WIN_APPDATA_DIR, &sRoamingAppDataDir);
|
||||
CacheDirAndAutoClear(dirSvc, NS_WIN_LOCAL_APPDATA_DIR, &sLocalAppDataDir);
|
||||
CacheDirAndAutoClear(dirSvc, XRE_USER_SYS_EXTENSION_DEV_DIR,
|
||||
&sUserExtensionsDevDir);
|
||||
#ifdef ENABLE_SYSTEM_EXTENSION_DIRS
|
||||
CacheDirAndAutoClear(dirSvc, XRE_USER_SYS_EXTENSION_DIR, &sUserExtensionsDir);
|
||||
CacheDirAndAutoClear(dirSvc, XRE_USER_SYS_EXTENSION_DIR,
|
||||
&sUserExtensionsDir);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create sLaunchErrors up front because ClearOnShutdown must be called on the
|
||||
// main thread.
|
||||
sLaunchErrors = MakeUnique<nsTHashtable<nsCStringHashKey>>();
|
||||
ClearOnShutdown(&sLaunchErrors);
|
||||
|
||||
// Cache prefs that are needed off main thread.
|
||||
Preferences::AddBoolVarCache(&sRddWin32kDisable,
|
||||
"security.sandbox.rdd.win32k-disable");
|
||||
Preferences::AddBoolVarCache(&sGmpWin32kDisable,
|
||||
"security.sandbox.gmp.win32k-disable");
|
||||
if (haveXPCOM) {
|
||||
// Cache prefs that are needed off main thread.
|
||||
Preferences::AddBoolVarCache(&sRddWin32kDisable,
|
||||
"security.sandbox.rdd.win32k-disable");
|
||||
Preferences::AddBoolVarCache(&sGmpWin32kDisable,
|
||||
"security.sandbox.gmp.win32k-disable");
|
||||
} else {
|
||||
sRddWin32kDisable = false;
|
||||
sGmpWin32kDisable = false;
|
||||
}
|
||||
}
|
||||
|
||||
SandboxBroker::SandboxBroker() {
|
||||
@ -1164,6 +1175,7 @@ bool SandboxBroker::AllowReadFile(wchar_t const* file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool SandboxBroker::AddTargetPeer(HANDLE aPeerProcess) {
|
||||
if (!sBrokerService) {
|
||||
return false;
|
||||
@ -1204,4 +1216,22 @@ SandboxBroker::~SandboxBroker() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _ARM64_
|
||||
// We can't include remoteSandboxBroker.h here directly, as it includes
|
||||
// IPDL headers, which include a different copy of the chromium base
|
||||
// libraries, which leads to conflicts.
|
||||
extern AbstractSandboxBroker* CreateRemoteSandboxBroker();
|
||||
#endif
|
||||
|
||||
// static
|
||||
AbstractSandboxBroker* AbstractSandboxBroker::Create(
|
||||
GeckoProcessType aProcessType) {
|
||||
#ifdef _ARM64_
|
||||
if (aProcessType == GeckoProcessType_GMPlugin) {
|
||||
return CreateRemoteSandboxBroker();
|
||||
}
|
||||
#endif
|
||||
return new SandboxBroker();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -26,6 +26,9 @@ class AbstractSandboxBroker {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractSandboxBroker)
|
||||
|
||||
static AbstractSandboxBroker *Create(GeckoProcessType aProcessType);
|
||||
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool LaunchApp(const wchar_t *aPath, const wchar_t *aArguments,
|
||||
base::EnvironmentMap &aEnvironment,
|
||||
GeckoProcessType aProcessType,
|
||||
@ -47,12 +50,6 @@ class AbstractSandboxBroker {
|
||||
// File system permissions
|
||||
virtual bool AllowReadFile(wchar_t const *file) = 0;
|
||||
|
||||
/**
|
||||
* Exposes AddTargetPeer from broker services, so that non-sandboxed
|
||||
* processes can be added as handle duplication targets.
|
||||
*/
|
||||
virtual bool AddTargetPeer(HANDLE aPeerProcess) = 0;
|
||||
|
||||
/**
|
||||
* Share a HANDLE with the child process. The HANDLE will be made available
|
||||
* in the child process at the memory address
|
||||
@ -71,6 +68,8 @@ class SandboxBroker : public AbstractSandboxBroker {
|
||||
|
||||
static void Initialize(sandbox::BrokerServices *aBrokerServices);
|
||||
|
||||
void Shutdown() override {}
|
||||
|
||||
/**
|
||||
* Do initialization that depends on parts of the Gecko machinery having been
|
||||
* created first.
|
||||
@ -102,7 +101,7 @@ class SandboxBroker : public AbstractSandboxBroker {
|
||||
* Exposes AddTargetPeer from broker services, so that non-sandboxed
|
||||
* processes can be added as handle duplication targets.
|
||||
*/
|
||||
bool AddTargetPeer(HANDLE aPeerProcess) override;
|
||||
static bool AddTargetPeer(HANDLE aPeerProcess);
|
||||
|
||||
/**
|
||||
* Share a HANDLE with the child process. The HANDLE will be made available
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(f60d76e5-62c3-4f58-89f6-b726c2b7bc20)]
|
||||
[scriptable, uuid(70bd93ff-88fa-4600-8af8-57c8d002dbac)]
|
||||
interface nsICrashService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -30,6 +30,7 @@ interface nsICrashService : nsISupports
|
||||
const long PROCESS_TYPE_VR = 6;
|
||||
const long PROCESS_TYPE_RDD = 7;
|
||||
const long PROCESS_TYPE_SOCKET = 8;
|
||||
const long PROCESS_TYPE_SANDBOX_BROKER = 9;
|
||||
// New process types should be added at the end of the above list.
|
||||
|
||||
const long CRASH_TYPE_CRASH = 0;
|
||||
|
@ -631,9 +631,10 @@ SYNC_ENUMS(GPU, GPU)
|
||||
SYNC_ENUMS(VR, VR)
|
||||
SYNC_ENUMS(RDD, RDD)
|
||||
SYNC_ENUMS(SOCKET, Socket)
|
||||
SYNC_ENUMS(SANDBOX_BROKER, RemoteSandboxBroker)
|
||||
|
||||
// .. and ensure that that is all of them:
|
||||
static_assert(GeckoProcessType_Socket + 1 == GeckoProcessType_End,
|
||||
static_assert(GeckoProcessType_RemoteSandboxBroker + 1 == GeckoProcessType_End,
|
||||
"Did not find the final GeckoProcessType");
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1535,11 +1536,11 @@ static const char kShieldPrefName[] = "app.shield.optoutstudies.enabled";
|
||||
static void OnLauncherPrefChanged(const char* aPref, void* aData) {
|
||||
const bool kLauncherPrefDefaultValue =
|
||||
# if defined(NIGHTLY_BUILD) || (MOZ_UPDATE_CHANNEL == beta)
|
||||
true
|
||||
true
|
||||
# else
|
||||
false
|
||||
false
|
||||
# endif // defined(NIGHTLY_BUILD) || (MOZ_UPDATE_CHANNEL == beta)
|
||||
;
|
||||
;
|
||||
bool prefVal = Preferences::GetBool(kShieldPrefName, false) &&
|
||||
Preferences::GetBool(PREF_WIN_LAUNCHER_PROCESS_ENABLED,
|
||||
kLauncherPrefDefaultValue);
|
||||
|
@ -91,6 +91,7 @@
|
||||
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
|
||||
# include "mozilla/sandboxTarget.h"
|
||||
# include "mozilla/sandboxing/loggingCallbacks.h"
|
||||
# include "mozilla/RemoteSandboxBrokerProcessChild.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
@ -123,6 +124,11 @@ using mozilla::_ipdltest::IPDLUnitTestProcessChild;
|
||||
# include "jprof.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
# include "mozilla/sandboxing/SandboxInitialization.h"
|
||||
# include "mozilla/sandboxing/sandboxLogging.h"
|
||||
#endif
|
||||
|
||||
#include "VRProcessChild.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -646,6 +652,7 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
|
||||
uiLoopType = MessageLoop::TYPE_MOZILLA_CHILD;
|
||||
break;
|
||||
case GeckoProcessType_GMPlugin:
|
||||
case GeckoProcessType_RemoteSandboxBroker:
|
||||
uiLoopType = MessageLoop::TYPE_DEFAULT;
|
||||
break;
|
||||
default:
|
||||
@ -653,6 +660,13 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
|
||||
if (aChildData->sandboxBrokerServices) {
|
||||
SandboxBroker::Initialize(aChildData->sandboxBrokerServices);
|
||||
SandboxBroker::GeckoDependentInitialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we are recording or replaying, initialize state and update arguments
|
||||
// according to those which were captured by the MiddlemanProcessChild in the
|
||||
// middleman process. No argument manipulation should happen between this
|
||||
@ -715,6 +729,11 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
|
||||
process = new net::SocketProcessImpl(parentPID);
|
||||
break;
|
||||
|
||||
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
|
||||
case GeckoProcessType_RemoteSandboxBroker:
|
||||
process = new RemoteSandboxBrokerProcessChild(parentPID);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Unknown main thread class");
|
||||
}
|
||||
@ -736,10 +755,13 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
|
||||
mozilla::sandboxing::InitLoggingIfRequired(
|
||||
aChildData->ProvideLogFunction);
|
||||
#endif
|
||||
mozilla::FilePreferences::InitDirectoriesWhitelist();
|
||||
mozilla::FilePreferences::InitPrefs();
|
||||
|
||||
OverrideDefaultLocaleIfNeeded();
|
||||
if (XRE_GetProcessType() != GeckoProcessType_RemoteSandboxBroker) {
|
||||
// Remote sandbox launcher process doesn't have prerequisites for
|
||||
// these...
|
||||
mozilla::FilePreferences::InitDirectoriesWhitelist();
|
||||
mozilla::FilePreferences::InitPrefs();
|
||||
OverrideDefaultLocaleIfNeeded();
|
||||
}
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
AddContentSandboxLevelAnnotation();
|
||||
|
@ -28,3 +28,4 @@ GECKO_PROCESS_TYPE(VR, "vr", VR)
|
||||
GECKO_PROCESS_TYPE(RDD, "rdd", RDD)
|
||||
// Socket process
|
||||
GECKO_PROCESS_TYPE(Socket, "socket", Socket)
|
||||
GECKO_PROCESS_TYPE(RemoteSandboxBroker, "sandbox", RemoteSandboxBroker)
|
||||
|
@ -31,6 +31,12 @@ struct XREChildData {
|
||||
* Function to provide a logging function to the chromium sandbox code.
|
||||
*/
|
||||
mozilla::sandboxing::ProvideLogFunctionCb ProvideLogFunction = nullptr;
|
||||
|
||||
/**
|
||||
* Chromium sandbox broker services; needed by the remote sandbox
|
||||
* launcher process.
|
||||
*/
|
||||
sandbox::BrokerServices* sandboxBrokerServices = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -512,6 +512,7 @@ nsresult nsComponentManagerImpl::Init() {
|
||||
// We are going to assume that only a select few (see below) process types
|
||||
// want to load chrome manifests, and that any new process types will not
|
||||
// want to load them, because they're not going to be executing JS.
|
||||
case GeckoProcessType_RemoteSandboxBroker:
|
||||
default:
|
||||
loadChromeManifests = false;
|
||||
break;
|
||||
|
@ -79,6 +79,7 @@ interface nsIXULRuntime : nsISupports
|
||||
const unsigned long PROCESS_TYPE_VR = 6;
|
||||
const unsigned long PROCESS_TYPE_RDD = 7;
|
||||
const unsigned long PROCESS_TYPE_SOCKET = 8;
|
||||
const unsigned long PROCESS_TYPE_SANDBOX_BROKER = 9;
|
||||
|
||||
/**
|
||||
* The type of the caller's process. Returns one of the values above.
|
||||
|
Loading…
Reference in New Issue
Block a user