[13] WebAnimation null-deref via stale microtask backpointer
Severity: Medium | Component: WebCore Web Animations / KeyframeEffect | c7e7785
Rated Medium because the observable effect is a deterministic null deref inside the renderer (matching the ASan SEGV stack), and projection to a UAF read primitive depends on whether the backpointer observed freed memory rather than only a null transition — the analyst flags this as the load-bearing unverified architectural question.
Source/WebCore/animation/KeyframeEffect.cpp
void KeyframeEffect::applyPendingAcceleratedActions()
{
if (m_pendingAcceleratedActions.isEmpty())
return;
+ if (!animation())
+ return;
+
CheckedPtr renderer = this->renderer();
Patch Details
An early-return guard in KeyframeEffect::applyPendingAcceleratedActions() bails when animation() returns null, immediately after the existing empty-pending-actions check. A regression test schedules a pending accelerated action via wasRemovedFromStack() (mutating styles and reassigning animation.effect = new KeyframeEffect(null, ...)) and then nulls/replaces the effect's animation linkage before the asynchronous microtask fires.
Failure to extend the owned animation's lifetime across an asynchronous microtask boundary, leaving a backpointer that can be nulled (or freed) before the deferred work runs.
Background
KeyframeEffect represents a CSS/JS animation effect attached to a WebAnimation; each effect carries a backpointer to its owning WebAnimation (exposed via KeyframeEffect::animation()). applyPendingAcceleratedActions() is the deferred drain function that hands queued play/pause/seek operations to the compositor through the renderer. WebKit's event loop allows native code to enqueue lambdas; lambdas capturing only weak references do not extend the captured object's lifetime. Assigning animation.effect = new KeyframeEffect(null, ...) detaches the previous effect from its animation.
Analysis
applyPendingAcceleratedActions() was reachable via an asynchronous microtask scheduled from KeyframeEffect::wasRemovedFromStack(). wasRemovedFromStack itself holds a Ref/RefPtr to the animation across its synchronous body, but the lambda enqueued for the microtask captures only the KeyframeEffect (or a weak-reference path) — it does not extend the animation's lifetime.
Aaaaaaa Aaaaaaaaaa Aaa Aaaaaaaaaa Aaaaaa Aaa Aaaaaa Aaa Aaaaaa Aaaa Aaa Aaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaa Aaaa Aa Aaa Aaaa Aaa Aaaaaaaaa Aaaaaa Aaa Aaaa Aaaaa Aa Aaa Aaa Aaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaaaa Aaaa Aaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaa Aaa Aaaaa Aaaa Aaaa Aaaa Aaaaaaa Aaa Aaaa Aaaaaa Aaaaaaaaa Aaaaaaaaaaaa Aaa Aaaaaaaaa Aaa Aaaaa Aaaaaa Aaa Aaaaaaaaaa Aa Aaa Aaaaa Aaaaaaaa Aaaaaaaaaaaaa Aa Aaa Aaa Aa Aaaaaaaa Aaaaa Aaaaaaa a Aaaaaaaa Aaaaaaaaaa Aaa Aaaaa Aaaaaaa a Aaaaaaaaaaaaaaaaaaa Aa Aaa Aaaaaa Aa Aaaaaaa Aaaaaaaaa Aaaaa Aaaaaaaaaaaaa Aaaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaaaaa Aaaaaa Aaa Aaaaaaaaaa Aaaaaaaaa Aa Aaa Aaaaaaaaaaa Aaaaaaaa Aaaaa Aaaaaa Aaaaaa Aaaa Aaaa Aaaaa Aaaaaaa Aaaa Aaaaa Aaaaaaaa Aa a Aaa Aaaa Aaaaaaa Aaa Aaaaa Aaaaaaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaaaa
Aaaaaaaaa Aaaa Aaaaaaaaaaaaaa Aaaaaaa a Aaaaaaa Aaa Aaaaaaaaaaa Aa a Aaaaaaaaa Aaaaaa a Aaa Aa Aaaaaa Aaaaaaaaaa Aaa Aaaaaaa Aaaaaa Aaaaaaa Aaaa Aaa Aaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaa Aaaaa Aaaaaaaa a Aaa Aaaaaaaa Aaaa Aaa Aaaa Aaaaa Aaa Aaaa Aaaaaaaaa Aaaaaa Aaaa Aaaaaaaa Aaaaaaa Aa Aaa Aaaaaaaa Aaaaa Aaa Aaaa Aaaa Aaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaa Aaaaaaaaa Aa Aaa Aaaaaa
🔒The lifetime story behind this microtask-deferred crash, and whether the immediate null dereference can plausibly escalate, is examined in detail.
Subscribe to read more
Audit directions
a Aaaaaaaaaa Aaaa Aaaaaaaaa Aaaa a Aaaaaa Aa Aaaaaaa Aa Aaaaa Aaaaaaaaaaaaaaa Aaaaa Aaaaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaa Aaaaaaaa Aaaaaaa Aaaaa Aaaaaaaaaaaa Aaaaaa Aa Aaaaaaaa Aa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaaa Aa Aaaaaa Aaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaa Aaaaaaaaaaa
a Aaaaaaaaaaaaaaaaaa Aaaaaaa Aaaaaaa Aaaaaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaaaaa Aaaaaaaa Aaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaa Aa Aaaaa Aaaaa Aaaa Aaaa Aaaa Aaa Aaaaaaaaaaaa Aaaa Aaaaaaaa Aaaaa Aa Aaaaaaaaaaaaa Aaaaaaaaa
a Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaa Aaaaaaa Aa Aaa Aaaaaaaaaaa Aaaaaaa Aaaaaa Aaaaa Aaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaa Aaaa Aaaaaaaaa Aaaaaaaaaaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa
a Aaaaaaaaaaaaaaaaa Aaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaa a Aaa Aaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaaaaaaaaaaaa Aaaaaaa Aaaaa Aaa Aaaaaaaaaa Aaaaa Aaaaaa Aaaaaaaaaaa Aaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaa Aaaaa Aaa Aaaa Aaaaaaaaaaaa Aaaaa
🔒Several reusable audit patterns identified across Web Animations, with concrete entry points for variant discovery in the deferred-work and detach paths.
Subscribe to read more