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

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 6 years, 2 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
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 DCHECK(pp_process_type > PP_UNKNOWN_NACL_PROCESS_TYPE && 294 DCHECK(pp_process_type > PP_UNKNOWN_NACL_PROCESS_TYPE &&
295 pp_process_type < PP_NUM_NACL_PROCESS_TYPES); 295 pp_process_type < PP_NUM_NACL_PROCESS_TYPES);
296 return static_cast<NaClAppProcessType>(pp_process_type); 296 return static_cast<NaClAppProcessType>(pp_process_type);
297 } 297 }
298 298
299 // Launch NaCl's sel_ldr process. 299 // Launch NaCl's sel_ldr process.
300 void LaunchSelLdr(PP_Instance instance, 300 void LaunchSelLdr(PP_Instance instance,
301 PP_Bool main_service_runtime, 301 PP_Bool main_service_runtime,
302 const char* alleged_url, 302 const char* alleged_url,
303 const PP_NaClFileInfo* nexe_file_info, 303 const PP_NaClFileInfo* nexe_file_info,
304 const PP_NaClResourceFileHandle* resource_file_handles,
304 PP_Bool uses_nonsfi_mode, 305 PP_Bool uses_nonsfi_mode,
305 PP_Bool enable_ppapi_dev, 306 PP_Bool enable_ppapi_dev,
306 PP_NaClAppProcessType pp_process_type, 307 PP_NaClAppProcessType pp_process_type,
307 void* imc_handle, 308 void* imc_handle,
308 PP_CompletionCallback callback) { 309 PP_CompletionCallback callback) {
309 CHECK(ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()-> 310 CHECK(ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->
310 BelongsToCurrentThread()); 311 BelongsToCurrentThread());
311 NaClAppProcessType process_type = PP_ToNaClAppProcessType(pp_process_type); 312 NaClAppProcessType process_type = PP_ToNaClAppProcessType(pp_process_type);
312 // Create the manifest service proxy here, so on error case, it will be 313 // Create the manifest service proxy here, so on error case, it will be
313 // destructed (without passing it to ManifestServiceChannel). 314 // destructed (without passing it to ManifestServiceChannel).
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 // must also check on the trusted side of the proxy. 348 // must also check on the trusted side of the proxy.
348 if (enable_ppapi_dev) 349 if (enable_ppapi_dev)
349 perm_bits |= ppapi::PERMISSION_DEV; 350 perm_bits |= ppapi::PERMISSION_DEV;
350 instance_info.permissions = 351 instance_info.permissions =
351 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); 352 ppapi::PpapiPermissions::GetForCommandLine(perm_bits);
352 std::string error_message_string; 353 std::string error_message_string;
353 NaClLaunchResult launch_result; 354 NaClLaunchResult launch_result;
354 355
355 IPC::PlatformFileForTransit nexe_for_transit = 356 IPC::PlatformFileForTransit nexe_for_transit =
356 IPC::InvalidPlatformFileForTransit(); 357 IPC::InvalidPlatformFileForTransit();
358 std::vector<IPC::PlatformFileForTransit> resource_files_for_transit;
359 std::vector<std::pair<uint64, uint64> > resource_file_tokens;
360 std::vector<std::string> resource_keys;
357 #if defined(OS_POSIX) 361 #if defined(OS_POSIX)
358 if (nexe_file_info->handle != PP_kInvalidFileHandle) 362 if (nexe_file_info->handle != PP_kInvalidFileHandle)
359 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true); 363 nexe_for_transit = base::FileDescriptor(nexe_file_info->handle, true);
364 for (size_t i = 0;
365 resource_file_handles &&
366 (resource_file_handles[i].handle != PP_kInvalidFileHandle);
367 ++i) {
368 resource_files_for_transit.push_back(
369 base::FileDescriptor(resource_file_handles[i].handle, true));
370 resource_file_tokens.push_back(
371 std::make_pair(resource_file_handles[i].token_lo,
372 resource_file_handles[i].token_hi));
373 resource_keys.push_back(resource_file_handles[i].key);
374 }
360 #elif defined(OS_WIN) 375 #elif defined(OS_WIN)
361 // Duplicate the handle on the browser side instead of the renderer. 376 // Duplicate the handle on the browser side instead of the renderer.
362 // This is because BrokerGetFileForProcess isn't part of content/public, and 377 // This is because BrokerGetFileForProcess isn't part of content/public, and
363 // it's simpler to do the duplication in the browser anyway. 378 // it's simpler to do the duplication in the browser anyway.
364 nexe_for_transit = nexe_file_info->handle; 379 nexe_for_transit = nexe_file_info->handle;
380 // TODO(yusukes): Support pre-opening resource files.
381 CHECK(resource_file_handles == NULL);
365 #else 382 #else
366 #error Unsupported target platform. 383 #error Unsupported target platform.
367 #endif 384 #endif
368 if (!sender->Send(new NaClHostMsg_LaunchNaCl( 385 if (!sender->Send(new NaClHostMsg_LaunchNaCl(
369 NaClLaunchParams( 386 NaClLaunchParams(
370 instance_info.url.spec(), 387 instance_info.url.spec(),
371 nexe_for_transit, 388 nexe_for_transit,
372 nexe_file_info->token_lo, 389 nexe_file_info->token_lo,
373 nexe_file_info->token_hi, 390 nexe_file_info->token_hi,
391 resource_files_for_transit,
392 resource_file_tokens,
393 resource_keys,
374 routing_id, 394 routing_id,
375 perm_bits, 395 perm_bits,
376 PP_ToBool(uses_nonsfi_mode), 396 PP_ToBool(uses_nonsfi_mode),
377 process_type), 397 process_type),
378 &launch_result, 398 &launch_result,
379 &error_message_string))) { 399 &error_message_string))) {
380 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( 400 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
381 FROM_HERE, 401 FROM_HERE,
382 base::Bind(callback.func, callback.user_data, 402 base::Bind(callback.func, callback.user_data,
383 static_cast<int32_t>(PP_ERROR_FAILED))); 403 static_cast<int32_t>(PP_ERROR_FAILED)));
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 } 694 }
675 } 695 }
676 696
677 // If the resource host isn't initialized, don't try to do that here. 697 // If the resource host isn't initialized, don't try to do that here.
678 // Just return because something is already very wrong. 698 // Just return because something is already very wrong.
679 if (g_pnacl_resource_host.Get().get() == NULL) 699 if (g_pnacl_resource_host.Get().get() == NULL)
680 return; 700 return;
681 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success); 701 g_pnacl_resource_host.Get()->ReportTranslationFinished(instance, success);
682 } 702 }
683 703
684 PP_FileHandle OpenNaClExecutable(PP_Instance instance, 704 PP_FileHandle OpenNaClExecutable(
teravest 2014/10/24 16:18:06 OpenNaClExecutable should probably be renamed to O
Yusuke Sato 2014/11/04 22:50:22 Done.
685 const char* file_url, 705 PP_Instance instance,
686 uint64_t* nonce_lo, 706 const char* file_url,
687 uint64_t* nonce_hi) { 707 uint64_t* nonce_lo,
708 uint64_t* nonce_hi,
709 const std::vector<std::string>& resource_file_urls,
710 PP_NaClResourceFileHandle** out_resource_file_handles) {
688 // Fast path only works for installed file URLs. 711 // Fast path only works for installed file URLs.
689 GURL gurl(file_url); 712 GURL gurl(file_url);
690 if (!gurl.SchemeIs("chrome-extension")) 713 if (!gurl.SchemeIs("chrome-extension"))
691 return PP_kInvalidFileHandle; 714 return PP_kInvalidFileHandle;
692 715
693 content::PepperPluginInstance* plugin_instance = 716 content::PepperPluginInstance* plugin_instance =
694 content::PepperPluginInstance::Get(instance); 717 content::PepperPluginInstance::Get(instance);
695 if (!plugin_instance) 718 if (!plugin_instance)
696 return PP_kInvalidFileHandle; 719 return PP_kInvalidFileHandle;
697 // IMPORTANT: Make sure the document can request the given URL. If we don't 720 // IMPORTANT: Make sure the document can request the given URL. If we don't
698 // check, a malicious app could probe the extension system. This enforces a 721 // check, a malicious app could probe the extension system. This enforces a
699 // same-origin policy which prevents the app from requesting resources from 722 // same-origin policy which prevents the app from requesting resources from
700 // another app. 723 // another app.
701 blink::WebSecurityOrigin security_origin = 724 blink::WebSecurityOrigin security_origin =
702 plugin_instance->GetContainer()->element().document().securityOrigin(); 725 plugin_instance->GetContainer()->element().document().securityOrigin();
703 if (!security_origin.canRequest(gurl)) 726 if (!security_origin.canRequest(gurl))
704 return PP_kInvalidFileHandle; 727 return PP_kInvalidFileHandle;
705 728
706 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); 729 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit();
707 IPC::Sender* sender = content::RenderThread::Get(); 730 IPC::Sender* sender = content::RenderThread::Get();
708 DCHECK(sender); 731 DCHECK(sender);
709 *nonce_lo = 0; 732 *nonce_lo = 0;
710 *nonce_hi = 0; 733 *nonce_hi = 0;
711 base::FilePath file_path; 734 base::FilePath file_path;
712 if (!sender->Send( 735
713 new NaClHostMsg_OpenNaClExecutable(GetRoutingID(instance), 736 std::vector<GURL> resource_urls;
714 GURL(file_url), 737 for (size_t i = 0; i < resource_file_urls.size(); ++i) {
715 &out_fd, 738 GURL gurl(resource_file_urls[i]);
716 nonce_lo, 739 if (!gurl.SchemeIs("chrome-extension"))
717 nonce_hi))) { 740 return PP_kInvalidFileHandle;
741 if (!security_origin.canRequest(gurl))
742 return PP_kInvalidFileHandle;
743 resource_urls.push_back(gurl);
744 }
745
746 nacl::NaClOpenExecutableResult open_result;
747 if (!sender->Send(new NaClHostMsg_OpenNaClExecutable(GetRoutingID(instance),
748 GURL(file_url),
749 resource_urls,
750 &open_result))) {
718 return PP_kInvalidFileHandle; 751 return PP_kInvalidFileHandle;
719 } 752 }
720 753
721 if (out_fd == IPC::InvalidPlatformFileForTransit()) 754 if (open_result.file == IPC::InvalidPlatformFileForTransit())
722 return PP_kInvalidFileHandle; 755 return PP_kInvalidFileHandle;
723 756
757 for (size_t i = 0; i < open_result.resource_files.size(); ++i) {
758 if (open_result.resource_files[i] == IPC::InvalidPlatformFileForTransit())
759 return PP_kInvalidFileHandle;
teravest 2014/10/24 16:18:06 There should at least be some debug logging added
Yusuke Sato 2014/11/04 22:50:22 Done.
760 }
761 CHECK(open_result.resource_files.size() ==
762 open_result.resource_file_tokens.size());
763
764 out_fd = open_result.file;
765 *nonce_lo = open_result.file_token_lo;
766 *nonce_lo = open_result.file_token_hi;
teravest 2014/10/24 16:18:06 Shouldn't this be nonce_hi? Is the behavior for fi
Yusuke Sato 2014/11/04 22:50:22 Good catch. Fixed. This will be used in the next C
767
768 if (out_resource_file_handles && !open_result.resource_files.empty()) {
769 *out_resource_file_handles =
770 new PP_NaClResourceFileHandle[open_result.resource_files.size() + 1];
771 for (size_t i = 0; i < open_result.resource_files.size(); ++i) {
772 PP_NaClResourceFileHandle& entry = (*out_resource_file_handles)[i];
773 entry.handle = IPC::PlatformFileForTransitToPlatformFile(
774 open_result.resource_files[i]);
775 entry.token_lo = open_result.resource_file_tokens[i].first;
776 entry.token_hi = open_result.resource_file_tokens[i].second;
777 entry.key = NULL; // DownloadNexe fills this later.
778 }
779 PP_NaClResourceFileHandle& sentinel =
780 (*out_resource_file_handles)[open_result.resource_files.size()];
teravest 2014/10/24 16:18:06 So, out_resource_file_handles is always guaranteed
Yusuke Sato 2014/11/04 22:50:22 Done.
781 sentinel.handle = PP_kInvalidFileHandle;
782 sentinel.token_lo = 0;
783 sentinel.token_hi = 0;
784 sentinel.key = NULL;
785 }
786
724 return IPC::PlatformFileForTransitToPlatformFile(out_fd); 787 return IPC::PlatformFileForTransitToPlatformFile(out_fd);
725 } 788 }
726 789
727 void DispatchEvent(PP_Instance instance, 790 void DispatchEvent(PP_Instance instance,
728 PP_NaClEventType event_type, 791 PP_NaClEventType event_type,
729 const char *resource_url, 792 const char *resource_url,
730 PP_Bool length_is_computable, 793 PP_Bool length_is_computable,
731 uint64_t loaded_bytes, 794 uint64_t loaded_bytes,
732 uint64_t total_bytes) { 795 uint64_t total_bytes) {
733 ProgressEvent event(event_type, 796 ProgressEvent event(event_type,
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 }; 1270 };
1208 1271
1209 void DownloadNexeCompletion(const DownloadNexeRequest& request, 1272 void DownloadNexeCompletion(const DownloadNexeRequest& request,
1210 PP_NaClFileInfo* out_file_info, 1273 PP_NaClFileInfo* out_file_info,
1211 FileDownloader::Status status, 1274 FileDownloader::Status status,
1212 base::File target_file, 1275 base::File target_file,
1213 int http_status); 1276 int http_status);
1214 1277
1215 void DownloadNexe(PP_Instance instance, 1278 void DownloadNexe(PP_Instance instance,
1216 const char* url, 1279 const char* url,
1280 PP_Bool download_resource_files,
1217 PP_NaClFileInfo* out_file_info, 1281 PP_NaClFileInfo* out_file_info,
1282 PP_NaClResourceFileHandle** out_resource_file_handles,
1218 PP_CompletionCallback callback) { 1283 PP_CompletionCallback callback) {
1219 CHECK(url); 1284 CHECK(url);
1220 CHECK(out_file_info); 1285 CHECK(out_file_info);
1286 CHECK(!download_resource_files || out_resource_file_handles);
1287
1221 DownloadNexeRequest request; 1288 DownloadNexeRequest request;
1222 request.instance = instance; 1289 request.instance = instance;
1223 request.url = url; 1290 request.url = url;
1224 request.callback = callback; 1291 request.callback = callback;
1225 request.start_time = base::Time::Now(); 1292 request.start_time = base::Time::Now();
1226 1293
1294 std::vector<std::string> resource_file_urls;
1295 std::vector<std::string> resource_file_keys;
1296 if (download_resource_files) {
1297 JsonManifest* manifest = GetJsonManifest(instance);
1298 if (manifest)
1299 manifest->GetFilesUrl(&resource_file_urls, &resource_file_keys);
1300 CHECK(resource_file_urls.size() == resource_file_keys.size());
1301
1302 // TODO(yusukes): Increase kMaxDescriptorsPerMessage in
1303 // ipc/file_descriptor_set_posix.h, NACL_ABI_IMC_USER_DESC_MAX in
1304 // native_client/src/public/imc_types.h, and NACL_HANDLE_COUNT_MAX in
1305 // native_client/src/shared/imc/nacl_imc_c.h, and remove the resize()
1306 // calls.
1307 if (resource_file_urls.size() > 2) {
teravest 2014/10/24 16:18:06 So what happens if more than two resource file url
Yusuke Sato 2014/11/04 22:50:22 Yes.
Yusuke Sato 2014/11/05 07:03:23 It turned out that removing the restriction does n
1308 resource_file_urls.resize(2);
1309 resource_file_keys.resize(2);
1310 }
1311 }
1312
1227 // Try the fast path for retrieving the file first. 1313 // Try the fast path for retrieving the file first.
1228 PP_FileHandle handle = OpenNaClExecutable(instance, 1314 PP_FileHandle handle = OpenNaClExecutable(instance,
1229 url, 1315 url,
1230 &out_file_info->token_lo, 1316 &out_file_info->token_lo,
1231 &out_file_info->token_hi); 1317 &out_file_info->token_hi,
1318 resource_file_urls,
1319 out_resource_file_handles);
1232 if (handle != PP_kInvalidFileHandle) { 1320 if (handle != PP_kInvalidFileHandle) {
1321 if (!resource_file_urls.empty()) {
1322 for (size_t i = 0; i < resource_file_urls.size(); ++i) {
1323 PP_NaClResourceFileHandle& entry = (*out_resource_file_handles)[i];
1324 CHECK(entry.handle != PP_kInvalidFileHandle) << i;
1325 entry.key = strdup(resource_file_keys[i].c_str());
1326 }
1327 }
1233 DownloadNexeCompletion(request, 1328 DownloadNexeCompletion(request,
1234 out_file_info, 1329 out_file_info,
1235 FileDownloader::SUCCESS, 1330 FileDownloader::SUCCESS,
1236 base::File(handle), 1331 base::File(handle),
1237 200); 1332 200);
1238 return; 1333 return;
1239 } 1334 }
1240 1335
1241 // The fast path didn't work, we'll fetch the file using URLLoader and write 1336 // The fast path didn't work, we'll fetch the file using URLLoader and write
1242 // it to local storage. 1337 // it to local storage.
1243 base::File target_file(CreateTemporaryFile(instance)); 1338 base::File target_file(CreateTemporaryFile(instance));
1244 GURL gurl(url); 1339 GURL gurl(url);
1245 1340
1341 // On the slow path, do not retry to pre-open the resource files.
1342 if (out_resource_file_handles)
1343 *out_resource_file_handles = NULL;
1344
1246 content::PepperPluginInstance* plugin_instance = 1345 content::PepperPluginInstance* plugin_instance =
1247 content::PepperPluginInstance::Get(instance); 1346 content::PepperPluginInstance::Get(instance);
1248 if (!plugin_instance) { 1347 if (!plugin_instance) {
1249 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( 1348 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
1250 FROM_HERE, 1349 FROM_HERE,
1251 base::Bind(callback.func, callback.user_data, 1350 base::Bind(callback.func, callback.user_data,
1252 static_cast<int32_t>(PP_ERROR_FAILED))); 1351 static_cast<int32_t>(PP_ERROR_FAILED)));
1253 } 1352 }
1254 const blink::WebDocument& document = 1353 const blink::WebDocument& document =
1255 plugin_instance->GetContainer()->element().document(); 1354 plugin_instance->GetContainer()->element().document();
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 kInvalidNaClFileInfo)); 1475 kInvalidNaClFileInfo));
1377 return; 1476 return;
1378 } 1477 }
1379 1478
1380 // Try the fast path for retrieving the file first. 1479 // Try the fast path for retrieving the file first.
1381 uint64_t file_token_lo = 0; 1480 uint64_t file_token_lo = 0;
1382 uint64_t file_token_hi = 0; 1481 uint64_t file_token_hi = 0;
1383 PP_FileHandle file_handle = OpenNaClExecutable(instance, 1482 PP_FileHandle file_handle = OpenNaClExecutable(instance,
1384 url.c_str(), 1483 url.c_str(),
1385 &file_token_lo, 1484 &file_token_lo,
1386 &file_token_hi); 1485 &file_token_hi,
1486 std::vector<std::string>(),
1487 NULL);
1387 if (file_handle != PP_kInvalidFileHandle) { 1488 if (file_handle != PP_kInvalidFileHandle) {
1388 PP_NaClFileInfo file_info; 1489 PP_NaClFileInfo file_info;
1389 file_info.handle = file_handle; 1490 file_info.handle = file_handle;
1390 file_info.token_lo = file_token_lo; 1491 file_info.token_lo = file_token_lo;
1391 file_info.token_hi = file_token_hi; 1492 file_info.token_hi = file_token_hi;
1392 base::MessageLoop::current()->PostTask( 1493 base::MessageLoop::current()->PostTask(
1393 FROM_HERE, 1494 FROM_HERE,
1394 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info)); 1495 base::Bind(callback, static_cast<int32_t>(PP_OK), file_info));
1395 return; 1496 return;
1396 } 1497 }
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 &StreamPexe 1799 &StreamPexe
1699 }; 1800 };
1700 1801
1701 } // namespace 1802 } // namespace
1702 1803
1703 const PPB_NaCl_Private* GetNaClPrivateInterface() { 1804 const PPB_NaCl_Private* GetNaClPrivateInterface() {
1704 return &nacl_interface; 1805 return &nacl_interface;
1705 } 1806 }
1706 1807
1707 } // namespace nacl 1808 } // namespace nacl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698