diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-19 04:52:14 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-19 04:52:14 +0000 |
commit | acd6854a1b0c51eeb0dc1042c3cbe95a38a84dcb (patch) | |
tree | 10da6f2598945147fca5ad7a94c00cd79ecc96de /ppapi | |
parent | f5a180a295979b2765e8d9493887fb2de99e2ef1 (diff) | |
download | chromium_src-acd6854a1b0c51eeb0dc1042c3cbe95a38a84dcb.zip chromium_src-acd6854a1b0c51eeb0dc1042c3cbe95a38a84dcb.tar.gz chromium_src-acd6854a1b0c51eeb0dc1042c3cbe95a38a84dcb.tar.bz2 |
CDM/PPAPI: Fix plugin-side ref-counting leak
This makes the reference counting such that we always pass a reference to the plugin (in-process and out-of-process).
This also reverts https://src.chromium.org/viewvc/chrome?view=rev&revision=173626, since this is a more correct/complete fix. Now, if we end up trying to send the same HostResource more than once to the plugin, we should fail a DCHECK with this upcoming CL:
https://codereview.chromium.org/11576024/
BUG=165717,166498,166341
Review URL: https://codereview.chromium.org/11593032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173855 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/cpp/private/content_decryptor_private.cc | 16 | ||||
-rw-r--r-- | ppapi/proxy/ppp_content_decryptor_private_proxy.cc | 91 | ||||
-rw-r--r-- | ppapi/shared_impl/scoped_pp_resource.cc | 3 |
3 files changed, 65 insertions, 45 deletions
diff --git a/ppapi/cpp/private/content_decryptor_private.cc b/ppapi/cpp/private/content_decryptor_private.cc index de9391b..4869094 100644 --- a/ppapi/cpp/private/content_decryptor_private.cc +++ b/ppapi/cpp/private/content_decryptor_private.cc @@ -99,13 +99,13 @@ void CancelKeyRequest(PP_Instance instance, PP_Var session_id_arg) { void Decrypt(PP_Instance instance, PP_Resource encrypted_resource, const PP_EncryptedBlockInfo* encrypted_block_info) { + pp::Buffer_Dev encrypted_block(encrypted_resource); + void* object = Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); if (!object) return; - pp::Buffer_Dev encrypted_block(encrypted_resource); - static_cast<ContentDecryptor_Private*>(object)->Decrypt( encrypted_block, *encrypted_block_info); @@ -115,13 +115,13 @@ void InitializeAudioDecoder( PP_Instance instance, const PP_AudioDecoderConfig* decoder_config, PP_Resource extra_data_resource) { + pp::Buffer_Dev extra_data_buffer(extra_data_resource); + void* object = Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); if (!object) return; - pp::Buffer_Dev extra_data_buffer(pp::PASS_REF, extra_data_resource); - static_cast<ContentDecryptor_Private*>(object)->InitializeAudioDecoder( *decoder_config, extra_data_buffer); @@ -131,13 +131,13 @@ void InitializeVideoDecoder( PP_Instance instance, const PP_VideoDecoderConfig* decoder_config, PP_Resource extra_data_resource) { + pp::Buffer_Dev extra_data_buffer(extra_data_resource); + void* object = Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); if (!object) return; - pp::Buffer_Dev extra_data_buffer(pp::PASS_REF, extra_data_resource); - static_cast<ContentDecryptor_Private*>(object)->InitializeVideoDecoder( *decoder_config, extra_data_buffer); @@ -170,13 +170,13 @@ void DecryptAndDecode(PP_Instance instance, PP_DecryptorStreamType decoder_type, PP_Resource encrypted_resource, const PP_EncryptedBlockInfo* encrypted_block_info) { + pp::Buffer_Dev encrypted_buffer(encrypted_resource); + void* object = Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); if (!object) return; - pp::Buffer_Dev encrypted_buffer(encrypted_resource); - static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode( decoder_type, encrypted_buffer, diff --git a/ppapi/proxy/ppp_content_decryptor_private_proxy.cc b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc index 7370849..5d98e0d 100644 --- a/ppapi/proxy/ppp_content_decryptor_private_proxy.cc +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc @@ -14,6 +14,7 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_buffer_proxy.h" #include "ppapi/proxy/serialized_var.h" +#include "ppapi/shared_impl/scoped_pp_resource.h" #include "ppapi/shared_impl/var_tracker.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_buffer_api.h" @@ -110,24 +111,6 @@ bool InitializePppDecryptorBuffer(PP_Instance instance, return true; } -PP_Resource GetOrAddProxyResource(const PPPDecryptor_Buffer& buffer) { - PluginResourceTracker* resource_tracker = - PluginGlobals::Get()->plugin_resource_tracker(); - PP_Resource resource = - resource_tracker->PluginResourceForHostResource(buffer.resource); - if (resource) { - // This buffer is already in the tracker. We don't need to create a plugin- - // side entry for it in the tracker; instead, just add a reference and - // return. - resource_tracker->AddRefResource(resource); - return resource; - } - // This is the first time we've seen this HostResource, so add it to the - // tracker. - return PPB_Buffer_Proxy::AddProxyResource(buffer.resource, buffer.handle, - buffer.size); -} - void GenerateKeyRequest(PP_Instance instance, PP_Var key_system, PP_Var type, @@ -204,6 +187,11 @@ void Decrypt(PP_Instance instance, return; } + // PluginResourceTracker in the plugin process assumes that resources that it + // tracks have been addrefed on behalf of the plugin at the renderer side. So + // we explicitly do it for |encryped_block| here. + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_block); + dispatcher->Send( new PpapiMsg_PPPContentDecryptor_Decrypt( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, @@ -237,6 +225,11 @@ void InitializeAudioDecoder( return; } + // PluginResourceTracker in the plugin process assumes that resources that it + // tracks have been addrefed on behalf of the plugin at the renderer side. So + // we explicitly do it for |extra_data_buffer| here. + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer); + dispatcher->Send( new PpapiMsg_PPPContentDecryptor_InitializeAudioDecoder( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, @@ -270,6 +263,11 @@ void InitializeVideoDecoder( return; } + // PluginResourceTracker in the plugin process assumes that resources that it + // tracks have been addrefed on behalf of the plugin at the renderer side. So + // we explicitly do it for |extra_data_buffer| here. + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer); + dispatcher->Send( new PpapiMsg_PPPContentDecryptor_InitializeVideoDecoder( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, @@ -338,6 +336,11 @@ void DecryptAndDecode(PP_Instance instance, return; } + // PluginResourceTracker in the plugin process assumes that resources that it + // tracks have been addrefed on behalf of the plugin at the renderer side. So + // we explicitly do it for |encrypted_buffer| here. + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_buffer); + dispatcher->Send( new PpapiMsg_PPPContentDecryptor_DecryptAndDecode( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, @@ -451,14 +454,18 @@ void PPP_ContentDecryptor_Private_Proxy::OnMsgDecrypt( PP_Instance instance, const PPPDecryptor_Buffer& encrypted_buffer, const std::string& serialized_block_info) { + ScopedPPResource plugin_resource( + ScopedPPResource::PassRef(), + PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource, + encrypted_buffer.handle, + encrypted_buffer.size)); if (ppp_decryptor_impl_) { - PP_Resource plugin_resource = GetOrAddProxyResource(encrypted_buffer); PP_EncryptedBlockInfo block_info; if (!DeserializeBlockInfo(serialized_block_info, &block_info)) return; CallWhileUnlocked(ppp_decryptor_impl_->Decrypt, instance, - plugin_resource, + plugin_resource.get(), const_cast<const PP_EncryptedBlockInfo*>(&block_info)); } } @@ -467,21 +474,25 @@ void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeAudioDecoder( PP_Instance instance, const std::string& serialized_decoder_config, const PPPDecryptor_Buffer& extra_data_buffer) { + ScopedPPResource plugin_resource; + if (extra_data_buffer.size > 0) { + plugin_resource = ScopedPPResource( + ScopedPPResource::PassRef(), + PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource, + extra_data_buffer.handle, + extra_data_buffer.size)); + } PP_AudioDecoderConfig decoder_config; if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config)) return; if (ppp_decryptor_impl_) { - PP_Resource plugin_resource = 0; - if (extra_data_buffer.size > 0) - plugin_resource = GetOrAddProxyResource(extra_data_buffer); - CallWhileUnlocked( ppp_decryptor_impl_->InitializeAudioDecoder, instance, const_cast<const PP_AudioDecoderConfig*>(&decoder_config), - plugin_resource); + plugin_resource.get()); } } @@ -489,21 +500,25 @@ void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeVideoDecoder( PP_Instance instance, const std::string& serialized_decoder_config, const PPPDecryptor_Buffer& extra_data_buffer) { + ScopedPPResource plugin_resource; + if (extra_data_buffer.resource.host_resource() != 0) { + plugin_resource = ScopedPPResource( + ScopedPPResource::PassRef(), + PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource, + extra_data_buffer.handle, + extra_data_buffer.size)); + } PP_VideoDecoderConfig decoder_config; if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config)) return; if (ppp_decryptor_impl_) { - PP_Resource plugin_resource = 0; - if (extra_data_buffer.resource.host_resource() != 0) - plugin_resource = GetOrAddProxyResource(extra_data_buffer); - CallWhileUnlocked( ppp_decryptor_impl_->InitializeVideoDecoder, instance, const_cast<const PP_VideoDecoderConfig*>(&decoder_config), - plugin_resource); + plugin_resource.get()); } } @@ -538,20 +553,24 @@ void PPP_ContentDecryptor_Private_Proxy::OnMsgDecryptAndDecode( PP_DecryptorStreamType decoder_type, const PPPDecryptor_Buffer& encrypted_buffer, const std::string& serialized_block_info) { + ScopedPPResource plugin_resource; + if (encrypted_buffer.resource.host_resource() != 0) { + plugin_resource = ScopedPPResource( + ScopedPPResource::PassRef(), + PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource, + encrypted_buffer.handle, + encrypted_buffer.size)); + } + if (ppp_decryptor_impl_) { PP_EncryptedBlockInfo block_info; if (!DeserializeBlockInfo(serialized_block_info, &block_info)) return; - - PP_Resource plugin_resource = 0; - if (encrypted_buffer.resource.host_resource() != 0) - plugin_resource = GetOrAddProxyResource(encrypted_buffer); - CallWhileUnlocked( ppp_decryptor_impl_->DecryptAndDecode, instance, decoder_type, - plugin_resource, + plugin_resource.get(), const_cast<const PP_EncryptedBlockInfo*>(&block_info)); } } diff --git a/ppapi/shared_impl/scoped_pp_resource.cc b/ppapi/shared_impl/scoped_pp_resource.cc index 8399208..45a1ad7 100644 --- a/ppapi/shared_impl/scoped_pp_resource.cc +++ b/ppapi/shared_impl/scoped_pp_resource.cc @@ -55,7 +55,8 @@ ScopedPPResource& ScopedPPResource::operator=( } PP_Resource ScopedPPResource::Release() { - CallRelease(); + // We do NOT call CallRelease, because we want to pass our reference to the + // caller. PP_Resource ret = id_; id_ = 0; |