| 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 |