Bug 1250745 - Share GMP processes when doing unencrypted decoding. r?jwwang
But make sure that there's no way a GMP can track and report what a user watches using unencrypted decoding.
MozReview-Commit-ID: DljjYjcziRS
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -1217,17 +1217,21 @@ ReadSalt(nsIFile* aPath, nsACString& aOu
}
NS_IMETHODIMP
GeckoMediaPluginServiceParent::IsPersistentStorageAllowed(const nsACString& aNodeId,
bool* aOutAllowed)
{
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
NS_ENSURE_ARG(aOutAllowed);
- *aOutAllowed = mPersistentStorageAllowed.Get(aNodeId);
+ // We disallow persistent storage for the NodeId used for shared GMP
+ // decoding, to prevent GMP decoding being used to track what a user
+ // watches somehow.
+ *aOutAllowed = !aNodeId.Equals(SHARED_GMP_DECODING_NODE_ID) &&
+ mPersistentStorageAllowed.Get(aNodeId);
return NS_OK;
}
nsresult
GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
bool aInPrivateBrowsing,
--- a/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp
@@ -131,17 +131,17 @@ GMPAudioDecoder::InitTags(nsTArray<nsCSt
if (gmp.isSome()) {
aTags.AppendElement(gmp.value());
}
}
nsCString
GMPAudioDecoder::GetNodeId()
{
- return NS_LITERAL_CSTRING("");
+ return SHARED_GMP_DECODING_NODE_ID;
}
void
GMPAudioDecoder::GMPInitDone(GMPAudioDecoderProxy* aGMP)
{
if (!aGMP) {
mInitPromise.Reject(MediaDataDecoder::DecoderFailureReason::INIT_ERROR, __func__);
return;
--- a/dom/media/platforms/agnostic/gmp/GMPDecoderModule.h
+++ b/dom/media/platforms/agnostic/gmp/GMPDecoderModule.h
@@ -5,16 +5,29 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(GMPDecoderModule_h_)
#define GMPDecoderModule_h_
#include "PlatformDecoderModule.h"
#include "mozilla/Maybe.h"
+// The special NodeId we use when doing unencrypted decoding using the GMP's
+// decoder. This ensures that each GMP MediaDataDecoder we create doesn't
+// require spinning up a new process, but instead we run all instances of
+// GMP decoders in the one process, to reduce overhead.
+//
+// Note: GMP storage is isolated by NodeId, and non persistent for this
+// special NodeId, and the only way a GMP can communicate with the outside
+// world is through the EME GMP APIs, and we never run EME with this NodeID
+// (because NodeIds are random strings which can't contain the '-' character),
+// so there's no way a malicious GMP can harvest, store, and then report any
+// privacy sensitive data about what users are watching.
+#define SHARED_GMP_DECODING_NODE_ID NS_LITERAL_CSTRING("gmp-shared-decoding")
+
namespace mozilla {
class GMPDecoderModule : public PlatformDecoderModule {
public:
GMPDecoderModule();
virtual ~GMPDecoderModule();
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
@@ -113,17 +113,17 @@ GMPVideoDecoder::InitTags(nsTArray<nsCSt
if (gmp.isSome()) {
aTags.AppendElement(gmp.value());
}
}
nsCString
GMPVideoDecoder::GetNodeId()
{
- return NS_LITERAL_CSTRING("");
+ return SHARED_GMP_DECODING_NODE_ID;
}
GMPUniquePtr<GMPVideoEncodedFrame>
GMPVideoDecoder::CreateFrame(MediaRawData* aSample)
{
GMPVideoFrame* ftmp = nullptr;
GMPErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp);
if (GMP_FAILED(err)) {