1// Copyright (c) 2012 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 COMPONENTS_NACL_BROWSER_NACL_PROCESS_HOST_H_
6#define COMPONENTS_NACL_BROWSER_NACL_PROCESS_HOST_H_
7
8#include "build/build_config.h"
9
10#include "base/files/file.h"
11#include "base/files/file_path.h"
12#include "base/files/file_util_proxy.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/shared_memory.h"
15#include "base/memory/weak_ptr.h"
16#include "base/message_loop/message_loop.h"
17#include "base/process/process.h"
18#include "components/nacl/common/nacl_types.h"
19#include "content/public/browser/browser_child_process_host_delegate.h"
20#include "content/public/browser/browser_child_process_host_iterator.h"
21#include "ipc/ipc_channel_handle.h"
22#include "native_client/src/public/nacl_file_info.h"
23#include "net/socket/socket_descriptor.h"
24#include "ppapi/shared_impl/ppapi_permissions.h"
25#include "url/gurl.h"
26
27namespace content {
28class BrowserChildProcessHost;
29class BrowserPpapiHost;
30}
31
32namespace IPC {
33class ChannelProxy;
34}
35
36namespace nacl {
37
38class NaClHostMessageFilter;
39void* AllocateAddressSpaceASLR(base::ProcessHandle process, size_t size);
40
41// Represents the browser side of the browser <--> NaCl communication
42// channel. There will be one NaClProcessHost per NaCl process
43// The browser is responsible for starting the NaCl process
44// when requested by the renderer.
45// After that, most of the communication is directly between NaCl plugin
46// running in the renderer and NaCl processes.
47class NaClProcessHost : public content::BrowserChildProcessHostDelegate {
48 public:
49  // manifest_url: the URL of the manifest of the Native Client plugin being
50  // executed.
51  // nexe_file: A file that corresponds to the nexe module to be loaded.
52  // nexe_token: A cache validation token for nexe_file.
53  // permissions: PPAPI permissions, to control access to private APIs.
54  // render_view_id: RenderView routing id, to control access to private APIs.
55  // permission_bits: controls which interfaces the NaCl plugin can use.
56  // uses_irt: whether the launched process should use the IRT.
57  // uses_nonsfi_mode: whether the program should be loaded under non-SFI mode.
58  // enable_dyncode_syscalls: whether the launched process should allow dyncode
59  //                          and mmap with PROT_EXEC.
60  // enable_exception_handling: whether the launched process should allow
61  //                            hardware exception handling.
62  // enable_crash_throttling: whether a crash of this process contributes
63  //                          to the crash throttling statistics, and also
64  //                          whether this process should not start when too
65  //                          many crashes have been observed.
66  // off_the_record: was the process launched from an incognito renderer?
67  // profile_directory: is the path of current profile directory.
68  NaClProcessHost(const GURL& manifest_url,
69                  base::File nexe_file,
70                  const NaClFileToken& nexe_token,
71                  ppapi::PpapiPermissions permissions,
72                  int render_view_id,
73                  uint32 permission_bits,
74                  bool uses_irt,
75                  bool uses_nonsfi_mode,
76                  bool enable_dyncode_syscalls,
77                  bool enable_exception_handling,
78                  bool enable_crash_throttling,
79                  bool off_the_record,
80                  const base::FilePath& profile_directory);
81  virtual ~NaClProcessHost();
82
83  virtual void OnProcessCrashed(int exit_status) OVERRIDE;
84
85  // Do any minimal work that must be done at browser startup.
86  static void EarlyStartup();
87
88  // Specifies throttling time in milliseconds for PpapiHostMsg_Keepalive IPCs.
89  static void SetPpapiKeepAliveThrottleForTesting(unsigned milliseconds);
90
91  // Initialize the new NaCl process. Result is returned by sending ipc
92  // message reply_msg.
93  void Launch(NaClHostMessageFilter* nacl_host_message_filter,
94              IPC::Message* reply_msg,
95              const base::FilePath& manifest_path);
96
97  virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
98
99#if defined(OS_WIN)
100  void OnProcessLaunchedByBroker(base::ProcessHandle handle);
101  void OnDebugExceptionHandlerLaunchedByBroker(bool success);
102#endif
103
104  bool Send(IPC::Message* msg);
105
106  content::BrowserChildProcessHost* process() { return process_.get(); }
107  content::BrowserPpapiHost* browser_ppapi_host() { return ppapi_host_.get(); }
108
109 private:
110  bool LaunchNaClGdb();
111
112  // Mark the process as using a particular GDB debug stub port and notify
113  // listeners (if the port is not kGdbDebugStubPortUnknown).
114  void SetDebugStubPort(int port);
115
116#if defined(OS_POSIX)
117  // Create bound TCP socket in the browser process so that the NaCl GDB debug
118  // stub can use it to accept incoming connections even when the Chrome sandbox
119  // is enabled.
120  net::SocketDescriptor GetDebugStubSocketHandle();
121#endif
122
123#if defined(OS_WIN)
124  // Called when the debug stub port has been selected.
125  void OnDebugStubPortSelected(uint16_t debug_stub_port);
126#endif
127
128  bool LaunchSelLdr();
129
130  // BrowserChildProcessHostDelegate implementation:
131  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
132  virtual void OnProcessLaunched() OVERRIDE;
133
134  void OnResourcesReady();
135
136  // Enable the PPAPI proxy only for NaCl processes corresponding to a renderer.
137  bool enable_ppapi_proxy() { return render_view_id_ != 0; }
138
139  // Sends the reply message to the renderer who is waiting for the plugin
140  // to load. Returns true on success.
141  bool ReplyToRenderer(
142      const IPC::ChannelHandle& ppapi_channel_handle,
143      const IPC::ChannelHandle& trusted_channel_handle,
144      const IPC::ChannelHandle& manifest_service_channel_handle);
145
146  // Sends the reply with error message to the renderer.
147  void SendErrorToRenderer(const std::string& error_message);
148
149  // Sends the reply message to the renderer. Either result or
150  // error message must be empty.
151  void SendMessageToRenderer(const NaClLaunchResult& result,
152                             const std::string& error_message);
153
154  // Sends the message to the NaCl process to load the plugin. Returns true
155  // on success.
156  bool StartNaClExecution();
157
158  // Does post-process-launching tasks for starting the NaCl process once
159  // we have a connection.
160  //
161  // Returns false on failure.
162  bool StartWithLaunchedProcess();
163
164  // Message handlers for validation caching.
165  void OnQueryKnownToValidate(const std::string& signature, bool* result);
166  void OnSetKnownToValidate(const std::string& signature);
167  void OnResolveFileToken(uint64 file_token_lo, uint64 file_token_hi,
168                          IPC::Message* reply_msg);
169  void OnResolveFileTokenAsync(uint64 file_token_lo, uint64 file_token_hi);
170  void FileResolved(const base::FilePath& file_path,
171                    IPC::Message* reply_msg,
172                    base::File file);
173  void FileResolvedAsync(uint64_t file_token_lo,
174                         uint64_t file_token_hi,
175                         const base::FilePath& file_path,
176                         base::File file);
177#if defined(OS_WIN)
178  // Message handler for Windows hardware exception handling.
179  void OnAttachDebugExceptionHandler(const std::string& info,
180                                     IPC::Message* reply_msg);
181  bool AttachDebugExceptionHandler(const std::string& info,
182                                   IPC::Message* reply_msg);
183#endif
184
185  // Called when the PPAPI IPC channels to the browser/renderer have been
186  // created.
187  void OnPpapiChannelsCreated(
188      const IPC::ChannelHandle& browser_channel_handle,
189      const IPC::ChannelHandle& ppapi_renderer_channel_handle,
190      const IPC::ChannelHandle& trusted_renderer_channel_handle,
191      const IPC::ChannelHandle& manifest_service_channel_handle);
192
193  GURL manifest_url_;
194  base::File nexe_file_;
195  NaClFileToken nexe_token_;
196
197  ppapi::PpapiPermissions permissions_;
198
199#if defined(OS_WIN)
200  // This field becomes true when the broker successfully launched
201  // the NaCl loader.
202  bool process_launched_by_broker_;
203#endif
204  // The NaClHostMessageFilter that requested this NaCl process.  We use
205  // this for sending the reply once the process has started.
206  scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter_;
207
208  // The reply message to send. We must always send this message when the
209  // sub-process either succeeds or fails to unblock the renderer waiting for
210  // the reply. NULL when there is no reply to send.
211  IPC::Message* reply_msg_;
212#if defined(OS_WIN)
213  bool debug_exception_handler_requested_;
214  scoped_ptr<IPC::Message> attach_debug_exception_handler_reply_msg_;
215#endif
216
217  // The file path to the manifest is passed to nacl-gdb when it is used to
218  // debug the NaCl loader.
219  base::FilePath manifest_path_;
220
221  scoped_ptr<content::BrowserChildProcessHost> process_;
222
223  bool uses_irt_;
224  bool uses_nonsfi_mode_;
225
226  bool enable_debug_stub_;
227  bool enable_dyncode_syscalls_;
228  bool enable_exception_handling_;
229  bool enable_crash_throttling_;
230
231  bool off_the_record_;
232
233  const base::FilePath profile_directory_;
234
235  // Channel proxy to terminate the NaCl-Browser PPAPI channel.
236  scoped_ptr<IPC::ChannelProxy> ipc_proxy_channel_;
237  // Browser host for plugin process.
238  scoped_ptr<content::BrowserPpapiHost> ppapi_host_;
239
240  int render_view_id_;
241
242  // Throttling time in milliseconds for PpapiHostMsg_Keepalive IPCs.
243  static unsigned keepalive_throttle_interval_milliseconds_;
244
245  // Shared memory provided to the plugin and renderer for
246  // reporting crash information.
247  base::SharedMemory crash_info_shmem_;
248
249  base::File socket_for_renderer_;
250  base::File socket_for_sel_ldr_;
251
252  base::WeakPtrFactory<NaClProcessHost> weak_factory_;
253
254  DISALLOW_COPY_AND_ASSIGN(NaClProcessHost);
255};
256
257}  // namespace nacl
258
259#endif  // COMPONENTS_NACL_BROWSER_NACL_PROCESS_HOST_H_
260