[15] ScrollerMac cross-thread UAF
Severity: High | Component: WebCore macOS scrolling | a926a67
Rated High because the diff fixes a deterministic cross-thread UAF: in-flight NSAnimation callbacks on the WebCore: Scrolling thread dereferenced a CheckedPtr<ScrollerMac> after the owning ScrollerPairMac had freed it on the main thread.
ScrollerMac was held in WebScrollbarPartAnimationMac and WebScrollerImpDelegateMac via CheckedPtr — non-owning, no cross-thread synchronization. Once ScrollerPairMac::~ScrollerPairMac ran on the main thread, the scrolling thread's [setCurrentProgress:] callback dereferenced freed memory.
Source/WebCore/page/scrolling/mac/ScrollerMac.h
-class ScrollerMac final : public CanMakeThreadSafeCheckedPtr<ScrollerMac> {
+class ScrollerMac final : public ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr<ScrollerMac, WTF::DestructionThread::Main> {
Source/WebCore/page/scrolling/mac/ScrollerMac.mm
@interface WebScrollbarPartAnimationMac : NSAnimation {
- CheckedPtr<WebCore::ScrollerMac> _scroller;
+ ThreadSafeWeakPtr<WebCore::ScrollerMac> _scroller;
- (void)setCurrentProgress:(NSAnimationProgress)progress
{
[super setCurrentProgress:progress];
+ RefPtr scroller = _scroller.get();
+ if (!scroller)
+ return;
Patch Details
ScrollerMac becomes ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr<ScrollerMac, DestructionThread::Main>. Delegates hold ThreadSafeWeakPtr<ScrollerMac> and promote to local RefPtr per callback. ScrollerPairMac stores its scrollers as Ref<ScrollerMac>. ~ScrollerMac() asserts isMainThread(). Null guards on m_pair cover lastKnownMousePositionInScrollbar, visibilityChanged, updateMinimumKnobLength for the window where a scrolling-thread RefPtr outlives ScrollerPairMac.
Non-owning cross-thread pointer to an object whose lifetime is bound to a different thread, with no synchronization between callback dispatch and destruction.
Background
ScrollerMac is the per-orientation scrollbar object in macOS WebCore; one vertical and one horizontal per ScrollerPairMac. WebScrollbarPartAnimationMac is an NSAnimation subclass whose setCurrentProgress: is invoked by AppKit's display-link from the WebCore: Scrolling thread. CheckedPtr<T> pairs with CanMakeCheckedPtr to assert at dereference that the pointee is still alive — debug-time UAF detection only, no cross-thread safety. ThreadSafeWeakPtr::get() returns a RefPtr<T> atomically. DestructionThread::Main routes the final delete to the main thread.
Analysis
CheckedPtr looks like "safe raw pointer" but its safety guarantee covers only same-thread access. Across threads it provides neither lifetime extension nor synchronization.
Aaa Aaa Aaaaa Aa Aaaaaaaa Aaa Aaaaaaaaa Aaaaaaaaaaa Aa Aaaaaa Aaa Aaaa Aaaaaa Aaa Aaaaaaaaaaaa Aaaa Aaaaaa Aa Aaaaaaaa Aaaaaa a Aaaaaaaaa Aaaaaaaaa Aaaa Aaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaaaaaaaaaaaaa Aaaaaaaa a Aaaaaaaaaaaaaaaa Aaaaaaaa Aaaaaaa Aaaaa a Aaaaaaaaaa Aaaaa Aaaaaaaaaaaa Aaaaaa Aaaaaa Aaaaaaa Aaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaaaaa Aaaaaa Aaa Aaaaaaaaaa Aaaaaaaa Aaa Aaaaaaaaa Aaaa a Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaa Aaa Aa Aaaaaaa Aa Aaa Aaaaaaaaa Aaaaaa Aaaaa Aaaaaaaaaaa Aaaaaaaa Aaa Aaaaaaaa Aaaaaaaa Aa Aaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaa Aaaaa Aaa Aaaaaaaaaaa
🔒Detailed cross-thread lifetime analysis covering the race window and reclamation feasibility for this scrolling-thread crash
Subscribe to read more
Audit directions
a Aaaaaaaaaaaaaaaaa Aa a Aaaaaaaaaaaa Aaaaaaaaaaaaaa Aaaa Aaaaaaaaaaa Aaaaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaa Aaaaaa Aaaaaa Aaaaaaaaaaaa Aaaaaa Aaa Aaa Aaaaaaaaaaa a Aaaaaa Aaaaaaaaaaaa Aaaaaa Aaaaaaaaa Aaaa Aaaaaa Aaa Aaaaaaaa Aaaa Aaaaaaaa Aaaaaaa Aaaaaaaa Aaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaaaaaaa
a Aaaaaaaaaaaaaaaa Aaaaaa Aa Aaaaaa Aaaaaaaaaa Aaaa Aaaaaaaaa Aaaaaaaaaa Aaaaaa Aaaaaaaaa Aa Aaaaaaaaaaaa Aaaa Aaaaaaaaaaaa Aaaaaaaa Aaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaaaaaaa Aaaaaaaaaa Aaaaaaaaaaa Aaaaaaaaaa Aaaaaa Aaaaaaa Aaaa Aaaa Aaaaaaaa Aaaaa Aaa Aaaaaaaaaaa Aaaaa Aaaaaaaaaaa Aa Aaaaa Aaaaaaaaaaaaa Aaaa a Aaaaaaaaaaaaaaa Aaaaaa Aaaaa a Aaaa Aaaaa Aaaaa Aaaaa Aaaaaaaaaa
a Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaa Aaaaaa Aaaaa Aaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaa
🔒Four reusable audit patterns identified for cross-thread lifetime bugs in Cocoa-bridging code, with concrete starting points across WebCore scrolling and platform layers
Subscribe to read more