summaryrefslogtreecommitdiffstats
path: root/chrome/plugin/plugin_channel_base.cc
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-20 07:05:23 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-20 07:05:23 +0000
commit4da8a2e32bc164d2402c29ade52c2babcfff0d39 (patch)
treecfd73d77e42cb9c49af61d2aef873ffc4ea16afd /chrome/plugin/plugin_channel_base.cc
parentca4a992e75a7466f9c0f50544af0883d9ef9a90b (diff)
downloadchromium_src-4da8a2e32bc164d2402c29ade52c2babcfff0d39.zip
chromium_src-4da8a2e32bc164d2402c29ade52c2babcfff0d39.tar.gz
chromium_src-4da8a2e32bc164d2402c29ade52c2babcfff0d39.tar.bz2
The renderer and plugin processes can send over raw NPObjects valid in the other side's address
space. Basically the way this works is if an NPObject is marshaled over to the other side, an NPObjectStub is created in the caller address space and a NPObjectProxy is created on the other side. The NPObjectProxy is passed the raw NPObject pointer which is used as a cookie. If the original NPObject needs to be passed back we pass the underlying NPObject saved in the NPObjectProxy. The receiver does not validate whether this NPObject is valid before invoking on it. While this is mostly fine, in the case of a compromised renderer invalid addresses could be passed back to the plugin which would invoke on these addresses and crash. Fix is to never pass raw object pointers across and just pass the corresponding routing id of the NPObjectStub. The receiver validates this object by invoking a new method GetNPObjectListenerForRoute on the PluginChannelBase. This method returns the corresponding NPObject listener for the routing id. We then retrieve the underlying NPObject from the listener and use it. The map of NPObjectListeners which is maintained by PluginChannelBase has been changed to hold NPObjectBase pointers instead. NPObjectStub and NPObjectProxy implement the new NPObjectBase interface which provides methods to return the underlying NPObject and the IPC::Channel::Listener pointer. Fixes bug http://code.google.com/p/chromium/issues/detail?id=31880 I verified with the steps outlined in the bug that this fix does address the underlying crash. Bug=31880 Test=We need a framework to test PluginChannel and NPObjectProxy/Stub. Will add a test case for this once we have this in place. Review URL: http://codereview.chromium.org/548046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36618 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/plugin/plugin_channel_base.cc')
-rw-r--r--chrome/plugin/plugin_channel_base.cc21
1 files changed, 17 insertions, 4 deletions
diff --git a/chrome/plugin/plugin_channel_base.cc b/chrome/plugin/plugin_channel_base.cc
index 026b9e5..f104fea 100644
--- a/chrome/plugin/plugin_channel_base.cc
+++ b/chrome/plugin/plugin_channel_base.cc
@@ -95,6 +95,15 @@ void PluginChannelBase::CleanupChannels() {
g_plugin_channels_.clear();
}
+NPObjectBase* PluginChannelBase::GetNPObjectListenerForRoute(int route_id) {
+ ListenerMap::iterator iter = npobject_listeners_.find(route_id);
+ if (iter == npobject_listeners_.end()) {
+ DLOG(WARNING) << "Invalid route id passed in:" << route_id;
+ return NULL;
+ }
+ return iter->second;
+}
+
bool PluginChannelBase::Init(MessageLoop* ipc_message_loop,
bool create_pipe_now) {
channel_.reset(new IPC::SyncChannel(
@@ -154,9 +163,9 @@ void PluginChannelBase::OnChannelConnected(int32 peer_pid) {
void PluginChannelBase::AddRoute(int route_id,
IPC::Channel::Listener* listener,
- bool npobject) {
+ NPObjectBase* npobject) {
if (npobject) {
- npobject_listeners_[route_id] = listener;
+ npobject_listeners_[route_id] = npobject;
} else {
plugin_count_++;
}
@@ -190,8 +199,12 @@ void PluginChannelBase::RemoveRoute(int route_id) {
AutoReset auto_reset_in_remove_route(&in_remove_route_, true);
for (ListenerMap::iterator npobj_iter = npobject_listeners_.begin();
npobj_iter != npobject_listeners_.end(); ++npobj_iter) {
- if (npobj_iter->second)
- npobj_iter->second->OnChannelError();
+ if (npobj_iter->second) {
+ IPC::Channel::Listener* channel_listener =
+ npobj_iter->second->GetChannelListener();
+ DCHECK(channel_listener != NULL);
+ channel_listener->OnChannelError();
+ }
}
for (PluginChannelMap::iterator iter = g_plugin_channels_.begin();