| Index: sandbox/mac/bootstrap_sandbox.cc
|
| diff --git a/sandbox/mac/bootstrap_sandbox.cc b/sandbox/mac/bootstrap_sandbox.cc
|
| index 6407c68f59f541cd051c35085e12bd83ce393876..a90f570eb47487524acecdd11e903c8e60eeeb40 100644
|
| --- a/sandbox/mac/bootstrap_sandbox.cc
|
| +++ b/sandbox/mac/bootstrap_sandbox.cc
|
| @@ -4,9 +4,13 @@
|
|
|
| #include "sandbox/mac/bootstrap_sandbox.h"
|
|
|
| +#include <servers/bootstrap.h>
|
| +#include <unistd.h>
|
| +
|
| #include "base/logging.h"
|
| +#include "base/mac/foundation_util.h"
|
| #include "base/mac/mach_logging.h"
|
| -
|
| +#include "base/strings/stringprintf.h"
|
| #include "sandbox/mac/launchd_interception_server.h"
|
|
|
| namespace sandbox {
|
| @@ -19,41 +23,28 @@ scoped_ptr<BootstrapSandbox> BootstrapSandbox::Create() {
|
| scoped_ptr<BootstrapSandbox> sandbox(new BootstrapSandbox());
|
| sandbox->server_.reset(new LaunchdInterceptionServer(sandbox.get()));
|
|
|
| - if (!sandbox->server_->Initialize())
|
| - return null.Pass();
|
| -
|
| - mach_port_t port = sandbox->server_->server_port();
|
| - kern_return_t kr = mach_port_insert_right(mach_task_self(), port, port,
|
| - MACH_MSG_TYPE_MAKE_SEND);
|
| + // Check in with launchd to get the receive right for the server that is
|
| + // published in the bootstrap namespace.
|
| + mach_port_t port = MACH_PORT_NULL;
|
| + kern_return_t kr = bootstrap_check_in(bootstrap_port,
|
| + sandbox->server_bootstrap_name().c_str(), &port);
|
| if (kr != KERN_SUCCESS) {
|
| - MACH_LOG(ERROR, kr) << "Failed to insert send right on bootstrap port.";
|
| + BOOTSTRAP_LOG(ERROR, kr)
|
| + << "Failed to bootstrap_check_in the sandbox server.";
|
| return null.Pass();
|
| }
|
| - base::mac::ScopedMachSendRight scoped_right(port);
|
| -
|
| - // Note that the extern global bootstrap_port (in bootstrap.h) will not
|
| - // be changed here. The parent only has its bootstrap port replaced
|
| - // permanently because changing it repeatedly in a multi-threaded program
|
| - // could lead to unsafe access patterns. In a single-threaded program,
|
| - // the port would be restored after fork(). See the design document for
|
| - // a larger discussion.
|
| - //
|
| - // By not changing the global bootstrap_port, users of the bootstrap port
|
| - // in the parent can potentially skip an unnecessary indirection through
|
| - // the sandbox server.
|
| - kr = task_set_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT, port);
|
| - if (kr != KERN_SUCCESS) {
|
| - MACH_LOG(ERROR, kr) << "Failed to set new bootstrap port.";
|
| + base::mac::ScopedMachReceiveRight scoped_port(port);
|
| +
|
| + // Start the sandbox server.
|
| + if (sandbox->server_->Initialize(scoped_port.get()))
|
| + ignore_result(scoped_port.release()); // Transferred to server_.
|
| + else
|
| return null.Pass();
|
| - }
|
|
|
| return sandbox.Pass();
|
| }
|
|
|
| BootstrapSandbox::~BootstrapSandbox() {
|
| - kern_return_t kr = task_set_special_port(mach_task_self(),
|
| - TASK_BOOTSTRAP_PORT, real_bootstrap_port_);
|
| - MACH_CHECK(kr == KERN_SUCCESS, kr);
|
| }
|
|
|
| void BootstrapSandbox::RegisterSandboxPolicy(
|
| @@ -69,6 +60,7 @@ void BootstrapSandbox::RegisterSandboxPolicy(
|
| void BootstrapSandbox::PrepareToForkWithPolicy(int sandbox_policy_id) {
|
| base::AutoLock lock(lock_);
|
|
|
| + // Verify that this is a real policy.
|
| CHECK(policies_.find(sandbox_policy_id) != policies_.end());
|
| CHECK_EQ(kNotAPolicy, effective_policy_id_)
|
| << "Cannot nest calls to PrepareToForkWithPolicy()";
|
| @@ -89,6 +81,7 @@ void BootstrapSandbox::FinishedFork(base::ProcessHandle handle) {
|
| CHECK_NE(kNotAPolicy, effective_policy_id_)
|
| << "Must PrepareToForkWithPolicy() before FinishedFork()";
|
|
|
| + // Apply the policy to the new process.
|
| if (handle != base::kNullProcessHandle) {
|
| const auto& existing_process = sandboxed_processes_.find(handle);
|
| CHECK(existing_process == sandboxed_processes_.end());
|
| @@ -125,7 +118,10 @@ const BootstrapSandboxPolicy* BootstrapSandbox::PolicyForProcess(
|
| }
|
|
|
| BootstrapSandbox::BootstrapSandbox()
|
| - : real_bootstrap_port_(MACH_PORT_NULL),
|
| + : server_bootstrap_name_(
|
| + base::StringPrintf("%s.sandbox.%d", base::mac::BaseBundleID(),
|
| + getpid())),
|
| + real_bootstrap_port_(MACH_PORT_NULL),
|
| effective_policy_id_(kNotAPolicy) {
|
| mach_port_t port = MACH_PORT_NULL;
|
| kern_return_t kr = task_get_special_port(
|
|
|