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 <dmercadier@chromium.org>
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 <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Darius Mercadier <dmercadier@chromium.org>
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 ma...@chromium.org
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