High watch CVSS 8.8 chrome OOB 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactOut of bounds memory access in WebML
DescriptionOut of bounds memory access in WebML
ComponentWebML
Sub-componentM-146
Bug ClassOOB
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker482875307
Fix commitc74e83f433f5 (external/github.com/google/ruy) +4/-3
CWECWE-125, CWE-787 (Out-of-bounds read, Out-of-bounds write)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-02-09 (per vendor advisory)
Fix landed2026-02-25 (public git)
Disclosed2026-03-10
Patch gap13 days — fix public in source before the advisory

Background

`ruy`
a matrix-multiplication library used by TensorFlow Lite CPU kernels; per the advisory the bug surfaces through WebML, and the link from WebNN to ruy via the TFLite CPU backend is (inferred) since the diff touches only ruy.
`MatLayout` / `FlatSize`
MatLayout describes a matrix’s rows, cols, stride and order; FlatSize returns the number of elements spanned (stride * outerdim) and is used to size and bound matrix buffers.
Packing
before multiplication, ruy copies source matrix blocks into a “packed” buffer in kernel-friendly order; pack_avx2_fma.cc holds the x86 AVX2/FMA packing routines, which spill trailing rows through a trailing_buf and memcpy them into packed_ptr.
32-bit index overflow
multiplying two int values whose product exceeds INT_MAX is undefined/wraps, so an int intermediate can yield a small or negative size/offset even when the result is later stored in a 64-bit std::ptrdiff_t.

Root Cause Analysis

In ruy::FlatSize, outerdim was declared int, so layout.stride * outerdim could be evaluated in 32-bit arithmetic and overflow for large matrices before being returned as std::ptrdiff_t, producing an undersized element count. In the AVX2/FMA packing routine shown in the pack_avx2_fma.cc hunk (its function name is not in the hunk), trailing_rows and non_trailing_rows were int, so the destination offset packed_ptr + kPackCols * non_trailing_rows was computed as an int product that can overflow for large src_rows, letting the subsequent memcpy of trailing_buf land outside the packed buffer. The invariant violated is that buffer sizes and pointer offsets derived from matrix dimensions must be computed in a type wide enough to hold them.

The patch widens these locals to std::ptrdiff_t (and adds <cstddef>), so the multiplications are done in 64-bit arithmetic on 64-bit targets; no bounds checks are added or relaxed. The diff does not show the callers, the allocation that uses FlatSize, or the WebNN code that feeds dimensions into ruy, so where the out-of-bounds access lands is (inferred).

Key insight
Matrix sizes and pack offsets were computed with 32-bit int intermediates that could overflow for large dimensions; the fix uses std::ptrdiff_t so size and offset arithmetic does not wrap.

Attack Path

  1. Build a large ML graph Web content uses the WebML (WebNN) API to construct an operation (e.g., a matrix multiply / fully connected layer) whose dimensions make stride * outerdim or kPackCols * non_trailing_rows exceed INT_MAX; the specific WebNN operator and dimension checks involved are (inferred).
  2. Dispatch to the CPU backend The graph runs on a TFLite CPU path that calls into ruy on an x86 machine selecting the AVX2/FMA packing code (inferred).
  3. Overflowed size/offset FlatSize returns a wrapped element count and/or the packing routine computes a wrapped packed_ptr offset in 32-bit arithmetic.
  4. Out-of-bounds memory access The trailing-row memcpy writes at a wrong offset relative to the packed buffer, or buffers sized from FlatSize are too small for later accesses; the exact corrupted memory is (inferred).

Impact Assessment

The vendor advisory rates this a high severity out-of-bounds memory access in WebML; the diff shows a potential out-of-bounds memcpy write in ruy packing and an undersized size computation, while the process it executes in (the process hosting WebNN’s CPU inference) and any escalation to code execution are (inferred). Preconditions: the WebNN API must be available to the page (whether it is enabled by default is not shown in the diff), the CPU/TFLite backend must route the operation into ruy on x86 hardware with AVX2/FMA, and the tensor dimensions must be large enough to overflow 32-bit arithmetic, which may also require that upstream size validation and memory limits permit such shapes (inferred).

Changed Functions

FunctionChangeNotes
if
ruy/pack_avx2_fma.cc
modified

Files Changed

  • ruy/mat.h
  • ruy/pack_avx2_fma.cc

Audit Directions

  • `int` intermediates in size math
    Grep ruy (other pack_*.cc variants such as AVX-512, AVX, NEON) and TFLite/XNNPACK kernels for int locals multiplied by strides or pack widths before being used as pointer offsets or allocation sizes.
  • Dimension limits at the WebNN boundary
    Check that WebNN graph validation bounds operand dimensions and checked-multiplies element counts before handing shapes to third-party CPU backends.
  • Return-type widening masks overflow
    Look for functions returning std::ptrdiff_t/size_t whose expressions are evaluated entirely in int (as FlatSize was), since the wide return type gives a false sense of safety.
From c74e83f433f56aa88465486c5be185369142e61e Mon Sep 17 00:00:00 2001
From: Reilly Grant <[email protected]>
Date: Wed, 25 Feb 2026 00:18:33 +0000
Subject: [PATCH] [M-146] Use std::ptrdiff_t for matrix dimensions and indices.

(Cherry-picked from 8a21714c60bdf0aa95405404e7322e455a34de72.)

PiperOrigin-RevId: 868743667
Bug: 482875307
Change-Id: I9de8e25ff4d22ff99bd63ad1573cfcc8d2aba990
---

diff --git a/ruy/mat.h b/ruy/mat.h
index c2254f9..520d717 100644
--- a/ruy/mat.h
+++ b/ruy/mat.h
@@ -328,7 +328,7 @@
 }
 
 inline std::ptrdiff_t FlatSize(const MatLayout& layout) {
-  const int outerdim =
+  const std::ptrdiff_t outerdim =
       layout.order == Order::kColMajor ? layout.cols : layout.rows;
   return layout.stride * outerdim;
 }
diff --git a/ruy/pack_avx2_fma.cc b/ruy/pack_avx2_fma.cc
index 2564b72..116854b 100644
--- a/ruy/pack_avx2_fma.cc
+++ b/ruy/pack_avx2_fma.cc
@@ -13,6 +13,7 @@
 limitations under the License.
 ==============================================================================*/
 
+#include <cstddef>
 #include <cstdint>
 #include <cstring>
 
@@ -595,9 +596,9 @@
       src_ptr, zerobuf, src_stride, remaining_src_cols, src_rows, packed_ptr,
       trailing_buf);
 
-  const int trailing_rows = src_rows & (kPackRows - 1);
+  const std::ptrdiff_t trailing_rows = src_rows & (kPackRows - 1);
   if (trailing_rows > 0) {
-    const int non_trailing_rows = src_rows & ~(kPackRows - 1);
+    const std::ptrdiff_t non_trailing_rows = src_rows & ~(kPackRows - 1);
     memcpy(packed_ptr + kPackCols * non_trailing_rows, trailing_buf,
            kPackCols * trailing_rows * sizeof(float));
   }
Loading diff…

Original Bug Report

reported by [email protected]

webnn_graph_mojolpm_fuzzer: Segv on unknown address in ruy::MulFrontEndFromTrMulParams

Detailed Report: https://clusterfuzz.com/testcase?key=5384407544168448

Fuzzing Engine: libFuzzer Fuzz Target: webnn_graph_mojolpm_fuzzer Job Type: mac_libfuzzer_chrome_asan Platform Id: mac

Crash Type: Segv on unknown address Crash Address: Crash State: ruy::MulFrontEndFromTrMulParams void ruy::MulFrontEnd< tflite::cpu_backend_gemm::detail::GemmImplUsingRuy<float, float, float, float,

Sanitizer: address (ASAN)

Regressed: https://clusterfuzz.com/revisions?job=mac_libfuzzer_chrome_asan&range=1468407:1468456

Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=5384407544168448

Issue filed automatically.

See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for instructions on reproducing this bug locally.

View on issue tracker