1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_NACL_BROWSER_NACL_BROWSER_H_
6 #define COMPONENTS_NACL_BROWSER_NACL_BROWSER_H_
10 #include "base/bind.h"
11 #include "base/containers/mru_cache.h"
12 #include "base/files/file_util_proxy.h"
13 #include "base/memory/singleton.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/platform_file.h"
16 #include "base/time/time.h"
17 #include "components/nacl/browser/nacl_validation_cache.h"
18 #include "components/nacl/common/nacl_browser_delegate.h"
25 // Open an immutable executable file that can be mmapped.
26 // This function should only be called on a thread that can perform file IO.
27 void OpenNaClExecutableImpl(const base::FilePath& file_path,
28 base::PlatformFile* file);
30 // Represents shared state for all NaClProcessHost objects in the browser.
33 static NaClBrowser* GetInstance();
35 // Will it be possible to launch a NaCl process, eventually?
38 // Are we ready to launch a NaCl process now? Implies IsOk().
41 // Attempt to asynchronously acquire all resources needed to start a process.
42 // This method is idempotent - it is safe to call multiple times.
43 void EnsureAllResourcesAvailable();
45 // Enqueues reply() in the message loop when all the resources needed to start
46 // a process have been acquired.
47 void WaitForResources(const base::Closure& reply);
49 // Asynchronously attempt to get the IRT open.
50 // This is entailed by EnsureInitialized. This method is exposed as part of
51 // the public interface, however, so the IRT can be explicitly opened as
52 // early as possible to prevent autoupdate issues.
53 void EnsureIrtAvailable();
55 // Path to IRT. Available even before IRT is loaded.
56 const base::FilePath& GetIrtFilePath();
58 // IRT file handle, only available when IsReady().
59 base::PlatformFile IrtFile() const;
61 // Methods for testing GDB debug stub in browser. If test adds debug stub
62 // port listener, Chrome will allocate a currently-unused TCP port number for
63 // debug stub server instead of a fixed one.
65 // Notify listener that new debug stub TCP port is allocated.
66 void FireGdbDebugStubPortOpened(int port);
67 bool HasGdbDebugStubPortListener();
68 void SetGdbDebugStubPortListener(base::Callback<void(int)> listener);
69 void ClearGdbDebugStubPortListener();
71 bool ValidationCacheIsEnabled() const {
72 return validation_cache_is_enabled_;
75 const std::string& GetValidationCacheKey() const {
76 return validation_cache_.GetValidationCacheKey();
79 // The NaCl singleton keeps information about NaCl executable files opened via
80 // PPAPI. This allows the NaCl process to get trusted information about the
81 // file directly from the browser process. In theory, a compromised renderer
82 // could provide a writable file handle or lie about the file's path. If we
83 // trusted the handle was read only but it was not, an mmapped file could be
84 // modified after validation, allowing an escape from the NaCl sandbox.
85 // Similarly, if we trusted the file path corresponded to the file handle but
86 // it did not, the validation cache could be tricked into bypassing validation
88 // Instead of allowing these attacks, the NaCl process only trusts information
89 // it gets directly from the browser process. Because the information is
90 // stored in a cache of bounded size, it is not guaranteed the browser process
91 // will be able to provide the requested information. In these cases, the
92 // NaCl process must make conservative assumptions about the origin of the
94 // In theory, a compromised renderer could guess file tokens in an attempt to
95 // read files it normally doesn't have access to. This would not compromise
96 // the NaCl sandbox, however, and only has a 1 in ~2**120 chance of success
98 // TODO(ncbray): move the cache onto NaClProcessHost so that we don't need to
99 // rely on tokens being unguessable by another process.
100 void PutFilePath(const base::FilePath& path, uint64* file_token_lo,
101 uint64* file_token_hi);
102 bool GetFilePath(uint64 file_token_lo, uint64 file_token_hi,
103 base::FilePath* path);
105 bool QueryKnownToValidate(const std::string& signature, bool off_the_record);
106 void SetKnownToValidate(const std::string& signature, bool off_the_record);
107 void ClearValidationCache(const base::Closure& callback);
109 // Get path to NaCl loader on the filesystem if possible.
110 // |exe_path| does not change if the method fails.
111 bool GetNaCl64ExePath(base::FilePath* exe_path);
115 static void SetDelegate(NaClBrowserDelegate* delegate);
116 static NaClBrowserDelegate* GetDelegate();
118 // Support for NaCl crash throttling.
119 // Each time a NaCl module crashes, the browser is notified.
120 void OnProcessCrashed();
121 // If "too many" crashes occur within a given time period, NaCl is throttled
122 // until the rate again drops below the threshold.
126 friend struct DefaultSingletonTraits<NaClBrowser>;
128 enum NaClResourceState {
129 NaClResourceUninitialized,
130 NaClResourceRequested,
137 void InitIrtFilePath();
139 void OpenIrtLibraryFile();
141 void OnIrtOpened(base::PlatformFileError error_code,
142 base::PassPlatformFile file, bool created);
144 void InitValidationCacheFilePath();
145 void EnsureValidationCacheAvailable();
146 void OnValidationCacheLoaded(const std::string* data);
147 void RunWithoutValidationCache();
149 // Dispatch waiting tasks if we are ready, or if we know we'll never be ready.
152 // Indicate that it is impossible to launch a NaCl process.
155 void MarkValidationCacheAsModified();
156 void PersistValidationCache();
158 // Singletons get destroyed at shutdown.
159 base::WeakPtrFactory<NaClBrowser> weak_factory_;
161 base::PlatformFile irt_platform_file_;
162 base::FilePath irt_filepath_;
163 NaClResourceState irt_state_;
164 NaClValidationCache validation_cache_;
165 NaClValidationCache off_the_record_validation_cache_;
166 base::FilePath validation_cache_file_path_;
167 bool validation_cache_is_enabled_;
168 bool validation_cache_is_modified_;
169 NaClResourceState validation_cache_state_;
170 base::Callback<void(int)> debug_stub_port_listener_;
172 typedef base::HashingMRUCache<std::string, base::FilePath> PathCacheType;
173 PathCacheType path_cache_;
177 // A list of pending tasks to start NaCl processes.
178 std::vector<base::Closure> waiting_;
180 scoped_ptr<NaClBrowserDelegate> browser_delegate_;
182 std::deque<base::Time> crash_times_;
184 DISALLOW_COPY_AND_ASSIGN(NaClBrowser);
189 #endif // COMPONENTS_NACL_BROWSER_NACL_BROWSER_H_