High firefox Memory Corruption 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionMemory safety bugs present in Firefox 135, Thunderbird 135, Firefox ESR 128.7, and Thunderbird 128.7. Some of these bugs showed evidence of memory corruption and we presume that with enough effort some of these could have been exploited to run arbitrary code.
ComponentDOM
Bug ClassMemory Corruption
Tracker1922889
Fix commit787243d05493 (firefox) +24/-9
CISA KEVNot listed
CreditedJulien Wajsberg, the Mozilla Fuzzing Team
Disclosed2025-03-04

Changed Functions

FunctionChangeNotes
for
dom/media/ipc/MFCDMChild.cpp
modified

Files Changed

  • dom/media/ipc/MFCDMChild.cpp
  • dom/media/ipc/MFCDMChild.h
diff --git a/dom/media/ipc/MFCDMChild.cpp b/dom/media/ipc/MFCDMChild.cpp
index 4cbc7403970..feb61c82afa 100644
--- a/dom/media/ipc/MFCDMChild.cpp
+++ b/dom/media/ipc/MFCDMChild.cpp
@@ -24,6 +24,7 @@ namespace mozilla {
         self->mManagerThread, callsite,                                      \
         [self, promiseId, callsite](                                         \
             PMFCDMChild::method##Promise::ResolveOrRejectValue&& result) {   \
+          MutexAutoLock lock(self->mMutex);                                  \
           auto iter = self->mPendingGenericPromises.find(promiseId);         \
           if (iter == self->mPendingGenericPromises.end()) {                 \
             return;                                                          \
@@ -135,15 +136,18 @@ void MFCDMChild::Shutdown() {
           mRemoteRequest.DisconnectIfExists();
           mInitRequest.DisconnectIfExists();
 
-          for (auto& promise : mPendingSessionPromises) {
-            promise.second.RejectIfExists(NS_ERROR_ABORT, __func__);
-          }
-          mPendingSessionPromises.clear();
+          {
+            MutexAutoLock lock(mMutex);
+            for (auto& promise : mPendingSessionPromises) {
+              promise.second.RejectIfExists(NS_ERROR_ABORT, __func__);
+            }
+            mPendingSessionPromises.clear();
 
-          for (auto& promise : mPendingGenericPromises) {
-            promise.second.RejectIfExists(NS_ERROR_ABORT, __func__);
+            for (auto& promise : mPendingGenericPromises) {
+              promise.second.RejectIfExists(NS_ERROR_ABORT, __func__);
+            }
+            mPendingGenericPromises.clear();
           }
-          mPendingGenericPromises.clear();
 
           mRemotePromiseHolder.RejectIfExists(NS_ERROR_ABORT, __func__);
           mCapabilitiesPromiseHolder.RejectIfExists(NS_ERROR_ABORT, __func__);
@@ -274,6 +278,7 @@ RefPtr<MFCDMChild::SessionPromise> MFCDMChild::CreateSessionAndGenerateRequest(
                                                        __func__);
   }
 
+  MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPendingSessionPromises.find(aPromiseId) ==
              mPendingSessionPromises.end());
   mPendingSessionPromises.emplace(aPromiseId,
@@ -287,6 +292,7 @@ RefPtr<MFCDMChild::SessionPromise> MFCDMChild::CreateSessionAndGenerateRequest(
         SendCreateSessionAndGenerateRequest(params)->Then(
             mManagerThread, __func__,
             [self, aPromiseId, this](const MFCDMSessionResult& result) {
+              MutexAutoLock lock(mMutex);
               auto iter = mPendingSessionPromises.find(aPromiseId);
               if (iter == mPendingSessionPromises.end()) {
                 return;
@@ -303,6 +309,7 @@ RefPtr<MFCDMChild::SessionPromise> MFCDMChild::CreateSessionAndGenerateRequest(
             },
             [self, aPromiseId,
              this](const mozilla::ipc::ResponseRejectReason& aReason) {
+              MutexAutoLock lock(mMutex);
               auto iter = mPendingSessionPromises.find(aPromiseId);
               if (iter == mPendingSessionPromises.end()) {
                 return;
@@ -325,6 +332,7 @@ RefPtr<GenericPromise> MFCDMChild::LoadSession(
     return GenericPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
   }
 
+  MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPendingGenericPromises.find(aPromiseId) ==
              mPendingGenericPromises.end());
   mPendingGenericPromises.emplace(aPromiseId,
@@ -343,6 +351,7 @@ RefPtr<GenericPromise> MFCDMChild::UpdateSession(uint32_t aPromiseId,
     return GenericPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
   }
 
+  MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPendingGenericPromises.find(aPromiseId) ==
              mPendingGenericPromises.end());
   mPendingGenericPromises.emplace(aPromiseId,
@@ -361,6 +370,7 @@ RefPtr<GenericPromise> MFCDMChild::CloseSession(uint32_t aPromiseId,
     return GenericPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
   }
 
+  MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPendingGenericPromises.find(aPromiseId) ==
              mPendingGenericPromises.end());
   mPendingGenericPromises.emplace(aPromiseId,
@@ -378,6 +388,7 @@ RefPtr<GenericPromise> MFCDMChild::RemoveSession(uint32_t aPromiseId,
     return GenericPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
   }
 
+  MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPendingGenericPromises.find(aPromiseId) ==
              mPendingGenericPromises.end());
   mPendingGenericPromises.emplace(aPromiseId,
@@ -395,6 +406,7 @@ RefPtr<GenericPromise> MFCDMChild::SetServerCertificate(
     return GenericPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
   }
 
+  MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPendingGenericPromises.find(aPromiseId) ==
              mPendingGenericPromises.end());
   mPendingGenericPromises.emplace(aPromiseId,
@@ -412,6 +424,7 @@ RefPtr<GenericPromise> MFCDMChild::GetStatusForPolicy(
     return GenericPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
   }
 
+  MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mPendingGenericPromises.find(aPromiseId) ==
              mPendingGenericPromises.end());
   mPendingGenericPromises.emplace(aPromiseId,
diff --git a/dom/media/ipc/MFCDMChild.h b/dom/media/ipc/MFCDMChild.h
index 2f36b9df0d1..fa83dc35a26 100644
--- a/dom/media/ipc/MFCDMChild.h
+++ b/dom/media/ipc/MFCDMChild.h
@@ -141,11 +141,13 @@ class MFCDMChild final : public PMFCDMChild {
   MozPromiseHolder<GenericPromise> mRemoveSessionPromiseHolder;
   MozPromiseRequestHolder<RemoveSessionPromise> mRemoveSessionRequest;
 
+  mutable Mutex mMutex{"MFCDMChild"};
+
   std::unordered_map<uint32_t, MozPromiseHolder<SessionPromise>>
-      mPendingSessionPromises;
+      mPendingSessionPromises MOZ_GUARDED_BY(mMutex);
 
   std::unordered_map<uint32_t, MozPromiseHolder<GenericPromise>>
-      mPendingGenericPromises;
+      mPendingGenericPromises MOZ_GUARDED_BY(mMutex);
 
   RefPtr<WMFCDMProxyCallback> mProxyCallback;
 };
Loading diff…