summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-20 19:39:41 +0000
committerpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-20 19:39:41 +0000
commit94ba73f2edeb8ea5c641da24d9bf0974fc96c89a (patch)
tree59c754f5c203cd9dadfe9005f2c1ba0638b37e5f /webkit
parentfc1964a7c6a613ca565bb3f03f765fb4a44529dd (diff)
downloadchromium_src-94ba73f2edeb8ea5c641da24d9bf0974fc96c89a.zip
chromium_src-94ba73f2edeb8ea5c641da24d9bf0974fc96c89a.tar.gz
chromium_src-94ba73f2edeb8ea5c641da24d9bf0974fc96c89a.tar.bz2
Dynamically check types of PPAPI IDs
BUG=none TEST=Pepper Flash, PPAPITests Review URL: http://codereview.chromium.org/6261017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71985 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/plugins/ppapi/resource_tracker.cc70
1 files changed, 59 insertions, 11 deletions
diff --git a/webkit/plugins/ppapi/resource_tracker.cc b/webkit/plugins/ppapi/resource_tracker.cc
index 38d55a9..730c36a 100644
--- a/webkit/plugins/ppapi/resource_tracker.cc
+++ b/webkit/plugins/ppapi/resource_tracker.cc
@@ -15,6 +15,30 @@
#include "webkit/plugins/ppapi/resource.h"
#include "webkit/plugins/ppapi/var.h"
+enum PPIdType {
+ PP_ID_TYPE_MODULE,
+ PP_ID_TYPE_INSTANCE,
+ PP_ID_TYPE_RESOURCE,
+ PP_ID_TYPE_VAR,
+ PP_ID_TYPE_COUNT
+};
+
+static const unsigned int kPPIdTypeBits = 2;
+COMPILE_ASSERT(PP_ID_TYPE_COUNT <= (1<<kPPIdTypeBits),
+ kPPIdTypeBits_is_too_small_for_all_id_types);
+
+template <typename T> static inline T MakeTypedId(T value, PPIdType type) {
+ return (value << kPPIdTypeBits) | static_cast<T>(type);
+}
+
+template <typename T> static inline bool CheckIdType(T id, PPIdType type) {
+ // 0 is a valid resource.
+ if (!id)
+ return true;
+ const T mask = (static_cast<T>(1) << kPPIdTypeBits) - 1;
+ return (id & mask) == type;
+}
+
namespace webkit {
namespace ppapi {
@@ -22,6 +46,8 @@ static base::LazyInstance<ResourceTracker> g_resource_tracker(
base::LINKER_INITIALIZED);
scoped_refptr<Resource> ResourceTracker::GetResource(PP_Resource res) const {
+ DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
+ << res << " is not a PP_Resource.";
ResourceMap::const_iterator result = live_resources_.find(res);
if (result == live_resources_.end()) {
return scoped_refptr<Resource>();
@@ -48,30 +74,32 @@ ResourceTracker* ResourceTracker::Get() {
}
PP_Resource ResourceTracker::AddResource(Resource* resource) {
- // If the plugin manages to create 4 billion resources, don't do crazy stuff.
- if (last_resource_id_ == std::numeric_limits<PP_Resource>::max())
+ // If the plugin manages to create 1 billion resources, don't do crazy stuff.
+ if (last_resource_id_ ==
+ (std::numeric_limits<PP_Resource>::max() >> kPPIdTypeBits))
return 0;
// Add the resource with plugin use-count 1.
- PP_Resource new_id = ++last_resource_id_;
+ PP_Resource new_id = MakeTypedId(++last_resource_id_, PP_ID_TYPE_RESOURCE);
live_resources_.insert(std::make_pair(new_id, std::make_pair(resource, 1)));
instance_to_resources_[resource->instance()->pp_instance()].insert(new_id);
return new_id;
}
int32 ResourceTracker::AddVar(Var* var) {
- // If the plugin manages to create 4B strings...
- if (last_var_id_ == std::numeric_limits<int32>::max()) {
+ // If the plugin manages to create 1B strings...
+ if (last_var_id_ == std::numeric_limits<int32>::max() >> kPPIdTypeBits) {
return 0;
}
// Add the resource with plugin use-count 1.
- ++last_var_id_;
- live_vars_.insert(std::make_pair(last_var_id_,
- std::make_pair(var, 1)));
- return last_var_id_;
+ int32 new_id = MakeTypedId(++last_var_id_, PP_ID_TYPE_VAR);
+ live_vars_.insert(std::make_pair(new_id, std::make_pair(var, 1)));
+ return new_id;
}
bool ResourceTracker::AddRefResource(PP_Resource res) {
+ DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
+ << res << " is not a PP_Resource.";
ResourceMap::iterator i = live_resources_.find(res);
if (i != live_resources_.end()) {
// We don't protect against overflow, since a plugin as malicious as to ref
@@ -85,6 +113,8 @@ bool ResourceTracker::AddRefResource(PP_Resource res) {
}
bool ResourceTracker::UnrefResource(PP_Resource res) {
+ DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
+ << res << " is not a PP_Resource.";
ResourceMap::iterator i = live_resources_.find(res);
if (i != live_resources_.end()) {
if (!--i->second.second) {
@@ -105,6 +135,8 @@ bool ResourceTracker::UnrefResource(PP_Resource res) {
}
void ResourceTracker::ForceDeletePluginResourceRefs(PP_Resource res) {
+ DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
+ << res << " is not a PP_Resource.";
ResourceMap::iterator i = live_resources_.find(res);
if (i == live_resources_.end())
return; // Nothing to do.
@@ -138,6 +170,8 @@ uint32 ResourceTracker::GetLiveObjectsForModule(PluginModule* module) const {
}
scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) const {
+ DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR))
+ << var_id << " is not a PP_Var ID.";
VarMap::const_iterator result = live_vars_.find(var_id);
if (result == live_vars_.end()) {
return scoped_refptr<Var>();
@@ -146,6 +180,8 @@ scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) const {
}
bool ResourceTracker::AddRefVar(int32 var_id) {
+ DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR))
+ << var_id << " is not a PP_Var ID.";
VarMap::iterator i = live_vars_.find(var_id);
if (i != live_vars_.end()) {
// We don't protect against overflow, since a plugin as malicious as to ref
@@ -158,6 +194,8 @@ bool ResourceTracker::AddRefVar(int32 var_id) {
}
bool ResourceTracker::UnrefVar(int32 var_id) {
+ DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR))
+ << var_id << " is not a PP_Var ID.";
VarMap::iterator i = live_vars_.find(var_id);
if (i != live_vars_.end()) {
if (!--i->second.second)
@@ -184,7 +222,8 @@ PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) {
// Need to make sure the random number isn't a duplicate or 0.
PP_Instance new_instance;
do {
- new_instance = static_cast<PP_Instance>(base::RandUint64());
+ new_instance = MakeTypedId(static_cast<PP_Instance>(base::RandUint64()),
+ PP_ID_TYPE_INSTANCE);
} while (!new_instance ||
instance_map_.find(new_instance) != instance_map_.end());
instance_map_[new_instance] = instance;
@@ -192,6 +231,8 @@ PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) {
}
void ResourceTracker::InstanceDeleted(PP_Instance instance) {
+ DLOG_IF(ERROR, !CheckIdType(instance, PP_ID_TYPE_INSTANCE))
+ << instance << " is not a PP_Instance.";
// Force release all plugin references to resources associated with the
// deleted instance.
ResourceSet& resource_set = instance_to_resources_[instance];
@@ -215,6 +256,8 @@ void ResourceTracker::InstanceDeleted(PP_Instance instance) {
}
PluginInstance* ResourceTracker::GetInstance(PP_Instance instance) {
+ DLOG_IF(ERROR, !CheckIdType(instance, PP_ID_TYPE_INSTANCE))
+ << instance << " is not a PP_Instance.";
InstanceMap::iterator found = instance_map_.find(instance);
if (found == instance_map_.end())
return NULL;
@@ -232,7 +275,8 @@ PP_Module ResourceTracker::AddModule(PluginModule* module) {
// See AddInstance above.
PP_Module new_module;
do {
- new_module = static_cast<PP_Module>(base::RandUint64());
+ new_module = MakeTypedId(static_cast<PP_Module>(base::RandUint64()),
+ PP_ID_TYPE_MODULE);
} while (!new_module ||
module_map_.find(new_module) != module_map_.end());
module_map_[new_module] = module;
@@ -240,6 +284,8 @@ PP_Module ResourceTracker::AddModule(PluginModule* module) {
}
void ResourceTracker::ModuleDeleted(PP_Module module) {
+ DLOG_IF(ERROR, !CheckIdType(module, PP_ID_TYPE_MODULE))
+ << module << " is not a PP_Module.";
ModuleMap::iterator found = module_map_.find(module);
if (found == module_map_.end()) {
NOTREACHED();
@@ -249,6 +295,8 @@ void ResourceTracker::ModuleDeleted(PP_Module module) {
}
PluginModule* ResourceTracker::GetModule(PP_Module module) {
+ DLOG_IF(ERROR, !CheckIdType(module, PP_ID_TYPE_MODULE))
+ << module << " is not a PP_Module.";
ModuleMap::iterator found = module_map_.find(module);
if (found == module_map_.end())
return NULL;