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> | 7 #include <AclAPI.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 if (NULL == thread_pool_) | 402 if (NULL == thread_pool_) |
403 thread_pool_ = new Win2kThreadPool(); | 403 thread_pool_ = new Win2kThreadPool(); |
404 | 404 |
405 // Create the TargetProcess object and spawn the target suspended. Note that | 405 // Create the TargetProcess object and spawn the target suspended. Note that |
406 // Brokerservices does not own the target object. It is owned by the Policy. | 406 // Brokerservices does not own the target object. It is owned by the Policy. |
407 base::win::ScopedProcessInformation process_info; | 407 base::win::ScopedProcessInformation process_info; |
408 TargetProcess* target = | 408 TargetProcess* target = |
409 new TargetProcess(std::move(initial_token), std::move(lockdown_token), | 409 new TargetProcess(std::move(initial_token), std::move(lockdown_token), |
410 std::move(lowbox_token), job.Get(), thread_pool_); | 410 std::move(lowbox_token), job.Get(), thread_pool_); |
411 | 411 |
412 DWORD win_result = target->Create(exe_path, command_line, inherit_handles, | 412 DWORD win_result; |
413 startup_info, &process_info); | 413 result = target->Create(exe_path, command_line, inherit_handles, startup_info, |
| 414 &process_info, &win_result); |
414 | 415 |
415 if (ERROR_SUCCESS != win_result) { | 416 if (result != SBOX_ALL_OK) { |
416 SpawnCleanup(target, win_result); | 417 SpawnCleanup(target, win_result); |
417 return SBOX_ERROR_CREATE_PROCESS; | 418 return result; |
418 } | 419 } |
419 | 420 |
420 // Now the policy is the owner of the target. | 421 // Now the policy is the owner of the target. |
421 if (!policy_base->AddTarget(target)) { | 422 result = policy_base->AddTarget(target); |
422 return SpawnCleanup(target, 0); | 423 |
| 424 if (result != SBOX_ALL_OK) { |
| 425 SpawnCleanup(target, 0); |
| 426 return result; |
423 } | 427 } |
424 | 428 |
425 // We are going to keep a pointer to the policy because we'll call it when | 429 // We are going to keep a pointer to the policy because we'll call it when |
426 // the job object generates notifications using the completion port. | 430 // the job object generates notifications using the completion port. |
427 policy_base->AddRef(); | 431 policy_base->AddRef(); |
428 if (job.IsValid()) { | 432 if (job.IsValid()) { |
429 std::unique_ptr<JobTracker> tracker( | 433 std::unique_ptr<JobTracker> tracker( |
430 new JobTracker(std::move(job), policy_base)); | 434 new JobTracker(std::move(job), policy_base)); |
431 | 435 |
432 // There is no obvious recovery after failure here. Previous version with | 436 // There is no obvious recovery after failure here. Previous version with |
433 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 | 437 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 |
434 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), | 438 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), |
435 tracker.get())); | 439 tracker.get())); |
436 | 440 |
437 // Save the tracker because in cleanup we might need to force closing | 441 // Save the tracker because in cleanup we might need to force closing |
438 // the Jobs. | 442 // the Jobs. |
439 tracker_list_.push_back(tracker.release()); | 443 tracker_list_.push_back(tracker.release()); |
440 child_process_ids_.insert(process_info.process_id()); | 444 child_process_ids_.insert(process_info.process_id()); |
441 } else { | 445 } else { |
442 // We have to signal the event once here because the completion port will | 446 // We have to signal the event once here because the completion port will |
443 // never get a message that this target is being terminated thus we should | 447 // never get a message that this target is being terminated thus we should |
444 // not block WaitForAllTargets until we have at least one target with job. | 448 // not block WaitForAllTargets until we have at least one target with job. |
445 if (child_process_ids_.empty()) | 449 if (child_process_ids_.empty()) |
446 ::SetEvent(no_targets_.Get()); | 450 ::SetEvent(no_targets_.Get()); |
447 } | 451 } |
448 | 452 |
449 *target_info = process_info.Take(); | 453 *target_info = process_info.Take(); |
450 return SBOX_ALL_OK; | 454 return result; |
451 } | 455 } |
452 | 456 |
453 | 457 |
454 ResultCode BrokerServicesBase::WaitForAllTargets() { | 458 ResultCode BrokerServicesBase::WaitForAllTargets() { |
455 ::WaitForSingleObject(no_targets_.Get(), INFINITE); | 459 ::WaitForSingleObject(no_targets_.Get(), INFINITE); |
456 return SBOX_ALL_OK; | 460 return SBOX_ALL_OK; |
457 } | 461 } |
458 | 462 |
459 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) { | 463 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) { |
460 AutoLock lock(&lock_); | 464 AutoLock lock(&lock_); |
461 return child_process_ids_.find(process_id) != child_process_ids_.end(); | 465 return child_process_ids_.find(process_id) != child_process_ids_.end(); |
462 } | 466 } |
463 | 467 |
464 } // namespace sandbox | 468 } // namespace sandbox |
OLD | NEW |