# CVE-2020-16009: Chrome Turbofan Type Confusion after Map Deprecation

V8 incorrectly deprecates a Map of double/tagged fields, so Turbofan skips deopt dependencies and JIT code transitions to a stale Map, yielding a type confusion RCE in Chrome.

- Payout: Real-world hack
- Severity: high
- Program: Google
- Analysis by: Samuel Groß
- Disclosed: 2020-11-02
- CVE: CVE-2020-16009
- Write-up quality: 8/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2020/CVE-2020-16009.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2020-16009
- Tags: area:os domain:browser impact:mass-exploit impact:rce kind:incident platform:project-zero sev:high tech:chromium technique:chained technique:source-review vuln:memory-corruption

**Target:** V8 JIT (Turbofan) Map transition/deprecation logic in Chrome
**Root cause:** Map::CanBeDeprecated assumes a Map with only Double/Tagged fields cannot be deprecated when FLAG_unbox_double_fields is false (pointer compression), so TransitionDependencyOffTheRecord installs no CodeDependency; V8 then accidentally deprecates such a Map, leaving JIT code that transitions to it un-deoptimized.
**Steps:**
1. JIT compile a function performing a transition from `map1{a:double}` to `map2{a:double,b:tagged}`; Turbofan assumes map2 can never be deprecated and installs no CodeDependency.
2. Trigger the bug to deprecate `map2`; the JIT code is not deoptimized.
3. In-place generalize `map1.a` to type `tagged`; `map2` is not generalized because it is deprecated.
4. Execute the JIT code: it transitions from `map1{a:tagged}` to `map2{a:double,b:whatever}`, producing a type confusion.
**How found:** Not stated; author notes it could be found via targeted fuzzing (hard to trigger) or manual audit of the known-complex, security-critical Map transition/deprecation code, a historically bug-prone area.
**Exploitation:** Used as a Chrome RCE stage towards Android in a zero-day exploit chain by the same actors as CVE-2020-15999/17087/16010/27930/27950/27932; full exploit flow still under analysis.
**Escalation:** Chained as the Chrome renderer RCE component of a multi-CVE zero-day operation against Android.
**Insight:** Map deprecation/transition invariants are a recurring V8 bug source: audit CanBeDeprecated-style predicates against flag combinations (e.g. pointer compression disabling unbox_double_fields) where a Map that 'cannot' be deprecated actually can, breaking JIT deopt dependencies.

