• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
sandbox() const35   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 
GetInstance()65 BootstrapSandboxPolicy* BootstrapSandboxPolicy::GetInstance() {
66   return Singleton<BootstrapSandboxPolicy>::get();
67 }
68 
BrowserChildProcessHostDisconnected(const ChildProcessData & data)69 void BootstrapSandboxPolicy::BrowserChildProcessHostDisconnected(
70       const ChildProcessData& data) {
71   sandbox()->ChildDied(data.handle);
72 }
73 
BrowserChildProcessCrashed(const ChildProcessData & data)74 void BootstrapSandboxPolicy::BrowserChildProcessCrashed(
75       const ChildProcessData& data) {
76   sandbox()->ChildDied(data.handle);
77 }
78 
Observe(int type,const NotificationSource & source,const NotificationDetails & details)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 
BootstrapSandboxPolicy()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 
~BootstrapSandboxPolicy()102 BootstrapSandboxPolicy::~BootstrapSandboxPolicy() {
103   BrowserChildProcessObserver::Remove(this);
104 }
105 
RegisterSandboxPolicies()106 void BootstrapSandboxPolicy::RegisterSandboxPolicies() {
107   RegisterRendererPolicy();
108 }
109 
RegisterRendererPolicy()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 
AddBaselinePolicy(sandbox::BootstrapSandboxPolicy * policy)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 
ShouldEnableBootstrapSandbox()141 bool ShouldEnableBootstrapSandbox() {
142   return false;
143 }
144 
GetBootstrapSandbox()145 sandbox::BootstrapSandbox* GetBootstrapSandbox() {
146   return BootstrapSandboxPolicy::GetInstance()->sandbox();
147 }
148 
149 }  // namespace content
150