CVE-2026-14428
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifsrc/dawn/native/vulkan/UtilsVulkan.cpp |
modified |
Files Changed
src/dawn/native/vulkan/UtilsVulkan.cpp
Patch
From dbeb906300358eb5c8f61e98a8f71f57285b714c Mon Sep 17 00:00:00 2001
From: Brandon Jones <bajones@chromium.org>
Date: Wed, 10 Jun 2026 20:18:38 -0700
Subject: [PATCH] Vulkan: Avoid UB in CreateSamplerYCbCrConversion
If the Chroma Filter is linear in CreateSamplerYCbCrConversion do
a check to ensure that the format allows for it and adjust the
filter to nearest if not to avoid undefined behavior in
CreateSamplerYcbcrConversion.
Fixed: 520180257
Change-Id: I6be11b5e72f83326f73a2e4ad9b6659172c83ae4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/314296
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Brandon Jones <bajones@chromium.org>
---
diff --git a/src/dawn/native/vulkan/UtilsVulkan.cpp b/src/dawn/native/vulkan/UtilsVulkan.cpp
index 9a1058d..96ebbf8 100644
--- a/src/dawn/native/vulkan/UtilsVulkan.cpp
+++ b/src/dawn/native/vulkan/UtilsVulkan.cpp
@@ -33,6 +33,7 @@
#include "src/dawn/native/ShaderModule.h"
#include "src/dawn/native/vulkan/DeviceVk.h"
#include "src/dawn/native/vulkan/Forward.h"
+#include "src/dawn/native/vulkan/PhysicalDeviceVk.h"
#include "src/dawn/native/vulkan/TextureVk.h"
#include "src/dawn/native/vulkan/VulkanError.h"
#include "src/dawn/native/vulkan/VulkanFunctions.h"
@@ -446,6 +447,25 @@
vulkanYCbCrCreateInfo.forceExplicitReconstruction =
static_cast<VkBool32>(yCbCrDescriptor.forceExplicitReconstruction);
+ // VUID-VkSamplerYcbcrConversionCreateInfo-chromaFilter-01657
+ // Adjust linear filter to nearest if the format doesn't support linear. This is to support
+ // samplers created with YCrCb conversion info directly, which can't easily validate against the
+ // driver information at creation time.
+ if (vulkanFormat != VK_FORMAT_UNDEFINED &&
+ vulkanYCbCrCreateInfo.chromaFilter == VK_FILTER_LINEAR) {
+ VkPhysicalDevice vkPhysicalDevice =
+ ToBackend(device->GetPhysicalDevice())->GetVkPhysicalDevice();
+ VkFormatProperties formatProperties;
+ device->fn.GetPhysicalDeviceFormatProperties(vkPhysicalDevice, vulkanFormat,
+ &formatProperties);
+ bool supportsLinear = IsSubset(
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT,
+ formatProperties.optimalTilingFeatures | formatProperties.linearTilingFeatures);
+ if (!supportsLinear) {
+ vulkanYCbCrCreateInfo.chromaFilter = VK_FILTER_NEAREST;
+ }
+ }
+
#if DAWN_PLATFORM_IS(ANDROID)
VkExternalFormatANDROID vulkanExternalFormat;
// Chain VkExternalFormatANDROID only if needed.
Original Bug Report
Potential Vulkan Driver Undefined Behavior via Unchecked VulkanYCbCrInfo on Android
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. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: A compromised renderer can supply a fabricated gpu::mojom::VulkanYCbCrInfo struct with modified format_features via a TransferableResource. Because compatibility checks in Viz deliberately ignore filter mismatches and Dawn lacks capability validation, this can result in the GPU process invoking vkCreateSamplerYcbcrConversion with invalid parameters. This violates Vulkan VUIDs and potentially triggers driver undefined behavior in the unsandboxed GPU process on Android.
Affected files:
third_party/dawn/src/dawn/native/Sampler.cppthird_party/dawn/src/dawn/native/vulkan/UtilsVulkan.cppgpu/ipc/common/vulkan_ycbcr_info_mojom_traits.hcomponents/viz/service/display_embedder/image_context_impl.ccgpu/command_buffer/service/shared_image/shared_image_format_service_utils.cccomponents/viz/service/display/external_use_client.cccomponents/viz/service/display_embedder/skia_output_surface_impl.cc
Estimated timestamp from git blame: 2019-05-09
Description
On Android with Skia Graphite and Dawn compositing enabled, a compromised renderer can potentially trigger Vulkan driver undefined behavior inside the GPU process. The issue stems from a lack of validation on the renderer-supplied gpu::mojom::VulkanYCbCrInfo structure transmitted via Mojo IPC within a TransferableResource.
Specifically, the renderer can fabricate the format_features field to claim support for VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT when the underlying hardware format does not support it. This fabricated information travels through the compositor’s promise texture pipeline and is eventually passed directly to the Vulkan driver function vkCreateSamplerYcbcrConversion with chromaFilter = VK_FILTER_LINEAR.
Potential Attack Chain / Technical Flow
- IPC Entry: A compromised renderer constructs a
viz::CompositorFramecontaining aTransferableResourcereferencing a valid SharedImage mailbox. - Fabricating Features: The renderer populates
ycbcr_info(gpu.mojom.VulkanYCbCrInfo) with matching format identifiers but setsformat_featuresto includeVK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT(lying about linear chroma filter support). - Mojo Deserialization: In the GPU process, the frame is deserialized. The trait implementation in
gpu/ipc/common/vulkan_ycbcr_info_mojom_traits.h:45-71performs zero validation on the deserializedformat_featuresfield. - Compatibility Bypass: When verifying the frame,
ImageContextImpl::BeginAccessIfNecessaryInternalincomponents/viz/service/display_embedder/image_context_impl.cc:452invokesDawnYCbCrVkDescriptorsAreCompatible. This compatibility check deliberately skips comparisons ofvkChromaFilter(lines 76-79) to avoid dropping video frames. - Immutable Sampler Packing: During draw recording,
DawnCaps::getImmutableSamplerInfointhird_party/skia/src/gpu/graphite/dawn/DawnCaps.cpp:620-632extracts and packs the promise texture’s YCbCr descriptor (including the fake linear filter mode). - Chaining and Sampler Creation: In
third_party/skia/src/gpu/graphite/dawn/DawnSampler.cpp:95-96, the descriptor is unpacked and chained to the Dawn sampler descriptor. Dawn’s frontend validation inValidateSamplerDescriptor(third_party/dawn/src/dawn/native/Sampler.cpp:73-91) fails to verify whether the format actually supports the requested filter mode. - VUID Violation: In Dawn’s Vulkan backend,
CreateSamplerYCbCrConversioninthird_party/dawn/src/dawn/native/vulkan/UtilsVulkan.cpp:463calls the Vulkan driver APIvkCreateSamplerYcbcrConversionwithchromaFilter = VK_FILTER_LINEAR. This violates Vulkan validation ruleVUID-VkSamplerYcbcrConversionCreateInfo-chromaFilter-01657and triggers driver undefined behavior.
Note: Because these steps represent potential execution paths identified via static code analysis, and we currently do not have a running proof-of-concept exploit, the behavior may vary depending on the specific Vulkan driver implementation.
Security Impact
On Android, the GPU process runs unsandboxed by default (the kAndroidGpuSandbox feature flag is disabled by default). If an attacker can leverage this Vulkan driver undefined behavior to achieve out-of-bounds memory access or corruption within the GPU process, it could potentially lead to arbitrary code execution outside the renderer’s sandbox.
Suggested Fix
To remediate this issue, validate that the renderer-supplied filter parameters are compatible with the actual physical hardware format capabilities before utilizing them to create Vulkan samplers.
Specifically, inside ImageContextImpl::BeginAccessIfNecessaryInternal or DawnYCbCrVkDescriptorsAreCompatible in components/viz/service/display_embedder/image_context_impl.cc, verify that if the promise texture descriptor requests wgpu::FilterMode::Linear for vkChromaFilter, the fulfillment texture’s actual YCbCr descriptor also supports linear filtering. If there is a capability mismatch (i.e., the fulfillment format lacks the required feature bit but the promise texture claimed it), reject the draw or fallback safely instead of passing the incompatible configuration to Dawn and the Vulkan driver.
Evaluated with Chrome root at commit: d8b226a3be7c9c1ac9240c09e14698866c82e4ac
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.