Home | History | Annotate | Download | only in browser
      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