diff options
author | tomfinegan@chromium.org <tomfinegan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-06 08:31:29 +0000 |
---|---|---|
committer | tomfinegan@chromium.org <tomfinegan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-06 08:31:29 +0000 |
commit | e2e1780fdad1e978712607ac987748ab1ddfd616 (patch) | |
tree | 413483e818a19d721dfed5c25505d6367920a433 /ppapi | |
parent | e4f159014d36bb7ec346118ffd9f6c2447433801 (diff) | |
download | chromium_src-e2e1780fdad1e978712607ac987748ab1ddfd616.zip chromium_src-e2e1780fdad1e978712607ac987748ab1ddfd616.tar.gz chromium_src-e2e1780fdad1e978712607ac987748ab1ddfd616.tar.bz2 |
Fix resource leaks in CDM implementation.
Two fixes:
1) Add a PassRef constructor to pp::Buffer_Dev to deal with reference counting
issues related to passing PP_Resources across the IPC proxy, and use it to
avoid adding unnecessary references on PP_Resources.
2) Use the PassRef ScopedPPResource contructor in PluginInstance::Decrypt to
avoid added an unnecessary reference on the buffer resource before it's
passed to the plugin interface code.
BUG=146200
TEST=PPB_Testing_Dev::GetLiveObjectsForInstance shows a stable live
object count.
Review URL: https://chromiumcodereview.appspot.com/10909068
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155145 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/cpp/dev/buffer_dev.cc | 5 | ||||
-rw-r--r-- | ppapi/cpp/dev/buffer_dev.h | 4 | ||||
-rw-r--r-- | ppapi/cpp/private/content_decryptor_private.cc | 4 | ||||
-rw-r--r-- | ppapi/proxy/ppp_content_decryptor_private_proxy.cc | 31 |
4 files changed, 34 insertions, 10 deletions
diff --git a/ppapi/cpp/dev/buffer_dev.cc b/ppapi/cpp/dev/buffer_dev.cc index 7994be2..aca7b1b 100644 --- a/ppapi/cpp/dev/buffer_dev.cc +++ b/ppapi/cpp/dev/buffer_dev.cc @@ -43,6 +43,11 @@ Buffer_Dev::Buffer_Dev(const InstanceHandle& instance, uint32_t size) Init(); } +Buffer_Dev::Buffer_Dev(PassRef, PP_Resource resource) + : Resource(PassRef(), resource) { + Init(); +} + Buffer_Dev::~Buffer_Dev() { get_interface<PPB_Buffer_Dev>()->Unmap(pp_resource()); } diff --git a/ppapi/cpp/dev/buffer_dev.h b/ppapi/cpp/dev/buffer_dev.h index da89cba..d82f92d 100644 --- a/ppapi/cpp/dev/buffer_dev.h +++ b/ppapi/cpp/dev/buffer_dev.h @@ -22,6 +22,10 @@ class Buffer_Dev : public Resource { // resulting object will be is_null() if either Create() or Map() fails. Buffer_Dev(const InstanceHandle& instance, uint32_t size); + // Constructor used when the buffer resource already has a reference count + // assigned. No additional reference is taken. + Buffer_Dev(PassRef, PP_Resource resource); + // Unmap the underlying shared memory. virtual ~Buffer_Dev(); diff --git a/ppapi/cpp/private/content_decryptor_private.cc b/ppapi/cpp/private/content_decryptor_private.cc index 633215a..6df9c2d 100644 --- a/ppapi/cpp/private/content_decryptor_private.cc +++ b/ppapi/cpp/private/content_decryptor_private.cc @@ -101,7 +101,7 @@ PP_Bool Decrypt(PP_Instance instance, if (!object) return PP_FALSE; - pp::Buffer_Dev encrypted_block(encrypted_resource); + pp::Buffer_Dev encrypted_block(pp::PassRef(), encrypted_resource); return PP_FromBool( static_cast<ContentDecryptor_Private*>(object)->Decrypt( @@ -117,7 +117,7 @@ PP_Bool DecryptAndDecode(PP_Instance instance, if (!object) return PP_FALSE; - pp::Buffer_Dev encrypted_block(encrypted_resource); + pp::Buffer_Dev encrypted_block(pp::PassRef(), encrypted_resource); return PP_FromBool( static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode( diff --git a/ppapi/proxy/ppp_content_decryptor_private_proxy.cc b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc index fe6a928..5314939 100644 --- a/ppapi/proxy/ppp_content_decryptor_private_proxy.cc +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc @@ -75,6 +75,22 @@ PP_Var ExtractReceivedVarAndAddRef(Dispatcher* dispatcher, return var; } +// Increments the reference count on |resource| to ensure that it remains valid +// until the plugin receives the resource within the asynchronous message sent +// from the proxy. The plugin side takes ownership of that reference. Returns +// PP_TRUE when the reference is successfully added, PP_FALSE otherwise. +PP_Bool AddRefResourceForPlugin(HostDispatcher* dispatcher, + PP_Resource resource) { + const PPB_Core* core = static_cast<const PPB_Core*>( + dispatcher->local_get_interface()(PPB_CORE_INTERFACE)); + if (!core) { + NOTREACHED(); + return PP_FALSE; + } + core->AddRefResource(resource); + return PP_TRUE; +} + PP_Bool GenerateKeyRequest(PP_Instance instance, PP_Var key_system, PP_Var init_data) { @@ -133,18 +149,12 @@ PP_Bool Decrypt(PP_Instance instance, NOTREACHED(); return PP_FALSE; } - const PPB_Core* core = static_cast<const PPB_Core*>( - dispatcher->local_get_interface()(PPB_CORE_INTERFACE)); - if (!core) { + + if (!AddRefResourceForPlugin(dispatcher, encrypted_block)) { NOTREACHED(); return PP_FALSE; } - // We need to take a ref on the resource now. The browser may drop - // references once we return from here, but we're sending an asynchronous - // message. The plugin side takes ownership of that reference. - core->AddRefResource(encrypted_block); - HostResource host_resource; host_resource.SetHostResource(instance, encrypted_block); @@ -184,6 +194,11 @@ PP_Bool DecryptAndDecode(PP_Instance instance, return PP_FALSE; } + if (!AddRefResourceForPlugin(dispatcher, encrypted_block)) { + NOTREACHED(); + return PP_FALSE; + } + HostResource host_resource; host_resource.SetHostResource(instance, encrypted_block); |