TDZ hole-check elided across a branch
V8 elides a let/const TDZ (the-hole) check based on a linear view of execution, but a conditional branch — a switch jump table, a continue, a labeled break, or a lowered module-variable load — reaches the use without having run the earlier check, so an uninitialized “hole” sentinel flows into code that assumes a real value.
continue, conditional break, a merge of branches) must open its own hole-check elision scope rather than inherit the linear one.Mechanism
continue, a labeled block that can break, or the two arms of a branch that later merge) shares the enclosing linear scope instead of opening its own, the generator concludes a variable was already checked on a path where it was not. The subsequent access reads TheHole — a special oddball sentinel — as if it were an ordinary value.Fix shape
HoleCheckElisionScope / HoleCheckElisionMergeScope) around each conditionally-executed region and merge the hole-check bitmap only across paths that all performed the check; for lowered loads that can legitimately be the hole (module variables), teach the “can be the hole” predicate to return maybe for that opcode.CVEs in this pattern
1 component · V8| CVE | What | Component | Vendor | Severity | Month | |
|---|---|---|---|---|---|---|
| CVE-2026-10935 | LogicError in V8 | V8 | chrome | High | 2026-06 | 🔧 |
| CVE-2026-1862 | TypeConfusion in V8 | V8 | chrome | High | 2026-02 | 🔧 |
| CVE-2026-0900 | LogicError in V8 | V8 | chrome | High | 2026-01 | 🔧 |
| CVE-2025-12429 | LogicError in V8 | V8 | chrome | High | 2025-10 | 🔧 |
| CVE-2025-12433 | LogicError in V8 | V8 | chrome | High | 2025-10 | 🔧 |
| CVE-2025-6554 | TypeConfusion in V8 | V8 | chrome | High | 2025-06 | ⚠️ 🔧 |
| CVE-2025-0434 | OOB in V8 | V8 | chrome | High | 2025-01 | 🔧 |
Hunt for siblings
Hunt in the V8 bytecode generator and Maglev/Turbofan hole handling for elision that crosses a branch without re-scoping.
rg -n 'HoleCheckElision|hole_check_bitmap_|CanBeTheHoleValue|kTheHoleValue' src/interpreter src/maglev
weggli '{ _ $b; if (_) { _; } $v; }' src/interpreter # branch that skips a prior use of $v
Mitigations that would catch this class
- Model conditionally-executed and branch-merge regions as first-class scopes in the bytecode generator, never as an extension of the linear scope.
- Fuzz TDZ semantics against control-flow shapes: switch jump tables,
continue/breakto labels, module namespace imports, generators. - Treat every optimizer “this value cannot be the hole” fast-path as a checked assumption and enumerate the opcodes that can in fact yield the hole.