Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: components/nacl/renderer/ppb_nacl_private_impl.cc

Issue 649603004: Non-SFI NaCl: Batch-open resource files (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: code review Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698