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