Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: sandbox/win/src/broker_services.cc

Issue 2456573002: Revert "Fix sandbox::PolicyBase leak" (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sandbox/win/src/broker_services.h ('k') | sandbox/win/src/policy_target_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 // executes TargetEventsThread(). 47 // executes TargetEventsThread().
48 enum { 48 enum {
49 THREAD_CTRL_NONE, 49 THREAD_CTRL_NONE,
50 THREAD_CTRL_QUIT, 50 THREAD_CTRL_QUIT,
51 THREAD_CTRL_LAST, 51 THREAD_CTRL_LAST,
52 }; 52 };
53 53
54 // Helper structure that allows the Broker to associate a job notification 54 // Helper structure that allows the Broker to associate a job notification
55 // with a job object and with a policy. 55 // with a job object and with a policy.
56 struct JobTracker { 56 struct JobTracker {
57 JobTracker(base::win::ScopedHandle job, 57 JobTracker(base::win::ScopedHandle job, sandbox::PolicyBase* policy)
58 scoped_refptr<sandbox::PolicyBase> policy)
59 : job(std::move(job)), policy(policy) {} 58 : job(std::move(job)), policy(policy) {}
60 ~JobTracker() { 59 ~JobTracker() {
61 FreeResources(); 60 FreeResources();
62 } 61 }
63 62
64 // Releases the Job and notifies the associated Policy object to release its 63 // Releases the Job and notifies the associated Policy object to release its
65 // resources as well. 64 // resources as well.
66 void FreeResources(); 65 void FreeResources();
67 66
68 base::win::ScopedHandle job; 67 base::win::ScopedHandle job;
69 scoped_refptr<sandbox::PolicyBase> policy; 68 sandbox::PolicyBase* policy;
70 }; 69 };
71 70
72 void JobTracker::FreeResources() { 71 void JobTracker::FreeResources() {
73 if (policy) { 72 if (policy) {
74 BOOL res = ::TerminateJobObject(job.Get(), sandbox::SBOX_ALL_OK); 73 BOOL res = ::TerminateJobObject(job.Get(), sandbox::SBOX_ALL_OK);
75 DCHECK(res); 74 DCHECK(res);
76 // Closing the job causes the target process to be destroyed so this needs 75 // Closing the job causes the target process to be destroyed so this needs
77 // to happen before calling OnJobEmpty(). 76 // to happen before calling OnJobEmpty().
78 HANDLE stale_job_handle = job.Get(); 77 HANDLE stale_job_handle = job.Get();
79 job.Close(); 78 job.Close();
80 79
81 // In OnJobEmpty() we don't actually use the job handle directly. 80 // In OnJobEmpty() we don't actually use the job handle directly.
82 policy->OnJobEmpty(stale_job_handle); 81 policy->OnJobEmpty(stale_job_handle);
83 policy = nullptr; 82 policy->Release();
83 policy = NULL;
84 } 84 }
85 } 85 }
86 86
87 } // namespace 87 } // namespace
88 88
89 namespace sandbox { 89 namespace sandbox {
90 90
91 BrokerServicesBase::BrokerServicesBase() : thread_pool_(NULL) { 91 BrokerServicesBase::BrokerServicesBase() : thread_pool_(NULL) {
92 } 92 }
93 93
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 NOTREACHED(); 135 NOTREACHED();
136 return; 136 return;
137 } 137 }
138 138
139 base::STLDeleteElements(&tracker_list_); 139 base::STLDeleteElements(&tracker_list_);
140 delete thread_pool_; 140 delete thread_pool_;
141 141
142 ::DeleteCriticalSection(&lock_); 142 ::DeleteCriticalSection(&lock_);
143 } 143 }
144 144
145 scoped_refptr<TargetPolicy> BrokerServicesBase::CreatePolicy() { 145 TargetPolicy* BrokerServicesBase::CreatePolicy() {
146 // If you change the type of the object being created here you must also 146 // If you change the type of the object being created here you must also
147 // change the downcast to it in SpawnTarget(). 147 // change the downcast to it in SpawnTarget().
148 scoped_refptr<TargetPolicy> policy(new PolicyBase); 148 return new PolicyBase;
149 // PolicyBase starts with refcount 1.
150 policy->Release();
151 return policy;
152 } 149 }
153 150
154 // The worker thread stays in a loop waiting for asynchronous notifications 151 // The worker thread stays in a loop waiting for asynchronous notifications
155 // from the job objects. Right now we only care about knowing when the last 152 // from the job objects. Right now we only care about knowing when the last
156 // process on a job terminates, but in general this is the place to tell 153 // process on a job terminates, but in general this is the place to tell
157 // the policy about events. 154 // the policy about events.
158 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) { 155 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) {
159 if (NULL == param) 156 if (NULL == param)
160 return 1; 157 return 1;
161 158
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 } 261 }
265 262
266 NOTREACHED(); 263 NOTREACHED();
267 return 0; 264 return 0;
268 } 265 }
269 266
270 // SpawnTarget does all the interesting sandbox setup and creates the target 267 // SpawnTarget does all the interesting sandbox setup and creates the target
271 // process inside the sandbox. 268 // process inside the sandbox.
272 ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, 269 ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
273 const wchar_t* command_line, 270 const wchar_t* command_line,
274 scoped_refptr<TargetPolicy> policy, 271 TargetPolicy* policy,
275 ResultCode* last_warning, 272 ResultCode* last_warning,
276 DWORD* last_error, 273 DWORD* last_error,
277 PROCESS_INFORMATION* target_info) { 274 PROCESS_INFORMATION* target_info) {
278 if (!exe_path) 275 if (!exe_path)
279 return SBOX_ERROR_BAD_PARAMS; 276 return SBOX_ERROR_BAD_PARAMS;
280 277
281 if (!policy) 278 if (!policy)
282 return SBOX_ERROR_BAD_PARAMS; 279 return SBOX_ERROR_BAD_PARAMS;
283 280
284 // Even though the resources touched by SpawnTarget can be accessed in 281 // Even though the resources touched by SpawnTarget can be accessed in
285 // multiple threads, the method itself cannot be called from more than 282 // multiple threads, the method itself cannot be called from more than
286 // 1 thread. This is to protect the global variables used while setting up 283 // 1 thread. This is to protect the global variables used while setting up
287 // the child process. 284 // the child process.
288 static DWORD thread_id = ::GetCurrentThreadId(); 285 static DWORD thread_id = ::GetCurrentThreadId();
289 DCHECK(thread_id == ::GetCurrentThreadId()); 286 DCHECK(thread_id == ::GetCurrentThreadId());
290 *last_warning = SBOX_ALL_OK; 287 *last_warning = SBOX_ALL_OK;
291 288
292 AutoLock lock(&lock_); 289 AutoLock lock(&lock_);
293 290
294 // This downcast is safe as long as we control CreatePolicy() 291 // This downcast is safe as long as we control CreatePolicy()
295 scoped_refptr<PolicyBase> policy_base(static_cast<PolicyBase*>(policy.get())); 292 PolicyBase* policy_base = static_cast<PolicyBase*>(policy);
296 293
297 // Construct the tokens and the job object that we are going to associate 294 // Construct the tokens and the job object that we are going to associate
298 // with the soon to be created target process. 295 // with the soon to be created target process.
299 base::win::ScopedHandle initial_token; 296 base::win::ScopedHandle initial_token;
300 base::win::ScopedHandle lockdown_token; 297 base::win::ScopedHandle lockdown_token;
301 base::win::ScopedHandle lowbox_token; 298 base::win::ScopedHandle lowbox_token;
302 ResultCode result = SBOX_ALL_OK; 299 ResultCode result = SBOX_ALL_OK;
303 300
304 result = 301 result =
305 policy_base->MakeTokens(&initial_token, &lockdown_token, &lowbox_token); 302 policy_base->MakeTokens(&initial_token, &lockdown_token, &lowbox_token);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 result = policy_base->AddTarget(target); 434 result = policy_base->AddTarget(target);
438 435
439 if (result != SBOX_ALL_OK) { 436 if (result != SBOX_ALL_OK) {
440 *last_error = ::GetLastError(); 437 *last_error = ::GetLastError();
441 SpawnCleanup(target); 438 SpawnCleanup(target);
442 return result; 439 return result;
443 } 440 }
444 441
445 // We are going to keep a pointer to the policy because we'll call it when 442 // We are going to keep a pointer to the policy because we'll call it when
446 // the job object generates notifications using the completion port. 443 // the job object generates notifications using the completion port.
444 policy_base->AddRef();
447 if (job.IsValid()) { 445 if (job.IsValid()) {
448 std::unique_ptr<JobTracker> tracker( 446 std::unique_ptr<JobTracker> tracker(
449 new JobTracker(std::move(job), policy_base)); 447 new JobTracker(std::move(job), policy_base));
450 448
451 // There is no obvious recovery after failure here. Previous version with 449 // There is no obvious recovery after failure here. Previous version with
452 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 450 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639
453 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), 451 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(),
454 tracker.get())); 452 tracker.get()));
455 453
456 // Save the tracker because in cleanup we might need to force closing 454 // Save the tracker because in cleanup we might need to force closing
(...skipping 17 matching lines...) Expand all
474 ::WaitForSingleObject(no_targets_.Get(), INFINITE); 472 ::WaitForSingleObject(no_targets_.Get(), INFINITE);
475 return SBOX_ALL_OK; 473 return SBOX_ALL_OK;
476 } 474 }
477 475
478 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) { 476 bool BrokerServicesBase::IsActiveTarget(DWORD process_id) {
479 AutoLock lock(&lock_); 477 AutoLock lock(&lock_);
480 return child_process_ids_.find(process_id) != child_process_ids_.end(); 478 return child_process_ids_.find(process_id) != child_process_ids_.end();
481 } 479 }
482 480
483 } // namespace sandbox 481 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/broker_services.h ('k') | sandbox/win/src/policy_target_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698