Bug 1250745 - Share GMP processes when doing unencrypted decoding. r?jwwang draft
authorChris Pearce <cpearce@mozilla.com>
Wed, 24 Feb 2016 14:38:56 +1300
changeset 333985 e828724bc913f7a67d899f450d2f9a6f3cdef768
parent 333377 a9e33d8c48b5ca93ca1937eba4220f681a0f05ec
child 514789 e53322ccb1eb3a0b08ce3059fb61d8269fd7817c
push id11412
push usercpearce@mozilla.com
push dateWed, 24 Feb 2016 01:42:00 +0000
reviewersjwwang
bugs1250745
milestone47.0a1
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
dom/media/gmp/GMPServiceParent.cpp
dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp
dom/media/platforms/agnostic/gmp/GMPDecoderModule.h
dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
--- 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)) {