Commit 94ba73f2 authored by piman@google.com's avatar piman@google.com

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
parent fc1964a7
...@@ -15,6 +15,30 @@ ...@@ -15,6 +15,30 @@
#include "webkit/plugins/ppapi/resource.h" #include "webkit/plugins/ppapi/resource.h"
#include "webkit/plugins/ppapi/var.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 webkit {
namespace ppapi { namespace ppapi {
...@@ -22,6 +46,8 @@ static base::LazyInstance<ResourceTracker> g_resource_tracker( ...@@ -22,6 +46,8 @@ static base::LazyInstance<ResourceTracker> g_resource_tracker(
base::LINKER_INITIALIZED); base::LINKER_INITIALIZED);
scoped_refptr<Resource> ResourceTracker::GetResource(PP_Resource res) const { 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); ResourceMap::const_iterator result = live_resources_.find(res);
if (result == live_resources_.end()) { if (result == live_resources_.end()) {
return scoped_refptr<Resource>(); return scoped_refptr<Resource>();
...@@ -48,30 +74,32 @@ ResourceTracker* ResourceTracker::Get() { ...@@ -48,30 +74,32 @@ ResourceTracker* ResourceTracker::Get() {
} }
PP_Resource ResourceTracker::AddResource(Resource* resource) { PP_Resource ResourceTracker::AddResource(Resource* resource) {
// If the plugin manages to create 4 billion resources, don't do crazy stuff. // If the plugin manages to create 1 billion resources, don't do crazy stuff.
if (last_resource_id_ == std::numeric_limits<PP_Resource>::max()) if (last_resource_id_ ==
(std::numeric_limits<PP_Resource>::max() >> kPPIdTypeBits))
return 0; return 0;
// Add the resource with plugin use-count 1. // 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))); live_resources_.insert(std::make_pair(new_id, std::make_pair(resource, 1)));
instance_to_resources_[resource->instance()->pp_instance()].insert(new_id); instance_to_resources_[resource->instance()->pp_instance()].insert(new_id);
return new_id; return new_id;
} }
int32 ResourceTracker::AddVar(Var* var) { int32 ResourceTracker::AddVar(Var* var) {
// If the plugin manages to create 4B strings... // If the plugin manages to create 1B strings...
if (last_var_id_ == std::numeric_limits<int32>::max()) { if (last_var_id_ == std::numeric_limits<int32>::max() >> kPPIdTypeBits) {
return 0; return 0;
} }
// Add the resource with plugin use-count 1. // Add the resource with plugin use-count 1.
++last_var_id_; int32 new_id = MakeTypedId(++last_var_id_, PP_ID_TYPE_VAR);
live_vars_.insert(std::make_pair(last_var_id_, live_vars_.insert(std::make_pair(new_id, std::make_pair(var, 1)));
std::make_pair(var, 1))); return new_id;
return last_var_id_;
} }
bool ResourceTracker::AddRefResource(PP_Resource res) { 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); ResourceMap::iterator i = live_resources_.find(res);
if (i != live_resources_.end()) { if (i != live_resources_.end()) {
// We don't protect against overflow, since a plugin as malicious as to ref // We don't protect against overflow, since a plugin as malicious as to ref
...@@ -85,6 +113,8 @@ bool ResourceTracker::AddRefResource(PP_Resource res) { ...@@ -85,6 +113,8 @@ bool ResourceTracker::AddRefResource(PP_Resource res) {
} }
bool ResourceTracker::UnrefResource(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); ResourceMap::iterator i = live_resources_.find(res);
if (i != live_resources_.end()) { if (i != live_resources_.end()) {
if (!--i->second.second) { if (!--i->second.second) {
...@@ -105,6 +135,8 @@ bool ResourceTracker::UnrefResource(PP_Resource res) { ...@@ -105,6 +135,8 @@ bool ResourceTracker::UnrefResource(PP_Resource res) {
} }
void ResourceTracker::ForceDeletePluginResourceRefs(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); ResourceMap::iterator i = live_resources_.find(res);
if (i == live_resources_.end()) if (i == live_resources_.end())
return; // Nothing to do. return; // Nothing to do.
...@@ -138,6 +170,8 @@ uint32 ResourceTracker::GetLiveObjectsForModule(PluginModule* module) const { ...@@ -138,6 +170,8 @@ uint32 ResourceTracker::GetLiveObjectsForModule(PluginModule* module) const {
} }
scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) 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); VarMap::const_iterator result = live_vars_.find(var_id);
if (result == live_vars_.end()) { if (result == live_vars_.end()) {
return scoped_refptr<Var>(); return scoped_refptr<Var>();
...@@ -146,6 +180,8 @@ scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) const { ...@@ -146,6 +180,8 @@ scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) const {
} }
bool ResourceTracker::AddRefVar(int32 var_id) { 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); VarMap::iterator i = live_vars_.find(var_id);
if (i != live_vars_.end()) { if (i != live_vars_.end()) {
// We don't protect against overflow, since a plugin as malicious as to ref // We don't protect against overflow, since a plugin as malicious as to ref
...@@ -158,6 +194,8 @@ bool ResourceTracker::AddRefVar(int32 var_id) { ...@@ -158,6 +194,8 @@ bool ResourceTracker::AddRefVar(int32 var_id) {
} }
bool ResourceTracker::UnrefVar(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); VarMap::iterator i = live_vars_.find(var_id);
if (i != live_vars_.end()) { if (i != live_vars_.end()) {
if (!--i->second.second) if (!--i->second.second)
...@@ -184,7 +222,8 @@ PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) { ...@@ -184,7 +222,8 @@ PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) {
// Need to make sure the random number isn't a duplicate or 0. // Need to make sure the random number isn't a duplicate or 0.
PP_Instance new_instance; PP_Instance new_instance;
do { 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 || } while (!new_instance ||
instance_map_.find(new_instance) != instance_map_.end()); instance_map_.find(new_instance) != instance_map_.end());
instance_map_[new_instance] = instance; instance_map_[new_instance] = instance;
...@@ -192,6 +231,8 @@ PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) { ...@@ -192,6 +231,8 @@ PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) {
} }
void ResourceTracker::InstanceDeleted(PP_Instance 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 // Force release all plugin references to resources associated with the
// deleted instance. // deleted instance.
ResourceSet& resource_set = instance_to_resources_[instance]; ResourceSet& resource_set = instance_to_resources_[instance];
...@@ -215,6 +256,8 @@ void ResourceTracker::InstanceDeleted(PP_Instance instance) { ...@@ -215,6 +256,8 @@ void ResourceTracker::InstanceDeleted(PP_Instance instance) {
} }
PluginInstance* ResourceTracker::GetInstance(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); InstanceMap::iterator found = instance_map_.find(instance);
if (found == instance_map_.end()) if (found == instance_map_.end())
return NULL; return NULL;
...@@ -232,7 +275,8 @@ PP_Module ResourceTracker::AddModule(PluginModule* module) { ...@@ -232,7 +275,8 @@ PP_Module ResourceTracker::AddModule(PluginModule* module) {
// See AddInstance above. // See AddInstance above.
PP_Module new_module; PP_Module new_module;
do { 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 || } while (!new_module ||
module_map_.find(new_module) != module_map_.end()); module_map_.find(new_module) != module_map_.end());
module_map_[new_module] = module; module_map_[new_module] = module;
...@@ -240,6 +284,8 @@ PP_Module ResourceTracker::AddModule(PluginModule* module) { ...@@ -240,6 +284,8 @@ PP_Module ResourceTracker::AddModule(PluginModule* module) {
} }
void ResourceTracker::ModuleDeleted(PP_Module 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); ModuleMap::iterator found = module_map_.find(module);
if (found == module_map_.end()) { if (found == module_map_.end()) {
NOTREACHED(); NOTREACHED();
...@@ -249,6 +295,8 @@ void ResourceTracker::ModuleDeleted(PP_Module module) { ...@@ -249,6 +295,8 @@ void ResourceTracker::ModuleDeleted(PP_Module module) {
} }
PluginModule* ResourceTracker::GetModule(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); ModuleMap::iterator found = module_map_.find(module);
if (found == module_map_.end()) if (found == module_map_.end())
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment