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 "content/browser/bootstrap_sandbox_mac.h" 6 7 #include "base/logging.h" 8 #include "base/mac/mac_util.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/singleton.h" 11 #include "content/browser/mach_broker_mac.h" 12 #include "content/common/sandbox_init_mac.h" 13 #include "content/public/browser/browser_child_process_observer.h" 14 #include "content/public/browser/child_process_data.h" 15 #include "content/public/browser/notification_details.h" 16 #include "content/public/browser/notification_observer.h" 17 #include "content/public/browser/notification_registrar.h" 18 #include "content/public/browser/notification_service.h" 19 #include "content/public/browser/notification_types.h" 20 #include "content/public/browser/render_process_host.h" 21 #include "content/public/common/sandbox_type_mac.h" 22 #include "sandbox/mac/bootstrap_sandbox.h" 23 24 namespace content { 25 26 namespace { 27 28 // This class is responsible for creating the BootstrapSandbox global 29 // singleton, as well as registering all associated policies with it. 30 class BootstrapSandboxPolicy : public BrowserChildProcessObserver, 31 public NotificationObserver { 32 public: 33 static BootstrapSandboxPolicy* GetInstance(); 34 35 sandbox::BootstrapSandbox* sandbox() const { 36 return sandbox_.get(); 37 } 38 39 // BrowserChildProcessObserver: 40 virtual void BrowserChildProcessHostDisconnected( 41 const ChildProcessData& data) OVERRIDE; 42 virtual void BrowserChildProcessCrashed( 43 const ChildProcessData& data) OVERRIDE; 44 45 // NotificationObserver: 46 virtual void Observe(int type, 47 const NotificationSource& source, 48 const NotificationDetails& details) OVERRIDE; 49 50 private: 51 friend struct DefaultSingletonTraits<BootstrapSandboxPolicy>; 52 BootstrapSandboxPolicy(); 53 virtual ~BootstrapSandboxPolicy(); 54 55 void RegisterSandboxPolicies(); 56 void RegisterRendererPolicy(); 57 58 void AddBaselinePolicy(sandbox::BootstrapSandboxPolicy* policy); 59 60 NotificationRegistrar notification_registrar_; 61 62 scoped_ptr<sandbox::BootstrapSandbox> sandbox_; 63 }; 64 65 BootstrapSandboxPolicy* BootstrapSandboxPolicy::GetInstance() { 66 return Singleton<BootstrapSandboxPolicy>::get(); 67 } 68 69 void BootstrapSandboxPolicy::BrowserChildProcessHostDisconnected( 70 const ChildProcessData& data) { 71 sandbox()->ChildDied(data.handle); 72 } 73 74 void BootstrapSandboxPolicy::BrowserChildProcessCrashed( 75 const ChildProcessData& data) { 76 sandbox()->ChildDied(data.handle); 77 } 78 79 void BootstrapSandboxPolicy::Observe(int type, 80 const NotificationSource& source, 81 const NotificationDetails& details) { 82 switch (type) { 83 case NOTIFICATION_RENDERER_PROCESS_CLOSED: 84 sandbox()->ChildDied( 85 Details<RenderProcessHost::RendererClosedDetails>(details)->handle); 86 break; 87 default: 88 NOTREACHED() << "Unexpected notification " << type; 89 break; 90 } 91 } 92 93 BootstrapSandboxPolicy::BootstrapSandboxPolicy() 94 : sandbox_(sandbox::BootstrapSandbox::Create()) { 95 CHECK(sandbox_.get()); 96 BrowserChildProcessObserver::Add(this); 97 notification_registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED, 98 NotificationService::AllBrowserContextsAndSources()); 99 RegisterSandboxPolicies(); 100 } 101 102 BootstrapSandboxPolicy::~BootstrapSandboxPolicy() { 103 BrowserChildProcessObserver::Remove(this); 104 } 105 106 void BootstrapSandboxPolicy::RegisterSandboxPolicies() { 107 RegisterRendererPolicy(); 108 } 109 110 void BootstrapSandboxPolicy::RegisterRendererPolicy() { 111 sandbox::BootstrapSandboxPolicy policy; 112 AddBaselinePolicy(&policy); 113 114 // Permit font queries. 115 policy.rules["com.apple.FontServer"] = sandbox::Rule(sandbox::POLICY_ALLOW); 116 policy.rules["com.apple.FontObjectsServer"] = 117 sandbox::Rule(sandbox::POLICY_ALLOW); 118 119 // Allow access to the windowserver. This is needed to get the colorspace 120 // during sandbox warmup. Since NSColorSpace conforms to NSCoding, this 121 // should be plumbed over IPC instead <http://crbug.com/265709>. 122 policy.rules["com.apple.windowserver.active"] = 123 sandbox::Rule(sandbox::POLICY_ALLOW); 124 125 sandbox_->RegisterSandboxPolicy(SANDBOX_TYPE_RENDERER, policy); 126 } 127 128 void BootstrapSandboxPolicy::AddBaselinePolicy( 129 sandbox::BootstrapSandboxPolicy* policy) { 130 auto& rules = policy->rules; 131 132 // Allow the child to send its task port to the MachBroker. 133 rules[MachBroker::GetMachPortName()] = sandbox::Rule(sandbox::POLICY_ALLOW); 134 135 // Allow logging to the syslog. 136 rules["com.apple.system.logger"] = sandbox::Rule(sandbox::POLICY_ALLOW); 137 } 138 139 } // namespace 140 141 bool ShouldEnableBootstrapSandbox() { 142 return false; 143 } 144 145 sandbox::BootstrapSandbox* GetBootstrapSandbox() { 146 return BootstrapSandboxPolicy::GetInstance()->sandbox(); 147 } 148 149 } // namespace content 150