← All issues

[14] Remove all KVO observers before [m_objcObserver disconnect]

Severity: Medium | Component: WebCore AVFoundation media backend | f2a3aa2

Rated Medium because the observable effect is an MTE-detected stale weak-reference dereference inside Foundation's KVO hash tables during media-element teardown, reachable from any page that creates and destroys media elements; on non-MTE hardware the same access is a silent stale-pointer read into a freed slot.

Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

[[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver];
+
+ if (m_avPlayerItem) {
+ for (NSString *keyName in itemKVOProperties())
+ [m_avPlayerItem removeObserver:m_objcObserver.get() forKeyPath:keyName];
+ }
+ if (m_avPlayer) {
+ for (NSString *keyName in playerKVOProperties())
+ [m_avPlayer removeObserver:m_objcObserver.get() forKeyPath:keyName];
+ setShouldObserveTimeControlStatus(false);
+ }
+ for (AVPlayerItemTrack *track in m_cachedTracks.get())
+ [track removeObserver:m_objcObserver.get() forKeyPath:@"enabled"];
+
[m_objcObserver disconnect];

The cleanup sequence in MediaPlayerPrivateAVFoundationObjC::cancelLoad() reorders three KVO unregistration loops to run before [m_objcObserver disconnect]. The post-disconnect blocks that previously held these loops are simplified to nil the member references and clear m_cachedTracks.

Cocoa observer-lifecycle ordering violation: invalidating a KVO observer object before deregistering it from each observed object, leaving stale weak references in Foundation's KVO hash tables.

KVO requires deregistration via -removeObserver:forKeyPath: before either the observer or observed object is destroyed; Foundation maintains internal hash tables keyed by (observed, observer, keyPath). m_objcObserver is the Objective-C observer wrapper owned by MediaPlayerPrivateAVFoundationObjC; its disconnect method severs the wrapper's pointer back to the C++ owner so callbacks become no-ops. MTE (Memory Tagging Extension) is an ARMv8.5+ hardware feature that tags allocations and traps wrong-tag dereferences.

cancelLoad() invoked disconnect while the observer was still registered on m_avPlayerItem, m_avPlayer, and the tracks in m_cachedTracks. After disconnect ran, the subsequent removeObserver:forKeyPath: calls walked Foundation's KVO hash tables to find each (observed, observer, keyPath) triple — and dereferenced weak references to state that had been torn down. MTE flagged the resulting tag mismatch.

🔒

The ownership and lifecycle implications of this teardown ordering, and whether the resulting stale-reference access can be escalated beyond a crash, are explored in depth.

Subscribe to read more

🔒

Multiple reusable audit patterns identified across WebKit's Objective-C/C++ observer bridges, with concrete starting points for variant discovery.

Subscribe to read more