Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: sandbox/mac/bootstrap_sandbox.h

Issue 1346923006: Refactor the bootstrap sandbox process launching integration. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_ 5 #ifndef SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_
6 #define SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_ 6 #define SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_
7 7
8 #include <mach/mach.h> 8 #include <mach/mach.h>
9 9
10 #include <map> 10 #include <map>
11 #include <string> 11 #include <string>
12 12
13 #include "base/mac/dispatch_source_mach.h"
13 #include "base/mac/scoped_mach_port.h" 14 #include "base/mac/scoped_mach_port.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "base/process/process_handle.h" 16 #include "base/process/process_handle.h"
16 #include "base/synchronization/lock.h" 17 #include "base/synchronization/lock.h"
17 #include "sandbox/mac/policy.h" 18 #include "sandbox/mac/policy.h"
18 #include "sandbox/sandbox_export.h" 19 #include "sandbox/sandbox_export.h"
19 20
20 namespace sandbox { 21 namespace sandbox {
21 22
22 class LaunchdInterceptionServer; 23 class LaunchdInterceptionServer;
24 class PreExecDelegate;
23 25
24 // The BootstrapSandbox is a second-layer sandbox for Mac. It is used to limit 26 // The BootstrapSandbox is a second-layer sandbox for Mac. It is used to limit
25 // the bootstrap namespace attack surface of child processes. The parent 27 // the bootstrap namespace attack surface of child processes. The parent
26 // process creates an instance of this class and registers policies that it 28 // process creates an instance of this class and registers policies that it
27 // can enforce on its children. 29 // can enforce on its children.
28 // 30 //
29 // With this sandbox, the parent process must replace the bootstrap port prior 31 // With this sandbox, the parent process must create the client using the
30 // to the sandboxed target's execution. This should be done by setting the 32 // sandbox's PreExecDelegate, which will replace the bootstrap port of the
31 // base::LaunchOptions.replacement_bootstrap_name to the 33 // child process. Requests from the child that would normally go to launchd
32 // server_bootstrap_name() of this class. Requests from the child that would 34 // are filtered based on the specified per-process policies. If a request is
33 // normally go to launchd are filtered based on the specified per-process 35 // permitted by the policy, it is forwarded on to launchd for servicing. If it
34 // policies. If a request is permitted by the policy, it is forwarded on to 36 // is not, then the sandbox will reply with a primitive that does not grant
35 // launchd for servicing. If it is not, then the sandbox will reply with a 37 // additional capabilities to the receiver.
36 // primitive that does not grant additional capabilities to the receiver.
37 //
38 // Clients that which to use the sandbox must inform it of the creation and
39 // death of child processes for which the sandbox should be enforced. The
40 // client of the sandbox is intended to be an unsandboxed parent process that
41 // fork()s sandboxed (and other unsandboxed) child processes.
42 // 38 //
43 // When the parent is ready to fork a new child process with this sandbox 39 // When the parent is ready to fork a new child process with this sandbox
44 // being enforced, it should use the pair of methods PrepareToForkWithPolicy() 40 // being enforced, it should use NewClient() to create a PreExecDelegate for
45 // and FinishedFork(), and call fork() between them. The first method will 41 // a sandbox policy ID and set it to the base::LaunchOptions.pre_exec_delegate.
46 // set the policy for the new process, and the second will finialize the
47 // association between the process ID and sandbox policy ID.
48 // 42 //
49 // All methods of this class may be called from any thread, but 43 // When a child process exits, the parent should call InvalidateClient() to
50 // PrepareToForkWithPolicy() and FinishedFork() must be non-nested and balanced. 44 // clean up any mappings in this class.
Mark Mentovai 2015/09/17 19:45:15 Or you could make a new receive right for each cli
Robert Sesek 2015/09/17 20:27:24 That's what I want(ed) to do, but because a task's
45 //
46 // All methods of this class may be called from any thread.
51 class SANDBOX_EXPORT BootstrapSandbox { 47 class SANDBOX_EXPORT BootstrapSandbox {
52 public: 48 public:
53 // Creates a new sandbox manager. Returns NULL on failure. 49 // Creates a new sandbox manager. Returns NULL on failure.
54 static scoped_ptr<BootstrapSandbox> Create(); 50 static scoped_ptr<BootstrapSandbox> Create();
55 51
52 // For use in newly created child processes. Checks in with the bootstrap
53 // sandbox manager running in the parent process. |sandbox_server_port| is
54 // the Mach send right to the sandbox |check_in_server_| (in the child).
55 // |sandbox_token| is the assigned token. On return, |bootstrap_port| is set
56 // to a new Mach send right to be used in the child as the task's bootstrap
57 // port.
58 static bool ClientCheckIn(mach_port_t sandbox_server_port,
59 uint64_t sandbox_token,
60 mach_port_t* bootstrap_port);
61
56 ~BootstrapSandbox(); 62 ~BootstrapSandbox();
57 63
58 // Registers a bootstrap policy associated it with an identifier. The 64 // Registers a bootstrap policy associated it with an identifier. The
59 // |sandbox_policy_id| must be greater than 0. 65 // |sandbox_policy_id| must be greater than 0.
60 void RegisterSandboxPolicy(int sandbox_policy_id, 66 void RegisterSandboxPolicy(int sandbox_policy_id,
61 const BootstrapSandboxPolicy& policy); 67 const BootstrapSandboxPolicy& policy);
62 68
63 // Called in the parent prior to fork()ing a child. The policy registered 69 // Creates a new PreExecDelegate to pass to base::LaunchOptions. This will
64 // to |sandbox_policy_id| will be enforced on the new child. This must be 70 // enforce the policy with |sandbox_policy_id| on the new process.
65 // followed by a call to FinishedFork(). 71 scoped_ptr<PreExecDelegate> NewClient(int sandbox_policy_id);
66 void PrepareToForkWithPolicy(int sandbox_policy_id);
67
68 // Called in the parent after fork()ing a child. It records the |handle|
69 // and associates it with the specified-above |sandbox_policy_id|.
70 // If fork() failed and a new child was not created, pass kNullProcessHandle.
71 void FinishedFork(base::ProcessHandle handle);
72 72
73 // Called in the parent when a process has died. It cleans up the references 73 // Called in the parent when a process has died. It cleans up the references
74 // to the process. 74 // to the process.
75 void ChildDied(base::ProcessHandle handle); 75 void InvalidateClient(base::ProcessHandle handle);
76 76
77 // Looks up the policy for a given process ID. If no policy is associated 77 // Looks up the policy for a given process ID. If no policy is associated
78 // with the |pid|, this returns NULL. 78 // with the |pid|, this returns NULL.
79 const BootstrapSandboxPolicy* PolicyForProcess(pid_t pid) const; 79 const BootstrapSandboxPolicy* PolicyForProcess(pid_t pid) const;
80 80
81 std::string server_bootstrap_name() const { return server_bootstrap_name_; } 81 std::string server_bootstrap_name() const { return server_bootstrap_name_; }
82 mach_port_t real_bootstrap_port() const { return real_bootstrap_port_; } 82 mach_port_t real_bootstrap_port() const { return real_bootstrap_port_; }
83 83
84 private: 84 private:
85 BootstrapSandbox(); 85 BootstrapSandbox();
86 86
87 // Dispatch callout for when a client sends a message on the
88 // |check_in_port_|. If the client message is valid, it will assign the
89 // client from |awaiting_processes_| to |sandboxed_processes_|.
90 void HandleChildCheckIn();
91
87 // The name in the system bootstrap server by which the |server_|'s port 92 // The name in the system bootstrap server by which the |server_|'s port
88 // is known. 93 // is known.
89 const std::string server_bootstrap_name_; 94 const std::string server_bootstrap_name_;
90 95
91 // The original bootstrap port of the process, which is connected to the 96 // The original bootstrap port of the process, which is connected to the
92 // real launchd server. 97 // real launchd server.
93 base::mac::ScopedMachSendRight real_bootstrap_port_; 98 base::mac::ScopedMachSendRight real_bootstrap_port_;
94 99
95 // The |lock_| protects all the following variables. 100 // The |lock_| protects all the following variables.
96 mutable base::Lock lock_; 101 mutable base::Lock lock_;
97 102
98 // The sandbox_policy_id that will be enforced for the new child.
99 int effective_policy_id_;
100
101 // All the policies that have been registered with this sandbox manager. 103 // All the policies that have been registered with this sandbox manager.
102 std::map<int, const BootstrapSandboxPolicy> policies_; 104 std::map<int, const BootstrapSandboxPolicy> policies_;
103 105
104 // The association between process ID and sandbox policy ID. 106 // The association between process ID and sandbox policy ID.
105 std::map<base::ProcessHandle, int> sandboxed_processes_; 107 std::map<base::ProcessHandle, int> sandboxed_processes_;
106 108
109 // The association between a new process' sandbox token and its policy ID.
110 // The entry is removed after the process checks in, and the mapping moves
111 // to |sandboxed_processes_|.
112 std::map<uint64_t, int> awaiting_processes_;
113
107 // A Mach IPC message server that is used to intercept and filter bootstrap 114 // A Mach IPC message server that is used to intercept and filter bootstrap
108 // requests. 115 // requests.
109 scoped_ptr<LaunchdInterceptionServer> server_; 116 scoped_ptr<LaunchdInterceptionServer> launchd_server_;
117
118 // The port and dispatch source for receiving client check in messages sent
119 // via ClientCheckIn().
120 base::mac::ScopedMachReceiveRight check_in_port_;
121 scoped_ptr<base::DispatchSourceMach> check_in_server_;
110 }; 122 };
111 123
112 } // namespace sandbox 124 } // namespace sandbox
113 125
114 #endif // SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_ 126 #endif // SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698