summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 04:52:14 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 04:52:14 +0000
commitacd6854a1b0c51eeb0dc1042c3cbe95a38a84dcb (patch)
tree10da6f2598945147fca5ad7a94c00cd79ecc96de /ppapi
parentf5a180a295979b2765e8d9493887fb2de99e2ef1 (diff)
downloadchromium_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.cc16
-rw-r--r--ppapi/proxy/ppp_content_decryptor_private_proxy.cc91
-rw-r--r--ppapi/shared_impl/scoped_pp_resource.cc3
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;