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

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

Issue 319573006: Add sandbox support for process memory limits (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ready for review Created 6 years, 6 months 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 | Annotate | Revision Log
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 "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/threading/platform_thread.h" 9 #include "base/threading/platform_thread.h"
10 #include "base/win/scoped_handle.h" 10 #include "base/win/scoped_handle.h"
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 130
131 if (WAIT_TIMEOUT == ::WaitForSingleObject(job_thread_, 1000)) { 131 if (WAIT_TIMEOUT == ::WaitForSingleObject(job_thread_, 1000)) {
132 // Cannot clean broker services. 132 // Cannot clean broker services.
133 NOTREACHED(); 133 NOTREACHED();
134 return; 134 return;
135 } 135 }
136 136
137 JobTrackerList::iterator it; 137 JobTrackerList::iterator it;
138 for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) { 138 for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) {
139 JobTracker* tracker = (*it); 139 JobTracker* tracker = (*it);
140 FreeResources(tracker); 140 FreeResources(tracker, SBOX_ALL_OK);
141 delete tracker; 141 delete tracker;
142 } 142 }
143 ::CloseHandle(job_thread_); 143 ::CloseHandle(job_thread_);
144 delete thread_pool_; 144 delete thread_pool_;
145 ::CloseHandle(no_targets_); 145 ::CloseHandle(no_targets_);
146 146
147 // Cancel the wait events and delete remaining peer trackers. 147 // Cancel the wait events and delete remaining peer trackers.
148 for (PeerTrackerMap::iterator it = peer_map_.begin(); 148 for (PeerTrackerMap::iterator it = peer_map_.begin();
149 it != peer_map_.end(); ++it) { 149 it != peer_map_.end(); ++it) {
150 DeregisterPeerTracker(it->second); 150 DeregisterPeerTracker(it->second);
151 } 151 }
152 152
153 // If job_port_ isn't NULL, assumes that the lock has been initialized. 153 // If job_port_ isn't NULL, assumes that the lock has been initialized.
154 if (job_port_) 154 if (job_port_)
155 ::DeleteCriticalSection(&lock_); 155 ::DeleteCriticalSection(&lock_);
156 } 156 }
157 157
158 TargetPolicy* BrokerServicesBase::CreatePolicy() { 158 TargetPolicy* BrokerServicesBase::CreatePolicy() {
159 // If you change the type of the object being created here you must also 159 // If you change the type of the object being created here you must also
160 // change the downcast to it in SpawnTarget(). 160 // change the downcast to it in SpawnTarget().
161 return new PolicyBase; 161 return new PolicyBase;
162 } 162 }
163 163
164 void BrokerServicesBase::FreeResources(JobTracker* tracker) { 164 void BrokerServicesBase::FreeResources(JobTracker* tracker, UINT exit_code) {
165 if (NULL != tracker->policy) { 165 if (NULL != tracker->policy) {
166 BOOL res = ::TerminateJobObject(tracker->job, SBOX_ALL_OK); 166 BOOL res = ::TerminateJobObject(tracker->job, exit_code);
167 DCHECK(res); 167 DCHECK(res);
168 // Closing the job causes the target process to be destroyed so this 168 // Closing the job causes the target process to be destroyed so this
169 // needs to happen before calling OnJobEmpty(). 169 // needs to happen before calling OnJobEmpty().
170 res = ::CloseHandle(tracker->job); 170 res = ::CloseHandle(tracker->job);
171 DCHECK(res); 171 DCHECK(res);
172 // In OnJobEmpty() we don't actually use the job handle directly. 172 // In OnJobEmpty() we don't actually use the job handle directly.
173 tracker->policy->OnJobEmpty(tracker->job); 173 tracker->policy->OnJobEmpty(tracker->job);
174 tracker->policy->Release(); 174 tracker->policy->Release();
175 tracker->policy = NULL; 175 tracker->policy = NULL;
176 } 176 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 // that jobs can send and some of them depend on the job attributes set. 209 // that jobs can send and some of them depend on the job attributes set.
210 JobTracker* tracker = reinterpret_cast<JobTracker*>(key); 210 JobTracker* tracker = reinterpret_cast<JobTracker*>(key);
211 211
212 switch (events) { 212 switch (events) {
213 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: { 213 case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: {
214 // The job object has signaled that the last process associated 214 // The job object has signaled that the last process associated
215 // with it has terminated. Assuming there is no way for a process 215 // with it has terminated. Assuming there is no way for a process
216 // to appear out of thin air in this job, it safe to assume that 216 // to appear out of thin air in this job, it safe to assume that
217 // we can tell the policy to destroy the target object, and for 217 // we can tell the policy to destroy the target object, and for
218 // us to release our reference to the policy object. 218 // us to release our reference to the policy object.
219 FreeResources(tracker); 219 FreeResources(tracker, SBOX_ALL_OK);
220 break; 220 break;
221 } 221 }
222 222
223 case JOB_OBJECT_MSG_NEW_PROCESS: { 223 case JOB_OBJECT_MSG_NEW_PROCESS: {
224 ++target_counter; 224 ++target_counter;
225 if (1 == target_counter) { 225 if (1 == target_counter) {
226 ::ResetEvent(no_targets); 226 ::ResetEvent(no_targets);
227 } 227 }
228 break; 228 break;
229 } 229 }
230 230
231 case JOB_OBJECT_MSG_EXIT_PROCESS: 231 case JOB_OBJECT_MSG_EXIT_PROCESS:
232 case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: { 232 case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: {
233 { 233 {
234 AutoLock lock(&broker->lock_); 234 AutoLock lock(&broker->lock_);
235 broker->child_process_ids_.erase(reinterpret_cast<DWORD>(ovl)); 235 broker->child_process_ids_.erase(reinterpret_cast<DWORD>(ovl));
236 } 236 }
237 --target_counter; 237 --target_counter;
238 if (0 == target_counter) 238 if (0 == target_counter)
239 ::SetEvent(no_targets); 239 ::SetEvent(no_targets);
240 240
241 DCHECK(target_counter >= 0); 241 DCHECK(target_counter >= 0);
242 break; 242 break;
243 } 243 }
244 244
245 case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: { 245 case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: {
246 break; 246 break;
247 } 247 }
248 248
249 case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: {
250 if(tracker->policy->WillTerminateOnJobMemoryLimit())
251 FreeResources(tracker, SBOX_FATAL_MEMORY_EXCEEDED);
cpu_(ooo_6.6-7.5) 2014/06/06 19:44:05 The code seems structured such that FreeResources(
jschuh 2014/06/06 20:13:14 Calling FreeResources here terminates the process
252 break;
253 }
254
249 default: { 255 default: {
250 NOTREACHED(); 256 NOTREACHED();
251 break; 257 break;
252 } 258 }
253 } 259 }
254 } else if (THREAD_CTRL_REMOVE_PEER == key) { 260 } else if (THREAD_CTRL_REMOVE_PEER == key) {
255 // Remove a process from our list of peers. 261 // Remove a process from our list of peers.
256 AutoLock lock(&broker->lock_); 262 AutoLock lock(&broker->lock_);
257 PeerTrackerMap::iterator it = 263 PeerTrackerMap::iterator it =
258 broker->peer_map_.find(reinterpret_cast<DWORD>(ovl)); 264 broker->peer_map_.find(reinterpret_cast<DWORD>(ovl));
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 return SBOX_ERROR_UNSUPPORTED; 507 return SBOX_ERROR_UNSUPPORTED;
502 508
503 base::string16 name = LookupAppContainer(sid); 509 base::string16 name = LookupAppContainer(sid);
504 if (name.empty()) 510 if (name.empty())
505 return SBOX_ERROR_INVALID_APP_CONTAINER; 511 return SBOX_ERROR_INVALID_APP_CONTAINER;
506 512
507 return DeleteAppContainer(sid); 513 return DeleteAppContainer(sid);
508 } 514 }
509 515
510 } // namespace sandbox 516 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698