CVE-2026-9898
Overview
Files Changed
gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h
Patch
From 2540f0d8870b855bd58a696ccfd9c213a2e95c88 Mon Sep 17 00:00:00 2001 From: Vasiliy Telezhnikov <[email protected]> Date: Thu, 07 May 2026 13:33:56 -0700 Subject: [PATCH] Validate YCbCr info enum values Due to dependency issues, we passed uint32_t values instead of enum historically, until we can resolve this we should validate against known values. Bug: 496282591,496565479 Change-Id: I36e3429b19cd71c32e4317cad24dfb1299c3406f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7823022 Reviewed-by: Joe Mason <[email protected]> Commit-Queue: Vasiliy Telezhnikov <[email protected]> Cr-Commit-Position: refs/heads/main@{#1627197} --- diff --git a/gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h b/gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h index e349c8bd..0048aef 100644 --- a/gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h +++ b/gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h @@ -51,6 +51,22 @@ out->suggested_xchroma_offset = data.suggested_xchroma_offset(); out->suggested_ychroma_offset = data.suggested_ychroma_offset(); out->format_features = data.format_features(); + + // Values from Vulkan definitions, because we can't easy depend on vulkan + // here. + // https://source.chromium.org/chromium/chromium/src/+/main:third_party/vulkan-headers/src/include/vulkan/vulkan_core.h;drc=f6a6f7ab165cedbfa2a7d0c93fe27a2d01ce09c8;l=5438 + const uint32_t VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4; + const uint32_t VK_CHROMA_LOCATION_MIDPOINT = 1; + const uint32_t VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1; + + if (out->suggested_ycbcr_model > + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 || + out->suggested_ycbcr_range > VK_SAMPLER_YCBCR_RANGE_ITU_NARROW || + out->suggested_xchroma_offset > VK_CHROMA_LOCATION_MIDPOINT || + out->suggested_ychroma_offset > VK_CHROMA_LOCATION_MIDPOINT) { + return false; + } + return true; } };
Original Bug Report
Potential GPU Sandbox Escape via unvalidated VulkanYCbCrInfo in IPC
Project Fortify, an experimental security project, has identified the following potential security issue.
Overview: The GPU process fails to validate Vulkan YCbCr conversion parameters received from the renderer via IPC. A compromised renderer can send out-of-bounds enum values that are passed directly to the Vulkan driver via Dawn or Skia. This can potentially trigger out-of-bounds memory access within the driver, leading to a GPU sandbox escape.
Affected files:
gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.hgpu/command_buffer/service/shared_image/shared_image_format_service_utils.cccomponents/viz/service/display_embedder/skia_output_surface_impl.cc
Estimated timestamp from git blame: 2019-08-13
Description
There is a potential sandbox escape vulnerability where a compromised Renderer process can send out-of-bounds Vulkan enum values to the GPU process via IPC. When these values are passed to the underlying Vulkan driver, they can cause undefined behavior (such as out-of-bounds array indexing), potentially allowing the attacker to execute arbitrary code within the highly privileged GPU process.
Root Cause
The gpu.mojom.VulkanYCbCrInfo Mojo struct defines Vulkan enum parameters (like suggested_ycbcr_model and suggested_ycbcr_range) as opaque uint32 and uint64 fields instead of strongly-typed Mojo enums. Consequently, Mojo’s automatic enum validation is bypassed.
During deserialization in the GPU process, StructTraits<gpu::mojom::VulkanYCbCrInfoDataView, gpu::VulkanYCbCrInfo>::Read (gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h) unconditionally copies these raw integer values into the C++ gpu::VulkanYCbCrInfo struct without any bounds checking.
Vulnerable Code Path
- A compromised renderer embeds a malicious
gpu::VulkanYCbCrInfoinside aviz::TransferableResourceand sends it to the Viz service in the GPU process. - In Viz, when compositing on Android with the Graphite/Dawn backend,
SkiaOutputSurfaceImpl::MakePromiseSkImageSinglePlaneis called to sample the texture. - The unvalidated
ycbcr_infois passed togpu::GraphitePromiseTextureInfo, which callsToDawnYCbCrVkDescriptor(gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc). - The raw
uint32_tvalues are copied directly into awgpu::YCbCrVkDescriptor. - Dawn processes this descriptor in
dawn::native::vulkan::CreateSamplerYCbCrConversionCreateInfo(third_party/dawn/src/dawn/native/vulkan/UtilsVulkan.cpp). It blindlystatic_casts the out-of-bounds integers to Vulkan enums (e.g.,VkSamplerYcbcrModelConversion) and passes them to thevkCreateSamplerYcbcrConversionVulkan API call. - Note: The Ganesh path is similarly vulnerable via
gpu::CreateVulkanYcbcrConversionInfoingpu/command_buffer/service/skia_utils.cc.
Production Vulkan drivers typically lack robust bounds checking for API enums due to performance reasons. Passing invalid enums is known to cause drivers to perform out-of-bounds array reads or writes when looking up internal formats or conversion matrices.
Potential Attacker Steps
Note: These are potential steps to trigger the vulnerability, as this AI agent does not currently have the capability to execute code or build a working Proof of Concept.
- Achieve arbitrary code execution within the Renderer process sandbox.
- Craft a malicious
viz::CompositorFramecontaining aviz::TransferableResource. - Populate the
ycbcr_infometadata field of theTransferableResource. - Set the underlying
uint32_tfields (e.g.,suggested_ycbcr_model,suggested_ycbcr_range,suggested_xchroma_offset,suggested_ychroma_offset) to extremely large values (e.g.,0xFFFFFFFF) that do not correspond to valid Vulkan enums. - Submit the
CompositorFrameto the Viz compositor in the GPU process via the standard Mojo IPC channel. - The GPU process will deserialize the frame, pass the malicious enums to the Vulkan driver, and trigger an out-of-bounds memory access, which the attacker can shape to achieve remote code execution in the GPU process.
Suggested Fix
Implement strict validation for all fields in gpu::VulkanYCbCrInfo when they cross the IPC boundary.
Modify StructTraits<gpu::mojom::VulkanYCbCrInfoDataView, gpu::VulkanYCbCrInfo>::Read in gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h to verify that each uint32_t value corresponds to a valid and supported Vulkan enum constant (e.g., checking against the maximum valid enum values for VkSamplerYcbcrModelConversion, VkSamplerYcbcrRange, etc.). If any value is out of bounds, the Read function should return false to reject the IPC message and terminate the misbehaving renderer.
Evaluated with Chrome root at commit: 0eb4855bda702feaaa8b899336664f97e3df88b8
Results 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. Please feel free to reach out to me if you have concerns or feedback.