Index: components/nacl/browser/nacl_host_message_filter.cc |
diff --git a/components/nacl/browser/nacl_host_message_filter.cc b/components/nacl/browser/nacl_host_message_filter.cc |
index 3726a7e1e1d349c59f6c6d9e0e6e0e8d0eab3042..18a695e7c54af6c46b4678c0b283a1aab49f9fc5 100644 |
--- a/components/nacl/browser/nacl_host_message_filter.cc |
+++ b/components/nacl/browser/nacl_host_message_filter.cc |
@@ -24,6 +24,11 @@ namespace nacl { |
namespace { |
+// The maximum number of resource file handles NaClProcessMsg_Start message |
+// can have. |
+// TODO(yusukes): Increase the number. |
+const size_t kMaxPreOpenResourceFiles = 2; |
+ |
ppapi::PpapiPermissions GetNaClPermissions( |
uint32 permission_bits, |
content::BrowserContext* browser_context, |
@@ -122,19 +127,16 @@ void NaClHostMessageFilter::OnLaunchNaCl( |
// of the whitelisting parameters anyway. |
if (launch_params.process_type == kPNaClTranslatorProcessType) { |
uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; |
- LaunchNaClContinuation( |
+ LaunchNaClContinuationOnIOThread( |
launch_params, |
reply_msg, |
+ std::vector<nacl::NaClResourceFileInfo>(), |
ppapi::PpapiPermissions(perms)); |
return; |
} |
- content::BrowserThread::PostTaskAndReplyWithResult( |
+ content::BrowserThread::PostTask( |
content::BrowserThread::UI, |
FROM_HERE, |
- base::Bind(&GetPpapiPermissions, |
- launch_params.permission_bits, |
- render_process_id_, |
- launch_params.render_view_id), |
base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, |
this, |
launch_params, |
@@ -143,8 +145,100 @@ void NaClHostMessageFilter::OnLaunchNaCl( |
void NaClHostMessageFilter::LaunchNaClContinuation( |
const nacl::NaClLaunchParams& launch_params, |
+ IPC::Message* reply_msg) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ |
+ ppapi::PpapiPermissions permissions = |
+ GetPpapiPermissions(launch_params.permission_bits, |
+ render_process_id_, |
+ launch_params.render_view_id); |
+ |
+ content::RenderViewHost* rvh = content::RenderViewHost::FromID( |
+ render_process_id(), launch_params.render_view_id); |
+ if (!rvh) { |
+ BadMessageReceived(); // Kill the renderer. |
+ return; |
+ } |
+ |
+ nacl::NaClLaunchParams safe_launch_params(launch_params); |
+ safe_launch_params.resource_files_to_prefetch.clear(); |
+ |
+ content::SiteInstance* site_instance = rvh->GetSiteInstance(); |
+ for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
+ GURL gurl(launch_params.resource_files_to_prefetch[i].second); |
+ // Important security check: Do the same check as OpenNaClExecutable() |
+ // in nacl_file_host.cc. |
+ if (!content::SiteInstance::IsSameWebSite( |
+ site_instance->GetBrowserContext(), |
+ site_instance->GetSiteURL(), |
+ gurl)) { |
+ continue; |
+ } |
+ safe_launch_params.resource_files_to_prefetch.push_back( |
+ launch_params.resource_files_to_prefetch[i]); |
+ } |
+ |
+ // Process a list of resource file URLs in |
+ // |launch_params.resource_files_to_prefetch|. |
+ content::BrowserThread::PostBlockingPoolTask( |
+ FROM_HERE, |
+ base::Bind(&NaClHostMessageFilter::BatchOpenResourceFiles, |
+ this, |
+ safe_launch_params, |
+ reply_msg, |
+ permissions)); |
+} |
+ |
+void NaClHostMessageFilter::BatchOpenResourceFiles( |
+ const nacl::NaClLaunchParams& launch_params, |
+ IPC::Message* reply_msg, |
+ ppapi::PpapiPermissions permissions) { |
+ std::vector<nacl::NaClResourceFileInfo> prefetched_resource_files_info; |
+ for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
+ nacl::NaClResourceFileInfo prefetched_resource_file; |
+ GURL gurl(launch_params.resource_files_to_prefetch[i].second); |
+ if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( |
+ gurl, |
+ true, // use_blocking_api |
+ profile_directory_, |
+ &prefetched_resource_file.file_path_metadata)) { |
+ continue; |
+ } |
+ base::File file = nacl::OpenNaClReadExecImpl( |
+ prefetched_resource_file.file_path_metadata, |
+ true /* is_executable */); |
+ if (!file.IsValid()) |
+ continue; |
+ |
+ prefetched_resource_file.file = |
+ IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle()); |
+ prefetched_resource_file.file_key = |
+ launch_params.resource_files_to_prefetch[i].first; |
+ |
+ prefetched_resource_files_info.push_back(prefetched_resource_file); |
+ if (prefetched_resource_files_info.size() >= kMaxPreOpenResourceFiles) |
+ break; |
+ } |
+ |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&NaClHostMessageFilter::LaunchNaClContinuationOnIOThread, |
+ this, |
+ launch_params, |
+ reply_msg, |
+ prefetched_resource_files_info, |
+ permissions)); |
+} |
+ |
+void NaClHostMessageFilter::LaunchNaClContinuationOnIOThread( |
+ const nacl::NaClLaunchParams& launch_params, |
IPC::Message* reply_msg, |
+ const std::vector< |
+ nacl::NaClResourceFileInfo>& prefetched_resource_files_info, |
ppapi::PpapiPermissions permissions) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
+ |
NaClFileToken nexe_token = { |
launch_params.nexe_token_lo, // lo |
launch_params.nexe_token_hi // hi |
@@ -179,6 +273,7 @@ void NaClHostMessageFilter::LaunchNaClContinuation( |
GURL(launch_params.manifest_url), |
base::File(nexe_file), |
nexe_token, |
+ prefetched_resource_files_info, |
permissions, |
launch_params.render_view_id, |
launch_params.permission_bits, |