Coordinated Disclosure Timeline
- 2023-7-17: Reported issue to Chromium security team as issue 1465326
- 2023-08-02: Issue fixed in Chrome version 15.0.5790.170/.171
Summary
A type confusion in VisitFindNonDefaultConstructorOrConstruct
can be exploited by an attacker to gain code execution in Chrome’s renderer.
Product
Chromium
Tested Version
115.0.5790.98
Details
Type confusion in VisitFindNonDefaultConstructorOrConstruct of Maglev (GHSL-2023-180
)
In the maglev implementation of VisitFindNonDefaultConstructorOrConstruct
, if new_target
is a constant function, then the object will be constructed directly using the initial_map
of new_target
[1], [2].
void MaglevGraphBuilder::VisitFindNonDefaultConstructorOrConstruct() {
...
compiler::OptionalHeapObjectRef new_target_function =
TryGetConstant(new_target);
if (kind == FunctionKind::kDefaultBaseConstructor) {
ValueNode* object;
if (new_target_function && new_target_function->IsJSFunction()) {
object = BuildAllocateFastObject(
FastObject(new_target_function->AsJSFunction(), zone(),
broker()),
AllocationType::kYoung);
This, however, has a couple of problems. First, when passing new_target
to FastObject
, it does not check whether new_target
actually has an initial_map
. If new_target
is Proxy
, then it will try to use the initial_map
field [3] in the corresponding JSFunctionData
. For functions that do not have an initial_map
, this would be null and so this would only result in a NULL pointer dereference, rather than a security issue.
A more serious issue is that, BuildAllocateFastObject
does not check whether the constructor
field of initial_map
is the same as the target
function. The implementation in FastNewObject
bails out to Runtime::kNewObject
when target
and the constructor of new_target
differ [4], which calls JSObject::New
and then calls JSFunction::GetDerivedMap
to create the correct initial_map
[5] to create the object.
This causes the object created by the maglev implementation to have an inconsistent object layout and map, which causes type confusion.
- https://source.chromium.org/chromium/chromium/src/+/ecca8fb3876014c0c5f245df70d7e45e07711e69:v8/src/maglev/maglev-graph-builder.cc;l=5384;bpv=0
- https://source.chromium.org/chromium/chromium/src/+/ecca8fb3876014c0c5f245df70d7e45e07711e69:v8/src/maglev/maglev-graph-builder.cc;l=8024;bpv=0
- https://source.chromium.org/chromium/chromium/src/+/9fa308f2af6566a1feabf5bafef0240cfc6cce33:v8/src/compiler/heap-refs.cc;l=498
- https://source.chromium.org/chromium/chromium/src/+/9fa308f2af6566a1feabf5bafef0240cfc6cce33:v8/src/builtins/builtins-constructor-gen.cc;l=313;bpv=0;bpt=0
- https://source.chromium.org/chromium/chromium/src/+/a328097ef1d47f51e76917b80110863037f4f744:v8/src/objects/js-objects.cc;l=2392;bpv=1;bpt=0
Impact
Can be exploited to cause RCE in Chrome renderer
Resources
Blog post Getting RCE in Chrome with incomplete object initialization in the Maglev compiler.
CVE
- CVE-2023-4069
Credit
This issue was discovered and reported by GHSL team member @m-y-mo (Man Yue Mo).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2023-180
in any communication regarding this issue.