# Google Chrome display locking fuzzing

Fuzzing Chrome's rendersubtree attribute surfaced a heap use-after-free in blink::PaintLayer::CommonAncestor, crashing the renderer via a crafted HTML page.

- Payout: $5,000
- Severity: high
- Program: Google
- Credited: Pawel Wylecial
- Disclosed: 2020-01-08
- Write-up quality: 6/10
- Original: https://blog.redteam.pl/2020/04/google-chrome-display-locking-fuzzing.html
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-redteam-pl-2020-04-google-chrome-display-locking-fuzzing-html
- Tags: domain:browser impact:dos impact:rce kind:bounty platform:blog sev:high tech:chromium technique:fuzzing vuln:memory-corruption

**Target:** Blink rendering engine (rendersubtree attribute / PaintLayer)
**Root cause:** Removing a layout object while rendersubtree invalidation is in flight leaves a dangling PaintLayer; CompositingInputsRoot::Update then reads a freed PaintLayer via CommonAncestor.
**Steps:**
1. Enable #enable-display-locking flag in Chrome 80/81 dev.
2. Load the minimized HTML: an SVG with <animate onrepeat=boom2()> and <title id=fuzz2>, plus an <audio id=fuzz1>.
3. boom1 fires on SVG load: registers DOMSubtreeModified listener, sets fuzz1 rendersubtree=invisible and src=x.
4. boom2 fires on animate repeat: sets fuzz2 rendersubtree=invisible, calls document.caretRangeFromPoint(71,6), then appends fuzz1 to body.
5. LayoutObject::WillBeRemovedFromTree triggers PaintLayer::RemoveChild -> CompositingInputsRoot::Update -> PaintLayer::CommonAncestor reading freed memory (ASAN heap-use-after-free).
**How found:** Targeted new rendering-affecting Chrome features (display locking) as likely bug sources; added rendersubtree attribute and onrendersubtreeactivation handler to domato grammar and fuzzed, filtering out NPDs until a UAF crash appeared after the implementation changed to the attribute form.
**Insight:** Newly-spec'd rendering/layout features that mutate the paint tree are prime UAF territory; fuzz them by combining attribute toggles with DOM mutation events and layout queries like caretRangeFromPoint to force re-entrant layer removal.
