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 #ifndef COMPONENTS_NACL_BROWSER_NACL_PROCESS_HOST_H_ 6 #define COMPONENTS_NACL_BROWSER_NACL_PROCESS_HOST_H_ 7 8 #include "base/memory/raw_ptr.h" 9 #include "build/build_config.h" 10 11 #include <stddef.h> 12 #include <stdint.h> 13 14 #include <vector> 15 16 #include "base/files/file.h" 17 #include "base/files/file_path.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 // permission_bits: controls which interfaces the NaCl plugin can use. 70 // off_the_record: was the process launched from an incognito renderer? 71 // process_type: the type of NaCl process. 72 // profile_directory: is the path of current profile directory. 73 NaClProcessHost( 74 const GURL& manifest_url, 75 base::File nexe_file, 76 const NaClFileToken& nexe_token, 77 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, 78 ppapi::PpapiPermissions permissions, 79 uint32_t permission_bits, 80 bool off_the_record, 81 NaClAppProcessType process_type, 82 const base::FilePath& profile_directory); 83 84 NaClProcessHost(const NaClProcessHost&) = delete; 85 NaClProcessHost& operator=(const NaClProcessHost&) = delete; 86 87 ~NaClProcessHost() override; 88 89 void OnProcessCrashed(int exit_status) override; 90 91 // Do any minimal work that must be done at browser startup. 92 static void EarlyStartup(); 93 94 // Specifies throttling time in milliseconds for PpapiHostMsg_Keepalive IPCs. 95 static void SetPpapiKeepAliveThrottleForTesting(unsigned milliseconds); 96 97 // Initialize the new NaCl process. Result is returned by sending ipc 98 // message reply_msg. 99 void Launch(NaClHostMessageFilter* nacl_host_message_filter, 100 IPC::Message* reply_msg, 101 const base::FilePath& manifest_path); 102 103 void OnChannelConnected(int32_t peer_pid) override; 104 105 #if BUILDFLAG(IS_WIN) 106 void OnProcessLaunchedByBroker(base::Process process); 107 void OnDebugExceptionHandlerLaunchedByBroker(bool success); 108 #endif 109 110 bool Send(IPC::Message* msg); 111 process()112 content::BrowserChildProcessHost* process() { return process_.get(); } browser_ppapi_host()113 content::BrowserPpapiHost* browser_ppapi_host() { return ppapi_host_.get(); } 114 115 private: 116 void LaunchNaClGdb(); 117 118 // Mark the process as using a particular GDB debug stub port and notify 119 // listeners (if the port is not kGdbDebugStubPortUnknown). 120 void SetDebugStubPort(int port); 121 122 #if BUILDFLAG(IS_POSIX) 123 // Create bound TCP socket in the browser process so that the NaCl GDB debug 124 // stub can use it to accept incoming connections even when the Chrome sandbox 125 // is enabled. 126 net::SocketDescriptor GetDebugStubSocketHandle(); 127 #endif 128 129 #if BUILDFLAG(IS_WIN) 130 // Called when the debug stub port has been selected. 131 void OnDebugStubPortSelected(uint16_t debug_stub_port); 132 #endif 133 134 bool LaunchSelLdr(); 135 136 // BrowserChildProcessHostDelegate implementation: 137 bool OnMessageReceived(const IPC::Message& msg) override; 138 void OnProcessLaunched() override; 139 140 void OnResourcesReady(); 141 142 // Sends the reply message to the renderer who is waiting for the plugin 143 // to load. Returns true on success. 144 void ReplyToRenderer( 145 mojo::ScopedMessagePipeHandle ppapi_channel_handle, 146 mojo::ScopedMessagePipeHandle trusted_channel_handle, 147 mojo::ScopedMessagePipeHandle manifest_service_channel_handle, 148 base::ReadOnlySharedMemoryRegion crash_info_shmem_region); 149 150 // Sends the reply with error message to the renderer. 151 void SendErrorToRenderer(const std::string& error_message); 152 153 // Sends the reply message to the renderer. Either result or 154 // error message must be empty. 155 void SendMessageToRenderer(const NaClLaunchResult& result, 156 const std::string& error_message); 157 158 // Sends the message to the NaCl process to load the plugin. Returns true 159 // on success. 160 bool StartNaClExecution(); 161 162 void StartNaClFileResolved( 163 NaClStartParams params, 164 const base::FilePath& file_path, 165 base::File nexe_file); 166 167 // Starts browser PPAPI proxy. Returns true on success. 168 bool StartPPAPIProxy(mojo::ScopedMessagePipeHandle channel_handle); 169 170 // Does post-process-launching tasks for starting the NaCl process once 171 // we have a connection. 172 // 173 // Returns false on failure. 174 bool StartWithLaunchedProcess(); 175 176 // Message handlers for validation caching. 177 void OnQueryKnownToValidate(const std::string& signature, bool* result); 178 void OnSetKnownToValidate(const std::string& signature); 179 void OnResolveFileToken(uint64_t file_token_lo, uint64_t file_token_hi); 180 void FileResolved(uint64_t file_token_lo, 181 uint64_t file_token_hi, 182 const base::FilePath& file_path, 183 base::File file); 184 #if BUILDFLAG(IS_WIN) 185 // Message handler for Windows hardware exception handling. 186 void OnAttachDebugExceptionHandler(const std::string& info, 187 IPC::Message* reply_msg); 188 bool AttachDebugExceptionHandler(const std::string& info, 189 IPC::Message* reply_msg); 190 #endif 191 192 // Called when the PPAPI IPC channels to the browser/renderer have been 193 // created. 194 void OnPpapiChannelsCreated( 195 const IPC::ChannelHandle& ppapi_browser_channel_handle, 196 const IPC::ChannelHandle& ppapi_renderer_channel_handle, 197 const IPC::ChannelHandle& trusted_renderer_channel_handle, 198 const IPC::ChannelHandle& manifest_service_channel_handle, 199 base::ReadOnlySharedMemoryRegion crash_info_shmem_region); 200 201 GURL manifest_url_; 202 base::File nexe_file_; 203 NaClFileToken nexe_token_; 204 std::vector<NaClResourcePrefetchResult> prefetched_resource_files_; 205 206 ppapi::PpapiPermissions permissions_; 207 208 #if BUILDFLAG(IS_WIN) 209 // This field becomes true when the broker successfully launched 210 // the NaCl loader. 211 bool process_launched_by_broker_; 212 #endif 213 // The NaClHostMessageFilter that requested this NaCl process. We use 214 // this for sending the reply once the process has started. 215 scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter_; 216 217 // The reply message to send. We must always send this message when the 218 // sub-process either succeeds or fails to unblock the renderer waiting for 219 // the reply. NULL when there is no reply to send. 220 raw_ptr<IPC::Message, DanglingUntriaged> reply_msg_; 221 #if BUILDFLAG(IS_WIN) 222 bool debug_exception_handler_requested_; 223 std::unique_ptr<IPC::Message> attach_debug_exception_handler_reply_msg_; 224 #endif 225 226 // The file path to the manifest is passed to nacl-gdb when it is used to 227 // debug the NaCl loader. 228 base::FilePath manifest_path_; 229 230 std::unique_ptr<content::BrowserChildProcessHost> process_; 231 232 bool enable_debug_stub_; 233 bool enable_crash_throttling_; 234 bool off_the_record_; 235 NaClAppProcessType process_type_; 236 237 const base::FilePath profile_directory_; 238 239 // Channel proxy to terminate the NaCl-Browser PPAPI channel. 240 std::unique_ptr<IPC::ChannelProxy> ipc_proxy_channel_; 241 // Browser host for plugin process. 242 std::unique_ptr<content::BrowserPpapiHost> ppapi_host_; 243 244 // Throttling time in milliseconds for PpapiHostMsg_Keepalive IPCs. 245 static unsigned keepalive_throttle_interval_milliseconds_; 246 247 base::WeakPtrFactory<NaClProcessHost> weak_factory_{this}; 248 }; 249 250 } // namespace nacl 251 252 #endif // COMPONENTS_NACL_BROWSER_NACL_PROCESS_HOST_H_ 253