 Chromium Code Reviews
 Chromium Code Reviews Issue 649603004:
  Non-SFI NaCl: Batch-open resource files  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 649603004:
  Non-SFI NaCl: Batch-open resource files  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| 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/renderer/ppb_nacl_private_impl.h" | 5 #include "components/nacl/renderer/ppb_nacl_private_impl.h" | 
| 6 | 6 | 
| 7 #include <numeric> | 7 #include <numeric> | 
| 8 #include <string> | 8 #include <string> | 
| 9 #include <vector> | 9 #include <vector> | 
| 10 | 10 | 
| 11 #include "base/bind.h" | 11 #include "base/bind.h" | 
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" | 
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" | 
| 14 #include "base/containers/scoped_ptr_hash_map.h" | 14 #include "base/containers/scoped_ptr_hash_map.h" | 
| 15 #include "base/cpu.h" | 15 #include "base/cpu.h" | 
| 16 #include "base/files/file.h" | 16 #include "base/files/file.h" | 
| 17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" | 
| 18 #include "base/logging.h" | 18 #include "base/logging.h" | 
| 19 #include "base/macros.h" | |
| 19 #include "base/rand_util.h" | 20 #include "base/rand_util.h" | 
| 20 #include "base/strings/string_split.h" | 21 #include "base/strings/string_split.h" | 
| 21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" | 
| 22 #include "components/nacl/common/nacl_host_messages.h" | 23 #include "components/nacl/common/nacl_host_messages.h" | 
| 23 #include "components/nacl/common/nacl_messages.h" | 24 #include "components/nacl/common/nacl_messages.h" | 
| 24 #include "components/nacl/common/nacl_nonsfi_util.h" | 25 #include "components/nacl/common/nacl_nonsfi_util.h" | 
| 25 #include "components/nacl/common/nacl_switches.h" | 26 #include "components/nacl/common/nacl_switches.h" | 
| 26 #include "components/nacl/common/nacl_types.h" | 27 #include "components/nacl/common/nacl_types.h" | 
| 27 #include "components/nacl/renderer/file_downloader.h" | 28 #include "components/nacl/renderer/file_downloader.h" | 
| 28 #include "components/nacl/renderer/histogram.h" | 29 #include "components/nacl/renderer/histogram.h" | 
| 29 #include "components/nacl/renderer/json_manifest.h" | 30 #include "components/nacl/renderer/json_manifest.h" | 
| 30 #include "components/nacl/renderer/manifest_downloader.h" | 31 #include "components/nacl/renderer/manifest_downloader.h" | 
| 31 #include "components/nacl/renderer/manifest_service_channel.h" | 32 #include "components/nacl/renderer/manifest_service_channel.h" | 
| 32 #include "components/nacl/renderer/nexe_load_manager.h" | 33 #include "components/nacl/renderer/nexe_load_manager.h" | 
| 33 #include "components/nacl/renderer/platform_info.h" | 34 #include "components/nacl/renderer/platform_info.h" | 
| 34 #include "components/nacl/renderer/pnacl_translation_resource_host.h" | 35 #include "components/nacl/renderer/pnacl_translation_resource_host.h" | 
| 35 #include "components/nacl/renderer/progress_event.h" | 36 #include "components/nacl/renderer/progress_event.h" | 
| 36 #include "components/nacl/renderer/trusted_plugin_channel.h" | 37 #include "components/nacl/renderer/trusted_plugin_channel.h" | 
| 37 #include "content/public/common/content_client.h" | 38 #include "content/public/common/content_client.h" | 
| 38 #include "content/public/common/content_switches.h" | 39 #include "content/public/common/content_switches.h" | 
| 39 #include "content/public/common/sandbox_init.h" | 40 #include "content/public/common/sandbox_init.h" | 
| 40 #include "content/public/renderer/pepper_plugin_instance.h" | 41 #include "content/public/renderer/pepper_plugin_instance.h" | 
| 41 #include "content/public/renderer/render_thread.h" | 42 #include "content/public/renderer/render_thread.h" | 
| 42 #include "content/public/renderer/render_view.h" | 43 #include "content/public/renderer/render_view.h" | 
| 43 #include "content/public/renderer/renderer_ppapi_host.h" | 44 #include "content/public/renderer/renderer_ppapi_host.h" | 
| 45 #include "ipc/ipc_message_attachment_set.h" | |
| 44 #include "native_client/src/public/imc_types.h" | 46 #include "native_client/src/public/imc_types.h" | 
| 45 #include "net/base/data_url.h" | 47 #include "net/base/data_url.h" | 
| 46 #include "net/base/net_errors.h" | 48 #include "net/base/net_errors.h" | 
| 47 #include "net/http/http_util.h" | 49 #include "net/http/http_util.h" | 
| 48 #include "ppapi/c/pp_bool.h" | 50 #include "ppapi/c/pp_bool.h" | 
| 49 #include "ppapi/c/private/pp_file_handle.h" | 51 #include "ppapi/c/private/pp_file_handle.h" | 
| 50 #include "ppapi/shared_impl/ppapi_globals.h" | 52 #include "ppapi/shared_impl/ppapi_globals.h" | 
| 51 #include "ppapi/shared_impl/ppapi_permissions.h" | 53 #include "ppapi/shared_impl/ppapi_permissions.h" | 
| 52 #include "ppapi/shared_impl/ppapi_preferences.h" | 54 #include "ppapi/shared_impl/ppapi_preferences.h" | 
| 53 #include "ppapi/shared_impl/var.h" | 55 #include "ppapi/shared_impl/var.h" | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 66 | 68 | 
| 67 namespace nacl { | 69 namespace nacl { | 
| 68 namespace { | 70 namespace { | 
| 69 | 71 | 
| 70 // The pseudo-architecture used to indicate portable native client. | 72 // The pseudo-architecture used to indicate portable native client. | 
| 71 const char* const kPortableArch = "portable"; | 73 const char* const kPortableArch = "portable"; | 
| 72 | 74 | 
| 73 // The base URL for resources used by the PNaCl translator processes. | 75 // The base URL for resources used by the PNaCl translator processes. | 
| 74 const char* kPNaClTranslatorBaseUrl = "chrome://pnacl-translator/"; | 76 const char* kPNaClTranslatorBaseUrl = "chrome://pnacl-translator/"; | 
| 75 | 77 | 
| 78 // The maximum number of resource files DownloadNexe() can open. | |
| 79 const size_t kMaxPreOpenResourceFiles = 2; | |
| 
Mark Seaborn
2015/02/12 03:57:34
How about adding a TODO to increase this, to docum
 
Yusuke Sato
2015/02/13 23:01:17
Done. Moved to nacl_host_message_filter.cc.
 | |
| 80 | |
| 81 #if defined(OS_POSIX) | |
| 82 // On POSIX platforms, the maximum number of files a process can pass to | |
| 83 // another is limited to kMaxDescriptorsPerMessage. Since the browser process | |
| 84 // may use up to 5 descriptors for passing non-resource files when creating | |
| 85 // the NaCl plugin process, kMaxPreOpenResourceFiles must be smaller than or | |
| 86 // equal to (IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage - 5). | |
| 87 COMPILE_ASSERT(kMaxPreOpenResourceFiles <= | |
| 
Mark Seaborn
2015/02/12 03:57:34
What would happen if we didn't have this check?
I
 
Yusuke Sato
2015/02/13 23:01:17
Ok, dropped.
 | |
| 88 IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage - 5, | |
| 89 k_max_pre_open_resource_files_too_large); | |
| 90 #endif | |
| 91 | |
| 76 base::LazyInstance<scoped_refptr<PnaclTranslationResourceHost> > | 92 base::LazyInstance<scoped_refptr<PnaclTranslationResourceHost> > | 
| 77 g_pnacl_resource_host = LAZY_INSTANCE_INITIALIZER; | 93 g_pnacl_resource_host = LAZY_INSTANCE_INITIALIZER; | 
| 78 | 94 | 
| 79 bool InitializePnaclResourceHost() { | 95 bool InitializePnaclResourceHost() { | 
| 80 // Must run on the main thread. | 96 // Must run on the main thread. | 
| 81 content::RenderThread* render_thread = content::RenderThread::Get(); | 97 content::RenderThread* render_thread = content::RenderThread::Get(); | 
| 82 if (!render_thread) | 98 if (!render_thread) | 
| 83 return false; | 99 return false; | 
| 84 if (!g_pnacl_resource_host.Get().get()) { | 100 if (!g_pnacl_resource_host.Get().get()) { | 
| 85 g_pnacl_resource_host.Get() = new PnaclTranslationResourceHost( | 101 g_pnacl_resource_host.Get() = new PnaclTranslationResourceHost( | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 97 ppapi::PpapiPermissions permissions; | 113 ppapi::PpapiPermissions permissions; | 
| 98 base::ProcessId plugin_pid; | 114 base::ProcessId plugin_pid; | 
| 99 int plugin_child_id; | 115 int plugin_child_id; | 
| 100 IPC::ChannelHandle channel_handle; | 116 IPC::ChannelHandle channel_handle; | 
| 101 }; | 117 }; | 
| 102 | 118 | 
| 103 class NaClPluginInstance { | 119 class NaClPluginInstance { | 
| 104 public: | 120 public: | 
| 105 NaClPluginInstance(PP_Instance instance): | 121 NaClPluginInstance(PP_Instance instance): | 
| 106 nexe_load_manager(instance), pexe_size(0) {} | 122 nexe_load_manager(instance), pexe_size(0) {} | 
| 123 ~NaClPluginInstance(); | |
| 107 | 124 | 
| 108 NexeLoadManager nexe_load_manager; | 125 NexeLoadManager nexe_load_manager; | 
| 109 scoped_ptr<JsonManifest> json_manifest; | 126 scoped_ptr<JsonManifest> json_manifest; | 
| 110 scoped_ptr<InstanceInfo> instance_info; | 127 scoped_ptr<InstanceInfo> instance_info; | 
| 128 std::vector<NaClResourceFileInfo> resource_files_info; | |
| 111 | 129 | 
| 112 // When translation is complete, this records the size of the pexe in | 130 // When translation is complete, this records the size of the pexe in | 
| 113 // bytes so that it can be reported in a later load event. | 131 // bytes so that it can be reported in a later load event. | 
| 114 uint64_t pexe_size; | 132 uint64_t pexe_size; | 
| 115 }; | 133 }; | 
| 116 | 134 | 
| 117 typedef base::ScopedPtrHashMap<PP_Instance, NaClPluginInstance> InstanceMap; | 135 typedef base::ScopedPtrHashMap<PP_Instance, NaClPluginInstance> InstanceMap; | 
| 118 base::LazyInstance<InstanceMap> g_instance_map = LAZY_INSTANCE_INITIALIZER; | 136 base::LazyInstance<InstanceMap> g_instance_map = LAZY_INSTANCE_INITIALIZER; | 
| 119 | 137 | 
| 138 NaClPluginInstance::~NaClPluginInstance() { | |
| 139 for (size_t i = 0; i < resource_files_info.size(); ++i) { | |
| 140 #if defined(OS_POSIX) | |
| 141 base::FileDescriptor fd(resource_files_info[i].file); | |
| 142 if (fd.auto_close) { | |
| 143 base::ScopedFD closer(ToNativeHandle(fd)); | |
| 144 } | |
| 145 #elif defined(OS_WIN) | |
| 146 // TOOD(yusukes): Implement once OS_WIN supports pre-opening resources. | |
| 147 #endif | |
| 148 } | |
| 149 } | |
| 150 | |
| 120 NaClPluginInstance* GetNaClPluginInstance(PP_Instance instance) { | 151 NaClPluginInstance* GetNaClPluginInstance(PP_Instance instance) { | 
| 121 InstanceMap& map = g_instance_map.Get(); | 152 InstanceMap& map = g_instance_map.Get(); | 
| 122 InstanceMap::iterator iter = map.find(instance); | 153 InstanceMap::iterator iter = map.find(instance); | 
| 123 if (iter == map.end()) | 154 if (iter == map.end()) | 
| 124 return NULL; | 155 return NULL; | 
| 125 return iter->second; | 156 return iter->second; | 
| 126 } | 157 } | 
| 127 | 158 | 
| 128 NexeLoadManager* GetNexeLoadManager(PP_Instance instance) { | 159 NexeLoadManager* GetNexeLoadManager(PP_Instance instance) { | 
| 129 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | 160 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | 
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 // must also check on the trusted side of the proxy. | 425 // must also check on the trusted side of the proxy. | 
| 395 if (load_manager->DevInterfacesEnabled()) | 426 if (load_manager->DevInterfacesEnabled()) | 
| 396 perm_bits |= ppapi::PERMISSION_DEV; | 427 perm_bits |= ppapi::PERMISSION_DEV; | 
| 397 instance_info.permissions = | 428 instance_info.permissions = | 
| 398 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); | 429 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); | 
| 399 std::string error_message_string; | 430 std::string error_message_string; | 
| 400 NaClLaunchResult launch_result; | 431 NaClLaunchResult launch_result; | 
| 401 | 432 | 
| 402 IPC::PlatformFileForTransit nexe_for_transit = | 433 IPC::PlatformFileForTransit nexe_for_transit = | 
| 403 IPC::InvalidPlatformFileForTransit(); | 434 IPC::InvalidPlatformFileForTransit(); | 
| 435 | |
| 436 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | |
| 404 #if defined(OS_POSIX) | 437 #if defined(OS_POSIX) | 
| 405 if (nexe_file_info->handle != PP_kInvalidFileHandle) | 438 if (nexe_file_info->handle != PP_kInvalidFileHandle) | 
| 406 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true); | 439 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true); | 
| 407 #elif defined(OS_WIN) | 440 #elif defined(OS_WIN) | 
| 408 // Duplicate the handle on the browser side instead of the renderer. | 441 // Duplicate the handle on the browser side instead of the renderer. | 
| 409 // This is because BrokerGetFileForProcess isn't part of content/public, and | 442 // This is because BrokerGetFileForProcess isn't part of content/public, and | 
| 410 // it's simpler to do the duplication in the browser anyway. | 443 // it's simpler to do the duplication in the browser anyway. | 
| 411 nexe_for_transit = nexe_file_info->handle; | 444 nexe_for_transit = nexe_file_info->handle; | 
| 445 // TODO(yusukes): Support pre-opening resource files on Windows. | |
| 412 #else | 446 #else | 
| 413 #error Unsupported target platform. | 447 #error Unsupported target platform. | 
| 414 #endif | 448 #endif | 
| 415 if (!sender->Send(new NaClHostMsg_LaunchNaCl( | 449 if (!sender->Send(new NaClHostMsg_LaunchNaCl( | 
| 416 NaClLaunchParams( | 450 NaClLaunchParams( | 
| 417 instance_info.url.spec(), | 451 instance_info.url.spec(), | 
| 418 nexe_for_transit, | 452 nexe_for_transit, | 
| 419 nexe_file_info->token_lo, | 453 nexe_file_info->token_lo, | 
| 420 nexe_file_info->token_hi, | 454 nexe_file_info->token_hi, | 
| 455 nacl_plugin_instance->resource_files_info, | |
| 421 routing_id, | 456 routing_id, | 
| 422 perm_bits, | 457 perm_bits, | 
| 423 PP_ToBool(uses_nonsfi_mode), | 458 PP_ToBool(uses_nonsfi_mode), | 
| 424 process_type), | 459 process_type), | 
| 425 &launch_result, | 460 &launch_result, | 
| 426 &error_message_string))) { | 461 &error_message_string))) { | 
| 427 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 462 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 
| 428 FROM_HERE, | 463 FROM_HERE, | 
| 429 base::Bind(callback.func, callback.user_data, | 464 base::Bind(callback.func, callback.user_data, | 
| 430 static_cast<int32_t>(PP_ERROR_FAILED))); | 465 static_cast<int32_t>(PP_ERROR_FAILED))); | 
| 466 nacl_plugin_instance->resource_files_info.clear(); | |
| 431 return; | 467 return; | 
| 432 } | 468 } | 
| 433 | 469 | 
| 470 nacl_plugin_instance->resource_files_info.clear(); | |
| 434 load_manager->set_nonsfi(PP_ToBool(uses_nonsfi_mode)); | 471 load_manager->set_nonsfi(PP_ToBool(uses_nonsfi_mode)); | 
| 435 | 472 | 
| 436 if (!error_message_string.empty()) { | 473 if (!error_message_string.empty()) { | 
| 437 if (PP_ToBool(main_service_runtime)) { | 474 if (PP_ToBool(main_service_runtime)) { | 
| 438 load_manager->ReportLoadError(PP_NACL_ERROR_SEL_LDR_LAUNCH, | 475 load_manager->ReportLoadError(PP_NACL_ERROR_SEL_LDR_LAUNCH, | 
| 439 "ServiceRuntime: failed to start", | 476 "ServiceRuntime: failed to start", | 
| 440 error_message_string); | 477 error_message_string); | 
| 441 } | 478 } | 
| 442 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 479 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 
| 443 FROM_HERE, | 480 FROM_HERE, | 
| 444 base::Bind(callback.func, callback.user_data, | 481 base::Bind(callback.func, callback.user_data, | 
| 445 static_cast<int32_t>(PP_ERROR_FAILED))); | 482 static_cast<int32_t>(PP_ERROR_FAILED))); | 
| 446 return; | 483 return; | 
| 447 } | 484 } | 
| 448 result_socket = launch_result.imc_channel_handle; | 485 result_socket = launch_result.imc_channel_handle; | 
| 449 instance_info.channel_handle = launch_result.ppapi_ipc_channel_handle; | 486 instance_info.channel_handle = launch_result.ppapi_ipc_channel_handle; | 
| 450 instance_info.plugin_pid = launch_result.plugin_pid; | 487 instance_info.plugin_pid = launch_result.plugin_pid; | 
| 451 instance_info.plugin_child_id = launch_result.plugin_child_id; | 488 instance_info.plugin_child_id = launch_result.plugin_child_id; | 
| 452 | 489 | 
| 453 // Don't save instance_info if channel handle is invalid. | 490 // Don't save instance_info if channel handle is invalid. | 
| 454 if (IsValidChannelHandle(instance_info.channel_handle)) { | 491 if (IsValidChannelHandle(instance_info.channel_handle)) | 
| 455 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | |
| 456 nacl_plugin_instance->instance_info.reset(new InstanceInfo(instance_info)); | 492 nacl_plugin_instance->instance_info.reset(new InstanceInfo(instance_info)); | 
| 457 } | |
| 458 | 493 | 
| 459 *(static_cast<NaClHandle*>(imc_handle)) = ToNativeHandle(result_socket); | 494 *(static_cast<NaClHandle*>(imc_handle)) = ToNativeHandle(result_socket); | 
| 460 | 495 | 
| 461 // Store the crash information shared memory handle. | 496 // Store the crash information shared memory handle. | 
| 462 load_manager->set_crash_info_shmem_handle( | 497 load_manager->set_crash_info_shmem_handle( | 
| 463 launch_result.crash_info_shmem_handle); | 498 launch_result.crash_info_shmem_handle); | 
| 464 | 499 | 
| 465 // Create the trusted plugin channel. | 500 // Create the trusted plugin channel. | 
| 466 if (IsValidChannelHandle(launch_result.trusted_ipc_channel_handle)) { | 501 if (IsValidChannelHandle(launch_result.trusted_ipc_channel_handle)) { | 
| 467 bool report_exit_status = PP_ToBool(main_service_runtime); | 502 bool report_exit_status = PP_ToBool(main_service_runtime); | 
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 replace_pos = r.find_first_not_of(white_list); | 611 replace_pos = r.find_first_not_of(white_list); | 
| 577 } | 612 } | 
| 578 return r; | 613 return r; | 
| 579 } | 614 } | 
| 580 | 615 | 
| 581 PP_FileHandle GetReadonlyPnaclFd(const char* url, | 616 PP_FileHandle GetReadonlyPnaclFd(const char* url, | 
| 582 bool is_executable, | 617 bool is_executable, | 
| 583 uint64_t* nonce_lo, | 618 uint64_t* nonce_lo, | 
| 584 uint64_t* nonce_hi) { | 619 uint64_t* nonce_hi) { | 
| 585 std::string filename = PnaclComponentURLToFilename(url); | 620 std::string filename = PnaclComponentURLToFilename(url); | 
| 586 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); | 621 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); | 
| 
Yusuke Sato
2015/02/11 05:54:21
reverted to the original code.
 | |
| 587 IPC::Sender* sender = content::RenderThread::Get(); | 622 IPC::Sender* sender = content::RenderThread::Get(); | 
| 623 NaClResourceFileInfo file_info; | |
| 
Mark Seaborn
2015/02/12 03:57:34
Not used now?
 
Yusuke Sato
2015/02/13 23:01:17
Done.
 | |
| 588 DCHECK(sender); | 624 DCHECK(sender); | 
| 589 if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD( | 625 if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD( | 
| 590 std::string(filename), is_executable, | 626 std::string(filename), is_executable, | 
| 591 &out_fd, nonce_lo, nonce_hi))) { | 627 &out_fd, nonce_lo, nonce_hi))) { | 
| 592 return PP_kInvalidFileHandle; | 628 return PP_kInvalidFileHandle; | 
| 593 } | 629 } | 
| 594 if (out_fd == IPC::InvalidPlatformFileForTransit()) { | 630 if (out_fd == IPC::InvalidPlatformFileForTransit()) { | 
| 595 return PP_kInvalidFileHandle; | 631 return PP_kInvalidFileHandle; | 
| 596 } | 632 } | 
| 597 return IPC::PlatformFileForTransitToPlatformFile(out_fd); | 633 return IPC::PlatformFileForTransitToPlatformFile(out_fd); | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 700 return; | 736 return; | 
| 701 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success); | 737 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success); | 
| 702 | 738 | 
| 703 // Record the pexe size for reporting in a later load event. | 739 // Record the pexe size for reporting in a later load event. | 
| 704 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | 740 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | 
| 705 if (nacl_plugin_instance) { | 741 if (nacl_plugin_instance) { | 
| 706 nacl_plugin_instance->pexe_size = pexe_size; | 742 nacl_plugin_instance->pexe_size = pexe_size; | 
| 707 } | 743 } | 
| 708 } | 744 } | 
| 709 | 745 | 
| 710 PP_FileHandle OpenNaClExecutable(PP_Instance instance, | 746 bool OpenNaClResources( | 
| 711 const char* file_url, | 747 PP_Instance instance, | 
| 712 uint64_t* nonce_lo, | 748 const std::vector<std::string>& resource_file_urls, | 
| 713 uint64_t* nonce_hi) { | 749 std::vector<NaClResourceFileInfo>* out_resource_file_handles) { | 
| 714 // Fast path only works for installed file URLs. | 750 DCHECK(out_resource_file_handles); | 
| 715 GURL gurl(file_url); | 751 if (resource_file_urls.empty()) | 
| 716 if (!gurl.SchemeIs("chrome-extension")) | 752 return false; | 
| 717 return PP_kInvalidFileHandle; | |
| 718 | 753 | 
| 719 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 754 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 
| 720 DCHECK(load_manager); | 755 DCHECK(load_manager); | 
| 721 if (!load_manager) | 756 if (!load_manager) | 
| 722 return PP_kInvalidFileHandle; | 757 return PP_kInvalidFileHandle; | 
| 723 | 758 | 
| 724 content::PepperPluginInstance* plugin_instance = | 759 content::PepperPluginInstance* plugin_instance = | 
| 725 content::PepperPluginInstance::Get(instance); | 760 content::PepperPluginInstance::Get(instance); | 
| 726 if (!plugin_instance) | 761 if (!plugin_instance) | 
| 727 return PP_kInvalidFileHandle; | 762 return false; | 
| 728 // IMPORTANT: Make sure the document can request the given URL. If we don't | |
| 729 // check, a malicious app could probe the extension system. This enforces a | |
| 730 // same-origin policy which prevents the app from requesting resources from | |
| 731 // another app. | |
| 732 blink::WebSecurityOrigin security_origin = | 763 blink::WebSecurityOrigin security_origin = | 
| 733 plugin_instance->GetContainer()->element().document().securityOrigin(); | 764 plugin_instance->GetContainer()->element().document().securityOrigin(); | 
| 734 if (!security_origin.canRequest(gurl)) | |
| 735 return PP_kInvalidFileHandle; | |
| 736 | |
| 737 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); | |
| 738 IPC::Sender* sender = content::RenderThread::Get(); | 765 IPC::Sender* sender = content::RenderThread::Get(); | 
| 739 DCHECK(sender); | 766 DCHECK(sender); | 
| 740 *nonce_lo = 0; | 767 | 
| 741 *nonce_hi = 0; | 768 std::vector<GURL> resource_gurls; | 
| 742 base::FilePath file_path; | 769 for (size_t i = 0; i < resource_file_urls.size(); ++i) { | 
| 743 if (!sender->Send( | 770 const GURL gurl(resource_file_urls[i]); | 
| 744 new NaClHostMsg_OpenNaClExecutable(GetRoutingID(instance), | 771 // Fast path only works for installed file URLs. | 
| 745 GURL(file_url), | 772 if (!gurl.SchemeIs("chrome-extension")) | 
| 746 !load_manager->nonsfi(), | 773 return false; | 
| 747 &out_fd, | 774 // IMPORTANT: Make sure the document can request the given URL. If we don't | 
| 748 nonce_lo, | 775 // check, a malicious app could probe the extension system. This enforces a | 
| 749 nonce_hi))) { | 776 // same-origin policy which prevents the app from requesting resources from | 
| 750 return PP_kInvalidFileHandle; | 777 // another app. | 
| 778 if (!security_origin.canRequest(gurl)) | |
| 779 return false; | |
| 780 resource_gurls.push_back(gurl); | |
| 751 } | 781 } | 
| 752 | 782 | 
| 753 if (out_fd == IPC::InvalidPlatformFileForTransit()) | 783 if (!sender->Send(new NaClHostMsg_OpenNaClResources( | 
| 754 return PP_kInvalidFileHandle; | 784 GetRoutingID(instance), | 
| 785 resource_gurls, | |
| 786 !load_manager->nonsfi(), | |
| 787 out_resource_file_handles))) { | |
| 788 return false; | |
| 789 } | |
| 755 | 790 | 
| 756 return IPC::PlatformFileForTransitToPlatformFile(out_fd); | 791 if (out_resource_file_handles->empty() || | 
| 792 (out_resource_file_handles->at(0).file == | |
| 793 IPC::InvalidPlatformFileForTransit())) { | |
| 794 DLOG(ERROR) << "Could not open the main nexe: " << resource_gurls[0]; | |
| 
Mark Seaborn
2015/02/12 03:57:34
I don't think you need this special-cased check.
 
Yusuke Sato
2015/02/13 23:01:17
Done, removed
 | |
| 795 return false; | |
| 796 } | |
| 797 return true; | |
| 757 } | 798 } | 
| 758 | 799 | 
| 759 void DispatchEvent(PP_Instance instance, | 800 void DispatchEvent(PP_Instance instance, | 
| 760 PP_NaClEventType event_type, | 801 PP_NaClEventType event_type, | 
| 761 const char* resource_url, | 802 const char* resource_url, | 
| 762 PP_Bool length_is_computable, | 803 PP_Bool length_is_computable, | 
| 763 uint64_t loaded_bytes, | 804 uint64_t loaded_bytes, | 
| 764 uint64_t total_bytes) { | 805 uint64_t total_bytes) { | 
| 765 ProgressEvent event(event_type, | 806 ProgressEvent event(event_type, | 
| 766 resource_url, | 807 resource_url, | 
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1204 }; | 1245 }; | 
| 1205 | 1246 | 
| 1206 void DownloadNexeCompletion(const DownloadNexeRequest& request, | 1247 void DownloadNexeCompletion(const DownloadNexeRequest& request, | 
| 1207 PP_NaClFileInfo* out_file_info, | 1248 PP_NaClFileInfo* out_file_info, | 
| 1208 FileDownloader::Status status, | 1249 FileDownloader::Status status, | 
| 1209 base::File target_file, | 1250 base::File target_file, | 
| 1210 int http_status); | 1251 int http_status); | 
| 1211 | 1252 | 
| 1212 void DownloadNexe(PP_Instance instance, | 1253 void DownloadNexe(PP_Instance instance, | 
| 1213 const char* url, | 1254 const char* url, | 
| 1255 PP_Bool download_resource_files, | |
| 1214 PP_NaClFileInfo* out_file_info, | 1256 PP_NaClFileInfo* out_file_info, | 
| 1215 PP_CompletionCallback callback) { | 1257 PP_CompletionCallback callback) { | 
| 1216 CHECK(url); | 1258 CHECK(url); | 
| 1217 CHECK(out_file_info); | 1259 CHECK(out_file_info); | 
| 1218 DownloadNexeRequest request; | 1260 DownloadNexeRequest request; | 
| 1219 request.instance = instance; | 1261 request.instance = instance; | 
| 1220 request.url = url; | 1262 request.url = url; | 
| 1221 request.callback = callback; | 1263 request.callback = callback; | 
| 1222 request.start_time = base::Time::Now(); | 1264 request.start_time = base::Time::Now(); | 
| 1223 | 1265 | 
| 1266 std::vector<std::string> file_urls; | |
| 1267 file_urls.push_back(url); // the main nexe must be the first element. | |
| 1268 | |
| 1269 std::vector< | |
| 1270 std::pair<std::string /*url*/, std::string /*key*/> > resource_files; | |
| 1271 if (download_resource_files) { | |
| 1272 JsonManifest* manifest = GetJsonManifest(instance); | |
| 1273 if (manifest) | |
| 1274 manifest->GetFiles(&resource_files, "chrome-extension"); | |
| 1275 if (resource_files.size() > kMaxPreOpenResourceFiles) | |
| 1276 resource_files.resize(kMaxPreOpenResourceFiles); | |
| 1277 for (size_t i = 0; i < resource_files.size(); ++i) { | |
| 1278 file_urls.push_back(resource_files[i].first); | |
| 1279 } | |
| 1280 } | |
| 1281 | |
| 1224 // Try the fast path for retrieving the file first. | 1282 // Try the fast path for retrieving the file first. | 
| 1225 PP_FileHandle handle = OpenNaClExecutable(instance, | 1283 std::vector<NaClResourceFileInfo> file_handles; | 
| 1226 url, | 1284 if (OpenNaClResources(instance, file_urls, &file_handles)) { | 
| 1227 &out_file_info->token_lo, | 1285 DCHECK(!file_handles.empty()); | 
| 1228 &out_file_info->token_hi); | 1286 out_file_info->handle = | 
| 1229 if (handle != PP_kInvalidFileHandle) { | 1287 IPC::PlatformFileForTransitToPlatformFile(file_handles[0].file); | 
| 1288 out_file_info->token_lo = file_handles[0].file_token_lo; | |
| 1289 out_file_info->token_hi = file_handles[0].file_token_hi; | |
| 1290 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | |
| 1291 for (size_t i = 1; i < file_handles.size(); ++i) { | |
| 1292 std::string key = resource_files[i - 1].second; | |
| 1293 nacl_plugin_instance->resource_files_info.push_back( | |
| 1294 NaClResourceFileInfo(file_handles[i].file, | |
| 1295 file_handles[i].file_token_lo, | |
| 1296 file_handles[i].file_token_hi, | |
| 1297 key)); | |
| 1298 } | |
| 1230 DownloadNexeCompletion(request, | 1299 DownloadNexeCompletion(request, | 
| 1231 out_file_info, | 1300 out_file_info, | 
| 1232 FileDownloader::SUCCESS, | 1301 FileDownloader::SUCCESS, | 
| 1233 base::File(handle), | 1302 base::File(out_file_info->handle), | 
| 1234 200); | 1303 200); | 
| 1235 return; | 1304 return; | 
| 1236 } | 1305 } | 
| 1237 | 1306 | 
| 1238 // The fast path didn't work, we'll fetch the file using URLLoader and write | 1307 // The fast path didn't work, we'll fetch the file using URLLoader and write | 
| 1239 // it to local storage. | 1308 // it to local storage. | 
| 1240 base::File target_file(CreateTemporaryFile(instance)); | 1309 base::File target_file(CreateTemporaryFile(instance)); | 
| 1241 GURL gurl(url); | 1310 GURL gurl(url); | 
| 1242 | 1311 | 
| 1312 // On the slow path, do not retry to pre-open the resource files. | |
| 1243 content::PepperPluginInstance* plugin_instance = | 1313 content::PepperPluginInstance* plugin_instance = | 
| 1244 content::PepperPluginInstance::Get(instance); | 1314 content::PepperPluginInstance::Get(instance); | 
| 1245 if (!plugin_instance) { | 1315 if (!plugin_instance) { | 
| 1246 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 1316 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 
| 1247 FROM_HERE, | 1317 FROM_HERE, | 
| 1248 base::Bind(callback.func, callback.user_data, | 1318 base::Bind(callback.func, callback.user_data, | 
| 1249 static_cast<int32_t>(PP_ERROR_FAILED))); | 1319 static_cast<int32_t>(PP_ERROR_FAILED))); | 
| 1250 } | 1320 } | 
| 1251 const blink::WebDocument& document = | 1321 const blink::WebDocument& document = | 
| 1252 plugin_instance->GetContainer()->element().document(); | 1322 plugin_instance->GetContainer()->element().document(); | 
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1368 if (!test_gurl.is_valid()) { | 1438 if (!test_gurl.is_valid()) { | 
| 1369 base::MessageLoop::current()->PostTask( | 1439 base::MessageLoop::current()->PostTask( | 
| 1370 FROM_HERE, | 1440 FROM_HERE, | 
| 1371 base::Bind(callback, | 1441 base::Bind(callback, | 
| 1372 static_cast<int32_t>(PP_ERROR_FAILED), | 1442 static_cast<int32_t>(PP_ERROR_FAILED), | 
| 1373 kInvalidNaClFileInfo)); | 1443 kInvalidNaClFileInfo)); | 
| 1374 return; | 1444 return; | 
| 1375 } | 1445 } | 
| 1376 | 1446 | 
| 1377 // Try the fast path for retrieving the file first. | 1447 // Try the fast path for retrieving the file first. | 
| 1378 uint64_t file_token_lo = 0; | 1448 std::vector<std::string> file_urls; | 
| 1379 uint64_t file_token_hi = 0; | 1449 file_urls.push_back(url); | 
| 1380 PP_FileHandle file_handle = OpenNaClExecutable(instance, | 1450 std::vector<NaClResourceFileInfo> out_handles; | 
| 1381 url.c_str(), | 1451 if (OpenNaClResources(instance, file_urls, &out_handles)) { | 
| 1382 &file_token_lo, | |
| 1383 &file_token_hi); | |
| 1384 if (file_handle != PP_kInvalidFileHandle) { | |
| 1385 PP_NaClFileInfo file_info; | 1452 PP_NaClFileInfo file_info; | 
| 1386 file_info.handle = file_handle; | 1453 file_info.handle = | 
| 1387 file_info.token_lo = file_token_lo; | 1454 IPC::PlatformFileForTransitToPlatformFile(out_handles[0].file); | 
| 1388 file_info.token_hi = file_token_hi; | 1455 file_info.token_lo = out_handles[0].file_token_lo; | 
| 1456 file_info.token_hi = out_handles[0].file_token_hi; | |
| 1389 base::MessageLoop::current()->PostTask( | 1457 base::MessageLoop::current()->PostTask( | 
| 1390 FROM_HERE, | 1458 FROM_HERE, | 
| 1391 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info)); | 1459 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info)); | 
| 1392 return; | 1460 return; | 
| 1393 } | 1461 } | 
| 1394 | 1462 | 
| 1395 // The fast path didn't work, we'll fetch the file using URLLoader and write | 1463 // The fast path didn't work, we'll fetch the file using URLLoader and write | 
| 1396 // it to local storage. | 1464 // it to local storage. | 
| 1397 base::File target_file(CreateTemporaryFile(instance)); | 1465 base::File target_file(CreateTemporaryFile(instance)); | 
| 1398 GURL gurl(url); | 1466 GURL gurl(url); | 
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1651 &StreamPexe | 1719 &StreamPexe | 
| 1652 }; | 1720 }; | 
| 1653 | 1721 | 
| 1654 } // namespace | 1722 } // namespace | 
| 1655 | 1723 | 
| 1656 const PPB_NaCl_Private* GetNaClPrivateInterface() { | 1724 const PPB_NaCl_Private* GetNaClPrivateInterface() { | 
| 1657 return &nacl_interface; | 1725 return &nacl_interface; | 
| 1658 } | 1726 } | 
| 1659 | 1727 | 
| 1660 } // namespace nacl | 1728 } // namespace nacl | 
| OLD | NEW |