| 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 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 if (NULL == thread_pool_) | 437 if (NULL == thread_pool_) |
| 438 thread_pool_ = new Win2kThreadPool(); | 438 thread_pool_ = new Win2kThreadPool(); |
| 439 | 439 |
| 440 // Create the TargetProcess object and spawn the target suspended. Note that | 440 // Create the TargetProcess object and spawn the target suspended. Note that |
| 441 // Brokerservices does not own the target object. It is owned by the Policy. | 441 // Brokerservices does not own the target object. It is owned by the Policy. |
| 442 base::win::ScopedProcessInformation process_info; | 442 base::win::ScopedProcessInformation process_info; |
| 443 TargetProcess* target = | 443 TargetProcess* target = |
| 444 new TargetProcess(std::move(initial_token), std::move(lockdown_token), | 444 new TargetProcess(std::move(initial_token), std::move(lockdown_token), |
| 445 std::move(lowbox_token), job.Get(), thread_pool_); | 445 std::move(lowbox_token), job.Get(), thread_pool_); |
| 446 | 446 |
| 447 DWORD win_result = target->Create(exe_path, command_line, inherit_handles, | 447 DWORD win_result; |
| 448 startup_info, &process_info); | 448 result = target->Create(exe_path, command_line, inherit_handles, startup_info, |
| 449 &process_info, &win_result); |
| 449 | 450 |
| 450 if (ERROR_SUCCESS != win_result) { | 451 if (result != SBOX_ALL_OK) { |
| 451 SpawnCleanup(target, win_result); | 452 SpawnCleanup(target, win_result); |
| 452 return SBOX_ERROR_CREATE_PROCESS; | 453 return result; |
| 453 } | 454 } |
| 454 | 455 |
| 455 // Now the policy is the owner of the target. | 456 // Now the policy is the owner of the target. |
| 456 if (!policy_base->AddTarget(target)) { | 457 result = policy_base->AddTarget(target); |
| 457 return SpawnCleanup(target, 0); | 458 |
| 459 if (result != SBOX_ALL_OK) { |
| 460 SpawnCleanup(target, 0); |
| 461 return result; |
| 458 } | 462 } |
| 459 | 463 |
| 460 // We are going to keep a pointer to the policy because we'll call it when | 464 // We are going to keep a pointer to the policy because we'll call it when |
| 461 // the job object generates notifications using the completion port. | 465 // the job object generates notifications using the completion port. |
| 462 policy_base->AddRef(); | 466 policy_base->AddRef(); |
| 463 if (job.IsValid()) { | 467 if (job.IsValid()) { |
| 464 std::unique_ptr<JobTracker> tracker( | 468 std::unique_ptr<JobTracker> tracker( |
| 465 new JobTracker(std::move(job), policy_base)); | 469 new JobTracker(std::move(job), policy_base)); |
| 466 | 470 |
| 467 // There is no obvious recovery after failure here. Previous version with | 471 // There is no obvious recovery after failure here. Previous version with |
| 468 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 | 472 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 |
| 469 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), | 473 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), |
| 470 tracker.get())); | 474 tracker.get())); |
| 471 | 475 |
| 472 // Save the tracker because in cleanup we might need to force closing | 476 // Save the tracker because in cleanup we might need to force closing |
| 473 // the Jobs. | 477 // the Jobs. |
| 474 tracker_list_.push_back(tracker.release()); | 478 tracker_list_.push_back(tracker.release()); |
| 475 child_process_ids_.insert(process_info.process_id()); | 479 child_process_ids_.insert(process_info.process_id()); |
| 476 } else { | 480 } else { |
| 477 // We have to signal the event once here because the completion port will | 481 // We have to signal the event once here because the completion port will |
| 478 // never get a message that this target is being terminated thus we should | 482 // never get a message that this target is being terminated thus we should |
| 479 // not block WaitForAllTargets until we have at least one target with job. | 483 // not block WaitForAllTargets until we have at least one target with job. |
| 480 if (child_process_ids_.empty()) | 484 if (child_process_ids_.empty()) |
| 481 ::SetEvent(no_targets_.Get()); | 485 ::SetEvent(no_targets_.Get()); |
| 482 // We can not track the life time of such processes and it is responsibility | 486 // We can not track the life time of such processes and it is responsibility |
| 483 // of the host application to make sure that spawned targets without jobs | 487 // of the host application to make sure that spawned targets without jobs |
| 484 // are terminated when the main application don't need them anymore. | 488 // are terminated when the main application don't need them anymore. |
| 485 // Sandbox policy engine needs to know that these processes are valid | 489 // Sandbox policy engine needs to know that these processes are valid |
| 486 // targets for e.g. BrokerDuplicateHandle so track them as peer processes. | 490 // targets for e.g. BrokerDuplicateHandle so track them as peer processes. |
| 487 AddTargetPeer(process_info.process_handle()); | 491 result = AddTargetPeer(process_info.process_handle()); |
| 488 } | 492 } |
| 489 | 493 |
| 490 *target_info = process_info.Take(); | 494 *target_info = process_info.Take(); |
| 491 return SBOX_ALL_OK; | 495 return result; |
| 492 } | 496 } |
| 493 | 497 |
| 494 | 498 |
| 495 ResultCode BrokerServicesBase::WaitForAllTargets() { | 499 ResultCode BrokerServicesBase::WaitForAllTargets() { |
| 496 ::WaitForSingleObject(no_targets_.Get(), INFINITE); | 500 ::WaitForSingleObject(no_targets_.Get(), INFINITE); |
| 497 return SBOX_ALL_OK; | 501 return SBOX_ALL_OK; |
| 498 } | 502 } |
| 499 | 503 |
| 500 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) { | 504 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) { |
| 501 AutoLock lock(&lock_); | 505 AutoLock lock(&lock_); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 peer_map_.erase(peer->id); | 539 peer_map_.erase(peer->id); |
| 536 return SBOX_ERROR_GENERIC; | 540 return SBOX_ERROR_GENERIC; |
| 537 } | 541 } |
| 538 | 542 |
| 539 // Release the pointer since it will be cleaned up by the callback. | 543 // Release the pointer since it will be cleaned up by the callback. |
| 540 ignore_result(peer.release()); | 544 ignore_result(peer.release()); |
| 541 return SBOX_ALL_OK; | 545 return SBOX_ALL_OK; |
| 542 } | 546 } |
| 543 | 547 |
| 544 } // namespace sandbox | 548 } // namespace sandbox |
| OLD | NEW |