Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in Media
DescriptionInsufficient validation of untrusted input in Media
ComponentMedia
Bug ClassLogic Error
Tracker513019760
Fix commit2e05633d0b58 (chromium/src) +7/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-05-27

Changed Functions

FunctionChangeNotes
if
media/gpu/chromeos/gl_image_processor_backend.cc
modified

Files Changed

  • media/gpu/chromeos/gl_image_processor_backend.cc
From 2e05633d0b58652e880bf77450c6ed90e8962b6c Mon Sep 17 00:00:00 2001
From: Hirokazu Honda <[email protected]>
Date: Tue, 19 May 2026 03:37:52 -0700
Subject: [PATCH] media/gpu/chromeos/GLIP: Validate GpuMemoryBufferHandle

This change introduces a validation step for GpuMemoryBufferHandle
within the GLImageProcessorBackend. Before creating GL bindings for
a frame, the code now calls VerifyGpuMemoryBufferHandle to confirm
that the handle is consistent with the frame's format and coded
size.

Bug: 513019760
Test: webrtc.RTCPeerConnection.*
Change-Id: I594e22cadc0a72b4032607bc989c42599b3df91d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7855451
Reviewed-by: Nathan Hebert <[email protected]>
Commit-Queue: Hirokazu Honda <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1632754}
---

diff --git a/media/gpu/chromeos/gl_image_processor_backend.cc b/media/gpu/chromeos/gl_image_processor_backend.cc
index 6b3e52ed..ffd4e53 100644
--- a/media/gpu/chromeos/gl_image_processor_backend.cc
+++ b/media/gpu/chromeos/gl_image_processor_backend.cc
@@ -12,6 +12,7 @@
 #include "base/trace_event/trace_event.h"
 #include "components/viz/common/resources/shared_image_format.h"
 #include "media/base/format_utils.h"
+#include "media/gpu/buffer_validation.h"
 #include "media/gpu/chromeos/frame_resource.h"
 #include "media/gpu/chromeos/platform_video_frame_utils.h"
 #include "media/gpu/macros.h"
@@ -100,6 +101,12 @@
     return nullptr;
   }
 
+  if (!VerifyGpuMemoryBufferHandle(frame->format(), frame->coded_size(),
+                                   gpu_memory_buffer_handle)) {
+    LOG(ERROR) << "Failed to validate GpuMemoryBufferHandle";
+    return nullptr;
+  }
+
   if (!should_split_planes) {
     auto native_pixmap = base::MakeRefCounted<gfx::NativePixmapDmaBuf>(
         frame->coded_size(), viz::MultiPlaneFormat::kNV12,
Loading diff…

Original Bug Report

reported by [email protected]

Potential GPU Process OOB Read in GLImageProcessorBackend via Forged DMA-BUF

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports without the Chrome Security team. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: GLImageProcessorBackend on ChromeOS ARM fails to validate the actual size of renderer-supplied DMA-BUF file descriptors before importing them into a private GL context. A compromised renderer could exploit this by providing an undersized DMA-BUF with large claimed dimensions, leading to an out-of-bounds read of GPU memory. The leaked memory can then be exfiltrated through the hardware video encoder’s output bitstream.

Affected files:

  • media/gpu/chromeos/gl_image_processor_backend.cc
  • ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc
  • media/gpu/v4l2/v4l2_video_encode_accelerator.cc
  • ui/ozone/common/native_pixmap_egl_binding.cc

Estimated timestamp from git blame: Unknown (Google3 checkout)

Technical Details

A potential security vulnerability has been identified in the GPU process on ChromeOS ARM platforms, specifically within the GLImageProcessorBackend component used for hardware-accelerated video frame scaling and conversion.

  1. Vulnerability Mechanism: When a renderer sends a VideoFrame to the GPU process (e.g., for encoding via media::MojoVideoEncodeAcceleratorService), the frame is deserialized using Mojo traits. If the frame uses SharedImageVideoFrameData, the GPU process attempts to import the underlying buffer handle.

  2. Validation Bypass: The import process involves ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc. The code performs a check on the gfx::BufferUsage of the handle. Crucially, for usages that do not require CPU access (such as gfx::BufferUsage::GPU_READ or gfx::BufferUsage::SCANOUT), the factory skips the physical size validation of the file descriptor (which is typically done via lseek(fd, 0, SEEK_END)). Instead, it returns a ClientNativePixmapOpaque (lines 125-131).

  3. OOB Read in GLImageProcessorBackend: On ARM devices, the V4L2VideoEncodeAccelerator may use GLImageProcessorBackend to perform NV12 scaling. The backend creates a private GL context with attribs.can_skip_validation = true (media/gpu/chromeos/gl_image_processor_backend.cc, line 285). It then imports the renderer-supplied buffer into this context as an EGLImage using the dimensions and strides provided in the Mojo message, which have not been verified against the actual size of the DMA-BUF FD.

  4. Information Disclosure: When the backend executes a GL draw call to scale the image, the GPU samples from the texture. Because the actual buffer is significantly smaller than the claimed dimensions, the GPU driver performs out-of-bounds reads from adjacent GPU memory. This leaked memory is written into the output frame, which is subsequently processed by the hardware video encoder. The resulting compressed bitstream is returned to the renderer, allowing the attacker to exfiltrate the leaked data.

Potential Steps to Trigger

Note: These steps are based on a code-level analysis and have not been verified with a live proof-of-concept.

  1. Renderer Compromise: Gain code execution in a renderer process.
  2. Buffer Forgery: Create a small DMA-BUF (e.g., 1 KB) but prepare a SharedImage metadata claim with large dimensions (e.g., 1920x1080) and set the usage to GPU_READ.
  3. VEA Initialization: Connect to the media.mojom.VideoEncodeAcceleratorProvider and initialize a hardware-accelerated encoder instance.
  4. Frame Submission: Submit the forged VideoFrame to the encoder via the Encode() Mojo method.
  5. Data Collection: Monitor the output bitstreams. If the backend triggers a GL-based conversion, the bitstream will contain the results of the OOB read.

Suggested Fix

All DMA-BUF imports in the GPU process should include a validation step that compares the actual file descriptor size (via fstat or lseek) against the claimed dimensions, format, offsets, and strides. The validation logic in ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc should be expanded to cover GPU_READ and SCANOUT usages when those buffers are destined for GL/EGL import in contexts where driver-side validation is disabled or insufficient.

Evaluated with Chrome root at commit: b3153093eb3c78c3e88ccf562bcbc20437a04b0e


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

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.

View on issue tracker