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" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
14 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
15 #include "sandbox/win/src/app_container.h" | 16 #include "sandbox/win/src/app_container.h" |
16 #include "sandbox/win/src/filesystem_dispatcher.h" | |
17 #include "sandbox/win/src/filesystem_policy.h" | 17 #include "sandbox/win/src/filesystem_policy.h" |
18 #include "sandbox/win/src/handle_dispatcher.h" | |
19 #include "sandbox/win/src/handle_policy.h" | 18 #include "sandbox/win/src/handle_policy.h" |
| 19 #include "sandbox/win/src/interception.h" |
20 #include "sandbox/win/src/job.h" | 20 #include "sandbox/win/src/job.h" |
21 #include "sandbox/win/src/interception.h" | |
22 #include "sandbox/win/src/process_mitigations.h" | |
23 #include "sandbox/win/src/named_pipe_dispatcher.h" | |
24 #include "sandbox/win/src/named_pipe_policy.h" | 21 #include "sandbox/win/src/named_pipe_policy.h" |
25 #include "sandbox/win/src/policy_broker.h" | 22 #include "sandbox/win/src/policy_broker.h" |
26 #include "sandbox/win/src/policy_engine_processor.h" | 23 #include "sandbox/win/src/policy_engine_processor.h" |
27 #include "sandbox/win/src/policy_low_level.h" | 24 #include "sandbox/win/src/policy_low_level.h" |
28 #include "sandbox/win/src/process_mitigations_win32k_dispatcher.h" | 25 #include "sandbox/win/src/process_mitigations.h" |
29 #include "sandbox/win/src/process_mitigations_win32k_policy.h" | 26 #include "sandbox/win/src/process_mitigations_win32k_policy.h" |
30 #include "sandbox/win/src/process_thread_dispatcher.h" | |
31 #include "sandbox/win/src/process_thread_policy.h" | 27 #include "sandbox/win/src/process_thread_policy.h" |
32 #include "sandbox/win/src/registry_dispatcher.h" | |
33 #include "sandbox/win/src/registry_policy.h" | 28 #include "sandbox/win/src/registry_policy.h" |
34 #include "sandbox/win/src/restricted_token_utils.h" | 29 #include "sandbox/win/src/restricted_token_utils.h" |
35 #include "sandbox/win/src/sandbox_policy.h" | 30 #include "sandbox/win/src/sandbox_policy.h" |
36 #include "sandbox/win/src/sandbox_utils.h" | 31 #include "sandbox/win/src/sandbox_utils.h" |
37 #include "sandbox/win/src/sync_dispatcher.h" | |
38 #include "sandbox/win/src/sync_policy.h" | 32 #include "sandbox/win/src/sync_policy.h" |
39 #include "sandbox/win/src/target_process.h" | 33 #include "sandbox/win/src/target_process.h" |
| 34 #include "sandbox/win/src/top_level_dispatcher.h" |
40 #include "sandbox/win/src/window.h" | 35 #include "sandbox/win/src/window.h" |
41 | 36 |
42 namespace { | 37 namespace { |
43 | 38 |
44 // The standard windows size for one memory page. | 39 // The standard windows size for one memory page. |
45 const size_t kOneMemPage = 4096; | 40 const size_t kOneMemPage = 4096; |
46 // The IPC and Policy shared memory sizes. | 41 // The IPC and Policy shared memory sizes. |
47 const size_t kIPCMemSize = kOneMemPage * 2; | 42 const size_t kIPCMemSize = kOneMemPage * 2; |
48 const size_t kPolMemSize = kOneMemPage * 14; | 43 const size_t kPolMemSize = kOneMemPage * 14; |
49 | 44 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 NTSTATUS status = CreateObjectDirectory(&handle, | 95 NTSTATUS status = CreateObjectDirectory(&handle, |
101 DIRECTORY_ALL_ACCESS, | 96 DIRECTORY_ALL_ACCESS, |
102 &obj_attr); | 97 &obj_attr); |
103 | 98 |
104 if (!NT_SUCCESS(status)) | 99 if (!NT_SUCCESS(status)) |
105 return NULL; | 100 return NULL; |
106 | 101 |
107 return handle; | 102 return handle; |
108 } | 103 } |
109 | 104 |
110 } | 105 } // namespace |
111 | 106 |
112 namespace sandbox { | 107 namespace sandbox { |
113 | 108 |
114 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level; | 109 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level; |
115 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations; | 110 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations; |
116 | 111 |
117 // Initializes static members. | 112 // Initializes static members. |
118 HWINSTA PolicyBase::alternate_winstation_handle_ = NULL; | 113 HWINSTA PolicyBase::alternate_winstation_handle_ = NULL; |
119 HDESK PolicyBase::alternate_desktop_handle_ = NULL; | 114 HDESK PolicyBase::alternate_desktop_handle_ = NULL; |
120 IntegrityLevel PolicyBase::alternate_desktop_integrity_level_label_ = | 115 IntegrityLevel PolicyBase::alternate_desktop_integrity_level_label_ = |
(...skipping 13 matching lines...) Expand all Loading... |
134 stdout_handle_(INVALID_HANDLE_VALUE), | 129 stdout_handle_(INVALID_HANDLE_VALUE), |
135 stderr_handle_(INVALID_HANDLE_VALUE), | 130 stderr_handle_(INVALID_HANDLE_VALUE), |
136 integrity_level_(INTEGRITY_LEVEL_LAST), | 131 integrity_level_(INTEGRITY_LEVEL_LAST), |
137 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), | 132 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), |
138 mitigations_(0), | 133 mitigations_(0), |
139 delayed_mitigations_(0), | 134 delayed_mitigations_(0), |
140 policy_maker_(NULL), | 135 policy_maker_(NULL), |
141 policy_(NULL), | 136 policy_(NULL), |
142 lowbox_sid_(NULL) { | 137 lowbox_sid_(NULL) { |
143 ::InitializeCriticalSection(&lock_); | 138 ::InitializeCriticalSection(&lock_); |
144 // Initialize the IPC dispatcher array. | 139 dispatcher_.reset(new TopLevelDispatcher(this)); |
145 memset(&ipc_targets_, NULL, sizeof(ipc_targets_)); | |
146 Dispatcher* dispatcher = NULL; | |
147 | |
148 dispatcher = new FilesystemDispatcher(this); | |
149 ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher; | |
150 ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher; | |
151 ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher; | |
152 ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher; | |
153 ipc_targets_[IPC_NTQUERYFULLATTRIBUTESFILE_TAG] = dispatcher; | |
154 | |
155 dispatcher = new NamedPipeDispatcher(this); | |
156 ipc_targets_[IPC_CREATENAMEDPIPEW_TAG] = dispatcher; | |
157 | |
158 dispatcher = new ThreadProcessDispatcher(this); | |
159 ipc_targets_[IPC_NTOPENTHREAD_TAG] = dispatcher; | |
160 ipc_targets_[IPC_NTOPENPROCESS_TAG] = dispatcher; | |
161 ipc_targets_[IPC_CREATEPROCESSW_TAG] = dispatcher; | |
162 ipc_targets_[IPC_NTOPENPROCESSTOKEN_TAG] = dispatcher; | |
163 ipc_targets_[IPC_NTOPENPROCESSTOKENEX_TAG] = dispatcher; | |
164 | |
165 dispatcher = new SyncDispatcher(this); | |
166 ipc_targets_[IPC_CREATEEVENT_TAG] = dispatcher; | |
167 ipc_targets_[IPC_OPENEVENT_TAG] = dispatcher; | |
168 | |
169 dispatcher = new RegistryDispatcher(this); | |
170 ipc_targets_[IPC_NTCREATEKEY_TAG] = dispatcher; | |
171 ipc_targets_[IPC_NTOPENKEY_TAG] = dispatcher; | |
172 | |
173 dispatcher = new HandleDispatcher(this); | |
174 ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG] = dispatcher; | |
175 | |
176 dispatcher = new ProcessMitigationsWin32KDispatcher(this); | |
177 ipc_targets_[IPC_GDI_GDIDLLINITIALIZE_TAG] = dispatcher; | |
178 ipc_targets_[IPC_GDI_GETSTOCKOBJECT_TAG] = dispatcher; | |
179 ipc_targets_[IPC_USER_REGISTERCLASSW_TAG] = dispatcher; | |
180 } | 140 } |
181 | 141 |
182 PolicyBase::~PolicyBase() { | 142 PolicyBase::~PolicyBase() { |
183 ClearSharedHandles(); | 143 ClearSharedHandles(); |
184 | 144 |
185 TargetSet::iterator it; | 145 TargetSet::iterator it; |
186 for (it = targets_.begin(); it != targets_.end(); ++it) { | 146 for (it = targets_.begin(); it != targets_.end(); ++it) { |
187 TargetProcess* target = (*it); | 147 TargetProcess* target = (*it); |
188 delete target; | 148 delete target; |
189 } | 149 } |
190 delete ipc_targets_[IPC_NTCREATEFILE_TAG]; | |
191 delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG]; | |
192 delete ipc_targets_[IPC_NTOPENTHREAD_TAG]; | |
193 delete ipc_targets_[IPC_CREATEEVENT_TAG]; | |
194 delete ipc_targets_[IPC_NTCREATEKEY_TAG]; | |
195 delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG]; | |
196 delete policy_maker_; | 150 delete policy_maker_; |
197 delete policy_; | 151 delete policy_; |
198 | 152 |
199 if (lowbox_sid_) | 153 if (lowbox_sid_) |
200 ::LocalFree(lowbox_sid_); | 154 ::LocalFree(lowbox_sid_); |
201 | 155 |
202 ::DeleteCriticalSection(&lock_); | 156 ::DeleteCriticalSection(&lock_); |
203 } | 157 } |
204 | 158 |
205 void PolicyBase::AddRef() { | 159 void PolicyBase::AddRef() { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 } | 436 } |
483 | 437 |
484 const HandleList& PolicyBase::GetHandlesBeingShared() { | 438 const HandleList& PolicyBase::GetHandlesBeingShared() { |
485 return handles_to_share_; | 439 return handles_to_share_; |
486 } | 440 } |
487 | 441 |
488 void PolicyBase::ClearSharedHandles() { | 442 void PolicyBase::ClearSharedHandles() { |
489 STLDeleteElements(&handles_to_share_); | 443 STLDeleteElements(&handles_to_share_); |
490 } | 444 } |
491 | 445 |
492 // When an IPC is ready in any of the targets we get called. We manage an array | |
493 // of IPC dispatchers which are keyed on the IPC tag so we normally delegate | |
494 // to the appropriate dispatcher unless we can handle the IPC call ourselves. | |
495 Dispatcher* PolicyBase::OnMessageReady(IPCParams* ipc, | |
496 CallbackGeneric* callback) { | |
497 DCHECK(callback); | |
498 static const IPCParams ping1 = {IPC_PING1_TAG, {UINT32_TYPE}}; | |
499 static const IPCParams ping2 = {IPC_PING2_TAG, {INOUTPTR_TYPE}}; | |
500 | |
501 if (ping1.Matches(ipc) || ping2.Matches(ipc)) { | |
502 *callback = reinterpret_cast<CallbackGeneric>( | |
503 static_cast<Callback1>(&PolicyBase::Ping)); | |
504 return this; | |
505 } | |
506 | |
507 Dispatcher* dispatch = GetDispatcher(ipc->ipc_tag); | |
508 if (!dispatch) { | |
509 NOTREACHED(); | |
510 return NULL; | |
511 } | |
512 return dispatch->OnMessageReady(ipc, callback); | |
513 } | |
514 | |
515 // Delegate to the appropriate dispatcher. | |
516 bool PolicyBase::SetupService(InterceptionManager* manager, int service) { | |
517 if (IPC_PING1_TAG == service || IPC_PING2_TAG == service) | |
518 return true; | |
519 | |
520 Dispatcher* dispatch = GetDispatcher(service); | |
521 if (!dispatch) { | |
522 NOTREACHED(); | |
523 return false; | |
524 } | |
525 return dispatch->SetupService(manager, service); | |
526 } | |
527 | |
528 ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { | 446 ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { |
529 if (job_level_ != JOB_NONE) { | 447 if (job_level_ != JOB_NONE) { |
530 // Create the windows job object. | 448 // Create the windows job object. |
531 Job job_obj; | 449 Job job_obj; |
532 DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_, | 450 DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_, |
533 memory_limit_); | 451 memory_limit_); |
534 if (ERROR_SUCCESS != result) | 452 if (ERROR_SUCCESS != result) |
535 return SBOX_ERROR_GENERIC; | 453 return SBOX_ERROR_GENERIC; |
536 | 454 |
537 *job = job_obj.Take(); | 455 *job = job_obj.Take(); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 return false; | 566 return false; |
649 } | 567 } |
650 | 568 |
651 if (!SetupAllInterceptions(target)) | 569 if (!SetupAllInterceptions(target)) |
652 return false; | 570 return false; |
653 | 571 |
654 if (!SetupHandleCloser(target)) | 572 if (!SetupHandleCloser(target)) |
655 return false; | 573 return false; |
656 | 574 |
657 // Initialize the sandbox infrastructure for the target. | 575 // Initialize the sandbox infrastructure for the target. |
658 if (ERROR_SUCCESS != target->Init(this, policy_, kIPCMemSize, kPolMemSize)) | 576 if (ERROR_SUCCESS != |
| 577 target->Init(dispatcher_.get(), policy_, kIPCMemSize, kPolMemSize)) |
659 return false; | 578 return false; |
660 | 579 |
661 g_shared_delayed_integrity_level = delayed_integrity_level_; | 580 g_shared_delayed_integrity_level = delayed_integrity_level_; |
662 ResultCode ret = target->TransferVariable( | 581 ResultCode ret = target->TransferVariable( |
663 "g_shared_delayed_integrity_level", | 582 "g_shared_delayed_integrity_level", |
664 &g_shared_delayed_integrity_level, | 583 &g_shared_delayed_integrity_level, |
665 sizeof(g_shared_delayed_integrity_level)); | 584 sizeof(g_shared_delayed_integrity_level)); |
666 g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; | 585 g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; |
667 if (SBOX_ALL_OK != ret) | 586 if (SBOX_ALL_OK != ret) |
668 return false; | 587 return false; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 } | 648 } |
730 | 649 |
731 HANDLE PolicyBase::GetStdoutHandle() { | 650 HANDLE PolicyBase::GetStdoutHandle() { |
732 return stdout_handle_; | 651 return stdout_handle_; |
733 } | 652 } |
734 | 653 |
735 HANDLE PolicyBase::GetStderrHandle() { | 654 HANDLE PolicyBase::GetStderrHandle() { |
736 return stderr_handle_; | 655 return stderr_handle_; |
737 } | 656 } |
738 | 657 |
739 // We service IPC_PING_TAG message which is a way to test a round trip of the | |
740 // IPC subsystem. We receive a integer cookie and we are expected to return the | |
741 // cookie times two (or three) and the current tick count. | |
742 bool PolicyBase::Ping(IPCInfo* ipc, void* arg1) { | |
743 switch (ipc->ipc_tag) { | |
744 case IPC_PING1_TAG: { | |
745 IPCInt ipc_int(arg1); | |
746 uint32 cookie = ipc_int.As32Bit(); | |
747 ipc->return_info.extended_count = 2; | |
748 ipc->return_info.extended[0].unsigned_int = ::GetTickCount(); | |
749 ipc->return_info.extended[1].unsigned_int = 2 * cookie; | |
750 return true; | |
751 } | |
752 case IPC_PING2_TAG: { | |
753 CountedBuffer* io_buffer = reinterpret_cast<CountedBuffer*>(arg1); | |
754 if (sizeof(uint32) != io_buffer->Size()) | |
755 return false; | |
756 | |
757 uint32* cookie = reinterpret_cast<uint32*>(io_buffer->Buffer()); | |
758 *cookie = (*cookie) * 3; | |
759 return true; | |
760 } | |
761 default: return false; | |
762 } | |
763 } | |
764 | |
765 Dispatcher* PolicyBase::GetDispatcher(int ipc_tag) { | |
766 if (ipc_tag >= IPC_LAST_TAG || ipc_tag <= IPC_UNUSED_TAG) | |
767 return NULL; | |
768 | |
769 return ipc_targets_[ipc_tag]; | |
770 } | |
771 | |
772 bool PolicyBase::SetupAllInterceptions(TargetProcess* target) { | 658 bool PolicyBase::SetupAllInterceptions(TargetProcess* target) { |
773 InterceptionManager manager(target, relaxed_interceptions_); | 659 InterceptionManager manager(target, relaxed_interceptions_); |
774 | 660 |
775 if (policy_) { | 661 if (policy_) { |
776 for (int i = 0; i < IPC_LAST_TAG; i++) { | 662 for (int i = 0; i < IPC_LAST_TAG; i++) { |
777 if (policy_->entry[i] && !ipc_targets_[i]->SetupService(&manager, i)) | 663 if (policy_->entry[i] && !dispatcher_->SetupService(&manager, i)) |
778 return false; | 664 return false; |
779 } | 665 } |
780 } | 666 } |
781 | 667 |
782 if (!blacklisted_dlls_.empty()) { | 668 if (!blacklisted_dlls_.empty()) { |
783 std::vector<base::string16>::iterator it = blacklisted_dlls_.begin(); | 669 std::vector<base::string16>::iterator it = blacklisted_dlls_.begin(); |
784 for (; it != blacklisted_dlls_.end(); ++it) { | 670 for (; it != blacklisted_dlls_.end(); ++it) { |
785 manager.AddToUnloadModules(it->c_str()); | 671 manager.AddToUnloadModules(it->c_str()); |
786 } | 672 } |
787 } | 673 } |
788 | 674 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 break; | 760 break; |
875 } | 761 } |
876 | 762 |
877 default: { return SBOX_ERROR_UNSUPPORTED; } | 763 default: { return SBOX_ERROR_UNSUPPORTED; } |
878 } | 764 } |
879 | 765 |
880 return SBOX_ALL_OK; | 766 return SBOX_ALL_OK; |
881 } | 767 } |
882 | 768 |
883 } // namespace sandbox | 769 } // namespace sandbox |
OLD | NEW |