CVE-2024-54551

Overview

Advisory: Apple Security Advisory

Impact:

Description: Processing web content may lead to a denial-of-service

Researchers: ajajfxhj

Attribute Value
CVE CVE-2024-54551
Bugzilla 275117
Component WebCore
Bug Class LogicError
Severity medium
Commit e73dfba967ee3b8d…
Advisory Apple Advisory

Root Cause Analysis

The issue was addressed with improved memory handling.

Files Changed

Source Files

  • Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp
  • Source/WebCore/platform/audio/PlatformMediaSessionManager.h
  • Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm

Patch Preview

diff --git a/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp b/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp
index 81dc8e026141..999b08a1e845 100644
--- a/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp
+++ b/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp
@@ -117,6 +117,11 @@ PlatformMediaSessionManager::PlatformMediaSessionManager()
 {
 }
 
+PlatformMediaSessionManager::~PlatformMediaSessionManager()
+{
+    m_taskGroup.cancel();
+}
+
 static inline unsigned indexFromMediaType(PlatformMediaSession::MediaType type)
 {
     return static_cast<unsigned>(type);
@@ -492,7 +497,7 @@ void PlatformMediaSessionManager::sessionCanProduceAudioChanged()
         return;
 
     m_alreadyScheduledSessionStatedUpdate = true;
-    callOnMainThread([this] {
+    enqueueTaskOnMainThread([this] {
         m_alreadyScheduledSessionStatedUpdate = false;
         maybeActivateAudioSession();
         updateSessionState();
@@ -656,7 +661,7 @@ void PlatformMediaSessionManager::scheduleUpdateSessionState()
         return;
 
     m_hasScheduledSessionStateUpdate = true;
-    callOnMainThread([this] {
+    enqueueTaskOnMainThread([this] {
         updateSessionState();
         m_hasScheduledSessionStateUpdate = false;
     });
@@ -903,6 +908,13 @@ bool PlatformMediaSessionManager::hasActiveNowPlayingSessionInGroup(MediaSession
     return hasActiveNowPlayingSession;
 }
 
+void PlatformMediaSessionManager::enqueueTaskOnMainThread(Function<void()>&& task)
+{
+    callOnMainThread(CancellableTask(m_taskGroup, [task = WTFMove(task)] () mutable {
+        task();
+    }));
+}
+
 #if !RELEASE_LOG_DISABLED
 WTFLogChannel& PlatformMediaSessionManager::logChannel() const
 {
diff --git a/Source/WebCore/platform/audio/PlatformMediaSessionManager.h b/Source/WebCore/platform/audio/PlatformMediaSessionManager.h
index 527d12fff117..e5dd5c0f9503 100644
--- a/Source/WebCore/platform/audio/PlatformMediaSessionManager.h
+++ b/Source/WebCore/platform/audio/PlatformMediaSessionManager.h
@@ -31,6 +31,7 @@
 #include "RemoteCommandListener.h"
 #include "Timer.h"
 #include <wtf/AggregateLogger.h>
+#include <wtf/CancellableTask.h>
 #include <wtf/Vector.h>
 #include <wtf/WeakHashSet.h>
 #include <wtf/WeakPtr.h>
@@ -83,7 +84,7 @@ class PlatformMediaSessionManager
     WEBCORE_EXPORT static void setMediaCapabilityGrantsEnabled(bool);
 #endif
 
-    virtual ~PlatformMediaSessionManager() = default;
+    virtual ~PlatformMediaSessionManager();
 
     virtual void scheduleSessionStatusUpdate() { }
 
@@ -227,6 +228,7 @@ class PlatformMediaSessionManager
     std::optional<bool> supportsSpatialAudioPlayback() { return m_supportsSpatialAudioPlayback; }
 
     void nowPlayingMetadataChanged(const NowPlayingMetadata&);
+    void enqueueTaskOnMainThread(Function<void()>&&);
 
 private:
     friend class Internals;
@@ -260,6 +262,7 @@ class PlatformMediaSessionManager
     bool m_hasScheduledSessionStateUpdate { false };
 
     WeakHashSet<NowPlayingMetadataObserver> m_nowPlayingMetadataObservers;
+    TaskCancellationGroup m_taskGroup;
 
 #if ENABLE(WEBM_FORMAT_READER)
     static bool m_webMFormatReaderEnabled;
diff --git a/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm b/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm
index 3c4000a571a1..d50c37334a7e 100644
--- a/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm
+++ b/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm
@@ -270,7 +270,7 @@
 
 void MediaSessionManagerCocoa::scheduleSessionStatusUpdate()
 {
-    callOnMainThread([this] () mutable {
+    enqueueTaskOnMainThread([this] () mutable {
         m_nowPlayingManager->setSupportsSeeking(computeSupportsSeeking());
         updateNowPlayingInfo();
 
@@ -329,7 +329,7 @@
 {