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