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

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

Issue 1460903002: Unify PolicyBase into TargetPolicy. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@policy_dispatcher
Patch Set: Rebase. Created 5 years 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
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 "sandbox/win/src/sandbox_policy_base.h" 5 #include "sandbox/win/src/sandbox_policy.h"
6 6
7 #include <sddl.h> 7 #include <sddl.h>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/win/windows_version.h" 15 #include "base/win/windows_version.h"
(...skipping 22 matching lines...) Expand all
38 38
39 // The standard windows size for one memory page. 39 // The standard windows size for one memory page.
40 const size_t kOneMemPage = 4096; 40 const size_t kOneMemPage = 4096;
41 // The IPC and Policy shared memory sizes. 41 // The IPC and Policy shared memory sizes.
42 const size_t kIPCMemSize = kOneMemPage * 2; 42 const size_t kIPCMemSize = kOneMemPage * 2;
43 const size_t kPolMemSize = kOneMemPage * 14; 43 const size_t kPolMemSize = kOneMemPage * 14;
44 44
45 // Helper function to allocate space (on the heap) for policy. 45 // Helper function to allocate space (on the heap) for policy.
46 sandbox::PolicyGlobal* MakeBrokerPolicyMemory() { 46 sandbox::PolicyGlobal* MakeBrokerPolicyMemory() {
47 const size_t kTotalPolicySz = kPolMemSize; 47 const size_t kTotalPolicySz = kPolMemSize;
48 sandbox::PolicyGlobal* policy = static_cast<sandbox::PolicyGlobal*> 48 sandbox::PolicyGlobal* policy =
49 (::operator new(kTotalPolicySz)); 49 static_cast<sandbox::PolicyGlobal*>(::operator new(kTotalPolicySz));
50 DCHECK(policy); 50 DCHECK(policy);
51 memset(policy, 0, kTotalPolicySz); 51 memset(policy, 0, kTotalPolicySz);
52 policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal); 52 policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal);
53 return policy; 53 return policy;
54 } 54 }
55 55
56 bool IsInheritableHandle(HANDLE handle) { 56 bool IsInheritableHandle(HANDLE handle) {
57 if (!handle) 57 if (!handle)
58 return false; 58 return false;
59 if (handle == INVALID_HANDLE_VALUE) 59 if (handle == INVALID_HANDLE_VALUE)
60 return false; 60 return false;
61 // File handles (FILE_TYPE_DISK) and pipe handles are known to be 61 // File handles (FILE_TYPE_DISK) and pipe handles are known to be
62 // inheritable. Console handles (FILE_TYPE_CHAR) are not 62 // inheritable. Console handles (FILE_TYPE_CHAR) are not
63 // inheritable via PROC_THREAD_ATTRIBUTE_HANDLE_LIST. 63 // inheritable via PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
64 DWORD handle_type = GetFileType(handle); 64 DWORD handle_type = GetFileType(handle);
65 return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE; 65 return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE;
66 } 66 }
67 67
68 HANDLE CreateLowBoxObjectDirectory(PSID lowbox_sid) { 68 HANDLE CreateLowBoxObjectDirectory(PSID lowbox_sid) {
69 DWORD session_id = 0; 69 DWORD session_id = 0;
70 if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) 70 if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id))
71 return NULL; 71 return NULL;
72 72
73 LPWSTR sid_string = NULL; 73 LPWSTR sid_string = NULL;
74 if (!::ConvertSidToStringSid(lowbox_sid, &sid_string)) 74 if (!::ConvertSidToStringSid(lowbox_sid, &sid_string))
75 return NULL; 75 return NULL;
76 76
77 base::string16 directory_path = base::StringPrintf( 77 base::string16 directory_path =
78 L"\\Sessions\\%d\\AppContainerNamedObjects\\%ls", 78 base::StringPrintf(L"\\Sessions\\%d\\AppContainerNamedObjects\\%ls",
79 session_id, sid_string).c_str(); 79 session_id, sid_string)
80 .c_str();
80 ::LocalFree(sid_string); 81 ::LocalFree(sid_string);
81 82
82 NtCreateDirectoryObjectFunction CreateObjectDirectory = NULL; 83 NtCreateDirectoryObjectFunction CreateObjectDirectory = NULL;
83 ResolveNTFunctionPtr("NtCreateDirectoryObject", &CreateObjectDirectory); 84 ResolveNTFunctionPtr("NtCreateDirectoryObject", &CreateObjectDirectory);
84 85
85 OBJECT_ATTRIBUTES obj_attr; 86 OBJECT_ATTRIBUTES obj_attr;
86 UNICODE_STRING obj_name; 87 UNICODE_STRING obj_name;
87 sandbox::InitObjectAttribs(directory_path, 88 sandbox::InitObjectAttribs(directory_path, OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
88 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, 89 NULL, &obj_attr, &obj_name, NULL);
89 NULL,
90 &obj_attr,
91 &obj_name,
92 NULL);
93 90
94 HANDLE handle = NULL; 91 HANDLE handle = NULL;
95 NTSTATUS status = CreateObjectDirectory(&handle, 92 NTSTATUS status =
96 DIRECTORY_ALL_ACCESS, 93 CreateObjectDirectory(&handle, DIRECTORY_ALL_ACCESS, &obj_attr);
97 &obj_attr);
98 94
99 if (!NT_SUCCESS(status)) 95 if (!NT_SUCCESS(status))
100 return NULL; 96 return NULL;
101 97
102 return handle; 98 return handle;
103 } 99 }
104 100
105 } // namespace 101 } // namespace
106 102
107 namespace sandbox { 103 namespace sandbox {
108 104
109 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level; 105 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level;
110 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations; 106 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations;
111 107
112 // Initializes static members. 108 // Initializes static members.
113 HWINSTA PolicyBase::alternate_winstation_handle_ = NULL; 109 HWINSTA TargetPolicy::alternate_winstation_handle_ = NULL;
114 HDESK PolicyBase::alternate_desktop_handle_ = NULL; 110 HDESK TargetPolicy::alternate_desktop_handle_ = NULL;
115 IntegrityLevel PolicyBase::alternate_desktop_integrity_level_label_ = 111 IntegrityLevel TargetPolicy::alternate_desktop_integrity_level_label_ =
116 INTEGRITY_LEVEL_SYSTEM; 112 INTEGRITY_LEVEL_SYSTEM;
117 113
118 PolicyBase::PolicyBase() 114 TargetPolicy::TargetPolicy()
119 : ref_count(1), 115 : ref_count(1),
120 lockdown_level_(USER_LOCKDOWN), 116 lockdown_level_(USER_LOCKDOWN),
121 initial_level_(USER_LOCKDOWN), 117 initial_level_(USER_LOCKDOWN),
122 job_level_(JOB_LOCKDOWN), 118 job_level_(JOB_LOCKDOWN),
123 ui_exceptions_(0), 119 ui_exceptions_(0),
124 memory_limit_(0), 120 memory_limit_(0),
125 use_alternate_desktop_(false), 121 use_alternate_desktop_(false),
126 use_alternate_winstation_(false), 122 use_alternate_winstation_(false),
127 file_system_init_(false), 123 file_system_init_(false),
128 relaxed_interceptions_(true), 124 relaxed_interceptions_(true),
129 stdout_handle_(INVALID_HANDLE_VALUE), 125 stdout_handle_(INVALID_HANDLE_VALUE),
130 stderr_handle_(INVALID_HANDLE_VALUE), 126 stderr_handle_(INVALID_HANDLE_VALUE),
131 integrity_level_(INTEGRITY_LEVEL_LAST), 127 integrity_level_(INTEGRITY_LEVEL_LAST),
132 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), 128 delayed_integrity_level_(INTEGRITY_LEVEL_LAST),
133 mitigations_(0), 129 mitigations_(0),
134 delayed_mitigations_(0), 130 delayed_mitigations_(0),
135 policy_maker_(NULL), 131 policy_maker_(NULL),
136 policy_(NULL), 132 policy_(NULL),
137 lowbox_sid_(NULL) { 133 lowbox_sid_(NULL) {
138 ::InitializeCriticalSection(&lock_); 134 ::InitializeCriticalSection(&lock_);
139 dispatcher_.reset(new TopLevelDispatcher(this)); 135 dispatcher_.reset(new TopLevelDispatcher(this));
140 } 136 }
141 137
142 PolicyBase::~PolicyBase() { 138 TargetPolicy::~TargetPolicy() {
143 ClearSharedHandles(); 139 ClearSharedHandles();
144 140
145 TargetSet::iterator it; 141 TargetSet::iterator it;
146 for (it = targets_.begin(); it != targets_.end(); ++it) { 142 for (it = targets_.begin(); it != targets_.end(); ++it) {
147 TargetProcess* target = (*it); 143 TargetProcess* target = (*it);
148 delete target; 144 delete target;
149 } 145 }
150 delete policy_maker_; 146 delete policy_maker_;
151 delete policy_; 147 delete policy_;
152 148
153 if (lowbox_sid_) 149 if (lowbox_sid_)
154 ::LocalFree(lowbox_sid_); 150 ::LocalFree(lowbox_sid_);
155 151
156 ::DeleteCriticalSection(&lock_); 152 ::DeleteCriticalSection(&lock_);
157 } 153 }
158 154
159 void PolicyBase::AddRef() { 155 void TargetPolicy::AddRef() {
160 ::InterlockedIncrement(&ref_count); 156 ::InterlockedIncrement(&ref_count);
161 } 157 }
162 158
163 void PolicyBase::Release() { 159 void TargetPolicy::Release() {
164 if (0 == ::InterlockedDecrement(&ref_count)) 160 if (0 == ::InterlockedDecrement(&ref_count))
165 delete this; 161 delete this;
166 } 162 }
167 163
168 ResultCode PolicyBase::SetTokenLevel(TokenLevel initial, TokenLevel lockdown) { 164 ResultCode TargetPolicy::SetTokenLevel(TokenLevel initial,
165 TokenLevel lockdown) {
169 if (initial < lockdown) { 166 if (initial < lockdown) {
170 return SBOX_ERROR_BAD_PARAMS; 167 return SBOX_ERROR_BAD_PARAMS;
171 } 168 }
172 initial_level_ = initial; 169 initial_level_ = initial;
173 lockdown_level_ = lockdown; 170 lockdown_level_ = lockdown;
174 return SBOX_ALL_OK; 171 return SBOX_ALL_OK;
175 } 172 }
176 173
177 TokenLevel PolicyBase::GetInitialTokenLevel() const { 174 TokenLevel TargetPolicy::GetInitialTokenLevel() const {
178 return initial_level_; 175 return initial_level_;
179 } 176 }
180 177
181 TokenLevel PolicyBase::GetLockdownTokenLevel() const{ 178 TokenLevel TargetPolicy::GetLockdownTokenLevel() const {
182 return lockdown_level_; 179 return lockdown_level_;
183 } 180 }
184 181
185 ResultCode PolicyBase::SetJobLevel(JobLevel job_level, uint32 ui_exceptions) { 182 ResultCode TargetPolicy::SetJobLevel(JobLevel job_level, uint32 ui_exceptions) {
186 if (memory_limit_ && job_level == JOB_NONE) { 183 if (memory_limit_ && job_level == JOB_NONE) {
187 return SBOX_ERROR_BAD_PARAMS; 184 return SBOX_ERROR_BAD_PARAMS;
188 } 185 }
189 job_level_ = job_level; 186 job_level_ = job_level;
190 ui_exceptions_ = ui_exceptions; 187 ui_exceptions_ = ui_exceptions;
191 return SBOX_ALL_OK; 188 return SBOX_ALL_OK;
192 } 189 }
193 190
194 ResultCode PolicyBase::SetJobMemoryLimit(size_t memory_limit) { 191 ResultCode TargetPolicy::SetJobMemoryLimit(size_t memory_limit) {
195 if (memory_limit && job_level_ == JOB_NONE) { 192 if (memory_limit && job_level_ == JOB_NONE) {
196 return SBOX_ERROR_BAD_PARAMS; 193 return SBOX_ERROR_BAD_PARAMS;
197 } 194 }
198 memory_limit_ = memory_limit; 195 memory_limit_ = memory_limit;
199 return SBOX_ALL_OK; 196 return SBOX_ALL_OK;
200 } 197 }
201 198
202 ResultCode PolicyBase::SetAlternateDesktop(bool alternate_winstation) { 199 ResultCode TargetPolicy::SetAlternateDesktop(bool alternate_winstation) {
203 use_alternate_desktop_ = true; 200 use_alternate_desktop_ = true;
204 use_alternate_winstation_ = alternate_winstation; 201 use_alternate_winstation_ = alternate_winstation;
205 return CreateAlternateDesktop(alternate_winstation); 202 return CreateAlternateDesktop(alternate_winstation);
206 } 203 }
207 204
208 base::string16 PolicyBase::GetAlternateDesktop() const { 205 base::string16 TargetPolicy::GetAlternateDesktop() const {
209 // No alternate desktop or winstation. Return an empty string. 206 // No alternate desktop or winstation. Return an empty string.
210 if (!use_alternate_desktop_ && !use_alternate_winstation_) { 207 if (!use_alternate_desktop_ && !use_alternate_winstation_) {
211 return base::string16(); 208 return base::string16();
212 } 209 }
213 210
214 // The desktop and winstation should have been created by now. 211 // The desktop and winstation should have been created by now.
215 // If we hit this scenario, it means that the user ignored the failure 212 // If we hit this scenario, it means that the user ignored the failure
216 // during SetAlternateDesktop, so we ignore it here too. 213 // during SetAlternateDesktop, so we ignore it here too.
217 if (use_alternate_desktop_ && !alternate_desktop_handle_) { 214 if (use_alternate_desktop_ && !alternate_desktop_handle_) {
218 return base::string16(); 215 return base::string16();
219 } 216 }
220 if (use_alternate_winstation_ && (!alternate_desktop_handle_ || 217 if (use_alternate_winstation_ &&
221 !alternate_winstation_handle_)) { 218 (!alternate_desktop_handle_ || !alternate_winstation_handle_)) {
222 return base::string16(); 219 return base::string16();
223 } 220 }
224 221
225 return GetFullDesktopName(alternate_winstation_handle_, 222 return GetFullDesktopName(alternate_winstation_handle_,
226 alternate_desktop_handle_); 223 alternate_desktop_handle_);
227 } 224 }
228 225
229 ResultCode PolicyBase::CreateAlternateDesktop(bool alternate_winstation) { 226 ResultCode TargetPolicy::CreateAlternateDesktop(bool alternate_winstation) {
230 if (alternate_winstation) { 227 if (alternate_winstation) {
231 // Previously called with alternate_winstation = false? 228 // Previously called with alternate_winstation = false?
232 if (!alternate_winstation_handle_ && alternate_desktop_handle_) 229 if (!alternate_winstation_handle_ && alternate_desktop_handle_)
233 return SBOX_ERROR_UNSUPPORTED; 230 return SBOX_ERROR_UNSUPPORTED;
234 231
235 // Check if it's already created. 232 // Check if it's already created.
236 if (alternate_winstation_handle_ && alternate_desktop_handle_) 233 if (alternate_winstation_handle_ && alternate_desktop_handle_)
237 return SBOX_ALL_OK; 234 return SBOX_ALL_OK;
238 235
239 DCHECK(!alternate_winstation_handle_); 236 DCHECK(!alternate_winstation_handle_);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 270
274 // Verify that everything is fine. 271 // Verify that everything is fine.
275 if (!alternate_desktop_handle_ || 272 if (!alternate_desktop_handle_ ||
276 GetWindowObjectName(alternate_desktop_handle_).empty()) 273 GetWindowObjectName(alternate_desktop_handle_).empty())
277 return SBOX_ERROR_CANNOT_CREATE_DESKTOP; 274 return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
278 } 275 }
279 276
280 return SBOX_ALL_OK; 277 return SBOX_ALL_OK;
281 } 278 }
282 279
283 void PolicyBase::DestroyAlternateDesktop() { 280 void TargetPolicy::DestroyAlternateDesktop() {
284 if (alternate_desktop_handle_) { 281 if (alternate_desktop_handle_) {
285 ::CloseDesktop(alternate_desktop_handle_); 282 ::CloseDesktop(alternate_desktop_handle_);
286 alternate_desktop_handle_ = NULL; 283 alternate_desktop_handle_ = NULL;
287 } 284 }
288 285
289 if (alternate_winstation_handle_) { 286 if (alternate_winstation_handle_) {
290 ::CloseWindowStation(alternate_winstation_handle_); 287 ::CloseWindowStation(alternate_winstation_handle_);
291 alternate_winstation_handle_ = NULL; 288 alternate_winstation_handle_ = NULL;
292 } 289 }
293 } 290 }
294 291
295 ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) { 292 ResultCode TargetPolicy::SetIntegrityLevel(IntegrityLevel integrity_level) {
296 integrity_level_ = integrity_level; 293 integrity_level_ = integrity_level;
297 return SBOX_ALL_OK; 294 return SBOX_ALL_OK;
298 } 295 }
299 296
300 IntegrityLevel PolicyBase::GetIntegrityLevel() const { 297 IntegrityLevel TargetPolicy::GetIntegrityLevel() const {
301 return integrity_level_; 298 return integrity_level_;
302 } 299 }
303 300
304 ResultCode PolicyBase::SetDelayedIntegrityLevel( 301 ResultCode TargetPolicy::SetDelayedIntegrityLevel(
305 IntegrityLevel integrity_level) { 302 IntegrityLevel integrity_level) {
306 delayed_integrity_level_ = integrity_level; 303 delayed_integrity_level_ = integrity_level;
307 return SBOX_ALL_OK; 304 return SBOX_ALL_OK;
308 } 305 }
309 306
310 ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) { 307 ResultCode TargetPolicy::SetAppContainer(const wchar_t* sid) {
311 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) 308 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8)
312 return SBOX_ALL_OK; 309 return SBOX_ALL_OK;
313 310
314 // SetLowBox and SetAppContainer are mutually exclusive. 311 // SetLowBox and SetAppContainer are mutually exclusive.
315 if (lowbox_sid_) 312 if (lowbox_sid_)
316 return SBOX_ERROR_UNSUPPORTED; 313 return SBOX_ERROR_UNSUPPORTED;
317 314
318 // Windows refuses to work with an impersonation token for a process inside 315 // Windows refuses to work with an impersonation token for a process inside
319 // an AppContainer. If the caller wants to use a more privileged initial 316 // an AppContainer. If the caller wants to use a more privileged initial
320 // token, or if the lockdown level will prevent the process from starting, 317 // token, or if the lockdown level will prevent the process from starting,
321 // we have to fail the operation. 318 // we have to fail the operation.
322 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) 319 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_)
323 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; 320 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER;
324 321
325 DCHECK(!appcontainer_list_.get()); 322 DCHECK(!appcontainer_list_.get());
326 appcontainer_list_.reset(new AppContainerAttributes); 323 appcontainer_list_.reset(new AppContainerAttributes);
327 ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_); 324 ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_);
328 if (rv != SBOX_ALL_OK) 325 if (rv != SBOX_ALL_OK)
329 return rv; 326 return rv;
330 327
331 return SBOX_ALL_OK; 328 return SBOX_ALL_OK;
332 } 329 }
333 330
334 ResultCode PolicyBase::SetCapability(const wchar_t* sid) { 331 ResultCode TargetPolicy::SetCapability(const wchar_t* sid) {
335 capabilities_.push_back(sid); 332 capabilities_.push_back(sid);
336 return SBOX_ALL_OK; 333 return SBOX_ALL_OK;
337 } 334 }
338 335
339 ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { 336 ResultCode TargetPolicy::SetLowBox(const wchar_t* sid) {
340 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) 337 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8)
341 return SBOX_ERROR_UNSUPPORTED; 338 return SBOX_ERROR_UNSUPPORTED;
342 339
343 // SetLowBox and SetAppContainer are mutually exclusive. 340 // SetLowBox and SetAppContainer are mutually exclusive.
344 if (appcontainer_list_.get()) 341 if (appcontainer_list_.get())
345 return SBOX_ERROR_UNSUPPORTED; 342 return SBOX_ERROR_UNSUPPORTED;
346 343
347 DCHECK(sid); 344 DCHECK(sid);
348 345
349 if (lowbox_sid_) 346 if (lowbox_sid_)
350 return SBOX_ERROR_BAD_PARAMS; 347 return SBOX_ERROR_BAD_PARAMS;
351 348
352 if (!ConvertStringSidToSid(sid, &lowbox_sid_)) 349 if (!ConvertStringSidToSid(sid, &lowbox_sid_))
353 return SBOX_ERROR_GENERIC; 350 return SBOX_ERROR_GENERIC;
354 351
355 return SBOX_ALL_OK; 352 return SBOX_ALL_OK;
356 } 353 }
357 354
358 ResultCode PolicyBase::SetProcessMitigations( 355 ResultCode TargetPolicy::SetProcessMitigations(MitigationFlags flags) {
359 MitigationFlags flags) {
360 if (!CanSetProcessMitigationsPreStartup(flags)) 356 if (!CanSetProcessMitigationsPreStartup(flags))
361 return SBOX_ERROR_BAD_PARAMS; 357 return SBOX_ERROR_BAD_PARAMS;
362 mitigations_ = flags; 358 mitigations_ = flags;
363 return SBOX_ALL_OK; 359 return SBOX_ALL_OK;
364 } 360 }
365 361
366 MitigationFlags PolicyBase::GetProcessMitigations() { 362 MitigationFlags TargetPolicy::GetProcessMitigations() {
367 return mitigations_; 363 return mitigations_;
368 } 364 }
369 365
370 ResultCode PolicyBase::SetDelayedProcessMitigations( 366 ResultCode TargetPolicy::SetDelayedProcessMitigations(MitigationFlags flags) {
371 MitigationFlags flags) {
372 if (!CanSetProcessMitigationsPostStartup(flags)) 367 if (!CanSetProcessMitigationsPostStartup(flags))
373 return SBOX_ERROR_BAD_PARAMS; 368 return SBOX_ERROR_BAD_PARAMS;
374 delayed_mitigations_ = flags; 369 delayed_mitigations_ = flags;
375 return SBOX_ALL_OK; 370 return SBOX_ALL_OK;
376 } 371 }
377 372
378 MitigationFlags PolicyBase::GetDelayedProcessMitigations() const { 373 MitigationFlags TargetPolicy::GetDelayedProcessMitigations() const {
379 return delayed_mitigations_; 374 return delayed_mitigations_;
380 } 375 }
381 376
382 void PolicyBase::SetStrictInterceptions() { 377 void TargetPolicy::SetStrictInterceptions() {
383 relaxed_interceptions_ = false; 378 relaxed_interceptions_ = false;
384 } 379 }
385 380
386 ResultCode PolicyBase::SetStdoutHandle(HANDLE handle) { 381 ResultCode TargetPolicy::SetStdoutHandle(HANDLE handle) {
387 if (!IsInheritableHandle(handle)) 382 if (!IsInheritableHandle(handle))
388 return SBOX_ERROR_BAD_PARAMS; 383 return SBOX_ERROR_BAD_PARAMS;
389 stdout_handle_ = handle; 384 stdout_handle_ = handle;
390 return SBOX_ALL_OK; 385 return SBOX_ALL_OK;
391 } 386 }
392 387
393 ResultCode PolicyBase::SetStderrHandle(HANDLE handle) { 388 ResultCode TargetPolicy::SetStderrHandle(HANDLE handle) {
394 if (!IsInheritableHandle(handle)) 389 if (!IsInheritableHandle(handle))
395 return SBOX_ERROR_BAD_PARAMS; 390 return SBOX_ERROR_BAD_PARAMS;
396 stderr_handle_ = handle; 391 stderr_handle_ = handle;
397 return SBOX_ALL_OK; 392 return SBOX_ALL_OK;
398 } 393 }
399 394
400 ResultCode PolicyBase::AddRule(SubSystem subsystem, 395 ResultCode TargetPolicy::AddRule(SubSystem subsystem,
401 Semantics semantics, 396 Semantics semantics,
402 const wchar_t* pattern) { 397 const wchar_t* pattern) {
403 ResultCode result = AddRuleInternal(subsystem, semantics, pattern); 398 ResultCode result = AddRuleInternal(subsystem, semantics, pattern);
404 LOG_IF(ERROR, result != SBOX_ALL_OK) << "Failed to add sandbox rule." 399 LOG_IF(ERROR, result != SBOX_ALL_OK)
405 << " error = " << result 400 << "Failed to add sandbox rule."
406 << ", subsystem = " << subsystem 401 << " error = " << result << ", subsystem = " << subsystem
407 << ", semantics = " << semantics 402 << ", semantics = " << semantics << ", pattern = '" << pattern << "'";
408 << ", pattern = '" << pattern << "'";
409 return result; 403 return result;
410 } 404 }
411 405
412 ResultCode PolicyBase::AddDllToUnload(const wchar_t* dll_name) { 406 ResultCode TargetPolicy::AddDllToUnload(const wchar_t* dll_name) {
413 blacklisted_dlls_.push_back(dll_name); 407 blacklisted_dlls_.push_back(dll_name);
414 return SBOX_ALL_OK; 408 return SBOX_ALL_OK;
415 } 409 }
416 410
417 ResultCode PolicyBase::AddKernelObjectToClose(const base::char16* handle_type, 411 ResultCode TargetPolicy::AddKernelObjectToClose(
418 const base::char16* handle_name) { 412 const base::char16* handle_type,
413 const base::char16* handle_name) {
419 return handle_closer_.AddHandle(handle_type, handle_name); 414 return handle_closer_.AddHandle(handle_type, handle_name);
420 } 415 }
421 416
422 void* PolicyBase::AddHandleToShare(HANDLE handle) { 417 void* TargetPolicy::AddHandleToShare(HANDLE handle) {
423 if (base::win::GetVersion() < base::win::VERSION_VISTA) 418 if (base::win::GetVersion() < base::win::VERSION_VISTA)
424 return nullptr; 419 return nullptr;
425 420
426 if (!handle) 421 if (!handle)
427 return nullptr; 422 return nullptr;
428 423
429 HANDLE duped_handle = nullptr; 424 HANDLE duped_handle = nullptr;
430 if (!::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(), 425 if (!::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(),
431 &duped_handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { 426 &duped_handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
432 return nullptr; 427 return nullptr;
433 } 428 }
434 handles_to_share_.push_back(new base::win::ScopedHandle(duped_handle)); 429 handles_to_share_.push_back(new base::win::ScopedHandle(duped_handle));
435 return duped_handle; 430 return duped_handle;
436 } 431 }
437 432
438 const HandleList& PolicyBase::GetHandlesBeingShared() { 433 const HandleList& TargetPolicy::GetHandlesBeingShared() {
439 return handles_to_share_; 434 return handles_to_share_;
440 } 435 }
441 436
442 void PolicyBase::ClearSharedHandles() { 437 void TargetPolicy::ClearSharedHandles() {
443 STLDeleteElements(&handles_to_share_); 438 STLDeleteElements(&handles_to_share_);
444 } 439 }
445 440
446 ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { 441 ResultCode TargetPolicy::MakeJobObject(base::win::ScopedHandle* job) {
447 if (job_level_ != JOB_NONE) { 442 if (job_level_ != JOB_NONE) {
448 // Create the windows job object. 443 // Create the windows job object.
449 Job job_obj; 444 Job job_obj;
450 DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_, 445 DWORD result =
451 memory_limit_); 446 job_obj.Init(job_level_, NULL, ui_exceptions_, memory_limit_);
452 if (ERROR_SUCCESS != result) 447 if (ERROR_SUCCESS != result)
453 return SBOX_ERROR_GENERIC; 448 return SBOX_ERROR_GENERIC;
454 449
455 *job = job_obj.Take(); 450 *job = job_obj.Take();
456 } else { 451 } else {
457 *job = base::win::ScopedHandle(); 452 *job = base::win::ScopedHandle();
458 } 453 }
459 return SBOX_ALL_OK; 454 return SBOX_ALL_OK;
460 } 455 }
461 456
462 ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, 457 ResultCode TargetPolicy::MakeTokens(base::win::ScopedHandle* initial,
463 base::win::ScopedHandle* lockdown, 458 base::win::ScopedHandle* lockdown,
464 base::win::ScopedHandle* lowbox) { 459 base::win::ScopedHandle* lowbox) {
465 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() && 460 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() &&
466 lowbox_sid_) { 461 lowbox_sid_) {
467 return SBOX_ERROR_BAD_PARAMS; 462 return SBOX_ERROR_BAD_PARAMS;
468 } 463 }
469 464
470 // Create the 'naked' token. This will be the permanent token associated 465 // Create the 'naked' token. This will be the permanent token associated
471 // with the process and therefore with any thread that is not impersonating. 466 // with the process and therefore with any thread that is not impersonating.
472 DWORD result = CreateRestrictedToken(lockdown_level_, integrity_level_, 467 DWORD result = CreateRestrictedToken(lockdown_level_, integrity_level_,
473 PRIMARY, lockdown); 468 PRIMARY, lockdown);
474 if (ERROR_SUCCESS != result) 469 if (ERROR_SUCCESS != result)
475 return SBOX_ERROR_GENERIC; 470 return SBOX_ERROR_GENERIC;
476 471
477 // If we're launching on the alternate desktop we need to make sure the 472 // If we're launching on the alternate desktop we need to make sure the
478 // integrity label on the object is no higher than the sandboxed process's 473 // integrity label on the object is no higher than the sandboxed process's
479 // integrity level. So, we lower the label on the desktop process if it's 474 // integrity level. So, we lower the label on the desktop process if it's
480 // not already low enough for our process. 475 // not already low enough for our process.
481 if (alternate_desktop_handle_ && use_alternate_desktop_ && 476 if (alternate_desktop_handle_ && use_alternate_desktop_ &&
482 integrity_level_ != INTEGRITY_LEVEL_LAST && 477 integrity_level_ != INTEGRITY_LEVEL_LAST &&
483 alternate_desktop_integrity_level_label_ < integrity_level_ && 478 alternate_desktop_integrity_level_label_ < integrity_level_ &&
484 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { 479 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) {
485 // Integrity label enum is reversed (higher level is a lower value). 480 // Integrity label enum is reversed (higher level is a lower value).
486 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, 481 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED,
487 "Integrity level ordering reversed."); 482 "Integrity level ordering reversed.");
488 result = SetObjectIntegrityLabel(alternate_desktop_handle_, 483 result =
489 SE_WINDOW_OBJECT, 484 SetObjectIntegrityLabel(alternate_desktop_handle_, SE_WINDOW_OBJECT,
490 L"", 485 L"", GetIntegrityLevelString(integrity_level_));
491 GetIntegrityLevelString(integrity_level_));
492 if (ERROR_SUCCESS != result) 486 if (ERROR_SUCCESS != result)
493 return SBOX_ERROR_GENERIC; 487 return SBOX_ERROR_GENERIC;
494 488
495 alternate_desktop_integrity_level_label_ = integrity_level_; 489 alternate_desktop_integrity_level_label_ = integrity_level_;
496 } 490 }
497 491
498 // We are maintaining two mutually exclusive approaches. One is to start an 492 // We are maintaining two mutually exclusive approaches. One is to start an
499 // AppContainer process through StartupInfoEx and other is replacing 493 // AppContainer process through StartupInfoEx and other is replacing
500 // existing token with LowBox token after process creation. 494 // existing token with LowBox token after process creation.
501 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { 495 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) {
(...skipping 15 matching lines...) Expand all
517 511
518 if (!lowbox_directory_.IsValid()) 512 if (!lowbox_directory_.IsValid())
519 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); 513 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_));
520 DCHECK(lowbox_directory_.IsValid()); 514 DCHECK(lowbox_directory_.IsValid());
521 515
522 // The order of handles isn't important in the CreateLowBoxToken call. 516 // The order of handles isn't important in the CreateLowBoxToken call.
523 // The kernel will maintain a reference to the object directory handle. 517 // The kernel will maintain a reference to the object directory handle.
524 HANDLE saved_handles[1] = {lowbox_directory_.Get()}; 518 HANDLE saved_handles[1] = {lowbox_directory_.Get()};
525 DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0; 519 DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0;
526 520
527 NTSTATUS status = CreateLowBoxToken(&token_lowbox, lockdown->Get(), 521 NTSTATUS status = CreateLowBoxToken(
528 TOKEN_ALL_ACCESS, &obj_attr, 522 &token_lowbox, lockdown->Get(), TOKEN_ALL_ACCESS, &obj_attr,
529 lowbox_sid_, 0, NULL, 523 lowbox_sid_, 0, NULL, saved_handles_count, saved_handles);
530 saved_handles_count, saved_handles);
531 if (!NT_SUCCESS(status)) 524 if (!NT_SUCCESS(status))
532 return SBOX_ERROR_GENERIC; 525 return SBOX_ERROR_GENERIC;
533 526
534 DCHECK(token_lowbox); 527 DCHECK(token_lowbox);
535 lowbox->Set(token_lowbox); 528 lowbox->Set(token_lowbox);
536 } 529 }
537 530
538 // Create the 'better' token. We use this token as the one that the main 531 // Create the 'better' token. We use this token as the one that the main
539 // thread uses when booting up the process. It should contain most of 532 // thread uses when booting up the process. It should contain most of
540 // what we need (before reaching main( )) 533 // what we need (before reaching main( ))
541 result = CreateRestrictedToken(initial_level_, integrity_level_, 534 result = CreateRestrictedToken(initial_level_, integrity_level_,
542 IMPERSONATION, initial); 535 IMPERSONATION, initial);
543 if (ERROR_SUCCESS != result) 536 if (ERROR_SUCCESS != result)
544 return SBOX_ERROR_GENERIC; 537 return SBOX_ERROR_GENERIC;
545 538
546 return SBOX_ALL_OK; 539 return SBOX_ALL_OK;
547 } 540 }
548 541
549 const AppContainerAttributes* PolicyBase::GetAppContainer() const { 542 const AppContainerAttributes* TargetPolicy::GetAppContainer() const {
550 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) 543 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer())
551 return NULL; 544 return NULL;
552 545
553 return appcontainer_list_.get(); 546 return appcontainer_list_.get();
554 } 547 }
555 548
556 PSID PolicyBase::GetLowBoxSid() const { 549 PSID TargetPolicy::GetLowBoxSid() const {
557 return lowbox_sid_; 550 return lowbox_sid_;
558 } 551 }
559 552
560 bool PolicyBase::AddTarget(TargetProcess* target) { 553 bool TargetPolicy::AddTarget(TargetProcess* target) {
561 if (NULL != policy_) 554 if (NULL != policy_)
562 policy_maker_->Done(); 555 policy_maker_->Done();
563 556
564 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), 557 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(),
565 mitigations_)) { 558 mitigations_)) {
566 return false; 559 return false;
567 } 560 }
568 561
569 if (!SetupAllInterceptions(target)) 562 if (!SetupAllInterceptions(target))
570 return false; 563 return false;
571 564
572 if (!SetupHandleCloser(target)) 565 if (!SetupHandleCloser(target))
573 return false; 566 return false;
574 567
575 // Initialize the sandbox infrastructure for the target. 568 // Initialize the sandbox infrastructure for the target.
576 if (ERROR_SUCCESS != 569 if (ERROR_SUCCESS !=
577 target->Init(dispatcher_.get(), policy_, kIPCMemSize, kPolMemSize)) 570 target->Init(dispatcher_.get(), policy_, kIPCMemSize, kPolMemSize))
578 return false; 571 return false;
579 572
580 g_shared_delayed_integrity_level = delayed_integrity_level_; 573 g_shared_delayed_integrity_level = delayed_integrity_level_;
581 ResultCode ret = target->TransferVariable( 574 ResultCode ret = target->TransferVariable(
582 "g_shared_delayed_integrity_level", 575 "g_shared_delayed_integrity_level", &g_shared_delayed_integrity_level,
583 &g_shared_delayed_integrity_level, 576 sizeof(g_shared_delayed_integrity_level));
584 sizeof(g_shared_delayed_integrity_level));
585 g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; 577 g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST;
586 if (SBOX_ALL_OK != ret) 578 if (SBOX_ALL_OK != ret)
587 return false; 579 return false;
588 580
589 // Add in delayed mitigations and pseudo-mitigations enforced at startup. 581 // Add in delayed mitigations and pseudo-mitigations enforced at startup.
590 g_shared_delayed_mitigations = delayed_mitigations_ | 582 g_shared_delayed_mitigations =
591 FilterPostStartupProcessMitigations(mitigations_); 583 delayed_mitigations_ | FilterPostStartupProcessMitigations(mitigations_);
592 if (!CanSetProcessMitigationsPostStartup(g_shared_delayed_mitigations)) 584 if (!CanSetProcessMitigationsPostStartup(g_shared_delayed_mitigations))
593 return false; 585 return false;
594 586
595 ret = target->TransferVariable("g_shared_delayed_mitigations", 587 ret = target->TransferVariable("g_shared_delayed_mitigations",
596 &g_shared_delayed_mitigations, 588 &g_shared_delayed_mitigations,
597 sizeof(g_shared_delayed_mitigations)); 589 sizeof(g_shared_delayed_mitigations));
598 g_shared_delayed_mitigations = 0; 590 g_shared_delayed_mitigations = 0;
599 if (SBOX_ALL_OK != ret) 591 if (SBOX_ALL_OK != ret)
600 return false; 592 return false;
601 593
602 AutoLock lock(&lock_); 594 AutoLock lock(&lock_);
603 targets_.push_back(target); 595 targets_.push_back(target);
604 return true; 596 return true;
605 } 597 }
606 598
607 bool PolicyBase::OnJobEmpty(HANDLE job) { 599 bool TargetPolicy::OnJobEmpty(HANDLE job) {
608 AutoLock lock(&lock_); 600 AutoLock lock(&lock_);
609 TargetSet::iterator it; 601 TargetSet::iterator it;
610 for (it = targets_.begin(); it != targets_.end(); ++it) { 602 for (it = targets_.begin(); it != targets_.end(); ++it) {
611 if ((*it)->Job() == job) 603 if ((*it)->Job() == job)
612 break; 604 break;
613 } 605 }
614 if (it == targets_.end()) { 606 if (it == targets_.end()) {
615 return false; 607 return false;
616 } 608 }
617 TargetProcess* target = *it; 609 TargetProcess* target = *it;
618 targets_.erase(it); 610 targets_.erase(it);
619 delete target; 611 delete target;
620 return true; 612 return true;
621 } 613 }
622 614
623 EvalResult PolicyBase::EvalPolicy(int service, 615 EvalResult TargetPolicy::EvalPolicy(int service,
624 CountedParameterSetBase* params) { 616 CountedParameterSetBase* params) {
625 if (NULL != policy_) { 617 if (NULL != policy_) {
626 if (NULL == policy_->entry[service]) { 618 if (NULL == policy_->entry[service]) {
627 // There is no policy for this particular service. This is not a big 619 // There is no policy for this particular service. This is not a big
628 // deal. 620 // deal.
629 return DENY_ACCESS; 621 return DENY_ACCESS;
630 } 622 }
631 for (int i = 0; i < params->count; i++) { 623 for (int i = 0; i < params->count; i++) {
632 if (!params->parameters[i].IsValid()) { 624 if (!params->parameters[i].IsValid()) {
633 NOTREACHED(); 625 NOTREACHED();
634 return SIGNAL_ALARM; 626 return SIGNAL_ALARM;
635 } 627 }
636 } 628 }
637 PolicyProcessor pol_evaluator(policy_->entry[service]); 629 PolicyProcessor pol_evaluator(policy_->entry[service]);
638 PolicyResult result = pol_evaluator.Evaluate(kShortEval, 630 PolicyResult result =
639 params->parameters, 631 pol_evaluator.Evaluate(kShortEval, params->parameters, params->count);
640 params->count);
641 if (POLICY_MATCH == result) { 632 if (POLICY_MATCH == result) {
642 return pol_evaluator.GetAction(); 633 return pol_evaluator.GetAction();
643 } 634 }
644 DCHECK(POLICY_ERROR != result); 635 DCHECK(POLICY_ERROR != result);
645 } 636 }
646 637
647 return DENY_ACCESS; 638 return DENY_ACCESS;
648 } 639 }
649 640
650 HANDLE PolicyBase::GetStdoutHandle() { 641 HANDLE TargetPolicy::GetStdoutHandle() {
651 return stdout_handle_; 642 return stdout_handle_;
652 } 643 }
653 644
654 HANDLE PolicyBase::GetStderrHandle() { 645 HANDLE TargetPolicy::GetStderrHandle() {
655 return stderr_handle_; 646 return stderr_handle_;
656 } 647 }
657 648
658 bool PolicyBase::SetupAllInterceptions(TargetProcess* target) { 649 bool TargetPolicy::SetupAllInterceptions(TargetProcess* target) {
659 InterceptionManager manager(target, relaxed_interceptions_); 650 InterceptionManager manager(target, relaxed_interceptions_);
660 651
661 if (policy_) { 652 if (policy_) {
662 for (int i = 0; i < IPC_LAST_TAG; i++) { 653 for (int i = 0; i < IPC_LAST_TAG; i++) {
663 if (policy_->entry[i] && !dispatcher_->SetupService(&manager, i)) 654 if (policy_->entry[i] && !dispatcher_->SetupService(&manager, i))
664 return false; 655 return false;
665 } 656 }
666 } 657 }
667 658
668 if (!blacklisted_dlls_.empty()) { 659 if (!blacklisted_dlls_.empty()) {
669 std::vector<base::string16>::iterator it = blacklisted_dlls_.begin(); 660 std::vector<base::string16>::iterator it = blacklisted_dlls_.begin();
670 for (; it != blacklisted_dlls_.end(); ++it) { 661 for (; it != blacklisted_dlls_.end(); ++it) {
671 manager.AddToUnloadModules(it->c_str()); 662 manager.AddToUnloadModules(it->c_str());
672 } 663 }
673 } 664 }
674 665
675 if (!SetupBasicInterceptions(&manager)) 666 if (!SetupBasicInterceptions(&manager))
676 return false; 667 return false;
677 668
678 if (!manager.InitializeInterceptions()) 669 if (!manager.InitializeInterceptions())
679 return false; 670 return false;
680 671
681 // Finally, setup imports on the target so the interceptions can work. 672 // Finally, setup imports on the target so the interceptions can work.
682 return SetupNtdllImports(target); 673 return SetupNtdllImports(target);
683 } 674 }
684 675
685 bool PolicyBase::SetupHandleCloser(TargetProcess* target) { 676 bool TargetPolicy::SetupHandleCloser(TargetProcess* target) {
686 return handle_closer_.InitializeTargetHandles(target); 677 return handle_closer_.InitializeTargetHandles(target);
687 } 678 }
688 679
689 ResultCode PolicyBase::AddRuleInternal(SubSystem subsystem, 680 ResultCode TargetPolicy::AddRuleInternal(SubSystem subsystem,
690 Semantics semantics, 681 Semantics semantics,
691 const wchar_t* pattern) { 682 const wchar_t* pattern) {
692 if (NULL == policy_) { 683 if (NULL == policy_) {
693 policy_ = MakeBrokerPolicyMemory(); 684 policy_ = MakeBrokerPolicyMemory();
694 DCHECK(policy_); 685 DCHECK(policy_);
695 policy_maker_ = new LowLevelPolicy(policy_); 686 policy_maker_ = new LowLevelPolicy(policy_);
696 DCHECK(policy_maker_); 687 DCHECK(policy_maker_);
697 } 688 }
698 689
699 switch (subsystem) { 690 switch (subsystem) {
700 case SUBSYS_FILES: { 691 case SUBSYS_FILES: {
701 if (!file_system_init_) { 692 if (!file_system_init_) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 break; 751 break;
761 } 752 }
762 753
763 default: { return SBOX_ERROR_UNSUPPORTED; } 754 default: { return SBOX_ERROR_UNSUPPORTED; }
764 } 755 }
765 756
766 return SBOX_ALL_OK; 757 return SBOX_ALL_OK;
767 } 758 }
768 759
769 } // namespace sandbox 760 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698