Chromium Code Reviews| 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/09 04:48:34
Why so low? I thought your aim was to pass more t
Yusuke Sato
2015/02/11 05:54:21
This is currently 2 because kMaxDescriptorsPerMess
Mark Seaborn
2015/02/12 03:57:33
OK, so the test is still covering the fast path.
Yusuke Sato
2015/02/13 23:01:16
Done.
| |
| 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 <= | |
| 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 15 matching lines...) Expand all Loading... | |
| 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) {} |
| 107 | 123 |
| 108 NexeLoadManager nexe_load_manager; | 124 NexeLoadManager nexe_load_manager; |
| 109 scoped_ptr<JsonManifest> json_manifest; | 125 scoped_ptr<JsonManifest> json_manifest; |
| 110 scoped_ptr<InstanceInfo> instance_info; | 126 scoped_ptr<InstanceInfo> instance_info; |
| 127 std::vector<NaClLaunchParams::ResourceFileInfo> resource_files_info; | |
|
Mark Seaborn
2015/02/09 04:48:34
If I read this right, NaClLaunchParams::ResourceFi
Yusuke Sato
2015/02/11 05:54:21
You're right. The IPC::PlatformFileForTransit hand
| |
| 111 | 128 |
| 112 // When translation is complete, this records the size of the pexe in | 129 // 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. | 130 // bytes so that it can be reported in a later load event. |
| 114 uint64_t pexe_size; | 131 uint64_t pexe_size; |
| 115 }; | 132 }; |
| 116 | 133 |
| 117 typedef base::ScopedPtrHashMap<PP_Instance, NaClPluginInstance> InstanceMap; | 134 typedef base::ScopedPtrHashMap<PP_Instance, NaClPluginInstance> InstanceMap; |
| 118 base::LazyInstance<InstanceMap> g_instance_map = LAZY_INSTANCE_INITIALIZER; | 135 base::LazyInstance<InstanceMap> g_instance_map = LAZY_INSTANCE_INITIALIZER; |
| 119 | 136 |
| 120 NaClPluginInstance* GetNaClPluginInstance(PP_Instance instance) { | 137 NaClPluginInstance* GetNaClPluginInstance(PP_Instance instance) { |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 // must also check on the trusted side of the proxy. | 411 // must also check on the trusted side of the proxy. |
| 395 if (load_manager->DevInterfacesEnabled()) | 412 if (load_manager->DevInterfacesEnabled()) |
| 396 perm_bits |= ppapi::PERMISSION_DEV; | 413 perm_bits |= ppapi::PERMISSION_DEV; |
| 397 instance_info.permissions = | 414 instance_info.permissions = |
| 398 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); | 415 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); |
| 399 std::string error_message_string; | 416 std::string error_message_string; |
| 400 NaClLaunchResult launch_result; | 417 NaClLaunchResult launch_result; |
| 401 | 418 |
| 402 IPC::PlatformFileForTransit nexe_for_transit = | 419 IPC::PlatformFileForTransit nexe_for_transit = |
| 403 IPC::InvalidPlatformFileForTransit(); | 420 IPC::InvalidPlatformFileForTransit(); |
| 421 | |
| 422 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | |
| 404 #if defined(OS_POSIX) | 423 #if defined(OS_POSIX) |
| 405 if (nexe_file_info->handle != PP_kInvalidFileHandle) | 424 if (nexe_file_info->handle != PP_kInvalidFileHandle) |
| 406 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true); | 425 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true); |
| 426 const std::vector<NaClLaunchParams::ResourceFileInfo>& resource_files_info = | |
| 427 nacl_plugin_instance->resource_files_info; | |
|
Mark Seaborn
2015/02/09 04:48:34
Shouldn't nacl_plugin_instance->resource_files_inf
Yusuke Sato
2015/02/11 05:54:21
Done.
| |
| 407 #elif defined(OS_WIN) | 428 #elif defined(OS_WIN) |
| 408 // Duplicate the handle on the browser side instead of the renderer. | 429 // Duplicate the handle on the browser side instead of the renderer. |
| 409 // This is because BrokerGetFileForProcess isn't part of content/public, and | 430 // This is because BrokerGetFileForProcess isn't part of content/public, and |
| 410 // it's simpler to do the duplication in the browser anyway. | 431 // it's simpler to do the duplication in the browser anyway. |
| 411 nexe_for_transit = nexe_file_info->handle; | 432 nexe_for_transit = nexe_file_info->handle; |
| 433 // TODO(yusukes): Support pre-opening resource files. | |
|
Mark Seaborn
2015/02/09 04:48:34
Add "on Windows"?
Yusuke Sato
2015/02/11 05:54:21
Done.
| |
| 434 std::vector<NaClLaunchParams::ResourceFileInfo> resource_files_info; // empty | |
| 412 #else | 435 #else |
| 413 #error Unsupported target platform. | 436 #error Unsupported target platform. |
| 414 #endif | 437 #endif |
| 415 if (!sender->Send(new NaClHostMsg_LaunchNaCl( | 438 if (!sender->Send(new NaClHostMsg_LaunchNaCl( |
| 416 NaClLaunchParams( | 439 NaClLaunchParams( |
| 417 instance_info.url.spec(), | 440 instance_info.url.spec(), |
| 418 nexe_for_transit, | 441 nexe_for_transit, |
| 419 nexe_file_info->token_lo, | 442 nexe_file_info->token_lo, |
| 420 nexe_file_info->token_hi, | 443 nexe_file_info->token_hi, |
| 444 resource_files_info, | |
| 421 routing_id, | 445 routing_id, |
| 422 perm_bits, | 446 perm_bits, |
| 423 PP_ToBool(uses_nonsfi_mode), | 447 PP_ToBool(uses_nonsfi_mode), |
| 424 process_type), | 448 process_type), |
| 425 &launch_result, | 449 &launch_result, |
| 426 &error_message_string))) { | 450 &error_message_string))) { |
| 427 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 451 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 428 FROM_HERE, | 452 FROM_HERE, |
| 429 base::Bind(callback.func, callback.user_data, | 453 base::Bind(callback.func, callback.user_data, |
| 430 static_cast<int32_t>(PP_ERROR_FAILED))); | 454 static_cast<int32_t>(PP_ERROR_FAILED))); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 444 base::Bind(callback.func, callback.user_data, | 468 base::Bind(callback.func, callback.user_data, |
| 445 static_cast<int32_t>(PP_ERROR_FAILED))); | 469 static_cast<int32_t>(PP_ERROR_FAILED))); |
| 446 return; | 470 return; |
| 447 } | 471 } |
| 448 result_socket = launch_result.imc_channel_handle; | 472 result_socket = launch_result.imc_channel_handle; |
| 449 instance_info.channel_handle = launch_result.ppapi_ipc_channel_handle; | 473 instance_info.channel_handle = launch_result.ppapi_ipc_channel_handle; |
| 450 instance_info.plugin_pid = launch_result.plugin_pid; | 474 instance_info.plugin_pid = launch_result.plugin_pid; |
| 451 instance_info.plugin_child_id = launch_result.plugin_child_id; | 475 instance_info.plugin_child_id = launch_result.plugin_child_id; |
| 452 | 476 |
| 453 // Don't save instance_info if channel handle is invalid. | 477 // Don't save instance_info if channel handle is invalid. |
| 454 if (IsValidChannelHandle(instance_info.channel_handle)) { | 478 if (IsValidChannelHandle(instance_info.channel_handle)) |
| 455 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | |
| 456 nacl_plugin_instance->instance_info.reset(new InstanceInfo(instance_info)); | 479 nacl_plugin_instance->instance_info.reset(new InstanceInfo(instance_info)); |
| 457 } | |
| 458 | 480 |
| 459 *(static_cast<NaClHandle*>(imc_handle)) = ToNativeHandle(result_socket); | 481 *(static_cast<NaClHandle*>(imc_handle)) = ToNativeHandle(result_socket); |
| 460 | 482 |
| 461 // Store the crash information shared memory handle. | 483 // Store the crash information shared memory handle. |
| 462 load_manager->set_crash_info_shmem_handle( | 484 load_manager->set_crash_info_shmem_handle( |
| 463 launch_result.crash_info_shmem_handle); | 485 launch_result.crash_info_shmem_handle); |
| 464 | 486 |
| 465 // Create the trusted plugin channel. | 487 // Create the trusted plugin channel. |
| 466 if (IsValidChannelHandle(launch_result.trusted_ipc_channel_handle)) { | 488 if (IsValidChannelHandle(launch_result.trusted_ipc_channel_handle)) { |
| 467 bool report_exit_status = PP_ToBool(main_service_runtime); | 489 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); | 598 replace_pos = r.find_first_not_of(white_list); |
| 577 } | 599 } |
| 578 return r; | 600 return r; |
| 579 } | 601 } |
| 580 | 602 |
| 581 PP_FileHandle GetReadonlyPnaclFd(const char* url, | 603 PP_FileHandle GetReadonlyPnaclFd(const char* url, |
| 582 bool is_executable, | 604 bool is_executable, |
| 583 uint64_t* nonce_lo, | 605 uint64_t* nonce_lo, |
| 584 uint64_t* nonce_hi) { | 606 uint64_t* nonce_hi) { |
| 585 std::string filename = PnaclComponentURLToFilename(url); | 607 std::string filename = PnaclComponentURLToFilename(url); |
| 586 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); | |
| 587 IPC::Sender* sender = content::RenderThread::Get(); | 608 IPC::Sender* sender = content::RenderThread::Get(); |
| 609 NaClFileInfo file_info; | |
| 588 DCHECK(sender); | 610 DCHECK(sender); |
| 589 if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD( | 611 if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD( |
| 590 std::string(filename), is_executable, | 612 std::string(filename), is_executable, &file_info))) { |
| 591 &out_fd, nonce_lo, nonce_hi))) { | |
| 592 return PP_kInvalidFileHandle; | 613 return PP_kInvalidFileHandle; |
| 593 } | 614 } |
| 594 if (out_fd == IPC::InvalidPlatformFileForTransit()) { | 615 if (file_info.file == IPC::InvalidPlatformFileForTransit()) { |
| 595 return PP_kInvalidFileHandle; | 616 return PP_kInvalidFileHandle; |
| 596 } | 617 } |
| 597 return IPC::PlatformFileForTransitToPlatformFile(out_fd); | 618 *nonce_lo = file_info.file_token_lo; |
| 619 *nonce_hi = file_info.file_token_hi; | |
| 620 return IPC::PlatformFileForTransitToPlatformFile(file_info.file); | |
| 598 } | 621 } |
| 599 | 622 |
| 600 void GetReadExecPnaclFd(const char* url, | 623 void GetReadExecPnaclFd(const char* url, |
| 601 PP_NaClFileInfo* out_file_info) { | 624 PP_NaClFileInfo* out_file_info) { |
| 602 *out_file_info = kInvalidNaClFileInfo; | 625 *out_file_info = kInvalidNaClFileInfo; |
| 603 out_file_info->handle = GetReadonlyPnaclFd(url, true /* is_executable */, | 626 out_file_info->handle = GetReadonlyPnaclFd(url, true /* is_executable */, |
| 604 &out_file_info->token_lo, | 627 &out_file_info->token_lo, |
| 605 &out_file_info->token_hi); | 628 &out_file_info->token_hi); |
| 606 } | 629 } |
| 607 | 630 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 700 return; | 723 return; |
| 701 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success); | 724 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success); |
| 702 | 725 |
| 703 // Record the pexe size for reporting in a later load event. | 726 // Record the pexe size for reporting in a later load event. |
| 704 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | 727 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); |
| 705 if (nacl_plugin_instance) { | 728 if (nacl_plugin_instance) { |
| 706 nacl_plugin_instance->pexe_size = pexe_size; | 729 nacl_plugin_instance->pexe_size = pexe_size; |
| 707 } | 730 } |
| 708 } | 731 } |
| 709 | 732 |
| 710 PP_FileHandle OpenNaClExecutable(PP_Instance instance, | 733 bool OpenNaClResources( |
| 711 const char* file_url, | 734 PP_Instance instance, |
| 712 uint64_t* nonce_lo, | 735 const std::vector<std::string>& resource_file_urls, |
| 713 uint64_t* nonce_hi) { | 736 std::vector<NaClFileInfo>* out_resource_file_handles) { |
| 714 // Fast path only works for installed file URLs. | 737 DCHECK(out_resource_file_handles); |
| 715 GURL gurl(file_url); | 738 if (resource_file_urls.empty()) |
| 716 if (!gurl.SchemeIs("chrome-extension")) | 739 return false; |
| 717 return PP_kInvalidFileHandle; | |
| 718 | 740 |
| 719 NexeLoadManager* load_manager = GetNexeLoadManager(instance); | 741 NexeLoadManager* load_manager = GetNexeLoadManager(instance); |
| 720 DCHECK(load_manager); | 742 DCHECK(load_manager); |
| 721 if (!load_manager) | 743 if (!load_manager) |
| 722 return PP_kInvalidFileHandle; | 744 return PP_kInvalidFileHandle; |
| 723 | 745 |
| 724 content::PepperPluginInstance* plugin_instance = | 746 content::PepperPluginInstance* plugin_instance = |
| 725 content::PepperPluginInstance::Get(instance); | 747 content::PepperPluginInstance::Get(instance); |
| 726 if (!plugin_instance) | 748 if (!plugin_instance) |
| 727 return PP_kInvalidFileHandle; | 749 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 = | 750 blink::WebSecurityOrigin security_origin = |
| 733 plugin_instance->GetContainer()->element().document().securityOrigin(); | 751 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(); | 752 IPC::Sender* sender = content::RenderThread::Get(); |
| 739 DCHECK(sender); | 753 DCHECK(sender); |
| 740 *nonce_lo = 0; | 754 |
| 741 *nonce_hi = 0; | 755 std::vector<GURL> resource_gurls; |
| 742 base::FilePath file_path; | 756 for (size_t i = 0; i < resource_file_urls.size(); ++i) { |
| 743 if (!sender->Send( | 757 resource_gurls.push_back(GURL(resource_file_urls[i])); |
| 744 new NaClHostMsg_OpenNaClExecutable(GetRoutingID(instance), | |
| 745 GURL(file_url), | |
| 746 !load_manager->nonsfi(), | |
| 747 &out_fd, | |
| 748 nonce_lo, | |
| 749 nonce_hi))) { | |
| 750 return PP_kInvalidFileHandle; | |
| 751 } | 758 } |
| 752 | 759 |
| 753 if (out_fd == IPC::InvalidPlatformFileForTransit()) | 760 for (size_t i = 0; i < resource_gurls.size(); ++i) { |
| 754 return PP_kInvalidFileHandle; | 761 const GURL& gurl = resource_gurls[i]; |
| 762 // Fast path only works for installed file URLs. | |
| 763 if (!gurl.SchemeIs("chrome-extension")) | |
| 764 return false; | |
| 765 // IMPORTANT: Make sure the document can request the given URL. If we don't | |
| 766 // check, a malicious app could probe the extension system. This enforces a | |
| 767 // same-origin policy which prevents the app from requesting resources from | |
| 768 // another app. | |
| 769 if (!security_origin.canRequest(gurl)) | |
| 770 return false; | |
| 771 } | |
| 755 | 772 |
| 756 return IPC::PlatformFileForTransitToPlatformFile(out_fd); | 773 if (!sender->Send(new NaClHostMsg_OpenNaClResources( |
| 774 GetRoutingID(instance), | |
| 775 resource_gurls, | |
| 776 !load_manager->nonsfi(), | |
| 777 out_resource_file_handles))) { | |
| 778 return false; | |
| 779 } | |
| 780 | |
| 781 if (out_resource_file_handles->empty() || | |
| 782 (out_resource_file_handles->at(0).file == | |
| 783 IPC::InvalidPlatformFileForTransit())) { | |
| 784 DLOG(ERROR) << "Could not open the main nexe: " << resource_gurls[0]; | |
| 785 return false; | |
| 786 } | |
| 787 return true; | |
| 757 } | 788 } |
| 758 | 789 |
| 759 void DispatchEvent(PP_Instance instance, | 790 void DispatchEvent(PP_Instance instance, |
| 760 PP_NaClEventType event_type, | 791 PP_NaClEventType event_type, |
| 761 const char* resource_url, | 792 const char* resource_url, |
| 762 PP_Bool length_is_computable, | 793 PP_Bool length_is_computable, |
| 763 uint64_t loaded_bytes, | 794 uint64_t loaded_bytes, |
| 764 uint64_t total_bytes) { | 795 uint64_t total_bytes) { |
| 765 ProgressEvent event(event_type, | 796 ProgressEvent event(event_type, |
| 766 resource_url, | 797 resource_url, |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1204 }; | 1235 }; |
| 1205 | 1236 |
| 1206 void DownloadNexeCompletion(const DownloadNexeRequest& request, | 1237 void DownloadNexeCompletion(const DownloadNexeRequest& request, |
| 1207 PP_NaClFileInfo* out_file_info, | 1238 PP_NaClFileInfo* out_file_info, |
| 1208 FileDownloader::Status status, | 1239 FileDownloader::Status status, |
| 1209 base::File target_file, | 1240 base::File target_file, |
| 1210 int http_status); | 1241 int http_status); |
| 1211 | 1242 |
| 1212 void DownloadNexe(PP_Instance instance, | 1243 void DownloadNexe(PP_Instance instance, |
| 1213 const char* url, | 1244 const char* url, |
| 1245 PP_Bool download_resource_files, | |
| 1214 PP_NaClFileInfo* out_file_info, | 1246 PP_NaClFileInfo* out_file_info, |
| 1215 PP_CompletionCallback callback) { | 1247 PP_CompletionCallback callback) { |
| 1216 CHECK(url); | 1248 CHECK(url); |
| 1217 CHECK(out_file_info); | 1249 CHECK(out_file_info); |
| 1218 DownloadNexeRequest request; | 1250 DownloadNexeRequest request; |
| 1219 request.instance = instance; | 1251 request.instance = instance; |
| 1220 request.url = url; | 1252 request.url = url; |
| 1221 request.callback = callback; | 1253 request.callback = callback; |
| 1222 request.start_time = base::Time::Now(); | 1254 request.start_time = base::Time::Now(); |
| 1223 | 1255 |
| 1256 std::vector<std::string> file_urls; | |
| 1257 file_urls.push_back(url); // the main nexe must be the first element. | |
| 1258 | |
| 1259 std::vector< | |
| 1260 std::pair<std::string /*url*/, std::string /*key*/> > resource_files; | |
| 1261 if (download_resource_files) { | |
| 1262 JsonManifest* manifest = GetJsonManifest(instance); | |
| 1263 if (manifest) | |
| 1264 manifest->GetFiles(&resource_files); | |
| 1265 if (resource_files.size() > kMaxPreOpenResourceFiles) | |
| 1266 resource_files.resize(kMaxPreOpenResourceFiles); | |
| 1267 for (size_t i = 0; i < resource_files.size(); ++i) { | |
| 1268 file_urls.push_back(resource_files[i].first); | |
| 1269 } | |
| 1270 } | |
| 1271 | |
| 1224 // Try the fast path for retrieving the file first. | 1272 // Try the fast path for retrieving the file first. |
| 1225 PP_FileHandle handle = OpenNaClExecutable(instance, | 1273 std::vector<NaClFileInfo> file_handles; |
| 1226 url, | 1274 if (OpenNaClResources(instance, file_urls, &file_handles)) { |
| 1227 &out_file_info->token_lo, | 1275 DCHECK(!file_handles.empty()); |
| 1228 &out_file_info->token_hi); | 1276 out_file_info->handle = |
| 1229 if (handle != PP_kInvalidFileHandle) { | 1277 IPC::PlatformFileForTransitToPlatformFile(file_handles[0].file); |
| 1278 out_file_info->token_lo = file_handles[0].file_token_lo; | |
| 1279 out_file_info->token_hi = file_handles[0].file_token_hi; | |
| 1280 NaClPluginInstance* nacl_plugin_instance = GetNaClPluginInstance(instance); | |
| 1281 for (size_t i = 1; i < file_handles.size(); ++i) { | |
| 1282 std::string key = resource_files[i - 1].second; | |
| 1283 nacl_plugin_instance->resource_files_info.push_back( | |
| 1284 NaClLaunchParams::ResourceFileInfo(file_handles[i], key)); | |
| 1285 } | |
| 1230 DownloadNexeCompletion(request, | 1286 DownloadNexeCompletion(request, |
| 1231 out_file_info, | 1287 out_file_info, |
| 1232 FileDownloader::SUCCESS, | 1288 FileDownloader::SUCCESS, |
| 1233 base::File(handle), | 1289 base::File(out_file_info->handle), |
| 1234 200); | 1290 200); |
| 1235 return; | 1291 return; |
| 1236 } | 1292 } |
| 1237 | 1293 |
| 1238 // The fast path didn't work, we'll fetch the file using URLLoader and write | 1294 // The fast path didn't work, we'll fetch the file using URLLoader and write |
| 1239 // it to local storage. | 1295 // it to local storage. |
| 1240 base::File target_file(CreateTemporaryFile(instance)); | 1296 base::File target_file(CreateTemporaryFile(instance)); |
| 1241 GURL gurl(url); | 1297 GURL gurl(url); |
| 1242 | 1298 |
| 1299 // On the slow path, do not retry to pre-open the resource files. | |
| 1243 content::PepperPluginInstance* plugin_instance = | 1300 content::PepperPluginInstance* plugin_instance = |
| 1244 content::PepperPluginInstance::Get(instance); | 1301 content::PepperPluginInstance::Get(instance); |
| 1245 if (!plugin_instance) { | 1302 if (!plugin_instance) { |
| 1246 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 1303 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 1247 FROM_HERE, | 1304 FROM_HERE, |
| 1248 base::Bind(callback.func, callback.user_data, | 1305 base::Bind(callback.func, callback.user_data, |
| 1249 static_cast<int32_t>(PP_ERROR_FAILED))); | 1306 static_cast<int32_t>(PP_ERROR_FAILED))); |
| 1250 } | 1307 } |
| 1251 const blink::WebDocument& document = | 1308 const blink::WebDocument& document = |
| 1252 plugin_instance->GetContainer()->element().document(); | 1309 plugin_instance->GetContainer()->element().document(); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1368 if (!test_gurl.is_valid()) { | 1425 if (!test_gurl.is_valid()) { |
| 1369 base::MessageLoop::current()->PostTask( | 1426 base::MessageLoop::current()->PostTask( |
| 1370 FROM_HERE, | 1427 FROM_HERE, |
| 1371 base::Bind(callback, | 1428 base::Bind(callback, |
| 1372 static_cast<int32_t>(PP_ERROR_FAILED), | 1429 static_cast<int32_t>(PP_ERROR_FAILED), |
| 1373 kInvalidNaClFileInfo)); | 1430 kInvalidNaClFileInfo)); |
| 1374 return; | 1431 return; |
| 1375 } | 1432 } |
| 1376 | 1433 |
| 1377 // Try the fast path for retrieving the file first. | 1434 // Try the fast path for retrieving the file first. |
| 1378 uint64_t file_token_lo = 0; | 1435 std::vector<std::string> file_urls; |
| 1379 uint64_t file_token_hi = 0; | 1436 file_urls.push_back(url); |
| 1380 PP_FileHandle file_handle = OpenNaClExecutable(instance, | 1437 std::vector<NaClFileInfo> out_handles; |
| 1381 url.c_str(), | 1438 if (OpenNaClResources(instance, file_urls, &out_handles)) { |
|
Mark Seaborn
2015/02/09 04:48:35
I think there's a potential performance regression
Yusuke Sato
2015/02/11 05:54:21
I wasn't aware that HTTP(S) URL was allowed in "fi
| |
| 1382 &file_token_lo, | |
| 1383 &file_token_hi); | |
| 1384 if (file_handle != PP_kInvalidFileHandle) { | |
| 1385 PP_NaClFileInfo file_info; | 1439 PP_NaClFileInfo file_info; |
| 1386 file_info.handle = file_handle; | 1440 file_info.handle = |
| 1387 file_info.token_lo = file_token_lo; | 1441 IPC::PlatformFileForTransitToPlatformFile(out_handles[0].file); |
| 1388 file_info.token_hi = file_token_hi; | 1442 file_info.token_lo = out_handles[0].file_token_lo; |
| 1443 file_info.token_hi = out_handles[0].file_token_hi; | |
| 1389 base::MessageLoop::current()->PostTask( | 1444 base::MessageLoop::current()->PostTask( |
| 1390 FROM_HERE, | 1445 FROM_HERE, |
| 1391 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info)); | 1446 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info)); |
| 1392 return; | 1447 return; |
| 1393 } | 1448 } |
| 1394 | 1449 |
| 1395 // The fast path didn't work, we'll fetch the file using URLLoader and write | 1450 // The fast path didn't work, we'll fetch the file using URLLoader and write |
| 1396 // it to local storage. | 1451 // it to local storage. |
| 1397 base::File target_file(CreateTemporaryFile(instance)); | 1452 base::File target_file(CreateTemporaryFile(instance)); |
| 1398 GURL gurl(url); | 1453 GURL gurl(url); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1651 &StreamPexe | 1706 &StreamPexe |
| 1652 }; | 1707 }; |
| 1653 | 1708 |
| 1654 } // namespace | 1709 } // namespace |
| 1655 | 1710 |
| 1656 const PPB_NaCl_Private* GetNaClPrivateInterface() { | 1711 const PPB_NaCl_Private* GetNaClPrivateInterface() { |
| 1657 return &nacl_interface; | 1712 return &nacl_interface; |
| 1658 } | 1713 } |
| 1659 | 1714 |
| 1660 } // namespace nacl | 1715 } // namespace nacl |
| OLD | NEW |