[6] MediaPlayerPrivateMediaSourceAVFObjC re-entrant KVO during destruction
Severity: Medium | Component: WebCore platform media | 4193d2c
Severity가 Medium으로 평가된 이유는, KVO re-entrancy를 통해 이미 소멸된 m_logger에 접근하는 MediaPlayerPrivateMediaSourceAVFObjC의 teardown 중 UAF를 수정하는 fix이기 때문입니다. Attacker가 행사할 수 있는 영향력은 teardown 형태를 조작하는 수준에 그치며, 즉각적인 결과는 제어 가능한 read/write가 아닌 renderer crash입니다.
~MediaPlayerPrivateMediaSourceAVFObjC()의 맨 앞에서 모든 weak pointer를 revoke하여, member 소멸 도중 발생하는 re-entrant callback을 차단합니다. C++은 선언 역순으로 member를 소멸하므로, m_logger는 m_mediaSourcePrivate보다 먼저 소멸됩니다. m_mediaSourcePrivate의 destructor는 동기적으로 KVO notification을 발생시킬 수 있으며, 이 notification은 부분적으로 소멸된 객체에서 WeakPtr로 보호된 callback을 호출합니다. CanMakeWeakPtr base 클래스의 destructor는 모든 derived class member destructor가 완료된 후에야 실행됩니다. 이 시점까지 WeakPtr::get()은 여전히 null이 아닌 값을 반환하여, callback이 이미 소멸된 member에 접근하는 상황이 발생합니다.
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
MediaPlayerPrivateMediaSourceAVFObjC::~MediaPlayerPrivateMediaSourceAVFObjC()
{
ALWAYS_LOG(LOGIDENTIFIER);
+ // member 소멸 중 re-entrant callback을 방지합니다. 이 코드가 없으면
+ // m_mediaSourcePrivate 소멸 중 발생한 KVO notification이
+ // WeakPtr로 보호된 callback을 통해 부분적으로 소멸된 객체를
+ // 재진입합니다(예: error callback이 setNetworkState()를 호출하고,
+ // 이미 소멸된 m_logger에 접근하는 경우).
+ weakPtrFactory().revokeAll();
+
cancelPendingSeek();
m_seekTimer.stop();
dispatchToRendererQueue([](auto& renderer) {
renderer.pause();
});
}
Patch Details
Destructor 맨 앞에 weakPtrFactory().revokeAll() 한 줄이 추가되었습니다. 이 호출은 해당 객체를 가리키는 모든 WeakPtr를 무효화합니다. 이후 m_mediaSourcePrivate 같은 member가 소멸되는 과정에서 KVO notification이 발생하더라도, WeakPtr를 역참조하여 부분적으로 소멸된 인스턴스로 돌아오는 경로가 차단됩니다.
Teardown 중 re-entrant callback이 도달할 수 있는 member를 소멸하기 전에 weak reference를 무효화하지 않은 패턴.
Background
WebKit의 WeakPtr는 non-owning reference로, CanMakeWeakPtr CRTP base를 통해 대상 객체에 저장된 WeakPtrFactory가 backing storage 역할을 담당합니다. Factory가 revoke되거나 소멸된 이후에만 WeakPtr::get()은 null을 반환합니다. C++에서 derived class의 member는 선언 역순으로 소멸되며, 이후 base class destructor가 실행됩니다. Factory를 revoke하는 CanMakeWeakPtr의 destructor는 base destructor에 해당하므로, 모든 derived class member destructor가 완료된 후에야 실행됩니다. KVO(Key-Value Observing)는 Cocoa의 observer pattern으로, AVFoundation 객체는 등록된 observer에게 동기적으로 KVO notification을 전달합니다. MediaPlayerPrivateMediaSourceAVFObjC는 MediaSourcePrivateAVFObjC 타입의 m_mediaSourcePrivate와 Logger 참조인 m_logger를 보유합니다. setNetworkState()는 network 상태 변화를 처리하는 MediaPlayer의 표준 hook입니다. 이 구현에서는 m_logger를 통해 상태 변화를 로그에 기록합니다.
Analysis
이 destructor는 CanMakeWeakPtr의 기본 teardown 순서에 의존하고 있었습니다. WeakPtrFactory는 base destructor가 실행될 때만 revoke되는데, 이 시점은 모든 derived class member가 이미 소멸된 이후입니다. Member 소멸 과정, 특히 m_mediaSourcePrivate의 destructor가 실행되는 동안 AVFoundation은 동기적으로 KVO notification을 발생시킬 수 있습니다. 이 notification들은 WeakPtr로 보호된 callback을 통해 전달됩니다. 이 시점에는 factory가 아직 revoke되지 않은 상태이므로, WeakPtr::get()은 여전히 null이 아닌 pointer를 반환합니다.
Aaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaa Aa Aaaa Aaaaaa a Aaaa Aa Aa Aa Aaa Aa Aa Aaa Aaaaaaaaaaa Aaaa Aaa Aaaaaa Aaaaa Aaaaa Aaa Aaa Aa Aaaaaaaaaaaaaaaaaaaaaa Aaaaa Aa a Aaaaaaaaaaaaaaaaa Aaa Aaaaaa Aaaaaa a Aaaa Aaaaaaaaaa a Aaa Aa Aaaaaaaaaa Aaaaaaaa a Aaaaaaa Aaa Aaaaaa Aa Aaa Aa Aaaaaaaaa Aaaa Aaaaaaaaaa Aaaa Aaaa Aaa Aaa Aaaa Aa Aaa Aaaaaa
a Aaaaaaaaaaaaaa Aaaaa Aaaaaaa Aaaaaaaa a Aaaaaaaaaa Aaaaaaaa Aaaaaa Aaaaaaa Aaaaaaa Aa Aaa Aaaaaaaaa Aaa Aaaaa Aaa Aaaa Aaaa Aaaaaaaaa Aaaa Aaaa Aaaaaaaa Aaa Aaaa Aaaaaa Aaaaaaaaaaa Aaaaaaaaa Aaaa a Aa Aaaaa Aaaaaaaaaaaaaaaa Aaaaa Aaaaaa Aaa Aa Aaaaa Aaaaaaaaaaaaaaaaa Aaaa Aaa a Aaaaaa Aaaaaaaaaaa Aaaaa Aaaaaaaaa Aaa a Aa Aaa Aaaaa Aaaa Aaaaaaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaaaaaaaaaa Aaaaaaaaa Aaaa Aaaaa Aaaaaaaa Aa Aa Aaa Aa Aaaaaa Aa Aaaa Aa Aa Aaaaaaaa Aa Aaaaaaaaaaaa Aaaaaa Aaa Aaa Aa Aaa a Aaaaaaaaaa a Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaa Aaaaaaaaaaaa Aa Aaaaa Aaaaaaaaa Aaaa Aa Aaaa Aa Aaaa Aa Aa Aaaaaaa a Aaaaaaa Aa Aaa Aaaaaaa Aa Aaa Aaaaaaaaaaaa Aaaa Aaaaa
🔒The ownership and destructor-ordering implications of this bug, and whether the resulting crash can be escalated beyond a renderer DoS, are analyzed in depth.
더 확인하려면 구독해 주세요
Audit directions
a Aaaaaaaa Aaaaaaaaaaa Aaaaa Aaaaaaaaa Aaaa a Aa Aaaaaaaaaaaaaaaa Aa Aaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaa Aaaaa Aaaaaaaaa Aaaaaaaa Aaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaa a Aaaa Aaaaaaaaaaaaaaaaa Aaaaa Aaaa Aaaaa Aaaaaaaaa Aaa Aaaaaaaaaaa Aaaaaaa Aaaa Aaaa Aa Aaaaaa Aaaaaaaaaaa a Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aa Aaa Aaaaaa Aaaaa Aaaa Aaaaaa Aa a Aaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaa a Aaaaaaaaaaaaaaaaa Aaa Aa Aaaa Aaa Aaaaaa
a Aaaaa Aaaaaaaaaaaaaa Aaaa Aaaaaaa Aaa Aaaaaaaa Aa Aaa Aaaaa Aa Aaa Aaaaaa Aa Aaaaa a Aaa Aa Aaaaaaaa Aaaa Aa Aa Aa Aa Aaaa Aa Aaaaaa Aaaaaaaaaaaaaa Aaaaaa Aaaa Aaaaaa Aa Aaa Aaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa a Aaaaaaaaaa Aa Aa Aaa Aaa Aaaa Aaaaaaaaaaaaaa Aa Aaa Aaaaaa
a Aaaaaaaaa Aaaaaaaaaaaaa Aa Aaaaaaaaaaa Aa Aaa Aaaaaaaa Aa Aaa Aaaa Aaa Aaa a Aaaa Aaaaaaa Aaaaaa Aaaaaaaaa Aaa Aaa Aaa Aaaaaaa Aa Aaa Aaaaaaa Aa Aa Aaaaaaaaaaaaa Aaa Aaaaaa Aaaaaa
a Aaaaa a Aa a Aa Aaaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaa Aaaaa Aaaaaaaaaaaa Aaa a Aaaaa Aaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaa Aaaa Aaaaaaaaaaa Aaaaaa Aaaa Aaaaaaaaaa Aa Aa Aaa Aa Aaa Aaaaaaaaa Aaaaaa
🔒Multiple reusable audit patterns identified for finding sibling bugs across WebKit's Cocoa-observer-owning classes, with concrete starting points for variant discovery.
더 확인하려면 구독해 주세요