Chromium Code Reviews| Index: sandbox/win/src/broker_services.cc |
| diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc |
| index 096e4bb821809a92d02fec21bf7dfdf3e89a581e..bf05a8e71c54fa71664e4d3175ace97a9e0f3016 100644 |
| --- a/sandbox/win/src/broker_services.cc |
| +++ b/sandbox/win/src/broker_services.cc |
| @@ -53,7 +53,8 @@ enum { |
| // Helper structure that allows the Broker to associate a job notification |
| // with a job object and with a policy. |
| struct JobTracker { |
| - JobTracker(base::win::ScopedHandle job, sandbox::PolicyBase* policy) |
| + JobTracker(base::win::ScopedHandle job, |
| + scoped_refptr<sandbox::PolicyBase> policy) |
| : job(std::move(job)), policy(policy) {} |
| ~JobTracker() { |
| FreeResources(); |
| @@ -64,7 +65,7 @@ struct JobTracker { |
| void FreeResources(); |
| base::win::ScopedHandle job; |
| - sandbox::PolicyBase* policy; |
| + scoped_refptr<sandbox::PolicyBase> policy; |
| }; |
| void JobTracker::FreeResources() { |
| @@ -78,8 +79,7 @@ void JobTracker::FreeResources() { |
| // In OnJobEmpty() we don't actually use the job handle directly. |
| policy->OnJobEmpty(stale_job_handle); |
| - policy->Release(); |
| - policy = NULL; |
| + policy = nullptr; |
| } |
| } |
| @@ -140,10 +140,13 @@ BrokerServicesBase::~BrokerServicesBase() { |
| ::DeleteCriticalSection(&lock_); |
| } |
| -TargetPolicy* BrokerServicesBase::CreatePolicy() { |
| +scoped_refptr<TargetPolicy> BrokerServicesBase::CreatePolicy() { |
| // If you change the type of the object being created here you must also |
| // change the downcast to it in SpawnTarget(). |
| - return new PolicyBase; |
| + scoped_refptr<TargetPolicy> policy(new PolicyBase); |
| + // PolicyBase starts with refcount 1. |
| + policy->Release(); |
| + return policy; |
| } |
| // The worker thread stays in a loop waiting for asynchronous notifications |
| @@ -266,7 +269,7 @@ DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) { |
| // process inside the sandbox. |
| ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, |
| const wchar_t* command_line, |
| - TargetPolicy* policy, |
| + scoped_refptr<TargetPolicy> policy, |
| ResultCode* last_warning, |
| DWORD* last_error, |
| PROCESS_INFORMATION* target_info) { |
| @@ -287,7 +290,7 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, |
| AutoLock lock(&lock_); |
| // This downcast is safe as long as we control CreatePolicy() |
| - PolicyBase* policy_base = static_cast<PolicyBase*>(policy); |
| + scoped_refptr<PolicyBase> policy_base(static_cast<PolicyBase*>(policy.get())); |
| // Construct the tokens and the job object that we are going to associate |
| // with the soon to be created target process. |
| @@ -439,7 +442,6 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, |
| // We are going to keep a pointer to the policy because we'll call it when |
| // the job object generates notifications using the completion port. |
| - policy_base->AddRef(); |
| if (job.IsValid()) { |
| std::unique_ptr<JobTracker> tracker = |
| base::MakeUnique<JobTracker>(std::move(job), policy_base); |
| @@ -454,6 +456,11 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, |
| tracker_list_.push_back(std::move(tracker)); |
| child_process_ids_.insert(process_info.process_id()); |
| } else { |
| + // Leak policy_base. This needs to outlive the child process, but there's |
| + // nothing that tracks that lifetime properly if there's no job object. |
| + // TODO(wfh): Find a way to make this have the correct lifetime. |
| + policy_base->AddRef(); |
|
Will Harris
2017/01/24 19:47:32
note: new change
|
| + |
| // We have to signal the event once here because the completion port will |
| // never get a message that this target is being terminated thus we should |
| // not block WaitForAllTargets until we have at least one target with job. |