diff options
author | nduca@google.com <nduca@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-27 00:59:39 +0000 |
---|---|---|
committer | nduca@google.com <nduca@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-27 00:59:39 +0000 |
commit | d29b3a8948b3ae214d3fefcb61ecfb000762a282 (patch) | |
tree | 945fdff2ab8b501f01fde0d63984f0d55f43b5ab | |
parent | 42f06f9ca2fe07018a88994569f87373a7c6c578 (diff) | |
download | chromium_src-d29b3a8948b3ae214d3fefcb61ecfb000762a282.zip chromium_src-d29b3a8948b3ae214d3fefcb61ecfb000762a282.tar.gz chromium_src-d29b3a8948b3ae214d3fefcb61ecfb000762a282.tar.bz2 |
Revert 129061 - Create a database for NaCl validation caching that is shared between processes.
Reverted due to perf regression, see
http://chromegw.corp.google.com/i/chromium/builders/Linux%20x64/builds/25780
This change primarily entails creating a SyncChannel between sel_ldr and the
browser. Queries to the database could be made from any thread inside sel_ldr,
so the query mechanism needs to be thread safe.
This feature is currently disabled by default, and requires an environment
variable to enable. A few changes need to be made before this features is safe
and can be enabled, such as making sure each installation has a unique,
crypographically secure key.
BUG= http://code.google.com/p/nativeclient/issues/detail?id=2515
TEST= Run NaCl w/ NACL_VALIDATION_CACHE=1
Review URL: http://codereview.chromium.org/9796006
TBR=ncbray@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9808113
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129077 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.cc | 53 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.h | 7 | ||||
-rw-r--r-- | chrome/chrome_exe.gypi | 1 | ||||
-rw-r--r-- | chrome/common/nacl_messages.h | 13 | ||||
-rw-r--r-- | chrome/nacl/nacl_listener.cc | 91 | ||||
-rw-r--r-- | chrome/nacl/nacl_listener.h | 22 | ||||
-rw-r--r-- | crypto/crypto.gyp | 53 | ||||
-rw-r--r-- | crypto/hmac_win.cc | 25 | ||||
-rw-r--r-- | crypto/symmetric_key_win.cc | 13 |
9 files changed, 32 insertions, 246 deletions
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index c4c602e..e493752 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/command_line.h" -#include "base/memory/mru_cache.h" #include "base/memory/singleton.h" #include "base/path_service.h" #include "base/string_util.h" @@ -196,27 +195,16 @@ class NaClBrowser { // Path to IRT. Available even before IRT is loaded. const FilePath& GetIrtFilePath(); - // Is the validation signature in the database? - bool QueryKnownToValidate(const std::string& signature); - - // Put the validation signature in the database. - void SetKnownToValidate(const std::string& signature); - private: base::PlatformFile irt_platform_file_; FilePath irt_filepath_; - typedef base::HashingMRUCache<std::string, bool> ValidationCacheType; - ValidationCacheType validation_cache_; - friend struct DefaultSingletonTraits<NaClBrowser>; NaClBrowser() : irt_platform_file_(base::kInvalidPlatformFileValue), - irt_filepath_(), - // For the moment, choose an arbitrary cache size. - validation_cache_(200) { + irt_filepath_() { InitIrtFilePath(); } @@ -855,42 +843,7 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) { internal_->sockets_for_sel_ldr.clear(); } -bool NaClBrowser::QueryKnownToValidate(const std::string& signature) { - ValidationCacheType::iterator iter = validation_cache_.Get(signature); - if (iter == validation_cache_.end()) { - // Not found. - return false; - } else { - return iter->second; - } -} - -void NaClBrowser::SetKnownToValidate(const std::string& signature) { - validation_cache_.Put(signature, true); -} - -void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, - bool* result) { - *result = NaClBrowser::GetInstance()->QueryKnownToValidate(signature); -} - -void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { - NaClBrowser::GetInstance()->SetKnownToValidate(signature); -} - -// Needed to handle sync messages in OnMessageRecieved. -bool NaClProcessHost::Send(IPC::Message* msg) { - return process_->Send(msg); -} - bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) - IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, - OnQueryKnownToValidate) - IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, - OnSetKnownToValidate) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; + NOTREACHED() << "Invalid message with type = " << msg.type(); + return false; } diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h index d4fe80b..f5e51ec 100644 --- a/chrome/browser/nacl_host/nacl_process_host.h +++ b/chrome/browser/nacl_host/nacl_process_host.h @@ -52,8 +52,6 @@ class NaClProcessHost : public content::BrowserChildProcessHostDelegate { void OnDebugExceptionHandlerLaunchedByBroker(); #endif - bool Send(IPC::Message* msg); - private: // Internal class that holds the nacl::Handle objecs so that // nacl_process_host.h doesn't include NaCl headers. Needed since it's @@ -75,10 +73,7 @@ class NaClProcessHost : public content::BrowserChildProcessHostDelegate { void IrtReady(); void SendStart(base::PlatformFile irt_file); - // Message handlers for validation caching. - void OnQueryKnownToValidate(const std::string& signature, bool* result); - void OnSetKnownToValidate(const std::string& signature); - + private: #if defined(OS_WIN) class DebugContext; diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index c1f029b..1271a2d 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi @@ -533,7 +533,6 @@ '../base/base.gyp:base_nacl_win64', '../base/base.gyp:base_static_win64', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64', - '../crypto/crypto.gyp:crypto_nacl_win64', '../ipc/ipc.gyp:ipc_win64', '../sandbox/sandbox.gyp:sandbox_win64', ], diff --git a/chrome/common/nacl_messages.h b/chrome/common/nacl_messages.h index 9c7a6f9..19ead85 100644 --- a/chrome/common/nacl_messages.h +++ b/chrome/common/nacl_messages.h @@ -18,7 +18,7 @@ //----------------------------------------------------------------------------- // NaClProcess messages -// These are messages sent between the browser and the NaCl process. +// These are messages sent from the browser to the NaCl process. // Tells the NaCl process to start. IPC_MESSAGE_CONTROL2(NaClProcessMsg_Start, std::vector<nacl::FileDescriptor> /* sockets */, @@ -47,14 +47,3 @@ IPC_MESSAGE_CONTROL1(NaClProcessMsg_DebugExceptionHandlerLaunched, // Notify the broker that all loader processes have been terminated and it // should shutdown. IPC_MESSAGE_CONTROL0(NaClProcessMsg_StopBroker) - -// Used by the NaCl process to query a database in the browser. The database -// contains the signatures of previously validated code chunks. -IPC_SYNC_MESSAGE_CONTROL1_1(NaClProcessMsg_QueryKnownToValidate, - std::string, /* A validation signature */ - bool /* Can validation be skipped? */) - -// Used by the NaCl process to add a validation signature to the validation -// database in the browser. -IPC_MESSAGE_CONTROL1(NaClProcessMsg_SetKnownToValidate, - std::string /* A validation signature */) diff --git a/chrome/nacl/nacl_listener.cc b/chrome/nacl/nacl_listener.cc index 0500a85..d4a4717 100644 --- a/chrome/nacl/nacl_listener.cc +++ b/chrome/nacl/nacl_listener.cc @@ -5,17 +5,13 @@ #include "chrome/nacl/nacl_listener.h" #include <errno.h> -#include <stdlib.h> #include "base/command_line.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "chrome/common/nacl_messages.h" -#include "chrome/nacl/nacl_validation_db.h" -#include "chrome/nacl/nacl_validation_query.h" -#include "ipc/ipc_sync_channel.h" -#include "ipc/ipc_sync_message_filter.h" +#include "ipc/ipc_channel.h" #include "ipc/ipc_switches.h" #include "native_client/src/trusted/service_runtime/sel_main_chrome.h" @@ -68,85 +64,19 @@ int CreateMemoryObject(size_t size, int executable) { } #endif - -// Use an env var because command line args are eaten by nacl_helper. -bool CheckEnvVar(const char* name, bool default_value) { - bool result = default_value; - const char* var = getenv(name); - if (var && strlen(var) > 0) { - result = var[0] != '0'; - } - return result; -} - } // namespace -class BrowserValidationDBProxy : public NaClValidationDB { - public: - explicit BrowserValidationDBProxy(NaClListener* listener) - : listener_(listener) { - } - - bool QueryKnownToValidate(const std::string& signature) { - // Initialize to false so that if the Send fails to write to the return - // value we're safe. For example if the message is (for some reason) - // dispatched as an async message the return parameter will not be written. - bool result = false; - if (!listener_->Send(new NaClProcessMsg_QueryKnownToValidate(signature, - &result))) { - LOG(ERROR) << "Failed to query NaCl validation cache."; - result = false; - } - return result; - } - - void SetKnownToValidate(const std::string& signature) { - // Caching is optional: NaCl will still work correctly if the IPC fails. - if (!listener_->Send(new NaClProcessMsg_SetKnownToValidate(signature))) { - LOG(ERROR) << "Failed to update NaCl validation cache."; - } - } - - private: - // The listener never dies, otherwise this might be a dangling reference. - NaClListener* listener_; -}; - - -NaClListener::NaClListener() : shutdown_event_(true, false), - io_thread_("NaCl_IOThread"), - main_loop_(NULL), - debug_enabled_(false) { - io_thread_.StartWithOptions(base::Thread::Options(MessageLoop::TYPE_IO, 0)); -} +NaClListener::NaClListener() : debug_enabled_(false) {} -NaClListener::~NaClListener() { - NOTREACHED(); - shutdown_event_.Signal(); -} - -bool NaClListener::Send(IPC::Message* msg) { - DCHECK(main_loop_ != NULL); - if (MessageLoop::current() == main_loop_) { - // This thread owns the channel. - return channel_->Send(msg); - } else { - // This thread does not own the channel. - return filter_->Send(msg); - } -} +NaClListener::~NaClListener() {} void NaClListener::Listen() { std::string channel_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kProcessChannelID); - channel_.reset(new IPC::SyncChannel(this, io_thread_.message_loop_proxy(), - &shutdown_event_)); - filter_.reset(new IPC::SyncMessageFilter(&shutdown_event_)); - channel_->AddFilter(filter_.get()); - channel_->Init(channel_name, IPC::Channel::MODE_CLIENT, true); - main_loop_ = MessageLoop::current(); - main_loop_->Run(); + IPC::Channel channel(channel_name, IPC::Channel::MODE_CLIENT, this); + CHECK(channel.Connect()); + MessageLoop::current()->Run(); } bool NaClListener::OnMessageReceived(const IPC::Message& msg) { @@ -190,15 +120,6 @@ void NaClListener::OnStartSelLdr(std::vector<nacl::FileDescriptor> handles, args->irt_fd = irt_handle; #endif - if (CheckEnvVar("NACL_VALIDATION_CACHE", false)) { - LOG(INFO) << "NaCl validation cache enabled."; - // The cache structure is not freed and exists until the NaCl process exits. - args->validation_cache = CreateValidationCache( - new BrowserValidationDBProxy(this), - // TODO(ncbray) plumb through real keys and versions. - "bogus key for HMAC....", "bogus version"); - } - CHECK(handles.size() == 1); args->imc_bootstrap_handle = nacl::ToNativeHandle(handles[0]); args->enable_exception_handling = enable_exception_handling; diff --git a/chrome/nacl/nacl_listener.h b/chrome/nacl/nacl_listener.h index 2b8bb21..2738d7b 100644 --- a/chrome/nacl/nacl_listener.h +++ b/chrome/nacl/nacl_listener.h @@ -8,17 +8,9 @@ #include <vector> -#include "base/memory/scoped_ptr.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" #include "chrome/common/nacl_types.h" #include "ipc/ipc_channel.h" -namespace IPC { -class SyncChannel; -class SyncMessageFilter; -} - // The NaClListener is an IPC channel listener that waits for a // request to start a NaCl module. class NaClListener : public IPC::Channel::Listener { @@ -29,25 +21,11 @@ class NaClListener : public IPC::Channel::Listener { void Listen(); void set_debug_enabled(bool value) {debug_enabled_ = value;} - bool Send(IPC::Message* msg); - private: void OnStartSelLdr(std::vector<nacl::FileDescriptor> handles, bool enable_exception_handling); virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; - // A channel back to the browser. - scoped_ptr<IPC::SyncChannel> channel_; - - // A filter that allows other threads to use the channel. - scoped_ptr<IPC::SyncMessageFilter> filter_; - - base::WaitableEvent shutdown_event_; - base::Thread io_thread_; - - // Used to identify what thread we're on. - MessageLoop* main_loop_; - bool debug_enabled_; DISALLOW_COPY_AND_ASSIGN(NaClListener); diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp index f095719..405ad0b 100644 --- a/crypto/crypto.gyp +++ b/crypto/crypto.gyp @@ -5,19 +5,6 @@ { 'variables': { 'chromium_code': 1, - # Put all transitive dependencies for Windows HMAC here. - # This is required so that we can build them for nacl win64. - 'hmac_win64_related_sources': [ - 'hmac.cc', - 'hmac.h', - 'hmac_win.cc', - 'secure_util.cc', - 'secure_util.h', - 'symmetric_key.h', - 'symmetric_key_win.cc', - 'third_party/nss/chromium-sha256.h', - 'third_party/nss/sha512.cc', - ], }, 'targets': [ { @@ -144,9 +131,6 @@ },], ], 'sources': [ - # NOTE: all transitive dependencies of HMAC on windows need - # to be placed in the source list above. - '<@(hmac_win64_related_sources)', 'capi_util.cc', 'capi_util.h', 'crypto_export.h', @@ -167,9 +151,12 @@ 'encryptor_nss.cc', 'encryptor_openssl.cc', 'encryptor_win.cc', + 'hmac.cc', + 'hmac.h', 'hmac_mac.cc', 'hmac_nss.cc', 'hmac_openssl.cc', + 'hmac_win.cc', 'keychain_mac.cc', 'keychain_mac.h', 'mac_security_services_lock.cc', @@ -198,6 +185,8 @@ 'secure_hash.h', 'secure_hash_default.cc', 'secure_hash_openssl.cc', + 'secure_util.cc', + 'secure_util.h', 'sha2.cc', 'sha2.h', 'signature_creator.h', @@ -208,14 +197,18 @@ 'signature_verifier.h', 'signature_verifier_nss.cc', 'signature_verifier_openssl.cc', + 'symmetric_key.h', 'symmetric_key_mac.cc', 'symmetric_key_nss.cc', 'symmetric_key_openssl.cc', + 'symmetric_key_win.cc', 'third_party/nss/chromium-blapi.h', 'third_party/nss/chromium-blapit.h', 'third_party/nss/chromium-nss.h', + 'third_party/nss/chromium-sha256.h', 'third_party/nss/pk11akey.cc', 'third_party/nss/secsign.cc', + 'third_party/nss/sha512.cc', ], }, { @@ -288,32 +281,4 @@ ], }, ], - 'conditions': [ - [ 'OS == "win"', { - 'targets': [ - { - 'target_name': 'crypto_nacl_win64', - 'type': '<(component)', - 'dependencies': [ - '../base/base.gyp:base_nacl_win64', - '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64', - ], - 'sources': [ - '<@(hmac_win64_related_sources)', - ], - 'defines': [ - 'CRYPTO_IMPLEMENTATION', - ], - 'msvs_disabled_warnings': [ - 4018, - ], - 'configurations': { - 'Common_Base': { - 'msvs_target_platform': 'x64', - }, - }, - }, - ], - }], - ], } diff --git a/crypto/hmac_win.cc b/crypto/hmac_win.cc index ef3e261..ffd08ce8 100644 --- a/crypto/hmac_win.cc +++ b/crypto/hmac_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -28,19 +28,6 @@ enum { SHA256_BLOCK_SIZE = 64 // Block size (in bytes) of the input to SHA-256. }; -// NSS doesn't accept size_t for text size, divide the data into smaller -// chunks as needed. -void Wrapped_SHA256_Update(SHA256Context* ctx, const unsigned char* text, - size_t text_len) { - const unsigned int kChunkSize = 1 << 30; - while (text_len > kChunkSize) { - SHA256_Update(ctx, text, kChunkSize); - text += kChunkSize; - text_len -= kChunkSize; - } - SHA256_Update(ctx, text, (unsigned int)text_len); -} - // See FIPS 198: The Keyed-Hash Message Authentication Code (HMAC). void ComputeHMACSHA256(const unsigned char* key, size_t key_len, const unsigned char* text, size_t text_len, @@ -51,7 +38,7 @@ void ComputeHMACSHA256(const unsigned char* key, size_t key_len, unsigned char key0[SHA256_BLOCK_SIZE]; if (key_len > SHA256_BLOCK_SIZE) { SHA256_Begin(&ctx); - Wrapped_SHA256_Update(&ctx, key, key_len); + SHA256_Update(&ctx, key, key_len); SHA256_End(&ctx, key0, NULL, SHA256_LENGTH); memset(key0 + SHA256_LENGTH, 0, SHA256_BLOCK_SIZE - SHA256_LENGTH); } else { @@ -70,7 +57,7 @@ void ComputeHMACSHA256(const unsigned char* key, size_t key_len, // Compute the inner hash. SHA256_Begin(&ctx); SHA256_Update(&ctx, padded_key, SHA256_BLOCK_SIZE); - Wrapped_SHA256_Update(&ctx, text, text_len); + SHA256_Update(&ctx, text, text_len); SHA256_End(&ctx, inner_hash, NULL, SHA256_LENGTH); // XOR key0 with opad. @@ -81,7 +68,7 @@ void ComputeHMACSHA256(const unsigned char* key, size_t key_len, SHA256_Begin(&ctx); SHA256_Update(&ctx, padded_key, SHA256_BLOCK_SIZE); SHA256_Update(&ctx, inner_hash, SHA256_LENGTH); - SHA256_End(&ctx, output, NULL, (unsigned int) output_len); + SHA256_End(&ctx, output, NULL, output_len); } } // namespace @@ -151,8 +138,8 @@ bool HMAC::Init(const unsigned char* key, int key_length) { memcpy(key_blob->key_data, key, key_length); if (!CryptImportKey(plat_->provider_, &key_blob_storage[0], - (DWORD)key_blob_storage.size(), 0, - CRYPT_IPSEC_HMAC_KEY, plat_->key_.receive())) { + key_blob_storage.size(), 0, CRYPT_IPSEC_HMAC_KEY, + plat_->key_.receive())) { NOTREACHED(); return false; } diff --git a/crypto/symmetric_key_win.cc b/crypto/symmetric_key_win.cc index 87e0bc3..d2034e0 100644 --- a/crypto/symmetric_key_win.cc +++ b/crypto/symmetric_key_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -50,12 +50,11 @@ ALG_ID GetAESAlgIDForKeySize(size_t key_size_in_bits) { // TODO(wtc): use this function in hmac_win.cc. bool ImportRawKey(HCRYPTPROV provider, ALG_ID alg, - const void* key_data, size_t key_size, + const void* key_data, DWORD key_size, ScopedHCRYPTKEY* key) { DCHECK_GT(key_size, 0); - DWORD actual_size = - static_cast<DWORD>(sizeof(PlaintextBlobHeader) + key_size); + DWORD actual_size = sizeof(PlaintextBlobHeader) + key_size; std::vector<BYTE> tmp_data(actual_size); BYTE* actual_key = &tmp_data[0]; memcpy(actual_key + sizeof(PlaintextBlobHeader), key_data, key_size); @@ -67,7 +66,7 @@ bool ImportRawKey(HCRYPTPROV provider, key_header->hdr.bVersion = CUR_BLOB_VERSION; key_header->hdr.aiKeyAlg = alg; - key_header->cbKeySize = static_cast<DWORD>(key_size); + key_header->cbKeySize = key_size; HCRYPTKEY unsafe_key = NULL; DWORD flags = CRYPT_EXPORTABLE; @@ -185,7 +184,7 @@ bool GenerateHMACKey(size_t key_size_in_bits, if (!ok) return false; - DWORD key_size_in_bytes = static_cast<DWORD>(key_size_in_bits / 8); + DWORD key_size_in_bytes = key_size_in_bits / 8; scoped_array<BYTE> random(new BYTE[key_size_in_bytes]); ok = CryptGenRandom(safe_provider, key_size_in_bytes, random.get()); if (!ok) @@ -259,7 +258,7 @@ bool ComputePBKDF2Block(HCRYPTHASH hash, // Iteration U_1: Compute PRF for S. ok = CryptHashData(safe_hash, reinterpret_cast<const BYTE*>(salt.data()), - static_cast<DWORD>(salt.size()), 0); + salt.size(), 0); if (!ok) return false; |