fune/dom/plugins/ipc/PluginProcessParent.cpp
Haik Aftandilian 331dda9367 Bug 1444291 - Part 3 - Add read access to the Mac Flash sandbox, support sandbox levels r=Alex_Gaynor
Replace the boolean pref "security.sandbox.mac.flash.enabled"
with "dom.ipc.plugins.sandbox-level.flash" to support sandbox
levels and be consistent with the Windows pref name.

Adds filesystem read access to the sandbox using sandbox extensions
granted by the file dialog machinery (level 1).

Add support for level 2 which blocks read access.

Allow the sandbox to be disabled with MOZ_DISABLE_NPAPI_SANDBOX.


MozReview-Commit-ID: 4rfobEoxQpF

--HG--
extra : rebase_source : 05dc54b46063967e959bc3fced21c61e5463de48
2018-03-15 20:23:19 -07:00

176 lines
4.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 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/. */
#include "mozilla/plugins/PluginProcessParent.h"
#include "base/string_util.h"
#include "base/process_util.h"
#include "mozilla/ipc/BrowserProcessSubThread.h"
#include "mozilla/plugins/PluginMessageUtils.h"
#include "mozilla/Telemetry.h"
#include "nsThreadUtils.h"
using std::vector;
using std::string;
using mozilla::ipc::BrowserProcessSubThread;
using mozilla::ipc::GeckoChildProcessHost;
using mozilla::plugins::LaunchCompleteTask;
using mozilla::plugins::PluginProcessParent;
#ifdef XP_WIN
PluginProcessParent::PidSet* PluginProcessParent::sPidSet = nullptr;
#endif
PluginProcessParent::PluginProcessParent(const std::string& aPluginFilePath) :
GeckoChildProcessHost(GeckoProcessType_Plugin)
, mPluginFilePath(aPluginFilePath)
, mTaskFactory(this)
, mMainMsgLoop(MessageLoop::current())
#ifdef XP_WIN
, mChildPid(0)
#endif
{
}
PluginProcessParent::~PluginProcessParent()
{
#ifdef XP_WIN
if (sPidSet && mChildPid) {
sPidSet->RemoveEntry(mChildPid);
if (sPidSet->IsEmpty()) {
delete sPidSet;
sPidSet = nullptr;
}
}
#endif
}
bool
PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchCompleteTask,
int32_t aSandboxLevel,
bool aIsSandboxLoggingEnabled)
{
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_SANDBOX)
// At present, the Mac Flash plugin sandbox does not support different
// levels and is enabled via a boolean pref or environment variable.
// On Mac, when |aSandboxLevel| is positive, we enable the sandbox.
#if defined(XP_WIN)
mSandboxLevel = aSandboxLevel;
#endif // XP_WIN
#else
if (aSandboxLevel != 0) {
MOZ_ASSERT(false,
"Can't enable an NPAPI process sandbox for platform/build.");
}
#endif
mLaunchCompleteTask = mozilla::Move(aLaunchCompleteTask);
vector<string> args;
args.push_back(MungePluginDsoPath(mPluginFilePath));
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
if (aSandboxLevel > 0) {
args.push_back("-flashSandboxLevel");
args.push_back(std::to_string(aSandboxLevel));
if (aIsSandboxLoggingEnabled) {
args.push_back("-flashSandboxLogging");
}
}
#endif
bool result = AsyncLaunch(args);
if (!result) {
mLaunchCompleteTask = nullptr;
}
return result;
}
void
PluginProcessParent::Delete()
{
MessageLoop* currentLoop = MessageLoop::current();
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
if (currentLoop == ioLoop) {
delete this;
return;
}
ioLoop->PostTask(
NewNonOwningRunnableMethod("plugins::PluginProcessParent::Delete",
this,
&PluginProcessParent::Delete));
}
/**
* This function exists so that we may provide an additional level of
* indirection between the task being posted to main event loop (a
* RunnableMethod) and the launch complete task itself. This is needed
* for cases when both WaitUntilConnected or OnChannel* race to invoke the
* task.
*/
void
PluginProcessParent::RunLaunchCompleteTask()
{
if (mLaunchCompleteTask) {
mLaunchCompleteTask->Run();
mLaunchCompleteTask = nullptr;
}
}
bool
PluginProcessParent::WaitUntilConnected(int32_t aTimeoutMs)
{
bool result = GeckoChildProcessHost::WaitUntilConnected(aTimeoutMs);
if (mLaunchCompleteTask) {
if (result) {
mLaunchCompleteTask->SetLaunchSucceeded();
}
RunLaunchCompleteTask();
}
return result;
}
void
PluginProcessParent::OnChannelConnected(int32_t peer_pid)
{
#ifdef XP_WIN
mChildPid = static_cast<uint32_t>(peer_pid);
if (!sPidSet) {
sPidSet = new PluginProcessParent::PidSet();
}
sPidSet->PutEntry(mChildPid);
#endif
GeckoChildProcessHost::OnChannelConnected(peer_pid);
}
void
PluginProcessParent::OnChannelError()
{
GeckoChildProcessHost::OnChannelError();
}
bool
PluginProcessParent::IsConnected()
{
mozilla::MonitorAutoLock lock(mMonitor);
return mProcessState == PROCESS_CONNECTED;
}
bool
PluginProcessParent::IsPluginProcessId(base::ProcessId procId) {
#ifdef XP_WIN
MOZ_ASSERT(XRE_IsParentProcess());
return sPidSet && sPidSet->Contains(static_cast<uint32_t>(procId));
#else
NS_ERROR("IsPluginProcessId not available on this platform.");
return false;
#endif
}