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.
5 #ifndef SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_
6 #define SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_
13 #include "base/mac/dispatch_source_mach.h"
14 #include "base/mac/scoped_mach_port.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/process/process_handle.h"
17 #include "base/synchronization/lock.h"
18 #include "sandbox/mac/policy.h"
19 #include "sandbox/sandbox_export.h"
23 class LaunchdInterceptionServer
;
24 class PreExecDelegate
;
26 // The BootstrapSandbox is a second-layer sandbox for Mac. It is used to limit
27 // the bootstrap namespace attack surface of child processes. The parent
28 // process creates an instance of this class and registers policies that it
29 // can enforce on its children.
31 // With this sandbox, the parent process must create the client using the
32 // sandbox's PreExecDelegate, which will replace the bootstrap port of the
33 // child process. Requests from the child that would normally go to launchd
34 // are filtered based on the specified per-process policies. If a request is
35 // permitted by the policy, it is forwarded on to launchd for servicing. If it
36 // is not, then the sandbox will reply with a primitive that does not grant
37 // additional capabilities to the receiver.
39 // When the parent is ready to fork a new child process with this sandbox
40 // being enforced, it should use NewClient() to create a PreExecDelegate for
41 // a sandbox policy ID and set it to the base::LaunchOptions.pre_exec_delegate.
43 // When a child process exits, the parent should call InvalidateClient() to
44 // clean up any mappings in this class.
46 // All methods of this class may be called from any thread.
47 class SANDBOX_EXPORT BootstrapSandbox
{
49 // Creates a new sandbox manager. Returns NULL on failure.
50 static scoped_ptr
<BootstrapSandbox
> Create();
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
58 static bool ClientCheckIn(mach_port_t sandbox_server_port
,
59 uint64_t sandbox_token
,
60 mach_port_t
* bootstrap_port
);
64 // Registers a bootstrap policy associated it with an identifier. The
65 // |sandbox_policy_id| must be greater than 0.
66 void RegisterSandboxPolicy(int sandbox_policy_id
,
67 const BootstrapSandboxPolicy
& policy
);
69 // Creates a new PreExecDelegate to pass to base::LaunchOptions. This will
70 // enforce the policy with |sandbox_policy_id| on the new process.
71 scoped_ptr
<PreExecDelegate
> NewClient(int sandbox_policy_id
);
73 // If a client did not launch properly, the sandbox provided to the
74 // PreExecDelegate should be invalidated using this method.
75 void RevokeToken(uint64_t token
);
77 // Called in the parent when a process has died. It cleans up the references
79 void InvalidateClient(base::ProcessHandle handle
);
81 // Looks up the policy for a given process ID. If no policy is associated
82 // with the |pid|, this returns NULL.
83 const BootstrapSandboxPolicy
* PolicyForProcess(pid_t pid
) const;
85 std::string
server_bootstrap_name() const { return server_bootstrap_name_
; }
86 mach_port_t
real_bootstrap_port() const { return real_bootstrap_port_
; }
91 // Dispatch callout for when a client sends a message on the
92 // |check_in_port_|. If the client message is valid, it will assign the
93 // client from |awaiting_processes_| to |sandboxed_processes_|.
94 void HandleChildCheckIn();
96 // The name in the system bootstrap server by which the |server_|'s port
98 const std::string server_bootstrap_name_
;
100 // The original bootstrap port of the process, which is connected to the
101 // real launchd server.
102 base::mac::ScopedMachSendRight real_bootstrap_port_
;
104 // The |lock_| protects all the following variables.
105 mutable base::Lock lock_
;
107 // All the policies that have been registered with this sandbox manager.
108 std::map
<int, const BootstrapSandboxPolicy
> policies_
;
110 // The association between process ID and sandbox policy ID.
111 std::map
<base::ProcessHandle
, int> sandboxed_processes_
;
113 // The association between a new process' sandbox token and its policy ID.
114 // The entry is removed after the process checks in, and the mapping moves
115 // to |sandboxed_processes_|.
116 std::map
<uint64_t, int> awaiting_processes_
;
118 // A Mach IPC message server that is used to intercept and filter bootstrap
120 scoped_ptr
<LaunchdInterceptionServer
> launchd_server_
;
122 // The port and dispatch source for receiving client check in messages sent
123 // via ClientCheckIn().
124 base::mac::ScopedMachReceiveRight check_in_port_
;
125 scoped_ptr
<base::DispatchSourceMach
> check_in_server_
;
128 } // namespace sandbox
130 #endif // SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_