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/broker_services.h" | 5 #include "sandbox/win/src/broker_services.h" |
6 | 6 |
| 7 #include <AclAPI.h> |
| 8 |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
9 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
10 #include "base/win/scoped_handle.h" | 12 #include "base/win/scoped_handle.h" |
11 #include "base/win/scoped_process_information.h" | 13 #include "base/win/scoped_process_information.h" |
12 #include "base/win/startup_information.h" | 14 #include "base/win/startup_information.h" |
13 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
14 #include "sandbox/win/src/app_container.h" | 16 #include "sandbox/win/src/app_container.h" |
15 #include "sandbox/win/src/process_mitigations.h" | 17 #include "sandbox/win/src/process_mitigations.h" |
16 #include "sandbox/win/src/sandbox_policy_base.h" | 18 #include "sandbox/win/src/sandbox_policy_base.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 75 |
74 void DeregisterPeerTracker(PeerTracker* peer) { | 76 void DeregisterPeerTracker(PeerTracker* peer) { |
75 // Deregistration shouldn't fail, but we leak rather than crash if it does. | 77 // Deregistration shouldn't fail, but we leak rather than crash if it does. |
76 if (::UnregisterWaitEx(peer->wait_object, INVALID_HANDLE_VALUE)) { | 78 if (::UnregisterWaitEx(peer->wait_object, INVALID_HANDLE_VALUE)) { |
77 delete peer; | 79 delete peer; |
78 } else { | 80 } else { |
79 NOTREACHED(); | 81 NOTREACHED(); |
80 } | 82 } |
81 } | 83 } |
82 | 84 |
| 85 // Utility function to pack token values into a key for the cache map. |
| 86 uint32_t GenerateTokenCacheKey(const sandbox::PolicyBase* policy) { |
| 87 const size_t kTokenShift = 3; |
| 88 uint32_t key; |
| 89 |
| 90 // Make sure our token values aren't too large to pack into the key. |
| 91 static_assert(sandbox::USER_LAST <= (1 << kTokenShift), |
| 92 "TokenLevel too large"); |
| 93 static_assert(sandbox::INTEGRITY_LEVEL_LAST <= (1 << kTokenShift), |
| 94 "IntegrityLevel too large"); |
| 95 static_assert(sizeof(key) < (kTokenShift * 3), |
| 96 "Token key type too small"); |
| 97 |
| 98 // The key is the enum values shifted to avoid overlap and OR'd together. |
| 99 key = policy->GetInitialTokenLevel(); |
| 100 key <<= kTokenShift; |
| 101 key |= policy->GetLockdownTokenLevel(); |
| 102 key <<= kTokenShift; |
| 103 key |= policy->GetIntegrityLevel(); |
| 104 |
| 105 return key; |
| 106 } |
| 107 |
83 } // namespace | 108 } // namespace |
84 | 109 |
85 namespace sandbox { | 110 namespace sandbox { |
86 | 111 |
87 BrokerServicesBase::BrokerServicesBase() | 112 BrokerServicesBase::BrokerServicesBase() |
88 : thread_pool_(NULL), job_port_(NULL), no_targets_(NULL), | 113 : thread_pool_(NULL), job_port_(NULL), no_targets_(NULL), |
89 job_thread_(NULL) { | 114 job_thread_(NULL) { |
90 } | 115 } |
91 | 116 |
92 // The broker uses a dedicated worker thread that services the job completion | 117 // The broker uses a dedicated worker thread that services the job completion |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 | 171 |
147 // Cancel the wait events and delete remaining peer trackers. | 172 // Cancel the wait events and delete remaining peer trackers. |
148 for (PeerTrackerMap::iterator it = peer_map_.begin(); | 173 for (PeerTrackerMap::iterator it = peer_map_.begin(); |
149 it != peer_map_.end(); ++it) { | 174 it != peer_map_.end(); ++it) { |
150 DeregisterPeerTracker(it->second); | 175 DeregisterPeerTracker(it->second); |
151 } | 176 } |
152 | 177 |
153 // If job_port_ isn't NULL, assumes that the lock has been initialized. | 178 // If job_port_ isn't NULL, assumes that the lock has been initialized. |
154 if (job_port_) | 179 if (job_port_) |
155 ::DeleteCriticalSection(&lock_); | 180 ::DeleteCriticalSection(&lock_); |
| 181 |
| 182 // Close any token in the cache. |
| 183 for (TokenCacheMap::iterator it = token_cache_.begin(); |
| 184 it != token_cache_.end(); ++it) { |
| 185 ::CloseHandle(it->second.first); |
| 186 ::CloseHandle(it->second.second); |
| 187 } |
156 } | 188 } |
157 | 189 |
158 TargetPolicy* BrokerServicesBase::CreatePolicy() { | 190 TargetPolicy* BrokerServicesBase::CreatePolicy() { |
159 // If you change the type of the object being created here you must also | 191 // If you change the type of the object being created here you must also |
160 // change the downcast to it in SpawnTarget(). | 192 // change the downcast to it in SpawnTarget(). |
161 return new PolicyBase; | 193 return new PolicyBase; |
162 } | 194 } |
163 | 195 |
164 void BrokerServicesBase::FreeResources(JobTracker* tracker) { | 196 void BrokerServicesBase::FreeResources(JobTracker* tracker) { |
165 if (NULL != tracker->policy) { | 197 if (NULL != tracker->policy) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 324 |
293 AutoLock lock(&lock_); | 325 AutoLock lock(&lock_); |
294 | 326 |
295 // This downcast is safe as long as we control CreatePolicy() | 327 // This downcast is safe as long as we control CreatePolicy() |
296 PolicyBase* policy_base = static_cast<PolicyBase*>(policy); | 328 PolicyBase* policy_base = static_cast<PolicyBase*>(policy); |
297 | 329 |
298 // Construct the tokens and the job object that we are going to associate | 330 // Construct the tokens and the job object that we are going to associate |
299 // with the soon to be created target process. | 331 // with the soon to be created target process. |
300 HANDLE initial_token_temp; | 332 HANDLE initial_token_temp; |
301 HANDLE lockdown_token_temp; | 333 HANDLE lockdown_token_temp; |
302 ResultCode result = policy_base->MakeTokens(&initial_token_temp, | 334 ResultCode result = SBOX_ALL_OK; |
303 &lockdown_token_temp); | 335 |
304 if (SBOX_ALL_OK != result) | 336 // Create the master tokens only once and save them in a cache. That way |
305 return result; | 337 // can just duplicate them to avoid hammering LSASS on every sandboxed |
| 338 // process launch. |
| 339 uint32_t token_key = GenerateTokenCacheKey(policy_base); |
| 340 TokenCacheMap::iterator it = token_cache_.find(token_key); |
| 341 if (it != token_cache_.end()) { |
| 342 initial_token_temp = it->second.first; |
| 343 lockdown_token_temp = it->second.second; |
| 344 } else { |
| 345 result = policy_base->MakeTokens(&initial_token_temp, |
| 346 &lockdown_token_temp); |
| 347 if (SBOX_ALL_OK != result) |
| 348 return result; |
| 349 token_cache_[token_key] = |
| 350 std::pair<HANDLE, HANDLE>(initial_token_temp, lockdown_token_temp); |
| 351 } |
| 352 |
| 353 if (!::DuplicateToken(initial_token_temp, SecurityImpersonation, |
| 354 &initial_token_temp)) { |
| 355 return SBOX_ERROR_GENERIC; |
| 356 } |
| 357 |
| 358 if (!::DuplicateTokenEx(lockdown_token_temp, TOKEN_ALL_ACCESS, 0, |
| 359 SecurityIdentification, TokenPrimary, |
| 360 &lockdown_token_temp)) { |
| 361 return SBOX_ERROR_GENERIC; |
| 362 } |
306 | 363 |
307 base::win::ScopedHandle initial_token(initial_token_temp); | 364 base::win::ScopedHandle initial_token(initial_token_temp); |
308 base::win::ScopedHandle lockdown_token(lockdown_token_temp); | 365 base::win::ScopedHandle lockdown_token(lockdown_token_temp); |
309 | 366 |
310 HANDLE job_temp; | 367 HANDLE job_temp; |
311 result = policy_base->MakeJobObject(&job_temp); | 368 result = policy_base->MakeJobObject(&job_temp); |
312 if (SBOX_ALL_OK != result) | 369 if (SBOX_ALL_OK != result) |
313 return result; | 370 return result; |
314 | 371 |
315 base::win::ScopedHandle job(job_temp); | 372 base::win::ScopedHandle job(job_temp); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 return SBOX_ERROR_UNSUPPORTED; | 558 return SBOX_ERROR_UNSUPPORTED; |
502 | 559 |
503 base::string16 name = LookupAppContainer(sid); | 560 base::string16 name = LookupAppContainer(sid); |
504 if (name.empty()) | 561 if (name.empty()) |
505 return SBOX_ERROR_INVALID_APP_CONTAINER; | 562 return SBOX_ERROR_INVALID_APP_CONTAINER; |
506 | 563 |
507 return DeleteAppContainer(sid); | 564 return DeleteAppContainer(sid); |
508 } | 565 } |
509 | 566 |
510 } // namespace sandbox | 567 } // namespace sandbox |
OLD | NEW |