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

Unified 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: cleanup Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
index bcf636254aa907ded1866aa8ca97aca6ee42fc4a..d26a97568009ed1d6e0b82e72019550d2547592e 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
@@ -365,6 +365,11 @@ PnaclCoordinator::PnaclCoordinator(
static_cast<void*>(this), static_cast<void*>(plugin)));
callback_factory_.Initialize(this);
ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get()));
+ pp::Module *module = pp::Module::Get();
+ DCHECK(module);
+ nacl_hash_private_interface_ = static_cast<const PPB_NaCl_Hash_Private*>(
+ module->GetBrowserInterface(PPB_NACL_HASH_PRIVATE_INTERFACE));
+ bitcode_hash_verifier_ = nacl_hash_private_interface_->CreateSHA256Hasher();
}
PnaclCoordinator::~PnaclCoordinator() {
@@ -379,6 +384,7 @@ PnaclCoordinator::~PnaclCoordinator() {
if (translate_thread_.get() != NULL) {
translate_thread_->AbortSubprocesses();
}
+ nacl_hash_private_interface_->Delete(bitcode_hash_verifier_);
}
void PnaclCoordinator::ReportNonPpapiError(enum PluginErrorCode err_code,
@@ -470,13 +476,20 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) {
if (pnacl_options_.HasCacheKey() && cached_nexe_file_ != NULL) {
// We are using a cache, but had a cache miss, which is why we did the
- // translation. Reset cached_nexe_file_ to have a random name,
- // for scratch purposes, before renaming to the final cache_identity.
- cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
- nacl::string(kPnaclTempDir)));
- pp::CompletionCallback cb = callback_factory_.NewCallback(
- &PnaclCoordinator::CachedNexeOpenedForWrite);
- cached_nexe_file_->OpenWrite(cb);
+ // translation.
+ if (BitcodeHashMatchesContents()) {
+ // Reset cached_nexe_file_ to have a random name, for scratch purposes,
+ // before renaming to the final cache_identity.
+ cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
+ nacl::string(kPnaclTempDir)));
+ pp::CompletionCallback cb = callback_factory_.NewCallback(
+ &PnaclCoordinator::CachedNexeOpenedForWrite);
+ cached_nexe_file_->OpenWrite(cb);
+ } else {
+ ReportNonPpapiError(
+ ERROR_PNACL_CACHE_HASH_MISMATCH,
+ "Bitcode hash does not match bitcode contents.");
+ }
} else {
// For now, tolerate bitcode that is missing a cache identity, and
// tolerate the lack of caching in incognito mode.
@@ -485,6 +498,31 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) {
}
}
+bool PnaclCoordinator::BitcodeHashMatchesContents() {
+ const nacl::string& expected_hash = pnacl_options_.GetBitcodeHash();
+ nacl::string actual_hash;
+ uint8_t hash_digest[32];
+ nacl_hash_private_interface_->Finish(bitcode_hash_verifier_,
+ &hash_digest,
+ sizeof hash_digest);
+ // Convert 32-byte binary digest to 64-byte hex digest for comparison.
+ for (size_t i = 0; i < sizeof hash_digest; i+=8) {
+ char buf[17]; // do 16 chars + a null byte at a time.
+ SNPRINTF(buf, sizeof buf, "%02x%02x%02x%02x%02x%02x%02x%02x",
+ hash_digest[i ], hash_digest[i+1],
+ hash_digest[i+2], hash_digest[i+3],
+ hash_digest[i+4], hash_digest[i+5],
+ hash_digest[i+6], hash_digest[i+7]);
+ actual_hash.append(buf);
+ }
+ if (expected_hash.size() != actual_hash.size()) {
+ return false;
+ }
+ return nacl_hash_private_interface_->SecureMemEqual(expected_hash.c_str(),
+ actual_hash.c_str(),
+ expected_hash.size());
+}
+
void PnaclCoordinator::CachedNexeOpenedForWrite(int32_t pp_error) {
if (pp_error != PP_OK) {
if (pp_error == PP_ERROR_NOACCESS) {
@@ -910,11 +948,17 @@ void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error,
PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%"
NACL_PRId32", data=%p)\n", pp_error, data ? &(*data)[0] : 0));
DCHECK(translate_thread_.get());
- translate_thread_->PutBytes(data, pp_error);
// If pp_error > 0, then it represents the number of bytes received.
- if (data && pp_error > 0) {
+ if (pp_error > 0) {
pexe_size_ += pp_error;
+ // Update hash for verification before data is taken by PutBytes.
+ if (pnacl_options_.HasCacheKey()) {
+ nacl_hash_private_interface_->Update(bitcode_hash_verifier_,
+ &(*data)[0],
+ pp_error);
+ }
}
+ translate_thread_->PutBytes(data, pp_error);
}
StreamCallback PnaclCoordinator::GetCallback() {
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h ('k') | ppapi/native_client/src/trusted/plugin/pnacl_options.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698