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

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

Powered by Google App Engine
This is Rietveld 408576698