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

Side by Side Diff: ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc

Issue 14683004: Check that the PNaCl cache hash is truly derived from the bitcode content. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: minor cleanup Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "native_client/src/trusted/plugin/pnacl_coordinator.h" 5 #include "native_client/src/trusted/plugin/pnacl_coordinator.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "native_client/src/include/checked_cast.h" 10 #include "native_client/src/include/checked_cast.h"
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 error_already_reported_(false), 358 error_already_reported_(false),
359 off_the_record_(false), 359 off_the_record_(false),
360 pnacl_init_time_(0), 360 pnacl_init_time_(0),
361 pexe_size_(0), 361 pexe_size_(0),
362 pexe_bytes_compiled_(0), 362 pexe_bytes_compiled_(0),
363 expected_pexe_size_(-1) { 363 expected_pexe_size_(-1) {
364 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", 364 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n",
365 static_cast<void*>(this), static_cast<void*>(plugin))); 365 static_cast<void*>(this), static_cast<void*>(plugin)));
366 callback_factory_.Initialize(this); 366 callback_factory_.Initialize(this);
367 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get())); 367 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get()));
368 pp::Module *module = pp::Module::Get();
369 DCHECK(module);
370 nacl_hash_private_interface_ = static_cast<const PPB_NaCl_Hash_Private*>(
371 module->GetBrowserInterface(PPB_NACL_HASH_PRIVATE_INTERFACE));
372 bitcode_hash_verifier_ = nacl_hash_private_interface_->CreateSHA256Hash();
368 } 373 }
369 374
370 PnaclCoordinator::~PnaclCoordinator() { 375 PnaclCoordinator::~PnaclCoordinator() {
371 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p, " 376 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p, "
372 "translate_thread=%p\n", 377 "translate_thread=%p\n",
373 static_cast<void*>(this), translate_thread_.get())); 378 static_cast<void*>(this), translate_thread_.get()));
374 // Stopping the translate thread will cause the translate thread to try to 379 // Stopping the translate thread will cause the translate thread to try to
375 // run translation_complete_callback_ on the main thread. This destructor is 380 // run translation_complete_callback_ on the main thread. This destructor is
376 // running from the main thread, and by the time it exits, callback_factory_ 381 // running from the main thread, and by the time it exits, callback_factory_
377 // will have been destroyed. This will result in the cancellation of 382 // will have been destroyed. This will result in the cancellation of
378 // translation_complete_callback_, so no notification will be delivered. 383 // translation_complete_callback_, so no notification will be delivered.
379 if (translate_thread_.get() != NULL) { 384 if (translate_thread_.get() != NULL) {
380 translate_thread_->AbortSubprocesses(); 385 translate_thread_->AbortSubprocesses();
381 } 386 }
387 nacl_hash_private_interface_->Delete(bitcode_hash_verifier_);
382 } 388 }
383 389
384 void PnaclCoordinator::ReportNonPpapiError(enum PluginErrorCode err_code, 390 void PnaclCoordinator::ReportNonPpapiError(enum PluginErrorCode err_code,
385 const nacl::string& message) { 391 const nacl::string& message) {
386 error_info_.SetReport(err_code, 392 error_info_.SetReport(err_code,
387 nacl::string("PnaclCoordinator: ") + message); 393 nacl::string("PnaclCoordinator: ") + message);
388 ExitWithError(); 394 ExitWithError();
389 } 395 }
390 396
391 void PnaclCoordinator::ReportPpapiError(enum PluginErrorCode err_code, 397 void PnaclCoordinator::ReportPpapiError(enum PluginErrorCode err_code,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 static_cast<int64_t>(nexe_size / 1024)); 469 static_cast<int64_t>(nexe_size / 1024));
464 HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); 470 HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size);
465 } 471 }
466 472
467 // The nexe is written to the temp_nexe_file_. We must Reset() the file 473 // The nexe is written to the temp_nexe_file_. We must Reset() the file
468 // pointer to be able to read it again from the beginning. 474 // pointer to be able to read it again from the beginning.
469 temp_nexe_file_->Reset(); 475 temp_nexe_file_->Reset();
470 476
471 if (pnacl_options_.HasCacheKey() && cached_nexe_file_ != NULL) { 477 if (pnacl_options_.HasCacheKey() && cached_nexe_file_ != NULL) {
472 // We are using a cache, but had a cache miss, which is why we did the 478 // We are using a cache, but had a cache miss, which is why we did the
473 // translation. Reset cached_nexe_file_ to have a random name, 479 // translation.
474 // for scratch purposes, before renaming to the final cache_identity. 480 if (BitcodeHashMatchesContents()) {
475 cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), 481 // Reset cached_nexe_file_ to have a random name, for scratch purposes,
476 nacl::string(kPnaclTempDir))); 482 // before renaming to the final cache_identity.
477 pp::CompletionCallback cb = callback_factory_.NewCallback( 483 cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
478 &PnaclCoordinator::CachedNexeOpenedForWrite); 484 nacl::string(kPnaclTempDir)));
479 cached_nexe_file_->OpenWrite(cb); 485 pp::CompletionCallback cb = callback_factory_.NewCallback(
486 &PnaclCoordinator::CachedNexeOpenedForWrite);
487 cached_nexe_file_->OpenWrite(cb);
488 } else {
489 ReportNonPpapiError(
490 ERROR_PNACL_CACHE_HASH_MISMATCH,
491 "Bitcode hash does not match bitcode contents.");
492 }
480 } else { 493 } else {
481 // For now, tolerate bitcode that is missing a cache identity, and 494 // For now, tolerate bitcode that is missing a cache identity, and
482 // tolerate the lack of caching in incognito mode. 495 // tolerate the lack of caching in incognito mode.
483 PLUGIN_PRINTF(("PnaclCoordinator -- not caching.\n")); 496 PLUGIN_PRINTF(("PnaclCoordinator -- not caching.\n"));
484 NexeReadDidOpen(PP_OK); 497 NexeReadDidOpen(PP_OK);
485 } 498 }
486 } 499 }
487 500
501 bool PnaclCoordinator::BitcodeHashMatchesContents() {
502 const nacl::string& expected_hash = pnacl_options_.GetBitcodeHash();
503 nacl::string actual_hash;
504 uint8_t hash_digest[32];
505 nacl_hash_private_interface_->Finish(bitcode_hash_verifier_,
506 &hash_digest,
507 sizeof hash_digest);
508 // Convert 32-byte binary digest to 64-byte hex digest for comparison.
509 for (size_t i = 0; i < sizeof hash_digest; i+=8) {
510 char buf[17]; // do 16 chars + a null byte at a time.
511 SNPRINTF(buf, sizeof buf, "%02x%02x%02x%02x%02x%02x%02x%02x",
512 hash_digest[i ], hash_digest[i+1],
513 hash_digest[i+2], hash_digest[i+3],
514 hash_digest[i+4], hash_digest[i+5],
515 hash_digest[i+6], hash_digest[i+7]);
516 actual_hash.append(buf);
517 }
518 if (expected_hash.size() != actual_hash.size()) {
519 return false;
520 }
521 return nacl_hash_private_interface_->SecureMemEqual(expected_hash.c_str(),
522 actual_hash.c_str(),
523 expected_hash.size());
524 }
525
488 void PnaclCoordinator::CachedNexeOpenedForWrite(int32_t pp_error) { 526 void PnaclCoordinator::CachedNexeOpenedForWrite(int32_t pp_error) {
489 if (pp_error != PP_OK) { 527 if (pp_error != PP_OK) {
490 if (pp_error == PP_ERROR_NOACCESS) { 528 if (pp_error == PP_ERROR_NOACCESS) {
491 ReportPpapiError( 529 ReportPpapiError(
492 ERROR_PNACL_CACHE_FILEOPEN_NOACCESS, 530 ERROR_PNACL_CACHE_FILEOPEN_NOACCESS,
493 pp_error, 531 pp_error,
494 "PNaCl translation cache failed to open file for write " 532 "PNaCl translation cache failed to open file for write "
495 "(no access)."); 533 "(no access).");
496 return; 534 return;
497 } 535 }
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 HistogramRatio("NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", 941 HistogramRatio("NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded",
904 pexe_bytes_compiled_, pexe_size_); 942 pexe_bytes_compiled_, pexe_size_);
905 } 943 }
906 } 944 }
907 945
908 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, 946 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error,
909 FileStreamData data) { 947 FileStreamData data) {
910 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" 948 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%"
911 NACL_PRId32", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); 949 NACL_PRId32", data=%p)\n", pp_error, data ? &(*data)[0] : 0));
912 DCHECK(translate_thread_.get()); 950 DCHECK(translate_thread_.get());
951 // If pp_error > 0, then it represents the number of bytes received.
952 if (pp_error > 0) {
953 pexe_size_ += pp_error;
954 // Update hash for verification before data is taken by PutBytes.
955 if (pnacl_options_.HasCacheKey()) {
956 nacl_hash_private_interface_->Update(bitcode_hash_verifier_,
Derek Schuff 2013/04/30 23:52:38 The hash we put in the bitcode header is not the h
jvoung (off chromium) 2013/05/01 00:01:30 The current hash generator is a function in the SD
957 &(*data)[0],
958 pp_error);
959 }
960 }
913 translate_thread_->PutBytes(data, pp_error); 961 translate_thread_->PutBytes(data, pp_error);
914 // If pp_error > 0, then it represents the number of bytes received.
915 if (data && pp_error > 0) {
916 pexe_size_ += pp_error;
917 }
918 } 962 }
919 963
920 StreamCallback PnaclCoordinator::GetCallback() { 964 StreamCallback PnaclCoordinator::GetCallback() {
921 return callback_factory_.NewCallbackWithOutput( 965 return callback_factory_.NewCallbackWithOutput(
922 &PnaclCoordinator::BitcodeStreamGotData); 966 &PnaclCoordinator::BitcodeStreamGotData);
923 } 967 }
924 968
925 void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error, 969 void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error,
926 int64_t bytes_compiled) { 970 int64_t bytes_compiled) {
927 // If we don't know the expected total yet, ask. 971 // If we don't know the expected total yet, ask.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 obj_file_.get(), 1029 obj_file_.get(),
986 temp_nexe_file_.get(), 1030 temp_nexe_file_.get(),
987 &error_info_, 1031 &error_info_,
988 resources_.get(), 1032 resources_.get(),
989 &pnacl_options_, 1033 &pnacl_options_,
990 this, 1034 this,
991 plugin_); 1035 plugin_);
992 } 1036 }
993 1037
994 } // namespace plugin 1038 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698