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 #ifndef SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_ 6 #define SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_ 7 8 #include <mach/mach.h> 9 10 #include <map> 11 #include <string> 12 13 #include "base/mac/scoped_mach_port.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/process/process_handle.h" 16 #include "base/synchronization/lock.h" 17 #include "sandbox/mac/policy.h" 18 #include "sandbox/sandbox_export.h" 19 20 namespace sandbox { 21 22 class LaunchdInterceptionServer; 23 24 // 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 26 // process creates an instance of this class and registers policies that it 27 // can enforce on its children. 28 // 29 // With this sandbox, the parent process must replace the bootstrap port prior 30 // to the sandboxed target's execution. This should be done by setting the 31 // base::LaunchOptions.replacement_bootstrap_name to the 32 // server_bootstrap_name() of this class. Requests from the child that would 33 // normally go to launchd are filtered based on the specified per-process 34 // policies. If a request is permitted by the policy, it is forwarded on to 35 // launchd for servicing. If it is not, then the sandbox will reply with a 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 // 43 // 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() 45 // and FinishedFork(), and call fork() between them. The first method will 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 // 49 // All methods of this class may be called from any thread, but 50 // PrepareToForkWithPolicy() and FinishedFork() must be non-nested and balanced. 51 class SANDBOX_EXPORT BootstrapSandbox { 52 public: 53 // Creates a new sandbox manager. Returns NULL on failure. 54 static scoped_ptr<BootstrapSandbox> Create(); 55 56 ~BootstrapSandbox(); 57 58 // Registers a bootstrap policy associated it with an identifier. The 59 // |sandbox_policy_id| must be greater than 0. 60 void RegisterSandboxPolicy(int sandbox_policy_id, 61 const BootstrapSandboxPolicy& policy); 62 63 // Called in the parent prior to fork()ing a child. The policy registered 64 // to |sandbox_policy_id| will be enforced on the new child. This must be 65 // followed by a call to FinishedFork(). 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 73 // Called in the parent when a process has died. It cleans up the references 74 // to the process. 75 void ChildDied(base::ProcessHandle handle); 76 77 // Looks up the policy for a given process ID. If no policy is associated 78 // with the |pid|, this returns NULL. 79 const BootstrapSandboxPolicy* PolicyForProcess(pid_t pid) const; 80 server_bootstrap_name()81 std::string server_bootstrap_name() const { return server_bootstrap_name_; } real_bootstrap_port()82 mach_port_t real_bootstrap_port() const { return real_bootstrap_port_; } 83 84 private: 85 BootstrapSandbox(); 86 87 // The name in the system bootstrap server by which the |server_|'s port 88 // is known. 89 const std::string server_bootstrap_name_; 90 91 // The original bootstrap port of the process, which is connected to the 92 // real launchd server. 93 base::mac::ScopedMachSendRight real_bootstrap_port_; 94 95 // The |lock_| protects all the following variables. 96 mutable base::Lock lock_; 97 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. 102 std::map<int, const BootstrapSandboxPolicy> policies_; 103 104 // The association between process ID and sandbox policy ID. 105 std::map<base::ProcessHandle, int> sandboxed_processes_; 106 107 // A Mach IPC message server that is used to intercept and filter bootstrap 108 // requests. 109 scoped_ptr<LaunchdInterceptionServer> server_; 110 }; 111 112 } // namespace sandbox 113 114 #endif // SANDBOX_MAC_BOOTSTRAP_SANDBOX_H_ 115