OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "sandbox/mac/bootstrap_sandbox.h" | |
6 | |
7 #include "base/logging.h" | |
8 | |
9 #include "sandbox/mac/launchd_interception_server.h" | |
10 | |
11 namespace sandbox { | |
12 | |
13 // static | |
14 scoped_ptr<BootstrapSandbox> BootstrapSandbox::Create() { | |
15 scoped_ptr<BootstrapSandbox> sandbox(new BootstrapSandbox()); | |
16 sandbox->server_.reset(new LaunchdInterceptionServer(sandbox.get())); | |
17 | |
18 if (!sandbox->server_->Initialize()) { | |
19 sandbox.reset(); | |
20 } else { | |
21 kern_return_t kr = task_set_special_port(mach_task_self(), | |
22 TASK_BOOTSTRAP_PORT, sandbox->server_->server_port()); | |
Mark Mentovai
2014/05/06 20:51:50
There’s a global extern mach_port_t named bootstra
Robert Sesek
2014/05/08 20:58:12
Right, this is something that I considered but was
Mark Mentovai
2014/05/09 20:11:19
rsesek wrote:
Robert Sesek
2014/05/09 22:04:03
Done.
| |
23 if (kr != KERN_SUCCESS) | |
24 sandbox.reset(); | |
25 } | |
26 | |
27 return sandbox.Pass(); | |
28 } | |
29 | |
30 BootstrapSandbox::~BootstrapSandbox() { | |
31 CHECK_EQ(KERN_SUCCESS, task_set_special_port(mach_task_self(), | |
32 TASK_BOOTSTRAP_PORT, real_bootstrap_port_)); | |
33 } | |
34 | |
35 void BootstrapSandbox::RegisterSandboxPolicy( | |
36 int sandbox_policy_id, | |
37 const BootstrapSandboxPolicy& policy) { | |
38 DCHECK(IsPolicyValid(policy)); | |
Mark Mentovai
2014/05/06 20:51:50
You’re CHECKy elsewhere, why’d you land on DCHECK
Robert Sesek
2014/05/08 20:58:12
Done.
| |
39 DCHECK_GT(sandbox_policy_id, 0); | |
40 base::AutoLock lock(lock_); | |
41 DCHECK(policies_.find(sandbox_policy_id) == policies_.end()); | |
42 policies_.insert(std::make_pair(sandbox_policy_id, policy)); | |
43 } | |
44 | |
45 bool BootstrapSandbox::PrepareToForkWithPolicy(int sandbox_policy_id) { | |
46 base::AutoLock lock(lock_); | |
47 | |
48 // Make sure the policy exists. | |
49 if (policies_.find(sandbox_policy_id) == policies_.end()) | |
50 return false; | |
Mark Mentovai
2014/05/06 20:51:50
Based on the implementation here, it appears that
Robert Sesek
2014/05/08 20:58:12
Not really, because the child could start executin
| |
51 | |
52 // Make sure that we aren't trying to fork() on two different threads | |
53 // simultaneously. | |
54 CHECK(!is_across_fork_) << "Cannot interleave PrepareToForkWithPolicy()"; | |
55 is_across_fork_ = true; | |
56 | |
57 // Store the policy for the process we're about to create. | |
58 effective_policy_id_ = sandbox_policy_id; | |
59 | |
60 return true; | |
61 } | |
62 | |
63 void BootstrapSandbox::FinishedFork(base::ProcessHandle handle) { | |
64 base::AutoLock lock(lock_); | |
65 CHECK(is_across_fork_) << | |
66 "Must PrepareToForkWithPolicy() before FinishedFork()"; | |
67 is_across_fork_ = false; | |
68 | |
69 const auto& existing_process = sandboxed_processes_.find(handle); | |
70 CHECK(existing_process == sandboxed_processes_.end()); | |
71 sandboxed_processes_.insert(std::make_pair(handle, effective_policy_id_)); | |
72 | |
73 VLOG(3) << "Bootstrap sandbox enforced for pid " << handle; | |
74 | |
75 effective_policy_id_ = -1; | |
76 } | |
77 | |
78 void BootstrapSandbox::ChildDied(base::ProcessHandle handle) { | |
79 base::AutoLock lock(lock_); | |
80 sandboxed_processes_.erase(handle); | |
Mark Mentovai
2014/05/06 20:51:50
You were very CHECKy about things not being in the
Robert Sesek
2014/05/08 20:58:12
Done.
| |
81 } | |
82 | |
83 const BootstrapSandboxPolicy* BootstrapSandbox::PolicyForProcess( | |
84 pid_t pid) const { | |
85 base::AutoLock lock(lock_); | |
86 const auto& process = sandboxed_processes_.find(pid); | |
87 | |
88 int policy_id = -1; | |
89 // The new child could send bootstrap requests before the parent calls | |
90 // FinishFork(). | |
91 if (process != sandboxed_processes_.end()) { | |
92 policy_id = process->second; | |
93 } else if (is_across_fork_) { | |
94 policy_id = effective_policy_id_; | |
95 } | |
Mark Mentovai
2014/05/06 20:51:50
You can just say “else return NULL” here and not h
Robert Sesek
2014/05/08 20:58:12
This is because effective_policy_id_ could be -1.
| |
96 | |
97 if (policy_id == -1) | |
98 return NULL; | |
99 | |
100 return &policies_.find(policy_id)->second; | |
101 } | |
102 | |
103 BootstrapSandbox::BootstrapSandbox() | |
104 : real_bootstrap_port_(MACH_PORT_NULL), | |
105 is_across_fork_(false), | |
106 effective_policy_id_(-1) { | |
107 CHECK_EQ(KERN_SUCCESS, task_get_special_port( | |
108 mach_task_self(), TASK_BOOTSTRAP_PORT, &real_bootstrap_port_)); | |
Mark Mentovai
2014/05/06 20:51:50
When you task_get_special_port, you need to mach_p
Robert Sesek
2014/05/08 20:58:12
Done.
| |
109 } | |
110 | |
111 } // namespace sandbox | |
OLD | NEW |