flawopen.com/Teardowns/cve-2024-4947-chrome-v8-type-confusion
CVE-2024-4947: Chrome V8 Maglev Type Confusion
Maglev’s store bug let a crafted page trigger type confusion and code execution inside Chrome’s renderer sandbox. Google confirmed exploitation.[1], [3], [2], [8]
A module export is like a read-only label on a shared library shelf: JavaScript cannot replace it with an ordinary write. Maglev treated that forbidden write like a normal object-field update. The compiler then used the wrong layout rule for the object, so later code interpreted its data using the wrong type. Chrome fixed the compiler’s classification and store handling.[4], [2]
Core Concepts & Subsystem Terms
Maglev JIT- V8’s optimizing compiler that turns frequently executed JavaScript paths into machine code.[7]
Module namespace object- The object exposed by an ECMAScript module namespace. Its exported bindings are not ordinary writable object properties; a store must follow the specification’s special semantics.[4], [2]
PropertyAccessInfo- V8 compiler metadata describing what kind of property access is valid and how it should be handled.[2]
Framework mappings
- CWE reference for the weakness described in this guide: CWE-843
- CISA KEV — added 2024-05-20 — CVE-2024-4947
Root Cause Analysis
The Maglev graph builder could receive PropertyAccessInfo for a store to a module namespace export and route it through the ordinary data-field store path. Module namespace writes have special ECMAScript semantics: they fail or have no effect, rather than updating a normal property slot. The resulting field access used an invalid layout assumption and could corrupt object metadata, causing type confusion. The upstream fix has two parts: AccessInfo rejects stores to module namespace objects, and the Maglev builder switches on the access kind so a module export cannot fall through to TryBuildStoreField. Google’s advisory confirms code execution inside Chrome’s sandbox and exploitation in the wild; it does not establish a sandbox escape or host compromise from this CVE alone.[2], [4], [5], [3]
Step-by-Step Attack Flow
Source Code: Flaw vs. Secure Implementation
This excerpt is from V8 commit 164b664ce2b203515c05f28633bf0a10c4c7c32d. The full fix also makes AccessInfo return Invalid for any store to a module namespace object. The explicit switch prevents kModuleExport from being treated as a data field; it mirrors the upstream patch rather than a speculative runtime guard.[2], [5]
Source excerpt: src/maglev/maglev-graph-builder.cc
// BEFORE FIX — an accessor was handled specially, but every other access
// was assumed to be a data-field store. Module exports were not excluded.
if (access_info.IsFastAccessorConstant()) {
return TryBuildPropertySetterCall(access_info, receiver,
GetAccumulatorTagged());
}
DCHECK(access_info.IsDataField() || access_info.IsFastDataConstant());
ReduceResult result = TryBuildStoreField(access_info, receiver, access_mode);
if (result.IsDone()) {
RecordKnownProperty(receiver, name,
current_interpreter_frame_.accumulator(),
AccessInfoGuaranteedConst(access_info), access_mode);
return result;
}
return ReduceResult::Fail();
// AFTER FIX — only valid store kinds use the field-store path.
switch (access_info.kind()) {
case compiler::PropertyAccessInfo::kFastAccessorConstant:
return TryBuildPropertySetterCall(access_info, receiver,
GetAccumulatorTagged());
case compiler::PropertyAccessInfo::kDataField:
case compiler::PropertyAccessInfo::kFastDataConstant: {
ReduceResult result = TryBuildStoreField(access_info, receiver, access_mode);
if (result.IsDone()) {
RecordKnownProperty(receiver, name,
current_interpreter_frame_.accumulator(),
AccessInfoGuaranteedConst(access_info), access_mode);
return result;
}
return ReduceResult::Fail();
}
case compiler::PropertyAccessInfo::kInvalid:
case compiler::PropertyAccessInfo::kNotFound:
case compiler::PropertyAccessInfo::kDictionaryProtoDataConstant:
case compiler::PropertyAccessInfo::kDictionaryProtoAccessorConstant:
case compiler::PropertyAccessInfo::kModuleExport:
case compiler::PropertyAccessInfo::kStringLength:
UNREACHABLE();
}
Engineering & System Hardening Checklist
- ✓Update Chrome and Chromium-based browsers through each vendor’s supported release channel; confirm the deployed version includes the
CVE-2024-4947fix.[1], [3] - ✓For embedded Chromium or V8, track the upstream fix commit and verify the exact downstream branch contains both the AccessInfo and Maglev changes.[2]
- ✓In JIT compiler code, model ECMAScript module-namespace stores as invalid or specification-defined operations; do not lower them as ordinary mutable data-field writes.[2], [4]
- ✓Add compiler regression tests for stores to module namespace exports across interpreter, Maglev, and other optimizing tiers; assert that optimized execution preserves the specified failure/no-op behavior.[2], [4]
Sources
- Google Chrome Releases — Stable Channel Update, May 15, 2024 (in-the-wild exploit confirmation)
- V8 upstream fix — “Don’t build AccessInfo for storing to module exports”
- NVD — CVE-2024-4947, affected Chrome versions and impact
- ECMAScript specification — module namespace [[Set]] semantics
- Technical analysis — Maglev AccessInfo error for module namespaces
- MITRE CWE-843 — Access of Resource Using Incompatible Type
- V8 — Maglev optimizing JIT overview
- CISA Known Exploited Vulnerabilities — CVE-2024-4947