| Index: chrome/browser/nacl_host/nacl_browser.cc
|
| diff --git a/chrome/browser/nacl_host/nacl_browser.cc b/chrome/browser/nacl_host/nacl_browser.cc
|
| index d05d42e0b6ece6e934517557f110019fe93345e1..b47187aeb979b4e81dbc34264c3ef918f55330aa 100644
|
| --- a/chrome/browser/nacl_host/nacl_browser.cc
|
| +++ b/chrome/browser/nacl_host/nacl_browser.cc
|
| @@ -10,6 +10,7 @@
|
| #include "base/metrics/histogram.h"
|
| #include "base/path_service.h"
|
| #include "base/pickle.h"
|
| +#include "base/rand_util.h"
|
| #include "base/strings/string_split.h"
|
| #include "base/win/windows_version.h"
|
| #include "build/build_config.h"
|
| @@ -36,6 +37,12 @@ enum ValidationCacheStatus {
|
| CACHE_MAX
|
| };
|
|
|
| +// Keep the cache bounded to an arbitrary size. If it's too small, useful
|
| +// entries could be evicted when multiple .nexes are loaded at once. On the
|
| +// other hand, entries are not always claimed, so the size of the cache will
|
| +// likely saturate at its maximum size.
|
| +const int kFilePathCacheSize = 100;
|
| +
|
| const base::FilePath::StringType NaClIrtName() {
|
| base::FilePath::StringType irt_name(FILE_PATH_LITERAL("nacl_irt_"));
|
|
|
| @@ -106,6 +113,40 @@ void LogCacheSet(ValidationCacheStatus status) {
|
|
|
| } // namespace
|
|
|
| +namespace nacl {
|
| +
|
| +void OpenNaClExecutableImpl(const base::FilePath& file_path,
|
| + base::PlatformFile* file) {
|
| + // Get a file descriptor. On Windows, we need 'GENERIC_EXECUTE' in order to
|
| + // memory map the executable.
|
| + // IMPORTANT: This file descriptor must not have write access - that could
|
| + // allow a NaCl inner sandbox escape.
|
| + base::PlatformFileError error_code;
|
| + *file = base::CreatePlatformFile(
|
| + file_path,
|
| + (base::PLATFORM_FILE_OPEN |
|
| + base::PLATFORM_FILE_READ |
|
| + base::PLATFORM_FILE_EXECUTE), // Windows only flag.
|
| + NULL,
|
| + &error_code);
|
| + if (error_code != base::PLATFORM_FILE_OK) {
|
| + *file = base::kInvalidPlatformFileValue;
|
| + return;
|
| + }
|
| + // Check that the file does not reference a directory. Returning a descriptor
|
| + // to an extension directory could allow an outer sandbox escape. openat
|
| + // could be used to traverse into the file system.
|
| + base::PlatformFileInfo file_info;
|
| + if (!base::GetPlatformFileInfo(*file, &file_info) ||
|
| + file_info.is_directory) {
|
| + base::ClosePlatformFile(*file);
|
| + *file = base::kInvalidPlatformFileValue;
|
| + return;
|
| + }
|
| +}
|
| +
|
| +}
|
| +
|
| NaClBrowser::NaClBrowser()
|
| : weak_factory_(this),
|
| irt_platform_file_(base::kInvalidPlatformFileValue),
|
| @@ -119,6 +160,7 @@ NaClBrowser::NaClBrowser()
|
| kValidationCacheEnabledByDefault)),
|
| validation_cache_is_modified_(false),
|
| validation_cache_state_(NaClResourceUninitialized),
|
| + path_cache_(kFilePathCacheSize),
|
| ok_(true) {
|
| InitIrtFilePath();
|
| InitValidationCacheFilePath();
|
| @@ -372,6 +414,41 @@ const base::FilePath& NaClBrowser::GetIrtFilePath() {
|
| return irt_filepath_;
|
| }
|
|
|
| +void NaClBrowser::PutFilePath(const base::FilePath& path, uint64 *file_token_lo,
|
| + uint64 *file_token_hi) {
|
| + while (true) {
|
| + uint64 file_token[2] = {base::RandUint64(), base::RandUint64()};
|
| + // A zero file_token indicates there is no file_token, if we get zero, ask
|
| + // for another number.
|
| + if (file_token[0] != 0 || file_token[1] != 0) {
|
| + // If the file_token is in use, ask for another number.
|
| + std::string key(reinterpret_cast<char *>(file_token), sizeof(file_token));
|
| + PathCacheType::iterator iter = path_cache_.Peek(key);
|
| + if (iter == path_cache_.end()) {
|
| + path_cache_.Put(key, path);
|
| + *file_token_lo = file_token[0];
|
| + *file_token_hi = file_token[1];
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool NaClBrowser::GetFilePath(uint64 file_token_lo, uint64 file_token_hi,
|
| + base::FilePath* path) {
|
| + uint64 file_token[2] = {file_token_lo, file_token_hi};
|
| + std::string key(reinterpret_cast<char *>(file_token), sizeof(file_token));
|
| + PathCacheType::iterator iter = path_cache_.Peek(key);
|
| + if (iter == path_cache_.end()) {
|
| + *path = base::FilePath(FILE_PATH_LITERAL(""));
|
| + return false;
|
| + }
|
| + *path = iter->second;
|
| + path_cache_.Erase(iter);
|
| + return true;
|
| +}
|
| +
|
| +
|
| bool NaClBrowser::QueryKnownToValidate(const std::string& signature,
|
| bool off_the_record) {
|
| if (off_the_record) {
|
|
|