Bug 1250745 - Share GMP processes when doing unencrypted decoding. r=jwwang
authorChris Pearce <cpearce@mozilla.com>
Wed, 24 Feb 2016 14:38:56 +1300
changeset 321702 e66d7c87d51a978cb1327ea21eaf1a64a52af8a0
parent 321701 fe6d5add734ec6bf779ccbca267e33b4d26f63ff
child 321703 883d9427c0abcf17cbc47039f6337ecc36a5df31
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwwang
bugs1250745
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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)) {