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 bool Send(IPC::Message* msg); 106 process()107 content::BrowserChildProcessHost* process() { return process_.get(); } browser_ppapi_host()108 content::BrowserPpapiHost* browser_ppapi_host() { return ppapi_host_.get(); } 109 110 private: 111 void LaunchNaClGdb(); 112 113 // Mark the process as using a particular GDB debug stub port and notify 114 // listeners (if the port is not kGdbDebugStubPortUnknown). 115 void SetDebugStubPort(int port); 116 117 #if BUILDFLAG(IS_POSIX) 118 // Create bound TCP socket in the browser process so that the NaCl GDB debug 119 // stub can use it to accept incoming connections even when the Chrome sandbox 120 // is enabled. 121 net::SocketDescriptor GetDebugStubSocketHandle(); 122 #endif 123 124 bool LaunchSelLdr(); 125 126 // BrowserChildProcessHostDelegate implementation: 127 bool OnMessageReceived(const IPC::Message& msg) override; 128 void OnProcessLaunched() override; 129 130 void OnResourcesReady(); 131 132 // Sends the reply message to the renderer who is waiting for the plugin 133 // to load. Returns true on success. 134 void ReplyToRenderer( 135 mojo::ScopedMessagePipeHandle ppapi_channel_handle, 136 mojo::ScopedMessagePipeHandle trusted_channel_handle, 137 mojo::ScopedMessagePipeHandle manifest_service_channel_handle, 138 base::ReadOnlySharedMemoryRegion crash_info_shmem_region); 139 140 // Sends the reply with error message to the renderer. 141 void SendErrorToRenderer(const std::string& error_message); 142 143 // Sends the reply message to the renderer. Either result or 144 // error message must be empty. 145 void SendMessageToRenderer(const NaClLaunchResult& result, 146 const std::string& error_message); 147 148 // Sends the message to the NaCl process to load the plugin. Returns true 149 // on success. 150 bool StartNaClExecution(); 151 152 void StartNaClFileResolved( 153 NaClStartParams params, 154 const base::FilePath& file_path, 155 base::File nexe_file); 156 157 // Starts browser PPAPI proxy. Returns true on success. 158 bool StartPPAPIProxy(mojo::ScopedMessagePipeHandle channel_handle); 159 160 // Does post-process-launching tasks for starting the NaCl process once 161 // we have a connection. 162 // 163 // Returns false on failure. 164 bool StartWithLaunchedProcess(); 165 166 // Message handlers for validation caching. 167 void OnQueryKnownToValidate(const std::string& signature, bool* result); 168 void OnSetKnownToValidate(const std::string& signature); 169 void OnResolveFileToken(uint64_t file_token_lo, uint64_t file_token_hi); 170 void FileResolved(uint64_t file_token_lo, 171 uint64_t file_token_hi, 172 const base::FilePath& file_path, 173 base::File file); 174 175 // Called when the PPAPI IPC channels to the browser/renderer have been 176 // created. 177 void OnPpapiChannelsCreated( 178 const IPC::ChannelHandle& ppapi_browser_channel_handle, 179 const IPC::ChannelHandle& ppapi_renderer_channel_handle, 180 const IPC::ChannelHandle& trusted_renderer_channel_handle, 181 const IPC::ChannelHandle& manifest_service_channel_handle, 182 base::ReadOnlySharedMemoryRegion crash_info_shmem_region); 183 184 GURL manifest_url_; 185 base::File nexe_file_; 186 NaClFileToken nexe_token_; 187 std::vector<NaClResourcePrefetchResult> prefetched_resource_files_; 188 189 ppapi::PpapiPermissions permissions_; 190 191 // The NaClHostMessageFilter that requested this NaCl process. We use 192 // this for sending the reply once the process has started. 193 scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter_; 194 195 // The reply message to send. We must always send this message when the 196 // sub-process either succeeds or fails to unblock the renderer waiting for 197 // the reply. NULL when there is no reply to send. 198 raw_ptr<IPC::Message, AcrossTasksDanglingUntriaged> reply_msg_; 199 200 // The file path to the manifest is passed to nacl-gdb when it is used to 201 // debug the NaCl loader. 202 base::FilePath manifest_path_; 203 204 std::unique_ptr<content::BrowserChildProcessHost> process_; 205 206 bool enable_debug_stub_; 207 bool enable_crash_throttling_; 208 bool off_the_record_; 209 NaClAppProcessType process_type_; 210 211 const base::FilePath profile_directory_; 212 213 // Channel proxy to terminate the NaCl-Browser PPAPI channel. 214 std::unique_ptr<IPC::ChannelProxy> ipc_proxy_channel_; 215 // Browser host for plugin process. 216 std::unique_ptr<content::BrowserPpapiHost> ppapi_host_; 217 218 // Throttling time in milliseconds for PpapiHostMsg_Keepalive IPCs. 219 static unsigned keepalive_throttle_interval_milliseconds_; 220 221 base::WeakPtrFactory<NaClProcessHost> weak_factory_{this}; 222 }; 223 224 } // namespace nacl 225 226 #endif // COMPONENTS_NACL_BROWSER_NACL_PROCESS_HOST_H_ 227