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

Side by Side Diff: chrome/browser/nacl_host/nacl_browser.cc

Issue 14750007: NaCl: enable meta-based validation for shared libraries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tweaks 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 "chrome/browser/nacl_host/nacl_browser.h" 5 #include "chrome/browser/nacl_host/nacl_browser.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "base/pickle.h" 12 #include "base/pickle.h"
13 #include "base/rand_util.h"
13 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
14 #include "base/win/windows_version.h" 15 #include "base/win/windows_version.h"
15 #include "build/build_config.h" 16 #include "build/build_config.h"
16 #include "chrome/common/chrome_paths.h" 17 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_paths_internal.h" 18 #include "chrome/common/chrome_paths_internal.h"
18 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
20 #include "extensions/common/url_pattern.h" 21 #include "extensions/common/url_pattern.h"
21 #include "googleurl/src/gurl.h" 22 #include "googleurl/src/gurl.h"
22 23
23 namespace { 24 namespace {
24 25
25 // An arbitrary delay to coalesce multiple writes to the cache. 26 // An arbitrary delay to coalesce multiple writes to the cache.
26 const int kValidationCacheCoalescingTimeMS = 6000; 27 const int kValidationCacheCoalescingTimeMS = 6000;
27 const char kValidationCacheSequenceName[] = "NaClValidationCache"; 28 const char kValidationCacheSequenceName[] = "NaClValidationCache";
28 const base::FilePath::CharType kValidationCacheFileName[] = 29 const base::FilePath::CharType kValidationCacheFileName[] =
29 FILE_PATH_LITERAL("nacl_validation_cache.bin"); 30 FILE_PATH_LITERAL("nacl_validation_cache.bin");
30 31
31 const bool kValidationCacheEnabledByDefault = true; 32 const bool kValidationCacheEnabledByDefault = true;
32 33
33 enum ValidationCacheStatus { 34 enum ValidationCacheStatus {
34 CACHE_MISS = 0, 35 CACHE_MISS = 0,
35 CACHE_HIT, 36 CACHE_HIT,
36 CACHE_MAX 37 CACHE_MAX
37 }; 38 };
38 39
40 // Keep the cache bounded to an arbitrary size. If it's too small, useful
41 // entries could be evicted when multiple .nexes are loaded at once. On the
42 // other hand, entries are not always claimed (and hence removed), so the size
43 // of the cache will likely saturate at its maximum size.
44 // Entries may not be claimed for two main reasons. 1) the NaCl process could
45 // be killed while it is loading. 2) the trusted NaCl plugin opens files using
46 // the code path but doesn't resolve them.
47 // TODO(ncbray) don't cache files that the plugin will not resolve.
48 const int kFilePathCacheSize = 100;
49
39 const base::FilePath::StringType NaClIrtName() { 50 const base::FilePath::StringType NaClIrtName() {
40 base::FilePath::StringType irt_name(FILE_PATH_LITERAL("nacl_irt_")); 51 base::FilePath::StringType irt_name(FILE_PATH_LITERAL("nacl_irt_"));
41 52
42 #if defined(ARCH_CPU_X86_FAMILY) 53 #if defined(ARCH_CPU_X86_FAMILY)
43 #if defined(ARCH_CPU_X86_64) 54 #if defined(ARCH_CPU_X86_64)
44 bool is64 = true; 55 bool is64 = true;
45 #elif defined(OS_WIN) 56 #elif defined(OS_WIN)
46 bool is64 = (base::win::OSInfo::GetInstance()->wow64_status() == 57 bool is64 = (base::win::OSInfo::GetInstance()->wow64_status() ==
47 base::win::OSInfo::WOW64_ENABLED); 58 base::win::OSInfo::WOW64_ENABLED);
48 #else 59 #else
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 UMA_HISTOGRAM_ENUMERATION("NaCl.ValidationCache.Query", status, CACHE_MAX); 110 UMA_HISTOGRAM_ENUMERATION("NaCl.ValidationCache.Query", status, CACHE_MAX);
100 } 111 }
101 112
102 void LogCacheSet(ValidationCacheStatus status) { 113 void LogCacheSet(ValidationCacheStatus status) {
103 // Bucket zero is reserved for future use. 114 // Bucket zero is reserved for future use.
104 UMA_HISTOGRAM_ENUMERATION("NaCl.ValidationCache.Set", status, CACHE_MAX); 115 UMA_HISTOGRAM_ENUMERATION("NaCl.ValidationCache.Set", status, CACHE_MAX);
105 } 116 }
106 117
107 } // namespace 118 } // namespace
108 119
120 namespace nacl {
121
122 void OpenNaClExecutableImpl(const base::FilePath& file_path,
123 base::PlatformFile* file) {
124 // Get a file descriptor. On Windows, we need 'GENERIC_EXECUTE' in order to
125 // memory map the executable.
126 // IMPORTANT: This file descriptor must not have write access - that could
127 // allow a NaCl inner sandbox escape.
128 base::PlatformFileError error_code;
129 *file = base::CreatePlatformFile(
130 file_path,
131 (base::PLATFORM_FILE_OPEN |
132 base::PLATFORM_FILE_READ |
133 base::PLATFORM_FILE_EXECUTE), // Windows only flag.
134 NULL,
135 &error_code);
136 if (error_code != base::PLATFORM_FILE_OK) {
137 *file = base::kInvalidPlatformFileValue;
138 return;
139 }
140 // Check that the file does not reference a directory. Returning a descriptor
141 // to an extension directory could allow an outer sandbox escape. openat(...)
142 // could be used to traverse into the file system.
143 base::PlatformFileInfo file_info;
144 if (!base::GetPlatformFileInfo(*file, &file_info) ||
145 file_info.is_directory) {
146 base::ClosePlatformFile(*file);
147 *file = base::kInvalidPlatformFileValue;
148 return;
149 }
150 }
151
152 }
153
109 NaClBrowser::NaClBrowser() 154 NaClBrowser::NaClBrowser()
110 : weak_factory_(this), 155 : weak_factory_(this),
111 irt_platform_file_(base::kInvalidPlatformFileValue), 156 irt_platform_file_(base::kInvalidPlatformFileValue),
112 irt_filepath_(), 157 irt_filepath_(),
113 irt_state_(NaClResourceUninitialized), 158 irt_state_(NaClResourceUninitialized),
114 debug_patterns_(), 159 debug_patterns_(),
115 inverse_debug_patterns_(false), 160 inverse_debug_patterns_(false),
116 validation_cache_file_path_(), 161 validation_cache_file_path_(),
117 validation_cache_is_enabled_( 162 validation_cache_is_enabled_(
118 CheckEnvVar("NACL_VALIDATION_CACHE", 163 CheckEnvVar("NACL_VALIDATION_CACHE",
119 kValidationCacheEnabledByDefault)), 164 kValidationCacheEnabledByDefault)),
120 validation_cache_is_modified_(false), 165 validation_cache_is_modified_(false),
121 validation_cache_state_(NaClResourceUninitialized), 166 validation_cache_state_(NaClResourceUninitialized),
167 path_cache_(kFilePathCacheSize),
122 ok_(true) { 168 ok_(true) {
123 InitIrtFilePath(); 169 InitIrtFilePath();
124 InitValidationCacheFilePath(); 170 InitValidationCacheFilePath();
125 } 171 }
126 172
127 NaClBrowser::~NaClBrowser() { 173 NaClBrowser::~NaClBrowser() {
128 if (irt_platform_file_ != base::kInvalidPlatformFileValue) 174 if (irt_platform_file_ != base::kInvalidPlatformFileValue)
129 base::ClosePlatformFile(irt_platform_file_); 175 base::ClosePlatformFile(irt_platform_file_);
130 } 176 }
131 177
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 void NaClBrowser::WaitForResources(const base::Closure& reply) { 411 void NaClBrowser::WaitForResources(const base::Closure& reply) {
366 waiting_.push_back(reply); 412 waiting_.push_back(reply);
367 EnsureAllResourcesAvailable(); 413 EnsureAllResourcesAvailable();
368 CheckWaiting(); 414 CheckWaiting();
369 } 415 }
370 416
371 const base::FilePath& NaClBrowser::GetIrtFilePath() { 417 const base::FilePath& NaClBrowser::GetIrtFilePath() {
372 return irt_filepath_; 418 return irt_filepath_;
373 } 419 }
374 420
421 void NaClBrowser::PutFilePath(const base::FilePath& path, uint64* file_token_lo,
422 uint64* file_token_hi) {
423 while (true) {
424 uint64 file_token[2] = {base::RandUint64(), base::RandUint64()};
425 // A zero file_token indicates there is no file_token, if we get zero, ask
426 // for another number.
427 if (file_token[0] != 0 || file_token[1] != 0) {
428 // If the file_token is in use, ask for another number.
429 std::string key(reinterpret_cast<char*>(file_token), sizeof(file_token));
430 PathCacheType::iterator iter = path_cache_.Peek(key);
431 if (iter == path_cache_.end()) {
432 path_cache_.Put(key, path);
433 *file_token_lo = file_token[0];
434 *file_token_hi = file_token[1];
435 break;
436 }
437 }
438 }
439 }
440
441 bool NaClBrowser::GetFilePath(uint64 file_token_lo, uint64 file_token_hi,
442 base::FilePath* path) {
443 uint64 file_token[2] = {file_token_lo, file_token_hi};
444 std::string key(reinterpret_cast<char*>(file_token), sizeof(file_token));
445 PathCacheType::iterator iter = path_cache_.Peek(key);
446 if (iter == path_cache_.end()) {
447 *path = base::FilePath(FILE_PATH_LITERAL(""));
448 return false;
449 }
450 *path = iter->second;
451 path_cache_.Erase(iter);
452 return true;
453 }
454
455
375 bool NaClBrowser::QueryKnownToValidate(const std::string& signature, 456 bool NaClBrowser::QueryKnownToValidate(const std::string& signature,
376 bool off_the_record) { 457 bool off_the_record) {
377 if (off_the_record) { 458 if (off_the_record) {
378 // If we're off the record, don't reorder the main cache. 459 // If we're off the record, don't reorder the main cache.
379 return validation_cache_.QueryKnownToValidate(signature, false) || 460 return validation_cache_.QueryKnownToValidate(signature, false) ||
380 off_the_record_validation_cache_.QueryKnownToValidate(signature, true); 461 off_the_record_validation_cache_.QueryKnownToValidate(signature, true);
381 } else { 462 } else {
382 bool result = validation_cache_.QueryKnownToValidate(signature, true); 463 bool result = validation_cache_.QueryKnownToValidate(signature, true);
383 LogCacheQuery(result ? CACHE_HIT : CACHE_MISS); 464 LogCacheQuery(result ? CACHE_HIT : CACHE_MISS);
384 // Queries can modify the MRU order of the cache. 465 // Queries can modify the MRU order of the cache.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 // because it can degrade the responsiveness of the browser. 546 // because it can degrade the responsiveness of the browser.
466 // The task is sequenced so that multiple writes happen in order. 547 // The task is sequenced so that multiple writes happen in order.
467 content::BrowserThread::PostBlockingPoolSequencedTask( 548 content::BrowserThread::PostBlockingPoolSequencedTask(
468 kValidationCacheSequenceName, 549 kValidationCacheSequenceName,
469 FROM_HERE, 550 FROM_HERE,
470 base::Bind(WriteCache, validation_cache_file_path_, 551 base::Bind(WriteCache, validation_cache_file_path_,
471 base::Owned(pickle))); 552 base::Owned(pickle)));
472 } 553 }
473 validation_cache_is_modified_ = false; 554 validation_cache_is_modified_ = false;
474 } 555 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698