Chromium Code Reviews| 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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |