Bug 1413480 - Check mCDM in ChromiumCDMChild::RecvXXX before dereferencing it. draft
authorJames Cheng <jacheng@mozilla.com>
Wed, 08 Nov 2017 15:44:34 +0800
changeset 694782 f49e45390e8acdd36e6df6c40a0deb3b4891c0ca
parent 694565 40df5dd35fdb7ce3652fe4448ac8961c075c928e
child 694783 09db8663bd92a186f5c136a5714eafc675242ffa
push id88246
push userbmo:jacheng@mozilla.com
push dateWed, 08 Nov 2017 08:36:31 +0000
bugs1413480
milestone58.0a1
Bug 1413480 - Check mCDM in ChromiumCDMChild::RecvXXX before dereferencing it. MozReview-Commit-ID: Dp4FOtZ8Yok
dom/media/gmp/ChromiumCDMChild.cpp
--- a/dom/media/gmp/ChromiumCDMChild.cpp
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -555,16 +555,17 @@ ChromiumCDMChild::RecvCreateSessionAndGe
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvLoadSession(const uint32_t& aPromiseId,
                                   const uint32_t& aSessionType,
                                   const nsCString& aSessionId)
 {
+  MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::RecvLoadSession(pid=%u, type=%u, sessionId=%s)",
           aPromiseId,
           aSessionType,
           aSessionId.get());
   if (mCDM) {
     mLoadSessionPromiseIds.AppendElement(aPromiseId);
     mCDM->LoadSession(aPromiseId,
                       static_cast<cdm::SessionType>(aSessionType),
@@ -732,16 +733,21 @@ ChromiumCDMChild::RecvDecrypt(const uint
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvInitializeVideoDecoder(
   const CDMVideoDecoderConfig& aConfig)
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   MOZ_ASSERT(!mDecoderInitialized);
+  if (!mCDM) {
+    GMP_LOG("ChromiumCDMChild::RecvInitializeVideoDecoder() no CDM");
+    Unused << SendOnDecoderInitDone(cdm::kInitializationError);
+    return IPC_OK();
+  }
   cdm::VideoDecoderConfig config;
   config.codec =
     static_cast<cdm::VideoDecoderConfig::VideoCodec>(aConfig.mCodec());
   config.profile =
     static_cast<cdm::VideoDecoderConfig::VideoCodecProfile>(aConfig.mProfile());
   config.format = static_cast<cdm::VideoFormat>(aConfig.mFormat());
   config.coded_size =
     mCodedSize = { aConfig.mImageWidth(), aConfig.mImageHeight() };
@@ -756,44 +762,50 @@ ChromiumCDMChild::RecvInitializeVideoDec
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDeinitializeVideoDecoder()
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::RecvDeinitializeVideoDecoder()");
   MOZ_ASSERT(mDecoderInitialized);
-  if (mDecoderInitialized) {
-    mDecoderInitialized = false;
+  if (mDecoderInitialized && mCDM) {
     mCDM->DeinitializeDecoder(cdm::kStreamTypeVideo);
   }
+  mDecoderInitialized = false;
   PurgeShmems();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvResetVideoDecoder()
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::RecvResetVideoDecoder()");
-  if (mDecoderInitialized) {
+  if (mDecoderInitialized && mCDM) {
     mCDM->ResetDecoder(cdm::kStreamTypeVideo);
   }
   Unused << SendResetVideoDecoderComplete();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer)
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
   GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() t=%" PRId64 ")",
           aBuffer.mTimestamp());
   MOZ_ASSERT(mDecoderInitialized);
 
+  if (!mCDM) {
+    GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() no CDM");
+    Unused << SendDecodeFailed(cdm::kDecodeError);
+    return IPC_OK();
+  }
+
   RefPtr<ChromiumCDMChild> self = this;
   auto autoDeallocateShmem = MakeScopeExit([&, self] {
     self->DeallocShmem(aBuffer.mData());
   });
 
   // The output frame may not have the same timestamp as the frame we put in.
   // We may need to input a number of frames before we receive output. The
   // CDM's decoder reorders to ensure frames output are in presentation order.
@@ -877,16 +889,21 @@ ChromiumCDMChild::ReturnOutput(WidevineV
     Unused << SendDecodedData(output, base->AsArrayBuffer()->ExtractBuffer());
   }
 }
 
 mozilla::ipc::IPCResult
 ChromiumCDMChild::RecvDrain()
 {
   MOZ_ASSERT(IsOnMessageLoopThread());
+  if (!mCDM) {
+    GMP_LOG("ChromiumCDMChild::RecvDrain() no CDM");
+    Unused << SendDrainComplete();
+    return IPC_OK();
+  }
   WidevineVideoFrame frame;
   cdm::InputBuffer sample;
   cdm::Status rv = mCDM->DecryptAndDecodeFrame(sample, &frame);
   GMP_LOG("ChromiumCDMChild::RecvDrain();  DecryptAndDecodeFrame() rv=%d", rv);
   if (rv == cdm::kSuccess) {
     MOZ_ASSERT(frame.Format() != cdm::kUnknownVideoFormat);
     ReturnOutput(frame);
   } else {