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

Side by Side Diff: sandbox/win/src/target_services.cc

Issue 1851213002: Remove sandbox on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix nacl compile issues Created 4 years, 8 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
« no previous file with comments | « sandbox/win/src/target_services.h ('k') | sandbox/win/src/threadpool_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "sandbox/win/src/target_services.h"
6
7 #include <new>
8
9 #include <process.h>
10 #include <stdint.h>
11
12 #include "base/win/windows_version.h"
13 #include "sandbox/win/src/crosscall_client.h"
14 #include "sandbox/win/src/handle_closer_agent.h"
15 #include "sandbox/win/src/handle_interception.h"
16 #include "sandbox/win/src/ipc_tags.h"
17 #include "sandbox/win/src/process_mitigations.h"
18 #include "sandbox/win/src/restricted_token_utils.h"
19 #include "sandbox/win/src/sandbox.h"
20 #include "sandbox/win/src/sandbox_nt_util.h"
21 #include "sandbox/win/src/sandbox_types.h"
22 #include "sandbox/win/src/sharedmem_ipc_client.h"
23
24 namespace {
25
26 // Flushing a cached key is triggered by just opening the key and closing the
27 // resulting handle. RegDisablePredefinedCache() is the documented way to flush
28 // HKCU so do not use it with this function.
29 bool FlushRegKey(HKEY root) {
30 HKEY key;
31 if (ERROR_SUCCESS == ::RegOpenKeyExW(root, NULL, 0, MAXIMUM_ALLOWED, &key)) {
32 if (ERROR_SUCCESS != ::RegCloseKey(key))
33 return false;
34 }
35 return true;
36 }
37
38 // This function forces advapi32.dll to release some internally cached handles
39 // that were made during calls to RegOpenkey and RegOpenKeyEx if it is called
40 // with a more restrictive token. Returns true if the flushing is succesful
41 // although this behavior is undocumented and there is no guarantee that in
42 // fact this will happen in future versions of windows.
43 bool FlushCachedRegHandles() {
44 return (FlushRegKey(HKEY_LOCAL_MACHINE) &&
45 FlushRegKey(HKEY_CLASSES_ROOT) &&
46 FlushRegKey(HKEY_USERS));
47 }
48
49 // Checks if we have handle entries pending and runs the closer.
50 // Updates is_csrss_connected based on which handle types are closed.
51 bool CloseOpenHandles(bool* is_csrss_connected) {
52 if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) {
53 sandbox::HandleCloserAgent handle_closer;
54 handle_closer.InitializeHandlesToClose(is_csrss_connected);
55 if (!handle_closer.CloseHandles())
56 return false;
57 }
58
59 return true;
60 }
61
62 // GetUserDefaultLocaleName is not available on WIN XP. So we'll
63 // load it on-the-fly.
64 const wchar_t kKernel32DllName[] = L"kernel32.dll";
65 typedef decltype(GetUserDefaultLocaleName)* GetUserDefaultLocaleNameFunction;
66
67 // Warm up language subsystems before the sandbox is turned on.
68 // Tested on Win8.1 x64:
69 // This needs to happen after RevertToSelf() is called, because (at least) in
70 // the case of GetUserDefaultLCID() it checks the TEB to see if the process is
71 // impersonating (TEB!IsImpersonating). If it is, the cached locale information
72 // is not used, nor is it set. Therefore, calls after RevertToSelf() will not
73 // have warmed-up values to use.
74 bool WarmupWindowsLocales() {
75 // NOTE(liamjm): When last checked (Win 8.1 x64) it wasn't necessary to
76 // warmup all of these functions, but let's not assume that.
77 ::GetUserDefaultLangID();
78 ::GetUserDefaultLCID();
79 static GetUserDefaultLocaleNameFunction GetUserDefaultLocaleName_func =
80 NULL;
81 if (!GetUserDefaultLocaleName_func) {
82 HMODULE kernel32_dll = ::GetModuleHandle(kKernel32DllName);
83 if (!kernel32_dll) {
84 return false;
85 }
86 GetUserDefaultLocaleName_func =
87 reinterpret_cast<GetUserDefaultLocaleNameFunction>(
88 GetProcAddress(kernel32_dll, "GetUserDefaultLocaleName"));
89 if (!GetUserDefaultLocaleName_func) {
90 return false;
91 }
92 }
93 wchar_t localeName[LOCALE_NAME_MAX_LENGTH] = {0};
94 return (0 != GetUserDefaultLocaleName_func(
95 localeName, LOCALE_NAME_MAX_LENGTH * sizeof(wchar_t)));
96 }
97
98 // Used as storage for g_target_services, because other allocation facilities
99 // are not available early. We can't use a regular function static because on
100 // VS2015, because the CRT tries to acquire a lock to guard initialization, but
101 // this code runs before the CRT is initialized.
102 char g_target_services_memory[sizeof(sandbox::TargetServicesBase)];
103 sandbox::TargetServicesBase* g_target_services = nullptr;
104
105 } // namespace
106
107 namespace sandbox {
108
109 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level =
110 INTEGRITY_LEVEL_LAST;
111 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations = 0;
112
113 TargetServicesBase::TargetServicesBase() {
114 }
115
116 ResultCode TargetServicesBase::Init() {
117 process_state_.SetInitCalled();
118 return SBOX_ALL_OK;
119 }
120
121 // Failure here is a breach of security so the process is terminated.
122 void TargetServicesBase::LowerToken() {
123 if (ERROR_SUCCESS !=
124 SetProcessIntegrityLevel(g_shared_delayed_integrity_level))
125 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_INTEGRITY);
126 process_state_.SetRevertedToSelf();
127 // If the client code as called RegOpenKey, advapi32.dll has cached some
128 // handles. The following code gets rid of them.
129 if (!::RevertToSelf())
130 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_DROPTOKEN);
131 if (!FlushCachedRegHandles())
132 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES);
133 if (ERROR_SUCCESS != ::RegDisablePredefinedCache())
134 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE);
135 if (!WarmupWindowsLocales())
136 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_WARMUP);
137 bool is_csrss_connected = true;
138 if (!CloseOpenHandles(&is_csrss_connected))
139 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES);
140 process_state_.SetCsrssConnected(is_csrss_connected);
141 // Enabling mitigations must happen last otherwise handle closing breaks
142 if (g_shared_delayed_mitigations &&
143 !ApplyProcessMitigationsToCurrentProcess(g_shared_delayed_mitigations))
144 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_MITIGATION);
145 }
146
147 ProcessState* TargetServicesBase::GetState() {
148 return &process_state_;
149 }
150
151 TargetServicesBase* TargetServicesBase::GetInstance() {
152 // Leak on purpose TargetServicesBase.
153 if (!g_target_services)
154 g_target_services = new (g_target_services_memory) TargetServicesBase;
155 return g_target_services;
156 }
157
158 // The broker services a 'test' IPC service with the IPC_PING_TAG tag.
159 bool TargetServicesBase::TestIPCPing(int version) {
160 void* memory = GetGlobalIPCMemory();
161 if (NULL == memory) {
162 return false;
163 }
164 SharedMemIPCClient ipc(memory);
165 CrossCallReturn answer = {0};
166
167 if (1 == version) {
168 uint32_t tick1 = ::GetTickCount();
169 uint32_t cookie = 717115;
170 ResultCode code = CrossCall(ipc, IPC_PING1_TAG, cookie, &answer);
171
172 if (SBOX_ALL_OK != code) {
173 return false;
174 }
175 // We should get two extended returns values from the IPC, one is the
176 // tick count on the broker and the other is the cookie times two.
177 if ((answer.extended_count != 2)) {
178 return false;
179 }
180 // We test the first extended answer to be within the bounds of the tick
181 // count only if there was no tick count wraparound.
182 uint32_t tick2 = ::GetTickCount();
183 if (tick2 >= tick1) {
184 if ((answer.extended[0].unsigned_int < tick1) ||
185 (answer.extended[0].unsigned_int > tick2)) {
186 return false;
187 }
188 }
189
190 if (answer.extended[1].unsigned_int != cookie * 2) {
191 return false;
192 }
193 } else if (2 == version) {
194 uint32_t cookie = 717111;
195 InOutCountedBuffer counted_buffer(&cookie, sizeof(cookie));
196 ResultCode code = CrossCall(ipc, IPC_PING2_TAG, counted_buffer, &answer);
197
198 if (SBOX_ALL_OK != code) {
199 return false;
200 }
201 if (cookie != 717111 * 3) {
202 return false;
203 }
204 } else {
205 return false;
206 }
207 return true;
208 }
209
210 ProcessState::ProcessState() : process_state_(0), csrss_connected_(true) {
211 }
212
213 bool ProcessState::IsKernel32Loaded() const {
214 return process_state_ != 0;
215 }
216
217 bool ProcessState::InitCalled() const {
218 return process_state_ > 1;
219 }
220
221 bool ProcessState::RevertedToSelf() const {
222 return process_state_ > 2;
223 }
224
225 bool ProcessState::IsCsrssConnected() const {
226 return csrss_connected_;
227 }
228
229 void ProcessState::SetKernel32Loaded() {
230 if (!process_state_)
231 process_state_ = 1;
232 }
233
234 void ProcessState::SetInitCalled() {
235 if (process_state_ < 2)
236 process_state_ = 2;
237 }
238
239 void ProcessState::SetRevertedToSelf() {
240 if (process_state_ < 3)
241 process_state_ = 3;
242 }
243
244 void ProcessState::SetCsrssConnected(bool csrss_connected) {
245 csrss_connected_ = csrss_connected;
246 }
247
248
249 ResultCode TargetServicesBase::DuplicateHandle(HANDLE source_handle,
250 DWORD target_process_id,
251 HANDLE* target_handle,
252 DWORD desired_access,
253 DWORD options) {
254 return sandbox::DuplicateHandleProxy(source_handle, target_process_id,
255 target_handle, desired_access, options);
256 }
257
258 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/target_services.h ('k') | sandbox/win/src/threadpool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698