| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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/src/broker_services.h" | 5 #include "sandbox/src/broker_services.h" |
| 6 | 6 |
| 7 #include <AclAPI.h> | |
| 8 | |
| 9 #include "base/logging.h" | 7 #include "base/logging.h" |
| 10 #include "base/threading/platform_thread.h" | 8 #include "base/threading/platform_thread.h" |
| 11 #include "sandbox/src/sandbox_policy_base.h" | 9 #include "sandbox/src/sandbox_policy_base.h" |
| 12 #include "sandbox/src/sandbox.h" | 10 #include "sandbox/src/sandbox.h" |
| 13 #include "sandbox/src/target_process.h" | 11 #include "sandbox/src/target_process.h" |
| 14 #include "sandbox/src/win2k_threadpool.h" | 12 #include "sandbox/src/win2k_threadpool.h" |
| 15 #include "sandbox/src/win_utils.h" | 13 #include "sandbox/src/win_utils.h" |
| 16 | 14 |
| 17 namespace { | 15 namespace { |
| 18 | 16 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 37 } | 35 } |
| 38 | 36 |
| 39 // the different commands that you can send to the worker thread that | 37 // the different commands that you can send to the worker thread that |
| 40 // executes TargetEventsThread(). | 38 // executes TargetEventsThread(). |
| 41 enum { | 39 enum { |
| 42 THREAD_CTRL_NONE, | 40 THREAD_CTRL_NONE, |
| 43 THREAD_CTRL_QUIT, | 41 THREAD_CTRL_QUIT, |
| 44 THREAD_CTRL_LAST | 42 THREAD_CTRL_LAST |
| 45 }; | 43 }; |
| 46 | 44 |
| 47 // Adds deny ACEs to broker and returns the security descriptor so it can | |
| 48 // be applied to target processes. The returned descriptor must be freed by | |
| 49 // calling LocalFree. | |
| 50 PSECURITY_DESCRIPTOR SetSecurityDescriptorForBroker() { | |
| 51 static bool is_initialized = false; | |
| 52 DWORD error = ERROR_SUCCESS; | |
| 53 PSECURITY_DESCRIPTOR security_descriptor = NULL; | |
| 54 | |
| 55 if (!is_initialized) { | |
| 56 error = sandbox::SetObjectDenyRestrictedAndNull(GetCurrentProcess(), | |
| 57 SE_KERNEL_OBJECT); | |
| 58 if (error) { | |
| 59 ::SetLastError(error); | |
| 60 return NULL; | |
| 61 } | |
| 62 | |
| 63 is_initialized = true; | |
| 64 } | |
| 65 | |
| 66 // Save off resulting security descriptor for spawning the targets. | |
| 67 error = ::GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, | |
| 68 DACL_SECURITY_INFORMATION, NULL, NULL, | |
| 69 NULL, NULL, &security_descriptor); | |
| 70 if (error) { | |
| 71 ::SetLastError(error); | |
| 72 return NULL; | |
| 73 } | |
| 74 | |
| 75 return security_descriptor; | |
| 76 } | |
| 77 | |
| 78 } | 45 } |
| 79 | 46 |
| 80 namespace sandbox { | 47 namespace sandbox { |
| 81 | 48 |
| 82 BrokerServicesBase::BrokerServicesBase() | 49 BrokerServicesBase::BrokerServicesBase() |
| 83 : thread_pool_(NULL), job_port_(NULL), no_targets_(NULL), | 50 : thread_pool_(NULL), job_port_(NULL), no_targets_(NULL), |
| 84 security_descriptor_(NULL), job_thread_(NULL) { | 51 job_thread_(NULL) { |
| 85 } | 52 } |
| 86 | 53 |
| 87 // The broker uses a dedicated worker thread that services the job completion | 54 // The broker uses a dedicated worker thread that services the job completion |
| 88 // port to perform policy notifications and associated cleanup tasks. | 55 // port to perform policy notifications and associated cleanup tasks. |
| 89 ResultCode BrokerServicesBase::Init() { | 56 ResultCode BrokerServicesBase::Init() { |
| 90 if ((NULL != job_port_) || (NULL != thread_pool_) || | 57 if ((NULL != job_port_) || (NULL != thread_pool_)) |
| 91 (NULL != security_descriptor_)) { | |
| 92 return SBOX_ERROR_UNEXPECTED_CALL; | 58 return SBOX_ERROR_UNEXPECTED_CALL; |
| 93 } | |
| 94 | 59 |
| 95 ::InitializeCriticalSection(&lock_); | 60 ::InitializeCriticalSection(&lock_); |
| 96 | 61 |
| 97 job_port_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); | 62 job_port_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); |
| 98 if (NULL == job_port_) | 63 if (NULL == job_port_) |
| 99 return SBOX_ERROR_GENERIC; | 64 return SBOX_ERROR_GENERIC; |
| 100 | 65 |
| 101 security_descriptor_ = SetSecurityDescriptorForBroker(); | |
| 102 if (NULL == security_descriptor_) | |
| 103 return SBOX_ERROR_GENERIC; | |
| 104 | |
| 105 no_targets_ = ::CreateEventW(NULL, TRUE, FALSE, NULL); | 66 no_targets_ = ::CreateEventW(NULL, TRUE, FALSE, NULL); |
| 106 | 67 |
| 107 job_thread_ = ::CreateThread(NULL, 0, // Default security and stack. | 68 job_thread_ = ::CreateThread(NULL, 0, // Default security and stack. |
| 108 TargetEventsThread, this, NULL, NULL); | 69 TargetEventsThread, this, NULL, NULL); |
| 109 if (NULL == job_thread_) | 70 if (NULL == job_thread_) |
| 110 return SBOX_ERROR_GENERIC; | 71 return SBOX_ERROR_GENERIC; |
| 111 | 72 |
| 112 return SBOX_ALL_OK; | 73 return SBOX_ALL_OK; |
| 113 } | 74 } |
| 114 | 75 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 136 | 97 |
| 137 JobTrackerList::iterator it; | 98 JobTrackerList::iterator it; |
| 138 for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) { | 99 for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) { |
| 139 JobTracker* tracker = (*it); | 100 JobTracker* tracker = (*it); |
| 140 FreeResources(tracker); | 101 FreeResources(tracker); |
| 141 delete tracker; | 102 delete tracker; |
| 142 } | 103 } |
| 143 ::CloseHandle(job_thread_); | 104 ::CloseHandle(job_thread_); |
| 144 delete thread_pool_; | 105 delete thread_pool_; |
| 145 ::CloseHandle(no_targets_); | 106 ::CloseHandle(no_targets_); |
| 146 | |
| 147 if (security_descriptor_) | |
| 148 ::LocalFree(security_descriptor_); | |
| 149 | |
| 150 // If job_port_ isn't NULL, assumes that the lock has been initialized. | 107 // If job_port_ isn't NULL, assumes that the lock has been initialized. |
| 151 if (job_port_) | 108 if (job_port_) |
| 152 ::DeleteCriticalSection(&lock_); | 109 ::DeleteCriticalSection(&lock_); |
| 153 } | 110 } |
| 154 | 111 |
| 155 TargetPolicy* BrokerServicesBase::CreatePolicy() { | 112 TargetPolicy* BrokerServicesBase::CreatePolicy() { |
| 156 // If you change the type of the object being created here you must also | 113 // If you change the type of the object being created here you must also |
| 157 // change the downcast to it in SpawnTarget(). | 114 // change the downcast to it in SpawnTarget(). |
| 158 return new PolicyBase; | 115 return new PolicyBase; |
| 159 } | 116 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 return SBOX_ERROR_GENERIC; | 256 return SBOX_ERROR_GENERIC; |
| 300 | 257 |
| 301 // Construct the thread pool here in case it is expensive. | 258 // Construct the thread pool here in case it is expensive. |
| 302 // The thread pool is shared by all the targets | 259 // The thread pool is shared by all the targets |
| 303 if (NULL == thread_pool_) | 260 if (NULL == thread_pool_) |
| 304 thread_pool_ = new Win2kThreadPool(); | 261 thread_pool_ = new Win2kThreadPool(); |
| 305 | 262 |
| 306 // Create the TargetProces object and spawn the target suspended. Note that | 263 // Create the TargetProces object and spawn the target suspended. Note that |
| 307 // Brokerservices does not own the target object. It is owned by the Policy. | 264 // Brokerservices does not own the target object. It is owned by the Policy. |
| 308 PROCESS_INFORMATION process_info = {0}; | 265 PROCESS_INFORMATION process_info = {0}; |
| 309 | |
| 310 TargetProcess* target = new TargetProcess(initial_token, lockdown_token, | 266 TargetProcess* target = new TargetProcess(initial_token, lockdown_token, |
| 311 job, thread_pool_); | 267 job, thread_pool_); |
| 312 | 268 |
| 313 std::wstring desktop = policy_base->GetAlternateDesktop(); | 269 std::wstring desktop = policy_base->GetAlternateDesktop(); |
| 314 | 270 |
| 315 // Set the security descriptor so the target picks up deny ACEs. | |
| 316 SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), | |
| 317 security_descriptor_, | |
| 318 FALSE}; | |
| 319 | |
| 320 win_result = target->Create(exe_path, command_line, | 271 win_result = target->Create(exe_path, command_line, |
| 321 desktop.empty() ? NULL : desktop.c_str(), | 272 desktop.empty() ? NULL : desktop.c_str(), |
| 322 &security_attributes, | |
| 323 &process_info); | 273 &process_info); |
| 324 if (ERROR_SUCCESS != win_result) | 274 if (ERROR_SUCCESS != win_result) |
| 325 return SpawnCleanup(target, win_result); | 275 return SpawnCleanup(target, win_result); |
| 326 | 276 |
| 327 if ((INVALID_HANDLE_VALUE == process_info.hProcess) || | 277 if ((INVALID_HANDLE_VALUE == process_info.hProcess) || |
| 328 (INVALID_HANDLE_VALUE == process_info.hThread)) | 278 (INVALID_HANDLE_VALUE == process_info.hThread)) |
| 329 return SpawnCleanup(target, win_result); | 279 return SpawnCleanup(target, win_result); |
| 330 | 280 |
| 331 // Now the policy is the owner of the target. | 281 // Now the policy is the owner of the target. |
| 332 if (!policy_base->AddTarget(target)) { | 282 if (!policy_base->AddTarget(target)) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 356 return SBOX_ALL_OK; | 306 return SBOX_ALL_OK; |
| 357 } | 307 } |
| 358 | 308 |
| 359 | 309 |
| 360 ResultCode BrokerServicesBase::WaitForAllTargets() { | 310 ResultCode BrokerServicesBase::WaitForAllTargets() { |
| 361 ::WaitForSingleObject(no_targets_, INFINITE); | 311 ::WaitForSingleObject(no_targets_, INFINITE); |
| 362 return SBOX_ALL_OK; | 312 return SBOX_ALL_OK; |
| 363 } | 313 } |
| 364 | 314 |
| 365 } // namespace sandbox | 315 } // namespace sandbox |
| OLD | NEW |