From 6018116f1cd8989b77a5f29b7afa5616875cad6d Mon Sep 17 00:00:00 2001 From: "teravest@chromium.org" Date: Fri, 26 Apr 2013 22:02:53 +0000 Subject: Pepper: Fix use-after-free bug in PluginVarTracker. A PluginDispatcher may destroy itself in reaction to a channel error. However, ProxyObjectVar instances may still have a pointer to the (destroyed) dispatcher. This is problematic when the plugin wants to send a message to the host to release the object; the ProxyObjectVar doesn't know the PluginDispatcher has been deleted. This change alters PluginDispatcher to invoke DidDeleteDispatcher() on the PluginVarTracker, which will clean up the dangling dispatcher pointers. BUG=233044 Review URL: https://chromiumcodereview.appspot.com/14054020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196850 0039d316-1c4b-4281-b951-d872f2087c98 --- ppapi/proxy/plugin_var_tracker.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'ppapi/proxy/plugin_var_tracker.cc') diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc index 14a8584..4561ac5 100644 --- a/ppapi/proxy/plugin_var_tracker.cc +++ b/ppapi/proxy/plugin_var_tracker.cc @@ -188,6 +188,16 @@ void PluginVarTracker::DidDeleteInstance(PP_Instance instance) { } } +void PluginVarTracker::DidDeleteDispatcher(PluginDispatcher* dispatcher) { + for (size_t i = 0; i < live_vars_.size(); ++i) { + if (live_vars_[i].var.get() == NULL) + continue; + ProxyObjectVar* object = live_vars_[i].var->AsProxyObjectVar(); + if (object && object->dispatcher() == dispatcher) + object->clear_dispatcher(); + } +} + ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { return new PluginArrayBufferVar(size_in_bytes); } @@ -340,14 +350,18 @@ PP_Var PluginVarTracker::GetOrCreateObjectVarID(ProxyObjectVar* object) { void PluginVarTracker::SendAddRefObjectMsg( const ProxyObjectVar& proxy_object) { int unused; - proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_AddRefObject( - API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id(), &unused)); + if (proxy_object.dispatcher()) { + proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_AddRefObject( + API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id(), &unused)); + } } void PluginVarTracker::SendReleaseObjectMsg( const ProxyObjectVar& proxy_object) { - proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_ReleaseObject( - API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id())); + if (proxy_object.dispatcher()) { + proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_ReleaseObject( + API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id())); + } } scoped_refptr PluginVarTracker::FindOrMakePluginVarFromHostVar( -- cgit v1.1