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 |