summaryrefslogtreecommitdiffstats
path: root/chrome/plugin/npobject_util.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/npobject_util.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/npobject_util.cc')
-rw-r--r--chrome/plugin/npobject_util.cc36
1 files changed, 22 insertions, 14 deletions
diff --git a/chrome/plugin/npobject_util.cc b/chrome/plugin/npobject_util.cc
index 229a984..c0c3d10f 100644
--- a/chrome/plugin/npobject_util.cc
+++ b/chrome/plugin/npobject_util.cc
@@ -176,12 +176,12 @@ void CreateNPVariantParam(const NPVariant& variant,
variant.value.stringValue.UTF8Length);
}
break;
- case NPVariantType_Object:
- {
+ case NPVariantType_Object: {
if (variant.value.objectValue->_class == NPObjectProxy::npclass()) {
- param->type = NPVARIANT_PARAM_OBJECT_POINTER;
- param->npobject_pointer =
- NPObjectProxy::GetProxy(variant.value.objectValue)->npobject_ptr();
+ param->type = NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID;
+ NPObjectProxy* proxy =
+ NPObjectProxy::GetProxy(variant.value.objectValue);
+ param->npobject_routing_id = proxy->route_id();
// Don't release, because our original variant is the same as our proxy.
release = false;
} else {
@@ -191,14 +191,12 @@ void CreateNPVariantParam(const NPVariant& variant,
// NPObjectStub adds its own reference to the NPObject it owns, so if
// we were supposed to release the corresponding variant
// (release==true), we should still do that.
- param->type = NPVARIANT_PARAM_OBJECT_ROUTING_ID;
+ param->type = NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID;
int route_id = channel->GenerateRouteID();
new NPObjectStub(
variant.value.objectValue, channel, route_id, containing_window,
page_url);
param->npobject_routing_id = route_id;
- param->npobject_pointer =
- reinterpret_cast<intptr_t>(variant.value.objectValue);
} else {
param->type = NPVARIANT_PARAM_VOID;
}
@@ -213,7 +211,7 @@ void CreateNPVariantParam(const NPVariant& variant,
WebBindings::releaseVariantValue(const_cast<NPVariant*>(&variant));
}
-void CreateNPVariant(const NPVariant_Param& param,
+bool CreateNPVariant(const NPVariant_Param& param,
PluginChannelBase* channel,
NPVariant* result,
gfx::NativeViewId containing_window,
@@ -244,22 +242,32 @@ void CreateNPVariant(const NPVariant_Param& param,
result->value.stringValue.UTF8Length =
static_cast<int>(param.string_value.size());
break;
- case NPVARIANT_PARAM_OBJECT_ROUTING_ID:
+ case NPVARIANT_PARAM_SENDER_OBJECT_ROUTING_ID:
result->type = NPVariantType_Object;
result->value.objectValue =
NPObjectProxy::Create(channel,
param.npobject_routing_id,
- param.npobject_pointer,
containing_window,
page_url);
break;
- case NPVARIANT_PARAM_OBJECT_POINTER:
+ case NPVARIANT_PARAM_RECEIVER_OBJECT_ROUTING_ID: {
+ NPObjectBase* npobject_base =
+ channel->GetNPObjectListenerForRoute(param.npobject_routing_id);
+ if (!npobject_base) {
+ DLOG(WARNING) << "Invalid routing id passed in"
+ << param.npobject_routing_id;
+ return false;
+ }
+
+ DCHECK(npobject_base->GetUnderlyingNPObject() != NULL);
+
result->type = NPVariantType_Object;
- result->value.objectValue =
- reinterpret_cast<NPObject*>(param.npobject_pointer);
+ result->value.objectValue = npobject_base->GetUnderlyingNPObject();
WebBindings::retainObject(result->value.objectValue);
break;
+ }
default:
NOTREACHED();
}
+ return true;
}