CVE-2026-11033
Overview
Files Changed
services/webnn/coreml/tensor_impl_coreml.mm
Patch
From 075420627d3caa36a8253a4c3c0d62d7ac77535c Mon Sep 17 00:00:00 2001 From: Bryan Enrique Gonzalez Velez <[email protected]> Date: Thu, 09 Apr 2026 09:26:26 -0700 Subject: [PATCH] [Project-Fortify] Zero out uninitialized memory in WebNN CoreML This is a quick fix for a potential security issue. This change zero out uninitialized IOSurface memory. Avoiding memory disclosure Project-Fortify (Internal only) go/code-terracotta-review-explainer Bug: 497926664 Change-Id: I55c5d4274dc1f4e766809b4c782daaf1469a8b27 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7735329 Reviewed-by: Stephen Nusko <[email protected]> Reviewed-by: Reilly Grant <[email protected]> Commit-Queue: Bryan Enrique Gonzalez <[email protected]> Cr-Commit-Position: refs/heads/main@{#1612294} --- diff --git a/services/webnn/coreml/tensor_impl_coreml.mm b/services/webnn/coreml/tensor_impl_coreml.mm index f35d6e20..ff7c757d 100644 --- a/services/webnn/coreml/tensor_impl_coreml.mm +++ b/services/webnn/coreml/tensor_impl_coreml.mm @@ -129,6 +129,16 @@ IOSurfaceRef surface = IOSurfaceCreate(base::apple::NSToCFPtrCast(iosurface_properties)); + CHECK_EQ(IOSurfaceLock(surface, 0, NULL), kIOReturnSuccess); + + // SAFETY: IOSurfaceGetAllocSize is guaranteed to return the total + // allocation size of the buffer. See: + // https://developer.apple.com/documentation/iosurface/iosurfacegetallocsize(_:) + UNSAFE_BUFFERS(memset(IOSurfaceGetBaseAddress(surface), 0, + IOSurfaceGetAllocSize(surface))); + + CHECK_EQ(IOSurfaceUnlock(surface, 0, NULL), kIOReturnSuccess); + CVPixelBufferRef pixel_buffer = nil; CVReturn pixel_buffer_result = CVPixelBufferCreateWithIOSurface( kCFAllocatorDefault, surface,
Original Bug Report
Potential uninitialized memory disclosure in WebNN CoreML float16 tensors
Project Fortify, an experimental security project, has identified the following potential security issue.
Overview: The WebNN CoreML backend on macOS fails to zero-initialize IOSurface-backed float16 tensors. Combined with a missing size validation check in WebNNContextImpl, this allows a web page or compromised renderer to read uninitialized GPU memory. This could leak sensitive cross-origin texture data or other process memory.
Affected files:
services/webnn/coreml/tensor_impl_coreml.mmservices/webnn/webnn_context_impl.ccservices/webnn/coreml/utils_coreml.mm
Estimated timestamp from git blame: 2025-08-18
Description
A potential uninitialized memory disclosure exists in the WebNN CoreML backend on macOS, which could allow an attacker to read uninitialized GPU process memory (such as recycled IOSurface buffers containing cross-origin WebGL textures or UI data).
There are two root causes that enable this:
-
Missing Zero-Initialization in CoreML Backend: In
services/webnn/coreml/tensor_impl_coreml.mm, the functionCreateMultiArrayBackedByIOSurfaceis used to allocate memory forfloat16tensors. It callsIOSurfaceCreatebut fails to clear or zero-initialize the newly allocated surface. This contrasts withCreateMultiArrayFromDescriptor(used for other types), which explicitly usesmemsetto zero out the memory. -
Missing Size Validation in WebNNContext: In
services/webnn/webnn_context_impl.cc, theWebNNContextImpl::CreateTensormethod contains a size-validation checktensor_data.size() != validated_descriptor->PackedByteLength(). However, this check is only performed if the tensor has thekGraphConstantusage flag. For non-constant tensors, it accepts an empty buffer (assuming the backend already zero-initialized the tensor) or an undersized buffer.
Potential Steps to Trigger
Note: These are suggested steps based on static analysis; our tooling cannot execute working proofs-of-concept to verify them dynamically.
Path A: Standard Web Page
- An attacker’s web page calls
MLContext.createTensor()requesting afloat16tensor. - The renderer sends a
CreateTensorMojo IPC with an emptyBigBuffer(0)for the initial data. - The GPU process allocates the
IOSurfaceviaCreateMultiArrayBackedByIOSurface(leaving it uninitialized). - In
WebNNContextImpl::CreateTensor, because the buffer size is 0, the code skips callingWriteTensorImpl(relying on the false assumption that the tensor is already zero-initialized). - The attacker calls
MLTensor.read()to read the tensor, receiving the uninitializedIOSurfacememory.
Path B: Compromised Renderer
- A compromised renderer sends a
CreateTensorMojo IPC for a largefloat16tensor (e.g., 2MB) but provides a tinytensor_databuffer (e.g., 1 byte). - Because the validation check is skipped for non-constant tensors,
WebNNContextImpl::CreateTensoraccepts the 1-byte buffer and passes it toWriteTensorImpl. RecursivelyWriteToMLMultiArray(inutils_coreml.mm) copies the 1-byte prefix into the tensor, leaving the rest of the 2MBIOSurfaceuninitialized.- The compromised renderer sends a
ReadTensorIPC, extracting the full 2MB of uninitialized memory.
Suggested Fix
- Zero-Initialize IOSurfaces: In
CreateMultiArrayBackedByIOSurface(services/webnn/coreml/tensor_impl_coreml.mm), map the newly createdCVPixelBufferorIOSurfaceand explicitly zero-initialize its contents before returning it. - Enforce Size Validation: In
WebNNContextImpl::CreateTensor(services/webnn/webnn_context_impl.cc), ensure thattensor_data.size()is validated againstvalidated_descriptor->PackedByteLength()for all tensors, not justkGraphConstanttensors. The size should be strictly equal to either0(for uninitialized/default tensors) or the exact packed byte length.
Evaluated with Chrome root at commit: a9cbf6e8b275fe4147435aa905f3b7f5a656f5f0
Results from so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.