• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 "components/nacl/browser/nacl_broker_host_win.h"
6 
7 #include <windows.h>
8 
9 #include <memory>
10 
11 #include "base/base_switches.h"
12 #include "base/command_line.h"
13 #include "base/memory/ptr_util.h"
14 #include "components/nacl/browser/nacl_broker_service_win.h"
15 #include "components/nacl/browser/nacl_browser.h"
16 #include "components/nacl/common/nacl_cmd_line.h"
17 #include "components/nacl/common/nacl_constants.h"
18 #include "components/nacl/common/nacl_messages.h"
19 #include "components/nacl/common/nacl_process_type.h"
20 #include "components/nacl/common/nacl_switches.h"
21 #include "content/public/browser/browser_child_process_host.h"
22 #include "content/public/browser/child_process_data.h"
23 #include "content/public/browser/child_process_host.h"
24 #include "content/public/common/content_switches.h"
25 #include "content/public/common/sandboxed_process_launcher_delegate.h"
26 #include "sandbox/policy/mojom/sandbox.mojom.h"
27 
28 namespace {
29 // NOTE: changes to this class need to be reviewed by the security team.
30 class NaClBrokerSandboxedProcessLauncherDelegate
31     : public content::SandboxedProcessLauncherDelegate {
32  public:
NaClBrokerSandboxedProcessLauncherDelegate()33   NaClBrokerSandboxedProcessLauncherDelegate() {}
34 
35   NaClBrokerSandboxedProcessLauncherDelegate(
36       const NaClBrokerSandboxedProcessLauncherDelegate&) = delete;
37   NaClBrokerSandboxedProcessLauncherDelegate& operator=(
38       const NaClBrokerSandboxedProcessLauncherDelegate&) = delete;
39 
GetSandboxType()40   sandbox::mojom::Sandbox GetSandboxType() override {
41     return sandbox::mojom::Sandbox::kNoSandbox;
42   }
43 
GetSandboxTag()44   std::string GetSandboxTag() override {
45     // kNoSandbox does not use a TargetPolicy, if the sandbox type is changed
46     // then provide a unique tag here.
47     return "";
48   }
49 };
50 }  // namespace
51 
52 namespace nacl {
53 
NaClBrokerHost()54 NaClBrokerHost::NaClBrokerHost() : is_terminating_(false) {
55 }
56 
~NaClBrokerHost()57 NaClBrokerHost::~NaClBrokerHost() {
58 }
59 
Init()60 bool NaClBrokerHost::Init() {
61   DCHECK(!process_);
62   process_ = content::BrowserChildProcessHost::Create(
63       static_cast<content::ProcessType>(PROCESS_TYPE_NACL_BROKER), this,
64       content::ChildProcessHost::IpcMode::kLegacy);
65   process_->SetMetricsName("NaCl Broker");
66   process_->GetHost()->CreateChannelMojo();
67 
68   // Create the path to the nacl broker/loader executable.
69   base::FilePath nacl_path;
70   if (!NaClBrowser::GetInstance()->GetNaCl64ExePath(&nacl_path))
71     return false;
72 
73   base::CommandLine* cmd_line = new base::CommandLine(nacl_path);
74   CopyNaClCommandLineArguments(cmd_line);
75 
76   cmd_line->AppendSwitchASCII(switches::kProcessType,
77                               switches::kNaClBrokerProcess);
78   if (NaClBrowser::GetDelegate()->DialogsAreSuppressed())
79     cmd_line->AppendSwitch(switches::kNoErrorDialogs);
80 
81   process_->Launch(
82       std::make_unique<NaClBrokerSandboxedProcessLauncherDelegate>(),
83       base::WrapUnique(cmd_line), true);
84   return true;
85 }
86 
OnMessageReceived(const IPC::Message & msg)87 bool NaClBrokerHost::OnMessageReceived(const IPC::Message& msg) {
88   bool handled = true;
89   IPC_BEGIN_MESSAGE_MAP(NaClBrokerHost, msg)
90     IPC_MESSAGE_HANDLER(NaClProcessMsg_LoaderLaunched, OnLoaderLaunched)
91     IPC_MESSAGE_HANDLER(NaClProcessMsg_DebugExceptionHandlerLaunched,
92                         OnDebugExceptionHandlerLaunched)
93     IPC_MESSAGE_UNHANDLED(handled = false)
94   IPC_END_MESSAGE_MAP()
95   return handled;
96 }
97 
LaunchLoader(int launch_id,mojo::ScopedMessagePipeHandle ipc_channel_handle)98 bool NaClBrokerHost::LaunchLoader(
99     int launch_id,
100     mojo::ScopedMessagePipeHandle ipc_channel_handle) {
101   return process_->Send(new NaClProcessMsg_LaunchLoaderThroughBroker(
102       launch_id, ipc_channel_handle.release()));
103 }
104 
OnLoaderLaunched(int launch_id,base::ProcessHandle handle)105 void NaClBrokerHost::OnLoaderLaunched(int launch_id,
106                                       base::ProcessHandle handle) {
107   NaClBrokerService::GetInstance()->OnLoaderLaunched(launch_id,
108                                                      base::Process(handle));
109 }
110 
LaunchDebugExceptionHandler(int32_t pid,base::ProcessHandle process_handle,const std::string & startup_info)111 bool NaClBrokerHost::LaunchDebugExceptionHandler(
112     int32_t pid,
113     base::ProcessHandle process_handle,
114     const std::string& startup_info) {
115   base::ProcessHandle broker_process =
116       process_->GetData().GetProcess().Handle();
117   base::ProcessHandle handle_in_broker_process;
118   if (!DuplicateHandle(::GetCurrentProcess(), process_handle,
119                        broker_process, &handle_in_broker_process,
120                        0, /* bInheritHandle= */ FALSE, DUPLICATE_SAME_ACCESS))
121     return false;
122   return process_->Send(new NaClProcessMsg_LaunchDebugExceptionHandler(
123       pid, handle_in_broker_process, startup_info));
124 }
125 
OnDebugExceptionHandlerLaunched(int32_t pid,bool success)126 void NaClBrokerHost::OnDebugExceptionHandlerLaunched(int32_t pid,
127                                                      bool success) {
128   NaClBrokerService::GetInstance()->OnDebugExceptionHandlerLaunched(pid,
129                                                                     success);
130 }
131 
StopBroker()132 void NaClBrokerHost::StopBroker() {
133   is_terminating_ = true;
134   process_->Send(new NaClProcessMsg_StopBroker());
135 }
136 
137 }  // namespace nacl
138