| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/nacl/browser/nacl_host_message_filter.h" | 5 #include "components/nacl/browser/nacl_host_message_filter.h" |
| 6 | 6 |
| 7 #include "base/sys_info.h" | 7 #include "base/sys_info.h" |
| 8 #include "components/nacl/browser/nacl_browser.h" | 8 #include "components/nacl/browser/nacl_browser.h" |
| 9 #include "components/nacl/browser/nacl_file_host.h" | 9 #include "components/nacl/browser/nacl_file_host.h" |
| 10 #include "components/nacl/browser/nacl_process_host.h" | 10 #include "components/nacl/browser/nacl_process_host.h" |
| 11 #include "components/nacl/browser/pnacl_host.h" | 11 #include "components/nacl/browser/pnacl_host.h" |
| 12 #include "components/nacl/common/nacl_host_messages.h" | 12 #include "components/nacl/common/nacl_host_messages.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/plugin_service.h" | 14 #include "content/public/browser/plugin_service.h" |
| 15 #include "content/public/browser/render_process_host.h" | 15 #include "content/public/browser/render_process_host.h" |
| 16 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
| 17 #include "ipc/ipc_platform_file.h" | 17 #include "ipc/ipc_platform_file.h" |
| 18 #include "net/url_request/url_request_context.h" | 18 #include "net/url_request/url_request_context.h" |
| 19 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
| 20 #include "ppapi/shared_impl/ppapi_permissions.h" | 20 #include "ppapi/shared_impl/ppapi_permissions.h" |
| 21 #include "url/gurl.h" | 21 #include "url/gurl.h" |
| 22 | 22 |
| 23 namespace nacl { | 23 namespace nacl { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // The maximum number of resource file handles NaClProcessMsg_Start message |
| 28 // can have. |
| 29 // TODO(yusukes): Increase the number. |
| 30 const size_t kMaxPreOpenResourceFiles = 2; |
| 31 |
| 27 ppapi::PpapiPermissions GetNaClPermissions( | 32 ppapi::PpapiPermissions GetNaClPermissions( |
| 28 uint32 permission_bits, | 33 uint32 permission_bits, |
| 29 content::BrowserContext* browser_context, | 34 content::BrowserContext* browser_context, |
| 30 const GURL& document_url) { | 35 const GURL& document_url) { |
| 31 // Only allow NaCl plugins to request certain permissions. We don't want | 36 // Only allow NaCl plugins to request certain permissions. We don't want |
| 32 // a compromised renderer to be able to start a nacl plugin with e.g. Flash | 37 // a compromised renderer to be able to start a nacl plugin with e.g. Flash |
| 33 // permissions which may expand the surface area of the sandbox. | 38 // permissions which may expand the surface area of the sandbox. |
| 34 uint32 masked_bits = permission_bits & ppapi::PERMISSION_DEV; | 39 uint32 masked_bits = permission_bits & ppapi::PERMISSION_DEV; |
| 35 if (content::PluginService::GetInstance()->PpapiDevChannelSupported( | 40 if (content::PluginService::GetInstance()->PpapiDevChannelSupported( |
| 36 browser_context, document_url)) | 41 browser_context, document_url)) |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 } | 120 } |
| 116 | 121 |
| 117 void NaClHostMessageFilter::OnLaunchNaCl( | 122 void NaClHostMessageFilter::OnLaunchNaCl( |
| 118 const nacl::NaClLaunchParams& launch_params, | 123 const nacl::NaClLaunchParams& launch_params, |
| 119 IPC::Message* reply_msg) { | 124 IPC::Message* reply_msg) { |
| 120 // If we're running llc or ld for the PNaCl translator, we don't need to look | 125 // If we're running llc or ld for the PNaCl translator, we don't need to look |
| 121 // up permissions, and we don't have the right browser state to look up some | 126 // up permissions, and we don't have the right browser state to look up some |
| 122 // of the whitelisting parameters anyway. | 127 // of the whitelisting parameters anyway. |
| 123 if (launch_params.process_type == kPNaClTranslatorProcessType) { | 128 if (launch_params.process_type == kPNaClTranslatorProcessType) { |
| 124 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; | 129 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; |
| 125 LaunchNaClContinuation( | 130 LaunchNaClContinuationOnIOThread( |
| 126 launch_params, | 131 launch_params, |
| 127 reply_msg, | 132 reply_msg, |
| 133 std::vector<nacl::NaClResourceFileInfo>(), |
| 128 ppapi::PpapiPermissions(perms)); | 134 ppapi::PpapiPermissions(perms)); |
| 129 return; | 135 return; |
| 130 } | 136 } |
| 131 content::BrowserThread::PostTaskAndReplyWithResult( | 137 content::BrowserThread::PostTask( |
| 132 content::BrowserThread::UI, | 138 content::BrowserThread::UI, |
| 133 FROM_HERE, | 139 FROM_HERE, |
| 134 base::Bind(&GetPpapiPermissions, | |
| 135 launch_params.permission_bits, | |
| 136 render_process_id_, | |
| 137 launch_params.render_view_id), | |
| 138 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, | 140 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, |
| 139 this, | 141 this, |
| 140 launch_params, | 142 launch_params, |
| 141 reply_msg)); | 143 reply_msg)); |
| 142 } | 144 } |
| 143 | 145 |
| 144 void NaClHostMessageFilter::LaunchNaClContinuation( | 146 void NaClHostMessageFilter::LaunchNaClContinuation( |
| 145 const nacl::NaClLaunchParams& launch_params, | 147 const nacl::NaClLaunchParams& launch_params, |
| 148 IPC::Message* reply_msg) { |
| 149 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 150 |
| 151 ppapi::PpapiPermissions permissions = |
| 152 GetPpapiPermissions(launch_params.permission_bits, |
| 153 render_process_id_, |
| 154 launch_params.render_view_id); |
| 155 |
| 156 content::RenderViewHost* rvh = content::RenderViewHost::FromID( |
| 157 render_process_id(), launch_params.render_view_id); |
| 158 if (!rvh) { |
| 159 BadMessageReceived(); // Kill the renderer. |
| 160 return; |
| 161 } |
| 162 |
| 163 nacl::NaClLaunchParams safe_launch_params(launch_params); |
| 164 safe_launch_params.resource_files_to_prefetch.clear(); |
| 165 |
| 166 content::SiteInstance* site_instance = rvh->GetSiteInstance(); |
| 167 for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
| 168 GURL gurl(launch_params.resource_files_to_prefetch[i].second); |
| 169 // Important security check: Do the same check as OpenNaClExecutable() |
| 170 // in nacl_file_host.cc. |
| 171 if (!content::SiteInstance::IsSameWebSite( |
| 172 site_instance->GetBrowserContext(), |
| 173 site_instance->GetSiteURL(), |
| 174 gurl)) { |
| 175 continue; |
| 176 } |
| 177 safe_launch_params.resource_files_to_prefetch.push_back( |
| 178 launch_params.resource_files_to_prefetch[i]); |
| 179 } |
| 180 |
| 181 // Process a list of resource file URLs in |
| 182 // |launch_params.resource_files_to_prefetch|. |
| 183 content::BrowserThread::PostBlockingPoolTask( |
| 184 FROM_HERE, |
| 185 base::Bind(&NaClHostMessageFilter::BatchOpenResourceFiles, |
| 186 this, |
| 187 safe_launch_params, |
| 188 reply_msg, |
| 189 permissions)); |
| 190 } |
| 191 |
| 192 void NaClHostMessageFilter::BatchOpenResourceFiles( |
| 193 const nacl::NaClLaunchParams& launch_params, |
| 146 IPC::Message* reply_msg, | 194 IPC::Message* reply_msg, |
| 147 ppapi::PpapiPermissions permissions) { | 195 ppapi::PpapiPermissions permissions) { |
| 196 std::vector<nacl::NaClResourceFileInfo> prefetched_resource_files_info; |
| 197 for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
| 198 nacl::NaClResourceFileInfo prefetched_resource_file; |
| 199 GURL gurl(launch_params.resource_files_to_prefetch[i].second); |
| 200 if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( |
| 201 gurl, |
| 202 true, // use_blocking_api |
| 203 profile_directory_, |
| 204 &prefetched_resource_file.file_path_metadata)) { |
| 205 continue; |
| 206 } |
| 207 base::File file = nacl::OpenNaClReadExecImpl( |
| 208 prefetched_resource_file.file_path_metadata, |
| 209 true /* is_executable */); |
| 210 if (!file.IsValid()) |
| 211 continue; |
| 212 |
| 213 prefetched_resource_file.file = |
| 214 IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle()); |
| 215 prefetched_resource_file.file_key = |
| 216 launch_params.resource_files_to_prefetch[i].first; |
| 217 |
| 218 prefetched_resource_files_info.push_back(prefetched_resource_file); |
| 219 if (prefetched_resource_files_info.size() >= kMaxPreOpenResourceFiles) |
| 220 break; |
| 221 } |
| 222 |
| 223 content::BrowserThread::PostTask( |
| 224 content::BrowserThread::IO, |
| 225 FROM_HERE, |
| 226 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuationOnIOThread, |
| 227 this, |
| 228 launch_params, |
| 229 reply_msg, |
| 230 prefetched_resource_files_info, |
| 231 permissions)); |
| 232 } |
| 233 |
| 234 void NaClHostMessageFilter::LaunchNaClContinuationOnIOThread( |
| 235 const nacl::NaClLaunchParams& launch_params, |
| 236 IPC::Message* reply_msg, |
| 237 const std::vector< |
| 238 nacl::NaClResourceFileInfo>& prefetched_resource_files_info, |
| 239 ppapi::PpapiPermissions permissions) { |
| 240 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 241 |
| 148 NaClFileToken nexe_token = { | 242 NaClFileToken nexe_token = { |
| 149 launch_params.nexe_token_lo, // lo | 243 launch_params.nexe_token_lo, // lo |
| 150 launch_params.nexe_token_hi // hi | 244 launch_params.nexe_token_hi // hi |
| 151 }; | 245 }; |
| 152 | 246 |
| 153 base::PlatformFile nexe_file; | 247 base::PlatformFile nexe_file; |
| 154 #if defined(OS_WIN) | 248 #if defined(OS_WIN) |
| 155 // Duplicate the nexe file handle from the renderer process into the browser | 249 // Duplicate the nexe file handle from the renderer process into the browser |
| 156 // process. | 250 // process. |
| 157 if (!::DuplicateHandle(PeerHandle(), | 251 if (!::DuplicateHandle(PeerHandle(), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 172 nexe_file = | 266 nexe_file = |
| 173 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); | 267 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); |
| 174 #else | 268 #else |
| 175 #error Unsupported platform. | 269 #error Unsupported platform. |
| 176 #endif | 270 #endif |
| 177 | 271 |
| 178 NaClProcessHost* host = new NaClProcessHost( | 272 NaClProcessHost* host = new NaClProcessHost( |
| 179 GURL(launch_params.manifest_url), | 273 GURL(launch_params.manifest_url), |
| 180 base::File(nexe_file), | 274 base::File(nexe_file), |
| 181 nexe_token, | 275 nexe_token, |
| 276 prefetched_resource_files_info, |
| 182 permissions, | 277 permissions, |
| 183 launch_params.render_view_id, | 278 launch_params.render_view_id, |
| 184 launch_params.permission_bits, | 279 launch_params.permission_bits, |
| 185 launch_params.uses_nonsfi_mode, | 280 launch_params.uses_nonsfi_mode, |
| 186 off_the_record_, | 281 off_the_record_, |
| 187 launch_params.process_type, | 282 launch_params.process_type, |
| 188 profile_directory_); | 283 profile_directory_); |
| 189 GURL manifest_url(launch_params.manifest_url); | 284 GURL manifest_url(launch_params.manifest_url); |
| 190 base::FilePath manifest_path; | 285 base::FilePath manifest_path; |
| 191 // We're calling MapUrlToLocalFilePath with the non-blocking API | 286 // We're calling MapUrlToLocalFilePath with the non-blocking API |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 reply_msg); | 390 reply_msg); |
| 296 } | 391 } |
| 297 | 392 |
| 298 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, | 393 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, |
| 299 bool* should_debug) { | 394 bool* should_debug) { |
| 300 *should_debug = | 395 *should_debug = |
| 301 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); | 396 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); |
| 302 } | 397 } |
| 303 | 398 |
| 304 } // namespace nacl | 399 } // namespace nacl |
| OLD | NEW |