fa43f625042ace39040e4caebdcc520fc8c2ba53 [M155] Reinsert PatternData into pattern map after reconstruction
Triage note: Identical to 67f6fef1e4, M155 cherry-pick: the unique_ptr<PatternData>& into pattern_map_ is invalidated when BuildPatternData() clears the map, then written through. Fix re-inserts via Set(). SVG patterns web-reachable.
The bug at a glance
Use-after-free in Blink SVG paint-server layout, reachable from any page that renders an SVG . A dangling reference into a LayoutSVGResourcePattern::pattern_map_ hash-table slot was written through after BuildPatternData re-entrantly cleared/rehashed the map. UAF-write in the renderer is a strong exploitation primitive; High. M155 release-branch cherry-pick (identical code to the M154 pick 67f6fef1e4).
Same iterator/reference-invalidation UAF as 67f6fef1e4: pattern_map_.insert(&client, nullptr).stored_value->value handed out a std::unique_ptr& into a hash-table slot, and BuildPatternData() can re-enter and clear/rehash pattern_map_, invalidating it. This is the M155 release-branch (refs/branch-heads/8059) cherry-pick of the same main fix dedbd3f9dee8.
Root cause
Identical to 67f6fef1e4: a std::unique_ptr& bound to pattern_map_.insert(…).stored_value->value was written through after BuildPatternData could clear/rehash pattern_map_, a UAF write into a freed/moved bucket. The fix does find() up front, builds into a local new_pattern_data, CHECK()s it, and re-inserts via pattern_map_.Set(&client, std::move(new_pattern_data)) after reconstruction, so no reference spans the re-entrant mutation.
Key code
layout_svg_resource_pattern.cc: don’t hold a map-slot reference across BuildPatternData; Set() afterward
auto iter = pattern_map_.find(&client);
PatternData* pattern_data =
(iter == pattern_map_.end() ? nullptr : iter->value.get());
if (pattern_data && pattern_data->paint_flags != paint_flags) {
pattern_data = nullptr;
}
if (!pattern_data) {
auto new_pattern_data = BuildPatternData(reference_box, paint_flags);
pattern_data = new_pattern_data.get();
CHECK(pattern_data);
pattern_map_.Set(&client, std::move(new_pattern_data));
pattern_data->paint_flags = paint_flags;
}
Patch walkthrough
third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc— The only code change; byte-identical to 67f6fef1e4. M155 branch cherry-pick of main commit dedbd3f9dee8 (Fixed: 565742179, branch bug 567399346).
Background
LayoutSVGResourcePattern / pattern_map_ — Blink layout object for an SVG paint server; pattern_map_ caches per-client std::unique_ptr.
WTF::HashMap AddResult / stored_value — insert() returns an AddResult whose stored_value points into the bucket; invalidated if the map is mutated before use.
BuildPatternData re-entrancy — Constructing pattern data can run layout/paint that clears pattern_map_, so a reference held across it may dangle.
Vulnerability window
- Main fix 2026-09-29 — dedbd3f9dee8 on main (CL 8464440), Fixed: 565742179.
- M155 cherry-pick — Cherry-picked to refs/branch-heads/8059 as fa43f62504 (CL 8485527, branch bug 567399346); identical code to the M154 pick 67f6fef1e4.
Proof of concept
No test or PoC ships in this cherry-pick diff. Conceptual trigger identical to 67f6fef1e4 (inferred): SVG painting where reconstruction re-enters and clears pattern_map_ while a reference into it is live. Web-reachable via ordinary SVG markup/CSS/script.
Exploitation
- Trigger — Paint an element using an SVG paint server and cause reconstruction to re-enter/clear pattern_map_ during BuildPatternData (inferred).
- Free / invalidate — The clear/rehash frees/moves the bucket the held reference pointed at (inferred).
- UAF write — Writing through the stale reference corrupts freed/reallocated heap; grooming could yield a controlled write (inferred).
Detection & hunting
For defenders and detection engineers:
- Reference/iterator into a WTF::HashMap held across a mutating call — Flag map-slot references kept live across non-trivial calls; re-look-up or Set() afterward.
- ASan heap-use-after-free WRITE in layout/svg paint-server code — Watch for UAF writes in LayoutSVGResourcePattern during pattern painting.
Audit directions
- Sibling SVG paint servers — Review LayoutSVGResourceGradient and other LayoutSVGResourceContainer subclasses for the same held-reference pattern.
- HashMap AddResult lifetime across callbacks — Grep Blink for .insert(…).stored_value held across functions that can mutate the same map.