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 |