diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-03 23:47:26 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-03 23:47:26 +0000 |
commit | feb22a0c7dbdbd8842ada71d458bebb97b48efa2 (patch) | |
tree | 6288bf545367c8e0793d1e78749d4c1f6eb18168 /content/browser/plugin_process_host.cc | |
parent | 81f0e654831b21bd01ff0328580002cb9981705e (diff) | |
download | chromium_src-feb22a0c7dbdbd8842ada71d458bebb97b48efa2.zip chromium_src-feb22a0c7dbdbd8842ada71d458bebb97b48efa2.tar.gz chromium_src-feb22a0c7dbdbd8842ada71d458bebb97b48efa2.tar.bz2 |
Fix crash in the browser when looking up a ResourceContext for an NPAPI initiated request.
This bug occurred because in certain conditions a renderer could have multiple channels open to the same plugin process. Every time a renderer creates an instance of a plugin, we reach NPChannelBase::GetChannel in the plugin process which consults a singleton to see if there's a channel to that renderer, and if not it creates it. When a plugin instance is removed, it ends up calling into NPChannelBase::RemoveRoute which, if it's the last instance to that renderer, will remove the PluginChannel from the map. The key thing is that the PluginChannel is still alive as long as there are live NPObjects using it. So if the renderer creates another plugin instance, then a new PluginChannel will be created. When the old PluginChannel is destroyed though, the entry in the browser process' map would be incorrectly deleted even though there's another PluginChannel to that renderer.
The fix is to make the map in PluginProcessHost ref counted.
BUG=302530
R=ananta@chromium.org
Review URL: https://codereview.chromium.org/25700008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226894 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/plugin_process_host.cc')
-rw-r--r-- | content/browser/plugin_process_host.cc | 34 |
1 files changed, 12 insertions, 22 deletions
diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index f71fa73..9ec7510 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -405,39 +405,29 @@ void PluginProcessHost::OnChannelCreated( Client* client = sent_requests_.front(); if (client) { - resource_context_map_[client->ID()] = client->GetResourceContext(); + if (!resource_context_map_.count(client->ID())) { + ResourceContextEntry entry; + entry.ref_count = 0; + entry.resource_context = client->GetResourceContext(); + resource_context_map_[client->ID()] = entry; + } + resource_context_map_[client->ID()].ref_count++; client->OnChannelOpened(channel_handle); } sent_requests_.pop_front(); } void PluginProcessHost::OnChannelDestroyed(int renderer_id) { - resource_context_map_.erase(renderer_id); - removed_pids_.insert(renderer_id); + resource_context_map_[renderer_id].ref_count--; + if (!resource_context_map_[renderer_id].ref_count) + resource_context_map_.erase(renderer_id); } void PluginProcessHost::GetContexts(const ResourceHostMsg_Request& request, ResourceContext** resource_context, net::URLRequestContext** request_context) { - *resource_context = resource_context_map_[request.origin_pid]; - if (!*resource_context) { - std::string url = request.first_party_for_cookies.spec(); - // Debugging http://crbug.com/302530 - url += std::string("_") + base::IntToString(request.origin_pid); - - for (std::map<int, ResourceContext*>::iterator i = - resource_context_map_.begin(); - i != resource_context_map_.end(); ++i) { - url += std::string("_") + base::IntToString(i->first); - } - - url += "_"; - for (std::set<int>::iterator i = removed_pids_.begin(); - i != removed_pids_.end(); ++i) { - url += std::string("_") + base::IntToString(*i); - } - GetContentClient()->SetActiveURL(GURL(url)); - } + *resource_context = + resource_context_map_[request.origin_pid].resource_context; *request_context = (*resource_context)->GetRequestContext(); } |