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.h"
13 #include "base/memory/singleton.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/time/time.h"
16 #include "components/nacl/browser/nacl_browser_delegate.h"
17 #include "components/nacl/browser/nacl_validation_cache.h"
28 static const int kGdbDebugStubPortUnknown
= -1;
29 static const int kGdbDebugStubPortUnused
= 0;
31 // Open an immutable executable file that can be mmapped (or a read-only file).
32 // This function should only be called on a thread that can perform file IO.
33 base::File
OpenNaClReadExecImpl(const base::FilePath
& file_path
,
36 // Represents shared state for all NaClProcessHost objects in the browser.
39 static NaClBrowser
* GetInstance();
41 // Will it be possible to launch a NaCl process, eventually?
44 // Are we ready to launch a NaCl process now? Implies IsOk().
47 // Attempt to asynchronously acquire all resources needed to start a process.
48 // This method is idempotent - it is safe to call multiple times.
49 void EnsureAllResourcesAvailable();
51 // Enqueues reply() in the message loop when all the resources needed to start
52 // a process have been acquired.
53 void WaitForResources(const base::Closure
& reply
);
55 // Asynchronously attempt to get the IRT open.
56 // This is entailed by EnsureInitialized. This method is exposed as part of
57 // the public interface, however, so the IRT can be explicitly opened as
58 // early as possible to prevent autoupdate issues.
59 void EnsureIrtAvailable();
61 // Path to IRT. Available even before IRT is loaded.
62 const base::FilePath
& GetIrtFilePath();
64 // IRT file handle, only available when IsReady().
65 const base::File
& IrtFile() const;
67 // Methods for testing GDB debug stub in browser. If test adds debug stub
68 // port listener, Chrome will allocate a currently-unused TCP port number for
69 // debug stub server instead of a fixed one.
71 // Notify listener that new debug stub TCP port is allocated.
72 void SetProcessGdbDebugStubPort(int process_id
, int port
);
73 void SetGdbDebugStubPortListener(base::Callback
<void(int)> listener
);
74 void ClearGdbDebugStubPortListener();
76 int GetProcessGdbDebugStubPort(int process_id
);
78 enum ValidationCacheStatus
{
84 bool ValidationCacheIsEnabled() const {
85 return validation_cache_is_enabled_
;
88 const std::string
& GetValidationCacheKey() const {
89 return validation_cache_
.GetValidationCacheKey();
92 // The NaCl singleton keeps information about NaCl executable files opened via
93 // PPAPI. This allows the NaCl process to get trusted information about the
94 // file directly from the browser process. In theory, a compromised renderer
95 // could provide a writable file handle or lie about the file's path. If we
96 // trusted the handle was read only but it was not, an mmapped file could be
97 // modified after validation, allowing an escape from the NaCl sandbox.
98 // Similarly, if we trusted the file path corresponded to the file handle but
99 // it did not, the validation cache could be tricked into bypassing validation
101 // Instead of allowing these attacks, the NaCl process only trusts information
102 // it gets directly from the browser process. Because the information is
103 // stored in a cache of bounded size, it is not guaranteed the browser process
104 // will be able to provide the requested information. In these cases, the
105 // NaCl process must make conservative assumptions about the origin of the
107 // In theory, a compromised renderer could guess file tokens in an attempt to
108 // read files it normally doesn't have access to. This would not compromise
109 // the NaCl sandbox, however, and only has a 1 in ~2**120 chance of success
111 // TODO(ncbray): move the cache onto NaClProcessHost so that we don't need to
112 // rely on tokens being unguessable by another process.
113 void PutFilePath(const base::FilePath
& path
, uint64
* file_token_lo
,
114 uint64
* file_token_hi
);
115 bool GetFilePath(uint64 file_token_lo
, uint64 file_token_hi
,
116 base::FilePath
* path
);
118 bool QueryKnownToValidate(const std::string
& signature
, bool off_the_record
);
119 void SetKnownToValidate(const std::string
& signature
, bool off_the_record
);
120 void ClearValidationCache(const base::Closure
& callback
);
122 // Get path to NaCl loader on the filesystem if possible.
123 // |exe_path| does not change if the method fails.
124 bool GetNaCl64ExePath(base::FilePath
* exe_path
);
128 static void SetDelegate(NaClBrowserDelegate
* delegate
);
129 static NaClBrowserDelegate
* GetDelegate();
131 // Each time a NaCl process ends, the browser is notified.
132 void OnProcessEnd(int process_id
);
133 // Support for NaCl crash throttling.
134 // Each time a NaCl module crashes, the browser is notified.
135 void OnProcessCrashed();
136 // If "too many" crashes occur within a given time period, NaCl is throttled
137 // until the rate again drops below the threshold.
141 friend struct DefaultSingletonTraits
<NaClBrowser
>;
143 enum NaClResourceState
{
144 NaClResourceUninitialized
,
145 NaClResourceRequested
,
152 void InitIrtFilePath();
154 void OpenIrtLibraryFile();
156 void OnIrtOpened(scoped_ptr
<base::FileProxy
> file_proxy
,
157 base::File::Error error_code
);
159 void InitValidationCacheFilePath();
160 void EnsureValidationCacheAvailable();
161 void OnValidationCacheLoaded(const std::string
* data
);
162 void RunWithoutValidationCache();
164 // Dispatch waiting tasks if we are ready, or if we know we'll never be ready.
167 // Indicate that it is impossible to launch a NaCl process.
170 void MarkValidationCacheAsModified();
171 void PersistValidationCache();
174 base::File irt_file_
;
175 base::FilePath irt_filepath_
;
176 NaClResourceState irt_state_
;
177 NaClValidationCache validation_cache_
;
178 NaClValidationCache off_the_record_validation_cache_
;
179 base::FilePath validation_cache_file_path_
;
180 bool validation_cache_is_enabled_
;
181 bool validation_cache_is_modified_
;
182 NaClResourceState validation_cache_state_
;
183 base::Callback
<void(int)> debug_stub_port_listener_
;
185 // Map from process id to debug stub port if any.
186 typedef std::map
<int, int> GdbDebugStubPortMap
;
187 GdbDebugStubPortMap gdb_debug_stub_port_map_
;
189 typedef base::HashingMRUCache
<std::string
, base::FilePath
> PathCacheType
;
190 PathCacheType path_cache_
;
194 // A list of pending tasks to start NaCl processes.
195 std::vector
<base::Closure
> waiting_
;
197 scoped_ptr
<NaClBrowserDelegate
> browser_delegate_
;
199 std::deque
<base::Time
> crash_times_
;
201 // Singletons get destroyed at shutdown.
202 base::WeakPtrFactory
<NaClBrowser
> weak_factory_
;
204 DISALLOW_COPY_AND_ASSIGN(NaClBrowser
);
209 #endif // COMPONENTS_NACL_BROWSER_NACL_BROWSER_H_