Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: sandbox/win/src/broker_services.cc

Issue 1228373003: Sandbox: Remove ::CloseHandle from BrokerServices. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rename and improve comments. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sandbox/win/src/broker_services.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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> 7 #include <AclAPI.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/stl_util.h"
11 #include "base/threading/platform_thread.h" 12 #include "base/threading/platform_thread.h"
12 #include "base/win/scoped_handle.h" 13 #include "base/win/scoped_handle.h"
13 #include "base/win/scoped_process_information.h" 14 #include "base/win/scoped_process_information.h"
14 #include "base/win/startup_information.h" 15 #include "base/win/startup_information.h"
15 #include "base/win/windows_version.h" 16 #include "base/win/windows_version.h"
16 #include "sandbox/win/src/app_container.h" 17 #include "sandbox/win/src/app_container.h"
17 #include "sandbox/win/src/process_mitigations.h" 18 #include "sandbox/win/src/process_mitigations.h"
18 #include "sandbox/win/src/sandbox_policy_base.h" 19 #include "sandbox/win/src/sandbox_policy_base.h"
19 #include "sandbox/win/src/sandbox.h" 20 #include "sandbox/win/src/sandbox.h"
20 #include "sandbox/win/src/target_process.h" 21 #include "sandbox/win/src/target_process.h"
(...skipping 27 matching lines...) Expand all
48 enum { 49 enum {
49 THREAD_CTRL_NONE, 50 THREAD_CTRL_NONE,
50 THREAD_CTRL_REMOVE_PEER, 51 THREAD_CTRL_REMOVE_PEER,
51 THREAD_CTRL_QUIT, 52 THREAD_CTRL_QUIT,
52 THREAD_CTRL_LAST, 53 THREAD_CTRL_LAST,
53 }; 54 };
54 55
55 // Helper structure that allows the Broker to associate a job notification 56 // Helper structure that allows the Broker to associate a job notification
56 // with a job object and with a policy. 57 // with a job object and with a policy.
57 struct JobTracker { 58 struct JobTracker {
58 HANDLE job; 59 JobTracker(base::win::ScopedHandle job, sandbox::PolicyBase* policy)
60 : job(job.Pass()), policy(policy) {
61 }
62 ~JobTracker() {
63 FreeResources();
64 }
65
66 // Releases the Job and notifies the associated Policy object to release its
67 // resources as well.
68 void FreeResources();
69
70 base::win::ScopedHandle job;
59 sandbox::PolicyBase* policy; 71 sandbox::PolicyBase* policy;
60 JobTracker(HANDLE cjob, sandbox::PolicyBase* cpolicy) 72 };
61 : job(cjob), policy(cpolicy) { 73
74 void JobTracker::FreeResources() {
75 if (policy) {
76 BOOL res = ::TerminateJobObject(job.Get(), sandbox::SBOX_ALL_OK);
77 DCHECK(res);
78 // Closing the job causes the target process to be destroyed so this needs
79 // to happen before calling OnJobEmpty().
80 HANDLE stale_job_handle = job.Get();
81 job.Close();
82
83 // In OnJobEmpty() we don't actually use the job handle directly.
84 policy->OnJobEmpty(stale_job_handle);
85 policy->Release();
86 policy = NULL;
62 } 87 }
63 }; 88 }
64 89
65 // Helper structure that allows the broker to track peer processes 90 // Helper structure that allows the broker to track peer processes
66 struct PeerTracker { 91 struct PeerTracker {
92 PeerTracker(DWORD process_id, HANDLE broker_job_port)
93 : wait_object(NULL), id(process_id), job_port(broker_job_port) {
94 }
95
67 HANDLE wait_object; 96 HANDLE wait_object;
68 base::win::ScopedHandle process; 97 base::win::ScopedHandle process;
69 DWORD id; 98 DWORD id;
70 HANDLE job_port; 99 HANDLE job_port;
71 PeerTracker(DWORD process_id, HANDLE broker_job_port)
72 : wait_object(NULL), id(process_id), job_port(broker_job_port) {
73 }
74 }; 100 };
75 101
76 void DeregisterPeerTracker(PeerTracker* peer) { 102 void DeregisterPeerTracker(PeerTracker* peer) {
77 // Deregistration shouldn't fail, but we leak rather than crash if it does. 103 // Deregistration shouldn't fail, but we leak rather than crash if it does.
78 if (::UnregisterWaitEx(peer->wait_object, INVALID_HANDLE_VALUE)) { 104 if (::UnregisterWaitEx(peer->wait_object, INVALID_HANDLE_VALUE)) {
79 delete peer; 105 delete peer;
80 } else { 106 } else {
81 NOTREACHED(); 107 NOTREACHED();
82 } 108 }
83 } 109 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 key <<= kTokenShift; 143 key <<= kTokenShift;
118 key |= policy->GetIntegrityLevel(); 144 key |= policy->GetIntegrityLevel();
119 145
120 return key; 146 return key;
121 } 147 }
122 148
123 } // namespace 149 } // namespace
124 150
125 namespace sandbox { 151 namespace sandbox {
126 152
127 BrokerServicesBase::BrokerServicesBase() 153 // TODO(rvargas): Replace this structure with a std::pair of ScopedHandles.
128 : job_port_(NULL), 154 struct BrokerServicesBase::TokenPair {
129 no_targets_(NULL), 155 TokenPair(base::win::ScopedHandle initial_token,
130 job_thread_(NULL), 156 base::win::ScopedHandle lockdown_token)
131 thread_pool_(NULL) { 157 : initial(initial_token.Pass()),
158 lockdown(lockdown_token.Pass()) {
159 }
160
161 base::win::ScopedHandle initial;
162 base::win::ScopedHandle lockdown;
163 };
164
165 BrokerServicesBase::BrokerServicesBase() : thread_pool_(NULL) {
132 } 166 }
133 167
134 // The broker uses a dedicated worker thread that services the job completion 168 // The broker uses a dedicated worker thread that services the job completion
135 // port to perform policy notifications and associated cleanup tasks. 169 // port to perform policy notifications and associated cleanup tasks.
136 ResultCode BrokerServicesBase::Init() { 170 ResultCode BrokerServicesBase::Init() {
137 if ((NULL != job_port_) || (NULL != thread_pool_)) 171 if (job_port_.IsValid() || (NULL != thread_pool_))
138 return SBOX_ERROR_UNEXPECTED_CALL; 172 return SBOX_ERROR_UNEXPECTED_CALL;
139 173
140 ::InitializeCriticalSection(&lock_); 174 ::InitializeCriticalSection(&lock_);
141 175
142 job_port_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); 176 job_port_.Set(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0));
143 if (NULL == job_port_) 177 if (!job_port_.IsValid())
144 return SBOX_ERROR_GENERIC; 178 return SBOX_ERROR_GENERIC;
145 179
146 no_targets_ = ::CreateEventW(NULL, TRUE, FALSE, NULL); 180 no_targets_.Set(::CreateEventW(NULL, TRUE, FALSE, NULL));
147 181
148 job_thread_ = ::CreateThread(NULL, 0, // Default security and stack. 182 job_thread_.Set(::CreateThread(NULL, 0, // Default security and stack.
149 TargetEventsThread, this, NULL, NULL); 183 TargetEventsThread, this, NULL, NULL));
150 if (NULL == job_thread_) 184 if (!job_thread_.IsValid())
151 return SBOX_ERROR_GENERIC; 185 return SBOX_ERROR_GENERIC;
152 186
153 return SBOX_ALL_OK; 187 return SBOX_ALL_OK;
154 } 188 }
155 189
156 // The destructor should only be called when the Broker process is terminating. 190 // The destructor should only be called when the Broker process is terminating.
157 // Since BrokerServicesBase is a singleton, this is called from the CRT 191 // Since BrokerServicesBase is a singleton, this is called from the CRT
158 // termination handlers, if this code lives on a DLL it is called during 192 // termination handlers, if this code lives on a DLL it is called during
159 // DLL_PROCESS_DETACH in other words, holding the loader lock, so we cannot 193 // DLL_PROCESS_DETACH in other words, holding the loader lock, so we cannot
160 // wait for threads here. 194 // wait for threads here.
161 BrokerServicesBase::~BrokerServicesBase() { 195 BrokerServicesBase::~BrokerServicesBase() {
162 // If there is no port Init() was never called successfully. 196 // If there is no port Init() was never called successfully.
163 if (!job_port_) 197 if (!job_port_.IsValid())
164 return; 198 return;
165 199
166 // Closing the port causes, that no more Job notifications are delivered to 200 // Closing the port causes, that no more Job notifications are delivered to
167 // the worker thread and also causes the thread to exit. This is what we 201 // the worker thread and also causes the thread to exit. This is what we
168 // want to do since we are going to close all outstanding Jobs and notifying 202 // want to do since we are going to close all outstanding Jobs and notifying
169 // the policy objects ourselves. 203 // the policy objects ourselves.
170 ::PostQueuedCompletionStatus(job_port_, 0, THREAD_CTRL_QUIT, FALSE); 204 ::PostQueuedCompletionStatus(job_port_.Get(), 0, THREAD_CTRL_QUIT, FALSE);
171 ::CloseHandle(job_port_);
172 205
173 if (WAIT_TIMEOUT == ::WaitForSingleObject(job_thread_, 1000)) { 206 if (job_thread_.IsValid() &&
207 WAIT_TIMEOUT == ::WaitForSingleObject(job_thread_.Get(), 1000)) {
174 // Cannot clean broker services. 208 // Cannot clean broker services.
175 NOTREACHED(); 209 NOTREACHED();
176 return; 210 return;
177 } 211 }
178 212
179 JobTrackerList::iterator it; 213 STLDeleteElements(&tracker_list_);
180 for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) {
181 JobTracker* tracker = (*it);
182 FreeResources(tracker);
183 delete tracker;
184 }
185 ::CloseHandle(job_thread_);
186 delete thread_pool_; 214 delete thread_pool_;
187 ::CloseHandle(no_targets_);
188 215
189 // Cancel the wait events and delete remaining peer trackers. 216 // Cancel the wait events and delete remaining peer trackers.
190 for (PeerTrackerMap::iterator it = peer_map_.begin(); 217 for (PeerTrackerMap::iterator it = peer_map_.begin();
191 it != peer_map_.end(); ++it) { 218 it != peer_map_.end(); ++it) {
192 DeregisterPeerTracker(it->second); 219 DeregisterPeerTracker(it->second);
193 } 220 }
194 221
195 // If job_port_ isn't NULL, assumes that the lock has been initialized. 222 ::DeleteCriticalSection(&lock_);
196 if (job_port_)
197 ::DeleteCriticalSection(&lock_);
198 223
199 // Close any token in the cache. 224 // Close any token in the cache.
200 for (TokenCacheMap::iterator it = token_cache_.begin(); 225 STLDeleteValues(&token_cache_);
201 it != token_cache_.end(); ++it) {
202 ::CloseHandle(it->second.first);
203 ::CloseHandle(it->second.second);
204 }
205 } 226 }
206 227
207 TargetPolicy* BrokerServicesBase::CreatePolicy() { 228 TargetPolicy* BrokerServicesBase::CreatePolicy() {
208 // If you change the type of the object being created here you must also 229 // If you change the type of the object being created here you must also
209 // change the downcast to it in SpawnTarget(). 230 // change the downcast to it in SpawnTarget().
210 return new PolicyBase; 231 return new PolicyBase;
211 } 232 }
212 233
213 void BrokerServicesBase::FreeResources(JobTracker* tracker) {
214 if (NULL != tracker->policy) {
215 BOOL res = ::TerminateJobObject(tracker->job, SBOX_ALL_OK);
216 DCHECK(res);
217 // Closing the job causes the target process to be destroyed so this
218 // needs to happen before calling OnJobEmpty().
219 res = ::CloseHandle(tracker->job);
220 DCHECK(res);
221 // In OnJobEmpty() we don't actually use the job handle directly.
222 tracker->policy->OnJobEmpty(tracker->job);
223 tracker->policy->Release();
224 tracker->policy = NULL;
225 }
226 }
227
228 // The worker thread stays in a loop waiting for asynchronous notifications 234 // The worker thread stays in a loop waiting for asynchronous notifications
229 // from the job objects. Right now we only care about knowing when the last 235 // from the job objects. Right now we only care about knowing when the last
230 // process on a job terminates, but in general this is the place to tell 236 // process on a job terminates, but in general this is the place to tell
231 // the policy about events. 237 // the policy about events.
232 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) { 238 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) {
233 if (NULL == param) 239 if (NULL == param)
234 return 1; 240 return 1;
235 241
236 base::PlatformThread::SetName("BrokerEvent"); 242 base::PlatformThread::SetName("BrokerEvent");
237 243
238 BrokerServicesBase* broker = reinterpret_cast<BrokerServicesBase*>(param); 244 BrokerServicesBase* broker = reinterpret_cast<BrokerServicesBase*>(param);
239 HANDLE port = broker->job_port_; 245 HANDLE port = broker->job_port_.Get();
240 HANDLE no_targets = broker->no_targets_; 246 HANDLE no_targets = broker->no_targets_.Get();
241 247
242 int target_counter = 0; 248 int target_counter = 0;
243 ::ResetEvent(no_targets); 249 ::ResetEvent(no_targets);
244 250
245 while (true) { 251 while (true) {
246 DWORD events = 0; 252 DWORD events = 0;
247 ULONG_PTR key = 0; 253 ULONG_PTR key = 0;
248 LPOVERLAPPED ovl = NULL; 254 LPOVERLAPPED ovl = NULL;
249 255
250 if (!::GetQueuedCompletionStatus(port, &events, &key, &ovl, INFINITE)) 256 if (!::GetQueuedCompletionStatus(port, &events, &key, &ovl, INFINITE)) {
251 // this call fails if the port has been closed before we have a 257 // this call fails if the port has been closed before we have a
252 // chance to service the last packet which is 'exit' anyway so 258 // chance to service the last packet which is 'exit' anyway so
253 // this is not an error. 259 // this is not an error.
254 return 1; 260 return 1;
261 }
255 262
256 if (key > THREAD_CTRL_LAST) { 263 if (key > THREAD_CTRL_LAST) {
257 // The notification comes from a job object. There are nine notifications 264 // The notification comes from a job object. There are nine notifications
258 // that jobs can send and some of them depend on the job attributes set. 265 // that jobs can send and some of them depend on the job attributes set.
259 JobTracker* tracker = reinterpret_cast<JobTracker*>(key); 266 JobTracker* tracker = reinterpret_cast<JobTracker*>(key);
260 267
261 switch (events) { 268 switch (events) {
262 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: { 269 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: {
263 // The job object has signaled that the last process associated 270 // The job object has signaled that the last process associated
264 // with it has terminated. Assuming there is no way for a process 271 // with it has terminated. Assuming there is no way for a process
265 // to appear out of thin air in this job, it safe to assume that 272 // to appear out of thin air in this job, it safe to assume that
266 // we can tell the policy to destroy the target object, and for 273 // we can tell the policy to destroy the target object, and for
267 // us to release our reference to the policy object. 274 // us to release our reference to the policy object.
268 FreeResources(tracker); 275 tracker->FreeResources();
269 break; 276 break;
270 } 277 }
271 278
272 case JOB_OBJECT_MSG_NEW_PROCESS: { 279 case JOB_OBJECT_MSG_NEW_PROCESS: {
273 ++target_counter; 280 ++target_counter;
274 if (1 == target_counter) { 281 if (1 == target_counter) {
275 ::ResetEvent(no_targets); 282 ::ResetEvent(no_targets);
276 } 283 }
277 break; 284 break;
278 } 285 }
(...skipping 11 matching lines...) Expand all
290 297
291 DCHECK(target_counter >= 0); 298 DCHECK(target_counter >= 0);
292 break; 299 break;
293 } 300 }
294 301
295 case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: { 302 case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: {
296 break; 303 break;
297 } 304 }
298 305
299 case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: { 306 case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: {
300 BOOL res = ::TerminateJobObject(tracker->job, 307 BOOL res = ::TerminateJobObject(tracker->job.Get(),
301 SBOX_FATAL_MEMORY_EXCEEDED); 308 SBOX_FATAL_MEMORY_EXCEEDED);
302 DCHECK(res); 309 DCHECK(res);
303 break; 310 break;
304 } 311 }
305 312
306 default: { 313 default: {
307 NOTREACHED(); 314 NOTREACHED();
308 break; 315 break;
309 } 316 }
310 } 317 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 base::win::ScopedHandle initial_token; 367 base::win::ScopedHandle initial_token;
361 base::win::ScopedHandle lockdown_token; 368 base::win::ScopedHandle lockdown_token;
362 ResultCode result = SBOX_ALL_OK; 369 ResultCode result = SBOX_ALL_OK;
363 370
364 if (IsTokenCacheable(policy_base)) { 371 if (IsTokenCacheable(policy_base)) {
365 // Create the master tokens only once and save them in a cache. That way 372 // Create the master tokens only once and save them in a cache. That way
366 // can just duplicate them to avoid hammering LSASS on every sandboxed 373 // can just duplicate them to avoid hammering LSASS on every sandboxed
367 // process launch. 374 // process launch.
368 uint32_t token_key = GenerateTokenCacheKey(policy_base); 375 uint32_t token_key = GenerateTokenCacheKey(policy_base);
369 TokenCacheMap::iterator it = token_cache_.find(token_key); 376 TokenCacheMap::iterator it = token_cache_.find(token_key);
370 HANDLE initial_token_temp; 377 TokenPair* tokens;
371 HANDLE lockdown_token_temp;
372 if (it != token_cache_.end()) { 378 if (it != token_cache_.end()) {
373 initial_token_temp = it->second.first; 379 tokens = it->second;
374 lockdown_token_temp = it->second.second;
375 } else { 380 } else {
376 result = policy_base->MakeTokens(&initial_token, &lockdown_token); 381 result = policy_base->MakeTokens(&initial_token, &lockdown_token);
377 if (SBOX_ALL_OK != result) 382 if (SBOX_ALL_OK != result)
378 return result; 383 return result;
379 token_cache_[token_key] = 384
380 std::make_pair(initial_token.Get(), lockdown_token.Get()); 385 tokens = new TokenPair(initial_token.Pass(), lockdown_token.Pass());
381 initial_token_temp = initial_token.Take(); 386 token_cache_[token_key] = tokens;
382 lockdown_token_temp = lockdown_token.Take();
383 } 387 }
384 388
385 if (!::DuplicateToken(initial_token_temp, SecurityImpersonation, 389 HANDLE temp_token;
386 &initial_token_temp)) { 390 if (!::DuplicateToken(tokens->initial.Get(), SecurityImpersonation,
391 &temp_token)) {
387 return SBOX_ERROR_GENERIC; 392 return SBOX_ERROR_GENERIC;
388 } 393 }
389 initial_token.Set(initial_token_temp); 394 initial_token.Set(temp_token);
390 395
391 if (!::DuplicateTokenEx(lockdown_token_temp, TOKEN_ALL_ACCESS, 0, 396 if (!::DuplicateTokenEx(tokens->lockdown.Get(), TOKEN_ALL_ACCESS, 0,
392 SecurityIdentification, TokenPrimary, 397 SecurityIdentification, TokenPrimary,
393 &lockdown_token_temp)) { 398 &temp_token)) {
394 return SBOX_ERROR_GENERIC; 399 return SBOX_ERROR_GENERIC;
395 } 400 }
396 lockdown_token.Set(lockdown_token_temp); 401 lockdown_token.Set(temp_token);
397 } else { 402 } else {
398 result = policy_base->MakeTokens(&initial_token, &lockdown_token); 403 result = policy_base->MakeTokens(&initial_token, &lockdown_token);
399 if (SBOX_ALL_OK != result) 404 if (SBOX_ALL_OK != result)
400 return result; 405 return result;
401 } 406 }
402 407
403 HANDLE job_temp; 408 HANDLE job_temp;
404 result = policy_base->MakeJobObject(&job_temp); 409 result = policy_base->MakeJobObject(&job_temp);
405 if (SBOX_ALL_OK != result) 410 if (SBOX_ALL_OK != result)
406 return result; 411 return result;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 521
517 // Now the policy is the owner of the target. 522 // Now the policy is the owner of the target.
518 if (!policy_base->AddTarget(target)) { 523 if (!policy_base->AddTarget(target)) {
519 return SpawnCleanup(target, 0); 524 return SpawnCleanup(target, 0);
520 } 525 }
521 526
522 // We are going to keep a pointer to the policy because we'll call it when 527 // We are going to keep a pointer to the policy because we'll call it when
523 // the job object generates notifications using the completion port. 528 // the job object generates notifications using the completion port.
524 policy_base->AddRef(); 529 policy_base->AddRef();
525 if (job.IsValid()) { 530 if (job.IsValid()) {
526 scoped_ptr<JobTracker> tracker(new JobTracker(job.Take(), policy_base)); 531 scoped_ptr<JobTracker> tracker(new JobTracker(job.Pass(), policy_base));
527 532
528 // There is no obvious recovery after failure here. Previous version with 533 // There is no obvious recovery after failure here. Previous version with
529 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 534 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639
530 CHECK(AssociateCompletionPort(tracker->job, job_port_, tracker.get())); 535 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(),
536 tracker.get()));
531 537
532 // Save the tracker because in cleanup we might need to force closing 538 // Save the tracker because in cleanup we might need to force closing
533 // the Jobs. 539 // the Jobs.
534 tracker_list_.push_back(tracker.release()); 540 tracker_list_.push_back(tracker.release());
535 child_process_ids_.insert(process_info.process_id()); 541 child_process_ids_.insert(process_info.process_id());
536 } else { 542 } else {
537 // We have to signal the event once here because the completion port will 543 // We have to signal the event once here because the completion port will
538 // never get a message that this target is being terminated thus we should 544 // never get a message that this target is being terminated thus we should
539 // not block WaitForAllTargets until we have at least one target with job. 545 // not block WaitForAllTargets until we have at least one target with job.
540 if (child_process_ids_.empty()) 546 if (child_process_ids_.empty())
541 ::SetEvent(no_targets_); 547 ::SetEvent(no_targets_.Get());
542 // We can not track the life time of such processes and it is responsibility 548 // We can not track the life time of such processes and it is responsibility
543 // of the host application to make sure that spawned targets without jobs 549 // of the host application to make sure that spawned targets without jobs
544 // are terminated when the main application don't need them anymore. 550 // are terminated when the main application don't need them anymore.
545 // Sandbox policy engine needs to know that these processes are valid 551 // Sandbox policy engine needs to know that these processes are valid
546 // targets for e.g. BrokerDuplicateHandle so track them as peer processes. 552 // targets for e.g. BrokerDuplicateHandle so track them as peer processes.
547 AddTargetPeer(process_info.process_handle()); 553 AddTargetPeer(process_info.process_handle());
548 } 554 }
549 555
550 *target_info = process_info.Take(); 556 *target_info = process_info.Take();
551 return SBOX_ALL_OK; 557 return SBOX_ALL_OK;
552 } 558 }
553 559
554 560
555 ResultCode BrokerServicesBase::WaitForAllTargets() { 561 ResultCode BrokerServicesBase::WaitForAllTargets() {
556 ::WaitForSingleObject(no_targets_, INFINITE); 562 ::WaitForSingleObject(no_targets_.Get(), INFINITE);
557 return SBOX_ALL_OK; 563 return SBOX_ALL_OK;
558 } 564 }
559 565
560 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) { 566 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) {
561 AutoLock lock(&lock_); 567 AutoLock lock(&lock_);
562 return child_process_ids_.find(process_id) != child_process_ids_.end() || 568 return child_process_ids_.find(process_id) != child_process_ids_.end() ||
563 peer_map_.find(process_id) != peer_map_.end(); 569 peer_map_.find(process_id) != peer_map_.end();
564 } 570 }
565 571
566 VOID CALLBACK BrokerServicesBase::RemovePeer(PVOID parameter, BOOLEAN timeout) { 572 VOID CALLBACK BrokerServicesBase::RemovePeer(PVOID parameter, BOOLEAN timeout) {
567 PeerTracker* peer = reinterpret_cast<PeerTracker*>(parameter); 573 PeerTracker* peer = reinterpret_cast<PeerTracker*>(parameter);
568 // Don't check the return code because we this may fail (safely) at shutdown. 574 // Don't check the return code because we this may fail (safely) at shutdown.
569 ::PostQueuedCompletionStatus( 575 ::PostQueuedCompletionStatus(
570 peer->job_port, 0, THREAD_CTRL_REMOVE_PEER, 576 peer->job_port, 0, THREAD_CTRL_REMOVE_PEER,
571 reinterpret_cast<LPOVERLAPPED>(static_cast<uintptr_t>(peer->id))); 577 reinterpret_cast<LPOVERLAPPED>(static_cast<uintptr_t>(peer->id)));
572 } 578 }
573 579
574 ResultCode BrokerServicesBase::AddTargetPeer(HANDLE peer_process) { 580 ResultCode BrokerServicesBase::AddTargetPeer(HANDLE peer_process) {
575 scoped_ptr<PeerTracker> peer(new PeerTracker(::GetProcessId(peer_process), 581 scoped_ptr<PeerTracker> peer(new PeerTracker(::GetProcessId(peer_process),
576 job_port_)); 582 job_port_.Get()));
577 if (!peer->id) 583 if (!peer->id)
578 return SBOX_ERROR_GENERIC; 584 return SBOX_ERROR_GENERIC;
579 585
580 HANDLE process_handle; 586 HANDLE process_handle;
581 if (!::DuplicateHandle(::GetCurrentProcess(), peer_process, 587 if (!::DuplicateHandle(::GetCurrentProcess(), peer_process,
582 ::GetCurrentProcess(), &process_handle, 588 ::GetCurrentProcess(), &process_handle,
583 SYNCHRONIZE, FALSE, 0)) { 589 SYNCHRONIZE, FALSE, 0)) {
584 return SBOX_ERROR_GENERIC; 590 return SBOX_ERROR_GENERIC;
585 } 591 }
586 peer->process.Set(process_handle); 592 peer->process.Set(process_handle);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 return SBOX_ERROR_UNSUPPORTED; 627 return SBOX_ERROR_UNSUPPORTED;
622 628
623 base::string16 name = LookupAppContainer(sid); 629 base::string16 name = LookupAppContainer(sid);
624 if (name.empty()) 630 if (name.empty())
625 return SBOX_ERROR_INVALID_APP_CONTAINER; 631 return SBOX_ERROR_INVALID_APP_CONTAINER;
626 632
627 return DeleteAppContainer(sid); 633 return DeleteAppContainer(sid);
628 } 634 }
629 635
630 } // namespace sandbox 636 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/broker_services.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698