diff options
author | ncbray@chromium.org <ncbray@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 00:19:27 +0000 |
---|---|---|
committer | ncbray@chromium.org <ncbray@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 00:19:27 +0000 |
commit | 041834525ed2e88ecdd260f449011d778fe6cf2a (patch) | |
tree | f41851d0f9ff423856b5c9c69f72d5c9bc299de6 /chrome/browser/nacl_host/nacl_process_host.cc | |
parent | 045098dbcd386e23ee9b69d9d453f5ec41cc8298 (diff) | |
download | chromium_src-041834525ed2e88ecdd260f449011d778fe6cf2a.zip chromium_src-041834525ed2e88ecdd260f449011d778fe6cf2a.tar.gz chromium_src-041834525ed2e88ecdd260f449011d778fe6cf2a.tar.bz2 |
NaCl: enable meta-based validation for shared libraries.
This is the Chrome-side half of a CL to allow mmaping and skipping validation
for chrome-extension: files we have seen before and know are safe. To do this
we need to know the path of the file on disk, but we don't entirely trust the
renderer not to tamper with it. To work around this, a nonce is passed along
with the file handle. This nonce can be used by the NaCl process to acquire the
file handle directly from the browser process, as well as a fresh copy of the
file handle.
This change significantly revises the OpenNaClExecutable method of the
PPB_NaCl_Private interface. The method was added anticipation of this CL, but
the overall design shifted after the method was added.
BUG=https://code.google.com/p/chromium/issues/detail?id=224434
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=202278
R=dmichael@chromium.org, jschuh@chromium.org, mseaborn@chromium.org
Review URL: https://codereview.chromium.org/14750007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202702 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/nacl_host/nacl_process_host.cc')
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.cc | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index e67b0df..037006d 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -619,6 +619,8 @@ bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { OnQueryKnownToValidate) IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, OnSetKnownToValidate) + IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken, + OnResolveFileToken) #if defined(OS_WIN) IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, OnAttachDebugExceptionHandler) @@ -757,7 +759,6 @@ bool NaClProcessHost::StartNaClExecution() { if (params.uses_irt) { base::PlatformFile irt_file = nacl_browser->IrtFile(); CHECK_NE(irt_file, base::kInvalidPlatformFileValue); - // Send over the IRT file handle. We don't close our own copy! if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) return false; @@ -926,6 +927,86 @@ void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { NaClBrowser::GetInstance()->SetKnownToValidate(signature, off_the_record_); } +void NaClProcessHost::FileResolved( + base::PlatformFile* file, + const base::FilePath& file_path, + IPC::Message* reply_msg) { + if (*file != base::kInvalidPlatformFileValue) { + IPC::PlatformFileForTransit handle = IPC::GetFileHandleForProcess( + *file, + process_->GetData().handle, + true /* close_source */); + NaClProcessMsg_ResolveFileToken::WriteReplyParams( + reply_msg, + handle, + file_path); + } else { + NaClProcessMsg_ResolveFileToken::WriteReplyParams( + reply_msg, + IPC::InvalidPlatformFileForTransit(), + base::FilePath(FILE_PATH_LITERAL(""))); + } + Send(reply_msg); +} + +void NaClProcessHost::OnResolveFileToken(uint64 file_token_lo, + uint64 file_token_hi, + IPC::Message* reply_msg) { + // Was the file registered? + // + // Note that the file path cache is of bounded size, and old entries can get + // evicted. If a large number of NaCl modules are being launched at once, + // resolving the file_token may fail because the path cache was thrashed + // while the file_token was in flight. In this case the query fails, and we + // need to fall back to the slower path. + // + // However: each NaCl process will consume 2-3 entries as it starts up, this + // means that eviction will not happen unless you start up 33+ NaCl processes + // at the same time, and this still requires worst-case timing. As a + // practical matter, no entries should be evicted prematurely. + // The cache itself should take ~ (150 characters * 2 bytes/char + ~60 bytes + // data structure overhead) * 100 = 35k when full, so making it bigger should + // not be a problem, if needed. + // + // Each NaCl process will consume 2-3 entries because the manifest and main + // nexe are currently not resolved. Shared libraries will be resolved. They + // will be loaded sequentially, so they will only consume a single entry + // while the load is in flight. + // + // TODO(ncbray): track behavior with UMA. If entries are getting evicted or + // bogus keys are getting queried, this would be good to know. + base::FilePath file_path; + if (!NaClBrowser::GetInstance()->GetFilePath(file_token_lo, file_token_hi, + &file_path)) { + NaClProcessMsg_ResolveFileToken::WriteReplyParams( + reply_msg, + IPC::InvalidPlatformFileForTransit(), + base::FilePath(FILE_PATH_LITERAL(""))); + Send(reply_msg); + return; + } + + // Scratch space to share between the callbacks. + base::PlatformFile* data = new base::PlatformFile(); + + // Open the file. + if (!content::BrowserThread::PostBlockingPoolTaskAndReply( + FROM_HERE, + base::Bind(nacl::OpenNaClExecutableImpl, + file_path, data), + base::Bind(&NaClProcessHost::FileResolved, + weak_factory_.GetWeakPtr(), + base::Owned(data), + file_path, + reply_msg))) { + NaClProcessMsg_ResolveFileToken::WriteReplyParams( + reply_msg, + IPC::InvalidPlatformFileForTransit(), + base::FilePath(FILE_PATH_LITERAL(""))); + Send(reply_msg); + } +} + #if defined(OS_WIN) void NaClProcessHost::OnAttachDebugExceptionHandler(const std::string& info, IPC::Message* reply_msg) { |