# CVE-2020-6418: Chrome incorrect side-effect modelling issue in Turbofan leading to type confusions

Turbofan's InferReceiverMapsUnsafe failed to mark kJSCreate as side-effecting, letting a Proxy in Reflect.construct mutate array element kinds and cause type confusion in Chrome.

- Payout: Real-world hack
- Severity: high
- Program: Google Chrome
- Credited: Samuel Groß and Sergei Glazunov, Project Zero (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2020-08-05)
- Disclosed: 2020-02-24
- CVE: CVE-2020-6418
- Write-up quality: 8/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2020/CVE-2020-6418.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2020-6418
- Tags: domain:browser impact:rce kind:incident platform:project-zero sev:high tech:chromium technique:chained technique:source-review vuln:memory-corruption

**Target:** V8 JIT compiler (Turbofan) in Chrome
**Root cause:** InferReceiverMapsUnsafe special-cases kJSCreate and, when the object isn't the kJSCreate output, continues the effect-chain walk without marking the inferred maps unreliable, though kJSCreate can trigger side effects (e.g. Proxy in Reflect.construct).
**Steps:**
1. Build a function that inlines Array.prototype.pop via `Array.prototype.pop.call(array)` inside a constructor invoked by `Reflect.construct(constructor, arguments, new_target)`.
2. Warm up ~20000 iterations with a plain function as new_target so Turbofan inlines pop and infers the array's map as reliable.
3. Trigger with a Proxy whose `get` handler writes `array[4] = 1.1`, changing elements kind from SMI to Double during the unexpected side effect.
4. Inlined pop then reads the array with the stale SMI map, returning a tagged pointer where a double is expected (or vice versa), yielding a type confusion.
5. Use the confusion to build fakeobj: treat an arbitrary value as an object pointer, construct a fake typed array, and overwrite a compiled WebAssembly function's machine code with shellcode.
**How found:** Project Zero notes JIT side-effect bugs rarely crash under generic fuzzing, so the bug was likely found via manual code analysis of the security-critical InferReceiverMapsUnsafe type-inference function, looking for missing side-effect modelling.
**Exploitation:** Attacker triggers the type confusion to obtain a fakeobj primitive, fabricates a fake typed array for arbitrary read/write, then overwrites the code of a JIT-compiled WebAssembly function with shellcode to execute arbitrary code in the renderer.
**Escalation:** Chained with Windows 0-days CVE-2020-0938, CVE-2020-1020, CVE-2020-1027 and Android n-days in a watering hole attack to escape the sandbox.
**Insight:** When auditing JIT type inference, check every special-cased node in effect-chain walks (like kJSCreate) for whether it can have side effects that invalidate inferred maps; a node correctly flagged as side-effecting upstream can still be mishandled by a consumer that special-cases it and skips the reliability check.
