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

Unified Diff: sandbox/src/broker_services.cc

Issue 9960045: Add sandbox support for associating peer processes (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sandbox/src/broker_services.h ('k') | sandbox/src/handle_policy_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/src/broker_services.cc
===================================================================
--- sandbox/src/broker_services.cc (revision 132034)
+++ sandbox/src/broker_services.cc (working copy)
@@ -41,12 +41,34 @@
// executes TargetEventsThread().
enum {
THREAD_CTRL_NONE,
+ THREAD_CTRL_REMOVE_PEER,
THREAD_CTRL_QUIT,
- THREAD_CTRL_LAST
+ THREAD_CTRL_LAST,
};
-}
+// Helper structure that allows the Broker to associate a job notification
+// with a job object and with a policy.
+struct JobTracker {
+ HANDLE job;
+ sandbox::PolicyBase* policy;
+ JobTracker(HANDLE cjob, sandbox::PolicyBase* cpolicy)
+ : job(cjob), policy(cpolicy) {
+ }
+};
+// Helper structure that allows the broker to track peer processes
+struct PeerTracker {
+ HANDLE wait_object;
+ base::win::ScopedHandle process;
+ DWORD id;
+ HANDLE job_port;
+ PeerTracker(DWORD process_id, HANDLE broker_job_port)
+ : wait_object(NULL), id(process_id), job_port(broker_job_port) {
+ }
+};
+
+} // namespace
+
namespace sandbox {
BrokerServicesBase::BrokerServicesBase()
@@ -85,6 +107,7 @@
// If there is no port Init() was never called successfully.
if (!job_port_)
return;
+
// Closing the port causes, that no more Job notifications are delivered to
// the worker thread and also causes the thread to exit. This is what we
// want to do since we are going to close all outstanding Jobs and notifying
@@ -107,6 +130,18 @@
::CloseHandle(job_thread_);
delete thread_pool_;
::CloseHandle(no_targets_);
+
+ // Cancel the wait events and delete remaining peer trackers.
+ for (PeerTrackerMap::iterator it = peer_map_.begin();
+ it != peer_map_.end(); ++it) {
+ // Deregistration shouldn't fail, but we leak rather than crash if it does.
+ if (::UnregisterWaitEx(it->second->wait_object, INVALID_HANDLE_VALUE)) {
+ delete it->second;
+ } else {
+ NOTREACHED();
+ }
+ }
+
// If job_port_ isn't NULL, assumes that the lock has been initialized.
if (job_port_)
::DeleteCriticalSection(&lock_);
@@ -209,9 +244,23 @@
}
}
+ } else if (THREAD_CTRL_REMOVE_PEER == key) {
+ // Remove a process from our list of peers.
+ AutoLock lock(&broker->lock_);
+ PeerTrackerMap::iterator it =
+ broker->peer_map_.find(reinterpret_cast<DWORD>(ovl));
+ // This shouldn't fail, but if it does leak the memory rather than crash.
+ if (::UnregisterWaitEx(it->second->wait_object, INVALID_HANDLE_VALUE)) {
+ delete it->second;
+ broker->peer_map_.erase(it);
+ } else {
+ NOTREACHED();
+ }
+
} else if (THREAD_CTRL_QUIT == key) {
// The broker object is being destroyed so the thread needs to exit.
return 0;
+
} else {
// We have not implemented more commands.
NOTREACHED();
@@ -312,7 +361,44 @@
bool BrokerServicesBase::IsActiveTarget(DWORD process_id) {
AutoLock lock(&lock_);
- return child_process_ids_.find(process_id) != child_process_ids_.end();
+ return child_process_ids_.find(process_id) != child_process_ids_.end() ||
+ peer_map_.find(process_id) != peer_map_.end();
}
+VOID CALLBACK BrokerServicesBase::RemovePeer(PVOID parameter, BOOLEAN) {
+ PeerTracker* peer = reinterpret_cast<PeerTracker*>(parameter);
+ // Don't check the return code because we this may fail (safely) at shutdown.
+ ::PostQueuedCompletionStatus(peer->job_port, 0, THREAD_CTRL_REMOVE_PEER,
+ reinterpret_cast<LPOVERLAPPED>(peer->id));
+}
+
+ResultCode BrokerServicesBase::AddTargetPeer(HANDLE peer_process) {
+ scoped_ptr<PeerTracker> peer(new PeerTracker(::GetProcessId(peer_process),
+ job_port_));
+ if (!peer->id)
+ return SBOX_ERROR_GENERIC;
+
+ if (!::DuplicateHandle(::GetCurrentProcess(), peer_process,
+ ::GetCurrentProcess(), peer->process.Receive(),
+ SYNCHRONIZE, FALSE, 0)) {
+ return SBOX_ERROR_GENERIC;
+ }
+
+ AutoLock lock(&lock_);
+ if (!peer_map_.insert(std::make_pair(peer->id, peer.get())).second)
+ return SBOX_ERROR_BAD_PARAMS;
+
+ if (!::RegisterWaitForSingleObject(&peer->wait_object,
+ peer->process, RemovePeer,
+ peer.get(), INFINITE, WT_EXECUTEONLYONCE |
+ WT_EXECUTEINWAITTHREAD)) {
+ peer_map_.erase(peer->id);
+ return SBOX_ERROR_GENERIC;
+ }
+
+ // Leak the pointer since it will be cleaned up by the callback.
+ peer.release();
+ return SBOX_ALL_OK;
+}
+
} // namespace sandbox
« no previous file with comments | « sandbox/src/broker_services.h ('k') | sandbox/src/handle_policy_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698