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

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

Issue 1378523002: Use scoped_refptr and RefCountedThreadSafe for TargetPolicy. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated patchset dependency Created 5 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 <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
13 #include "base/stl_util.h" 14 #include "base/stl_util.h"
14 #include "base/threading/platform_thread.h" 15 #include "base/threading/platform_thread.h"
15 #include "base/win/scoped_handle.h" 16 #include "base/win/scoped_handle.h"
16 #include "base/win/scoped_process_information.h" 17 #include "base/win/scoped_process_information.h"
17 #include "base/win/startup_information.h" 18 #include "base/win/startup_information.h"
18 #include "base/win/windows_version.h" 19 #include "base/win/windows_version.h"
19 #include "sandbox/win/src/app_container.h" 20 #include "sandbox/win/src/app_container.h"
20 #include "sandbox/win/src/process_mitigations.h" 21 #include "sandbox/win/src/process_mitigations.h"
21 #include "sandbox/win/src/sandbox.h" 22 #include "sandbox/win/src/sandbox.h"
(...skipping 29 matching lines...) Expand all
51 enum { 52 enum {
52 THREAD_CTRL_NONE, 53 THREAD_CTRL_NONE,
53 THREAD_CTRL_REMOVE_PEER, 54 THREAD_CTRL_REMOVE_PEER,
54 THREAD_CTRL_QUIT, 55 THREAD_CTRL_QUIT,
55 THREAD_CTRL_LAST, 56 THREAD_CTRL_LAST,
56 }; 57 };
57 58
58 // Helper structure that allows the Broker to associate a job notification 59 // Helper structure that allows the Broker to associate a job notification
59 // with a job object and with a policy. 60 // with a job object and with a policy.
60 struct JobTracker { 61 struct JobTracker {
61 JobTracker(base::win::ScopedHandle job, sandbox::TargetPolicy* policy) 62 JobTracker(base::win::ScopedHandle job,
62 : job(job.Pass()), policy(policy) { 63 scoped_refptr<sandbox::TargetPolicy> policy)
63 } 64 : job(job.Pass()), policy(policy.Pass()) {}
64 ~JobTracker() { 65 ~JobTracker() { FreeResources(); }
65 FreeResources();
66 }
67 66
68 // Releases the Job and notifies the associated Policy object to release its 67 // Releases the Job and notifies the associated Policy object to release its
69 // resources as well. 68 // resources as well.
70 void FreeResources(); 69 void FreeResources();
71 70
72 base::win::ScopedHandle job; 71 base::win::ScopedHandle job;
73 sandbox::TargetPolicy* policy; 72 scoped_refptr<sandbox::TargetPolicy> policy;
74 }; 73 };
75 74
76 void JobTracker::FreeResources() { 75 void JobTracker::FreeResources() {
77 if (policy) { 76 if (policy) {
78 BOOL res = ::TerminateJobObject(job.Get(), sandbox::SBOX_ALL_OK); 77 BOOL res = ::TerminateJobObject(job.Get(), sandbox::SBOX_ALL_OK);
79 DCHECK(res); 78 DCHECK(res);
80 // Closing the job causes the target process to be destroyed so this needs 79 // Closing the job causes the target process to be destroyed so this needs
81 // to happen before calling OnJobEmpty(). 80 // to happen before calling OnJobEmpty().
82 HANDLE stale_job_handle = job.Get(); 81 HANDLE stale_job_handle = job.Get();
83 job.Close(); 82 job.Close();
84 83
85 // In OnJobEmpty() we don't actually use the job handle directly. 84 // In OnJobEmpty() we don't actually use the job handle directly.
86 policy->OnJobEmpty(stale_job_handle); 85 policy->OnJobEmpty(stale_job_handle);
87 policy->Release();
88 policy = NULL; 86 policy = NULL;
89 } 87 }
90 } 88 }
91 89
92 // Helper structure that allows the broker to track peer processes 90 // Helper structure that allows the broker to track peer processes
93 struct PeerTracker { 91 struct PeerTracker {
94 PeerTracker(DWORD process_id, HANDLE broker_job_port) 92 PeerTracker(DWORD process_id, HANDLE broker_job_port)
95 : wait_object(NULL), id(process_id), job_port(broker_job_port) { 93 : wait_object(NULL), id(process_id), job_port(broker_job_port) {
96 } 94 }
97 95
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 165
168 // Cancel the wait events and delete remaining peer trackers. 166 // Cancel the wait events and delete remaining peer trackers.
169 for (PeerTrackerMap::iterator it = peer_map_.begin(); 167 for (PeerTrackerMap::iterator it = peer_map_.begin();
170 it != peer_map_.end(); ++it) { 168 it != peer_map_.end(); ++it) {
171 DeregisterPeerTracker(it->second); 169 DeregisterPeerTracker(it->second);
172 } 170 }
173 171
174 ::DeleteCriticalSection(&lock_); 172 ::DeleteCriticalSection(&lock_);
175 } 173 }
176 174
177 TargetPolicy* BrokerServicesBase::CreatePolicy() { 175 scoped_refptr<TargetPolicy> BrokerServicesBase::CreatePolicy() {
178 return new TargetPolicy; 176 return make_scoped_refptr(new TargetPolicy);
179 } 177 }
180 178
181 // The worker thread stays in a loop waiting for asynchronous notifications 179 // The worker thread stays in a loop waiting for asynchronous notifications
182 // from the job objects. Right now we only care about knowing when the last 180 // from the job objects. Right now we only care about knowing when the last
183 // process on a job terminates, but in general this is the place to tell 181 // process on a job terminates, but in general this is the place to tell
184 // the policy about events. 182 // the policy about events.
185 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) { 183 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) {
186 if (NULL == param) 184 if (NULL == param)
187 return 1; 185 return 1;
188 186
(...skipping 23 matching lines...) Expand all
212 // that jobs can send and some of them depend on the job attributes set. 210 // that jobs can send and some of them depend on the job attributes set.
213 JobTracker* tracker = reinterpret_cast<JobTracker*>(key); 211 JobTracker* tracker = reinterpret_cast<JobTracker*>(key);
214 212
215 switch (events) { 213 switch (events) {
216 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: { 214 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: {
217 // The job object has signaled that the last process associated 215 // The job object has signaled that the last process associated
218 // with it has terminated. Assuming there is no way for a process 216 // with it has terminated. Assuming there is no way for a process
219 // to appear out of thin air in this job, it safe to assume that 217 // to appear out of thin air in this job, it safe to assume that
220 // we can tell the policy to destroy the target object, and for 218 // we can tell the policy to destroy the target object, and for
221 // us to release our reference to the policy object. 219 // us to release our reference to the policy object.
220 // TODO(rickyz): Is tracker removed from tracker_list_ or destroyed?
222 tracker->FreeResources(); 221 tracker->FreeResources();
223 break; 222 break;
224 } 223 }
225 224
226 case JOB_OBJECT_MSG_NEW_PROCESS: { 225 case JOB_OBJECT_MSG_NEW_PROCESS: {
227 ++target_counter; 226 ++target_counter;
228 if (1 == target_counter) { 227 if (1 == target_counter) {
229 ::ResetEvent(no_targets); 228 ::ResetEvent(no_targets);
230 } 229 }
231 break; 230 break;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 278 }
280 279
281 NOTREACHED(); 280 NOTREACHED();
282 return 0; 281 return 0;
283 } 282 }
284 283
285 // SpawnTarget does all the interesting sandbox setup and creates the target 284 // SpawnTarget does all the interesting sandbox setup and creates the target
286 // process inside the sandbox. 285 // process inside the sandbox.
287 ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, 286 ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
288 const wchar_t* command_line, 287 const wchar_t* command_line,
289 TargetPolicy* policy, 288 scoped_refptr<TargetPolicy> policy,
290 PROCESS_INFORMATION* target_info) { 289 PROCESS_INFORMATION* target_info) {
291 if (!exe_path) 290 if (!exe_path)
292 return SBOX_ERROR_BAD_PARAMS; 291 return SBOX_ERROR_BAD_PARAMS;
293 292
294 if (!policy) 293 if (!policy)
295 return SBOX_ERROR_BAD_PARAMS; 294 return SBOX_ERROR_BAD_PARAMS;
296 295
297 // Even though the resources touched by SpawnTarget can be accessed in 296 // Even though the resources touched by SpawnTarget can be accessed in
298 // multiple threads, the method itself cannot be called from more than 297 // multiple threads, the method itself cannot be called from more than
299 // 1 thread. This is to protect the global variables used while setting up 298 // 1 thread. This is to protect the global variables used while setting up
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 if (ERROR_SUCCESS != win_result) { 423 if (ERROR_SUCCESS != win_result) {
425 SpawnCleanup(target, win_result); 424 SpawnCleanup(target, win_result);
426 return SBOX_ERROR_CREATE_PROCESS; 425 return SBOX_ERROR_CREATE_PROCESS;
427 } 426 }
428 427
429 // Now the policy is the owner of the target. 428 // Now the policy is the owner of the target.
430 if (!policy->AddTarget(target)) { 429 if (!policy->AddTarget(target)) {
431 return SpawnCleanup(target, 0); 430 return SpawnCleanup(target, 0);
432 } 431 }
433 432
434 // We are going to keep a pointer to the policy because we'll call it when
435 // the job object generates notifications using the completion port.
436 policy->AddRef();
437 if (job.IsValid()) { 433 if (job.IsValid()) {
438 scoped_ptr<JobTracker> tracker(new JobTracker(job.Pass(), policy)); 434 scoped_ptr<JobTracker> tracker(new JobTracker(job.Pass(), policy.Pass()));
439 435
440 // There is no obvious recovery after failure here. Previous version with 436 // There is no obvious recovery after failure here. Previous version with
441 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 437 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639
442 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), 438 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(),
443 tracker.get())); 439 tracker.get()));
444 440
445 // 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
446 // the Jobs. 442 // the Jobs.
447 tracker_list_.push_back(tracker.release()); 443 tracker_list_.push_back(tracker.release());
448 child_process_ids_.insert(process_info.process_id()); 444 child_process_ids_.insert(process_info.process_id());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 return SBOX_ERROR_UNSUPPORTED; 530 return SBOX_ERROR_UNSUPPORTED;
535 531
536 base::string16 name = LookupAppContainer(sid); 532 base::string16 name = LookupAppContainer(sid);
537 if (name.empty()) 533 if (name.empty())
538 return SBOX_ERROR_INVALID_APP_CONTAINER; 534 return SBOX_ERROR_INVALID_APP_CONTAINER;
539 535
540 return DeleteAppContainer(sid); 536 return DeleteAppContainer(sid);
541 } 537 }
542 538
543 } // namespace sandbox 539 } // 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