OLD | NEW |
---|---|
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_base.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" |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 use_alternate_winstation_(false), | 91 use_alternate_winstation_(false), |
92 file_system_init_(false), | 92 file_system_init_(false), |
93 relaxed_interceptions_(true), | 93 relaxed_interceptions_(true), |
94 stdout_handle_(INVALID_HANDLE_VALUE), | 94 stdout_handle_(INVALID_HANDLE_VALUE), |
95 stderr_handle_(INVALID_HANDLE_VALUE), | 95 stderr_handle_(INVALID_HANDLE_VALUE), |
96 integrity_level_(INTEGRITY_LEVEL_LAST), | 96 integrity_level_(INTEGRITY_LEVEL_LAST), |
97 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), | 97 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), |
98 mitigations_(0), | 98 mitigations_(0), |
99 delayed_mitigations_(0), | 99 delayed_mitigations_(0), |
100 policy_maker_(NULL), | 100 policy_maker_(NULL), |
101 policy_(NULL) { | 101 policy_(NULL), |
102 lowbox_sid_(NULL) { | |
102 ::InitializeCriticalSection(&lock_); | 103 ::InitializeCriticalSection(&lock_); |
103 // Initialize the IPC dispatcher array. | 104 // Initialize the IPC dispatcher array. |
104 memset(&ipc_targets_, NULL, sizeof(ipc_targets_)); | 105 memset(&ipc_targets_, NULL, sizeof(ipc_targets_)); |
105 Dispatcher* dispatcher = NULL; | 106 Dispatcher* dispatcher = NULL; |
106 | 107 |
107 dispatcher = new FilesystemDispatcher(this); | 108 dispatcher = new FilesystemDispatcher(this); |
108 ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher; | 109 ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher; |
109 ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher; | 110 ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher; |
110 ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher; | 111 ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher; |
111 ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher; | 112 ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 delete target; | 146 delete target; |
146 } | 147 } |
147 delete ipc_targets_[IPC_NTCREATEFILE_TAG]; | 148 delete ipc_targets_[IPC_NTCREATEFILE_TAG]; |
148 delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG]; | 149 delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG]; |
149 delete ipc_targets_[IPC_NTOPENTHREAD_TAG]; | 150 delete ipc_targets_[IPC_NTOPENTHREAD_TAG]; |
150 delete ipc_targets_[IPC_CREATEEVENT_TAG]; | 151 delete ipc_targets_[IPC_CREATEEVENT_TAG]; |
151 delete ipc_targets_[IPC_NTCREATEKEY_TAG]; | 152 delete ipc_targets_[IPC_NTCREATEKEY_TAG]; |
152 delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG]; | 153 delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG]; |
153 delete policy_maker_; | 154 delete policy_maker_; |
154 delete policy_; | 155 delete policy_; |
156 | |
157 if (lowbox_sid_) | |
158 LocalFree(lowbox_sid_); | |
159 | |
155 ::DeleteCriticalSection(&lock_); | 160 ::DeleteCriticalSection(&lock_); |
156 } | 161 } |
157 | 162 |
158 void PolicyBase::AddRef() { | 163 void PolicyBase::AddRef() { |
159 ::InterlockedIncrement(&ref_count); | 164 ::InterlockedIncrement(&ref_count); |
160 } | 165 } |
161 | 166 |
162 void PolicyBase::Release() { | 167 void PolicyBase::Release() { |
163 if (0 == ::InterlockedDecrement(&ref_count)) | 168 if (0 == ::InterlockedDecrement(&ref_count)) |
164 delete this; | 169 delete this; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 return rv; | 329 return rv; |
325 | 330 |
326 return SBOX_ALL_OK; | 331 return SBOX_ALL_OK; |
327 } | 332 } |
328 | 333 |
329 ResultCode PolicyBase::SetCapability(const wchar_t* sid) { | 334 ResultCode PolicyBase::SetCapability(const wchar_t* sid) { |
330 capabilities_.push_back(sid); | 335 capabilities_.push_back(sid); |
331 return SBOX_ALL_OK; | 336 return SBOX_ALL_OK; |
332 } | 337 } |
333 | 338 |
339 ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { | |
340 // SetLowBox and SetAppContainer are mutually exclusive. | |
341 if (appcontainer_list_.get()) | |
342 return SBOX_ERROR_UNEXPECTED_CALL; | |
343 | |
344 DCHECK(sid); | |
345 | |
346 if (lowbox_sid_) | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: This should be an error.
Shrikant Kelkar
2015/02/28 01:55:41
Done.
| |
347 LocalFree(lowbox_sid_); | |
348 | |
349 if (!ConvertStringSidToSid(sid, &lowbox_sid_)) | |
rvargas (doing something else)
2015/02/28 01:10:06
The should be an OS version check here
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
350 return SBOX_ERROR_GENERIC; | |
351 | |
352 return SBOX_ALL_OK; | |
353 } | |
354 | |
334 ResultCode PolicyBase::SetProcessMitigations( | 355 ResultCode PolicyBase::SetProcessMitigations( |
335 MitigationFlags flags) { | 356 MitigationFlags flags) { |
336 if (!CanSetProcessMitigationsPreStartup(flags)) | 357 if (!CanSetProcessMitigationsPreStartup(flags)) |
337 return SBOX_ERROR_BAD_PARAMS; | 358 return SBOX_ERROR_BAD_PARAMS; |
338 mitigations_ = flags; | 359 mitigations_ = flags; |
339 return SBOX_ALL_OK; | 360 return SBOX_ALL_OK; |
340 } | 361 } |
341 | 362 |
342 MitigationFlags PolicyBase::GetProcessMitigations() { | 363 MitigationFlags PolicyBase::GetProcessMitigations() { |
343 return mitigations_; | 364 return mitigations_; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
441 return SBOX_ERROR_GENERIC; | 462 return SBOX_ERROR_GENERIC; |
442 } | 463 } |
443 *job = job_obj.Detach(); | 464 *job = job_obj.Detach(); |
444 } else { | 465 } else { |
445 *job = NULL; | 466 *job = NULL; |
446 } | 467 } |
447 return SBOX_ALL_OK; | 468 return SBOX_ALL_OK; |
448 } | 469 } |
449 | 470 |
450 ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { | 471 ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { |
472 if (appcontainer_list_.get() && | |
473 appcontainer_list_->HasAppContainer() && | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: send this to the previous line
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
474 lowbox_sid_) | |
rvargas (doing something else)
2015/02/28 01:10:06
nit : requires {}
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
475 return SBOX_ERROR_UNEXPECTED_CALL; | |
rvargas (doing something else)
2015/02/28 01:10:06
SBOX_ERROR_BAD_PARAMS ?
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
476 | |
451 // Create the 'naked' token. This will be the permanent token associated | 477 // Create the 'naked' token. This will be the permanent token associated |
452 // with the process and therefore with any thread that is not impersonating. | 478 // with the process and therefore with any thread that is not impersonating. |
453 DWORD result = CreateRestrictedToken(lockdown, lockdown_level_, | 479 DWORD result = CreateRestrictedToken(lockdown, lockdown_level_, |
454 integrity_level_, PRIMARY); | 480 integrity_level_, PRIMARY); |
455 if (ERROR_SUCCESS != result) | 481 if (ERROR_SUCCESS != result) |
456 return SBOX_ERROR_GENERIC; | 482 return SBOX_ERROR_GENERIC; |
457 | 483 |
458 // If we're launching on the alternate desktop we need to make sure the | 484 // If we're launching on the alternate desktop we need to make sure the |
459 // integrity label on the object is no higher than the sandboxed process's | 485 // integrity label on the object is no higher than the sandboxed process's |
460 // integrity level. So, we lower the label on the desktop process if it's | 486 // integrity level. So, we lower the label on the desktop process if it's |
461 // not already low enough for our process. | 487 // not already low enough for our process. |
462 if (alternate_desktop_handle_ && use_alternate_desktop_ && | 488 if (alternate_desktop_handle_ && use_alternate_desktop_ && |
463 integrity_level_ != INTEGRITY_LEVEL_LAST && | 489 integrity_level_ != INTEGRITY_LEVEL_LAST && |
464 alternate_desktop_integrity_level_label_ < integrity_level_ && | 490 alternate_desktop_integrity_level_label_ < integrity_level_ && |
465 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { | 491 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { |
466 // Integrity label enum is reversed (higher level is a lower value). | 492 // Integrity label enum is reversed (higher level is a lower value). |
467 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, | 493 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, |
468 "Integrity level ordering reversed."); | 494 "Integrity level ordering reversed."); |
469 result = SetObjectIntegrityLabel(alternate_desktop_handle_, | 495 result = SetObjectIntegrityLabel(alternate_desktop_handle_, |
470 SE_WINDOW_OBJECT, | 496 SE_WINDOW_OBJECT, |
471 L"", | 497 L"", |
472 GetIntegrityLevelString(integrity_level_)); | 498 GetIntegrityLevelString(integrity_level_)); |
473 if (ERROR_SUCCESS != result) | 499 if (ERROR_SUCCESS != result) |
474 return SBOX_ERROR_GENERIC; | 500 return SBOX_ERROR_GENERIC; |
475 | 501 |
476 alternate_desktop_integrity_level_label_ = integrity_level_; | 502 alternate_desktop_integrity_level_label_ = integrity_level_; |
477 } | 503 } |
478 | 504 |
505 // We are maintaining two approaches this time and making them mutually | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: this time? (aka, remove)
rvargas (doing something else)
2015/02/28 01:10:06
nit: we are not making them mutually exclusive...
Shrikant Kelkar
2015/02/28 01:55:41
Done.
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
506 // exclusive. One is to start appcontainer process through StartupInfoEx | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: start an AppContainer
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
507 // and other is by attaching LowBox token after process creation. | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: We don't attach a token, we replace the token
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
479 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { | 508 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { |
480 // Windows refuses to work with an impersonation token. See SetAppContainer | 509 // Windows refuses to work with an impersonation token. See SetAppContainer |
481 // implementation for more details. | 510 // implementation for more details. |
482 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) | 511 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) |
483 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; | 512 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; |
484 | 513 |
485 *initial = INVALID_HANDLE_VALUE; | 514 *initial = INVALID_HANDLE_VALUE; |
486 return SBOX_ALL_OK; | 515 return SBOX_ALL_OK; |
516 } else if (lowbox_sid_) { | |
517 NtCreateLowBoxToken CreateLowBox = NULL; | |
518 ResolveNTFunctionPtr("NtCreateLowBoxToken", &CreateLowBox); | |
519 | |
520 HANDLE token_lowbox = NULL; | |
521 | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: remove empty line. In fact, move line 520 to
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
522 OBJECT_ATTRIBUTES obj_attr; | |
523 InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL); | |
524 | |
525 NTSTATUS status = CreateLowBox(&token_lowbox, | |
526 *lockdown, | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: we can fit more arguments per line here...
Shrikant Kelkar
2015/02/28 01:55:42
Done.
| |
527 TOKEN_ALL_ACCESS, | |
528 &obj_attr, | |
529 lowbox_sid_, | |
530 0, | |
531 NULL, | |
532 0, | |
533 NULL); | |
534 if (!NT_SUCCESS(status)) { | |
rvargas (doing something else)
2015/02/28 01:10:06
nit: no {}
Shrikant Kelkar
2015/02/28 01:55:41
Done.
| |
535 return SBOX_ERROR_GENERIC; | |
536 } | |
537 DCHECK(token_lowbox); | |
538 ::CloseHandle(*lockdown); | |
539 *lockdown = token_lowbox; | |
487 } | 540 } |
488 | 541 |
489 // Create the 'better' token. We use this token as the one that the main | 542 // Create the 'better' token. We use this token as the one that the main |
490 // thread uses when booting up the process. It should contain most of | 543 // thread uses when booting up the process. It should contain most of |
491 // what we need (before reaching main( )) | 544 // what we need (before reaching main( )) |
492 result = CreateRestrictedToken(initial, initial_level_, | 545 result = CreateRestrictedToken(initial, initial_level_, |
493 integrity_level_, IMPERSONATION); | 546 integrity_level_, IMPERSONATION); |
494 if (ERROR_SUCCESS != result) { | 547 if (ERROR_SUCCESS != result) { |
495 ::CloseHandle(*lockdown); | 548 ::CloseHandle(*lockdown); |
496 return SBOX_ERROR_GENERIC; | 549 return SBOX_ERROR_GENERIC; |
497 } | 550 } |
498 return SBOX_ALL_OK; | 551 return SBOX_ALL_OK; |
499 } | 552 } |
500 | 553 |
501 const AppContainerAttributes* PolicyBase::GetAppContainer() const { | 554 const AppContainerAttributes* PolicyBase::GetAppContainer() const { |
502 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) | 555 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) |
503 return NULL; | 556 return NULL; |
504 | 557 |
505 return appcontainer_list_.get(); | 558 return appcontainer_list_.get(); |
506 } | 559 } |
507 | 560 |
561 const PSID PolicyBase::GetLowBoxSid() const { | |
562 return lowbox_sid_; | |
563 } | |
564 | |
508 bool PolicyBase::AddTarget(TargetProcess* target) { | 565 bool PolicyBase::AddTarget(TargetProcess* target) { |
509 if (NULL != policy_) | 566 if (NULL != policy_) |
510 policy_maker_->Done(); | 567 policy_maker_->Done(); |
511 | 568 |
512 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), | 569 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), |
513 mitigations_)) { | 570 mitigations_)) { |
514 return false; | 571 return false; |
515 } | 572 } |
516 | 573 |
517 if (!SetupAllInterceptions(target)) | 574 if (!SetupAllInterceptions(target)) |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
740 break; | 797 break; |
741 } | 798 } |
742 | 799 |
743 default: { return SBOX_ERROR_UNSUPPORTED; } | 800 default: { return SBOX_ERROR_UNSUPPORTED; } |
744 } | 801 } |
745 | 802 |
746 return SBOX_ALL_OK; | 803 return SBOX_ALL_OK; |
747 } | 804 } |
748 | 805 |
749 } // namespace sandbox | 806 } // namespace sandbox |
OLD | NEW |