Chrome · V8
CVE-2026-5871
Type Confusion in V8
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
src/maglev/maglev-graph-builder.cc
Patch
From c1e78b455e3224e286914b5ac241fbea064cb51d Mon Sep 17 00:00:00 2001 From: Darius Mercadier <[email protected]> Date: Thu, 26 Mar 2026 10:36:49 +0100 Subject: [PATCH] [maglev] Account for phi smi type widening in BuildCheckHeapObject Bug: 495679730 Change-Id: Icecb844aac559f2de15ac4ec3065ab1df6fb0585 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7701796 Reviewed-by: Leszek Swirski <[email protected]> Commit-Queue: Leszek Swirski <[email protected]> Auto-Submit: Darius Mercadier <[email protected]> Cr-Commit-Position: refs/heads/main@{#106058} --- diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc index d7a31c2..5bff3e6 100644 --- a/src/maglev/maglev-graph-builder.cc +++ b/src/maglev/maglev-graph-builder.cc @@ -4196,8 +4196,8 @@ ReduceResult MaglevGraphBuilder::BuildCheckHeapObject(ValueNode* object) { // Check for the empty type first so that we catch the case where // GetType(object) is already empty. - if (IsEmptyNodeType( - IntersectType(GetType(object), NodeType::kAnyHeapObject))) { + NodeType initial_type = GetType(object); + if (IsEmptyNodeType(IntersectType(initial_type, NodeType::kAnyHeapObject))) { return EmitUnconditionalDeopt(DeoptimizeReason::kSmi); } if (Phi* phi = object->TryCast<Phi>()) { @@ -4208,6 +4208,17 @@ phi->SetUseRequiresHeapObject(); } if (EnsureType(object, NodeType::kAnyHeapObject)) return ReduceResult::Done(); + if (object->Is<Phi>() && NodeTypeCanBe(initial_type, NodeType::kSmi)) { + // If {initial_type} contains kSmi, then phi untagging could widen this to a + // HeapNumber. Since the `EnsureType(.. kAnyHeapObject)` above just removed + // `kSmi` from the type, we need to make sure that still don't forget that + // HeapNumber is actually still a possibility. + // TODO(dmercadier): this is only a small band-aid: actually, any + // GetType(phi) could return Smi when the actual type ends up being + // HeapNumber. + NodeInfo* info = GetOrCreateInfoFor(object); + info->UnionType(NodeType::kHeapNumber); + } return AddNewNode<CheckHeapObject>({object}); }
Loading diff…
Original Bug Report
reported by [email protected]
Phi untagging invalidates BuildCheckHeapObject's type refinement
Splitting from https://issues.chromium.org/u/1/issues/495149864#comment17 because this might be a separate bug.
Repro:
let o = { x : "abc" };
o.x = []; // Making non-string, non-const, but still HeapObject
function foo(c1, c2) {
let phi1 = c1 ? 42 : 0x40000000;
phi1 + 1; // inserting smi check
let phi2 = c2 ? true : phi1;
o.x = phi2;
}
%PrepareFunctionForOptimization(foo);
foo(true, true);
foo(true, true);
%OptimizeMaglevOnNextCall(foo);
foo(true, true);
foo(true, true);
foo(false, false);
with flags –allow-natives-syntax –maglev-untagged-phis –maglev-assert-types
Failure:
CheckMaglevType failed
DebugPrint: 0xf9e0104b685: [HeapNumber]
- map: 0x0f9e00000515 <Map[12](HEAP_NUMBER_TYPE)>
- value: 1073741824.0
0xf9e00000515: [Map] in ReadOnlySpace
- map: 0x0f9e00000475 <MetaMap (0x0f9e0000002d <null>)>
- type: HEAP_NUMBER_TYPE
- instance size: 12
- elements kind: HOLEY_ELEMENTS
- enum length: invalid
- stable_map
- non-extensible
- back pointer: 0x0f9e00000011 <undefined>
- prototype_validity_cell: 0
- instance descriptors (own) #0: 0x0f9e0000080d <DescriptorArray[0]>
- prototype: 0x0f9e0000002d <null>
- constructor: 0x0f9e0000002d <null>
- dependent code: 0x0f9e000007f5 <Other heap object (WEAK_ARRAY_LIST_TYPE)>
- construction counter: 0
Expected type: : DebugPrint: Smi: 0x10 (16)
Actual type: : DebugPrint: Smi: 0x2 (2)
References
On This Page