High chrome UAF 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in SVG
DescriptionUse after free in SVG
ComponentSVG
Bug ClassUAF
Tracker574791952
Fix commit270d5d328add (chromium/src) +3/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-10-27

Background

SVG SMIL animation
<animate>, <set>, <animateTransform>, etc. are “timed elements” that schedule themselves on an SVG time container (the document timeline) to drive animations.
`SVGSMILElement`
the Blink base class (third_party/blink/renderer/core/svg/animation/svg_smil_element.cc) for these timed elements; it manages scheduling, target-element resolution, and event/condition references. It is an Oilpan GarbageCollected object referenced via Member<>/raw references from the time container.
`<use>` shadow tree
<svg:use> instantiates a referenced subtree as a shadow (instance) tree. Instance-tree nodes are clones and are not supposed to participate independently in document machinery such as the animation timeline.
`InUseShadowTree()`
predicate that is true when the element lives inside a <use>-generated shadow tree.
The modified method
the removal/disconnection path that runs ClearResourceAndEventBaseReferences() and DisconnectConditions(), then decides, via isConnected(), whether to detach the element from the timeline and clear its target.

Root Cause Analysis

When a timed element is removed/disconnected, the method clears its resource and event-base references and disconnects its conditions, then checks if (!isConnected()) to decide whether to also reset the target element and bail out (i.e., stop participating in the timeline). The invariant the code assumed was: a timed element is either genuinely connected to the document (and should be scheduled) or not connected (and should be treated as absent). That missed a third state — a timed element that has been inserted into a <use> shadow tree. The commit notes this is “currently possible via a cloned event handler”: a cloned handler path can land a live SVGSMILElement inside a <use> instance tree where isConnected() is true, so the old code left it scheduled on the timeline and keeping a target element. Instance-tree nodes have a distinct, controller-managed lifetime; a timed element still registered with the time container (or still holding a target reference) after its instance subtree is rebuilt/destroyed leaves the timeline holding a dangling reference to a freed Oilpan object — the use-after-free the advisory reports.

The one-line fix changes the guard to if (!isConnected() || InUseShadowTree()), so an element in a <use> shadow tree takes the same path as a disconnected one: SetTargetElement(nullptr) and early return, making it inert on the timeline exactly as the commit title says (“Make timed elements inserted into <use> shadow trees inert”). Because these are Oilpan GarbageCollected objects, the specific freed object and the dangling edge (time-container scheduling list vs. target Member) are not shown by this diff and are (inferred) from the advisory’s UAF label and the fix’s intent; what the diff proves is that an in-<use>-shadow timed element was wrongly kept active.

Key insight
The disconnection guard only distinguished connected vs. disconnected, so a timed element smuggled into a <use> shadow tree (via a cloned event handler) stayed scheduled on the timeline, leaving a dangling reference once its instance tree was torn down.

Attack Path

  1. Craft SVG Attacker builds an SVG with a <use> referencing a subtree and an event handler that, when cloned into the instance tree, carries/creates a SMIL timed element. (cloned-event-handler mechanism per commit)
  2. Insertion into instance tree The clone path places the live SVGSMILElement inside the <use> shadow tree where isConnected() is true. (inferred specifics)
  3. Stays scheduled Because the old guard only checked isConnected(), the element remains registered on the time container and retains a target element.
  4. Instance teardown The <use> instance tree is rebuilt or removed, freeing the instance nodes while the timeline still references the timed element. (freed-memory inferred)
  5. Primitive The timeline dereferences the dangling timed element during scheduling, a renderer use-after-free. (escalation inferred)

Impact Assessment

Runs in the renderer process and is fully web-reachable via a crafted SVG document with <use> and animation elements; no special privilege. The advisory’s UAF classification is consistent with the fix (making an improperly-scheduled instance-tree element inert). The diff substantiates the logic gap (missing InUseShadowTree() case) directly; the freed object, the exact dangling pointer, and any escalation to RCE are (inferred) since the one-line guard does not expose the sink. If the inferred dangling-timeline-reference is as described, this is a strong, remotely-triggerable UAF; at minimum the diff proves a lifetime/scheduling invariant was violated.

Files Changed

  • third_party/blink/renderer/core/svg/animation/svg_smil_element.cc

Audit Directions

  • `isConnected()`-only lifetime checks in SVG
    Search core/svg for places that gate scheduling/registration solely on isConnected() without excluding <use> instance trees; the same third-state gap may exist elsewhere (e.g., resource references, event bases).
  • `<use>` instance-tree participation
    Review which node types can end up inside a <use> shadow tree via cloned handlers/attributes and whether any register with document-level managers (timeline, resources, observers).
  • Time-container registration/unregistration
    Verify every path that adds a timed element to the time container has a matching removal when the element becomes inert, including instance-tree rebuilds.
From 270d5d328addf47356621fb27f93873d5cd5e96f Mon Sep 17 00:00:00 2001
From: Fredrik Söderquist <fs@opera.com>
Date: Mon, 19 Oct 2026 13:53:59 -0700
Subject: [PATCH] Make timed elements inserted into <use> shadow trees inert

If timed elements somehow make it into a <use> shadow tree, they should
not be scheduled on the timeline. Treat them the same as if they were
not in the document at all.

Fixed: 574791952
Change-Id: I0a88c3a352139fbe2b93f4634794de929826ff47
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8610829
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Auto-Submit: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/main@{#1722305}
---
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index f64f6064..fe85e6a 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -328,7 +328,9 @@
   ClearResourceAndEventBaseReferences();
   DisconnectConditions();
 
-  if (!isConnected()) {
+  // Ignore timed elements that are inserted into a <use> shadow tree. This is
+  // currently possible via a cloned event handler.
+  if (!isConnected() || InUseShadowTree()) {
     // Reset the target element if we are no longer in the document.
     SetTargetElement(nullptr);
     return;
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.