Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in GPU
DescriptionInsufficient validation of untrusted input in GPU
ComponentGPU
Bug ClassLogic Error
Tracker497487755
Fix commitd8b65122a180 (chromium/src) +202/-21
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Changed Functions

FunctionChangeNotes
if
components/viz/service/display_embedder/skia_output_device_dcomp.cc
modified
SharedContextState
components/viz/service/display_embedder/skia_output_device_dcomp.h
modified
SharedImageRepresentationFactory
components/viz/service/display_embedder/skia_output_device_dcomp.h
modified
FeatureInfo
components/viz/service/display_embedder/skia_output_device_dcomp.h
modified
GpuDriverBugWorkarounds
components/viz/service/display_embedder/skia_output_device_dcomp.h
modified
SkiaOutputDeviceDComp
components/viz/service/display_embedder/skia_output_device_dcomp.h
modified
VIZ_SERVICE_EXPORT
components/viz/service/display_embedder/skia_output_device_dcomp.h
modified
OverlayData
components/viz/service/display_embedder/skia_output_device_dcomp.h
modified

Files Changed

  • components/viz/service/BUILD.gn
  • components/viz/service/display_embedder/skia_output_device.cc
  • components/viz/service/display_embedder/skia_output_device_dcomp.cc
  • components/viz/service/display_embedder/skia_output_device_dcomp.h
  • components/viz/service/display_embedder/skia_output_device_dcomp_unittest.cc
From d8b65122a180cf8391e21b694d83b1a8de833465 Mon Sep 17 00:00:00 2001
From: Sunny Sachanandani <sunnyps@chromium.org>
Date: Wed, 08 Apr 2026 10:36:37 -0700
Subject: [PATCH] [viz] Clamp DComp overlay content rect

SkiaOutputDeviceDComp::ScheduleOverlays calculated content_rect without
clamping it to the actual image size, which could lead to out-of-bounds
memory access if the UV rect was out of bounds.

This CL adds clamping to the content_rect to ensure it stays within the
image bounds. It also handles cases where resource_size_in_pixels is
larger than the actual image size by clamping to the image dimensions.

Also, refactored SkiaOutputDeviceDComp to take GpuDriverBugWorkarounds
instead of FeatureInfo to simplify dependencies and make it easier to
test.

Added unit tests to verify the clamping behavior.

Bug: 497487755
Test: SkiaOutputDeviceDCompTest.*
Change-Id: Ie62e7504935ca27630d8b4fc8cc7629d6a6a6964
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7738282
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1611628}
---

diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 42a96534..668242b6 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -736,6 +736,7 @@
     sources += [
       "display/overlay_dc_unittest.cc",
       "display_embedder/output_device_backing_unittest.cc",
+      "display_embedder/skia_output_device_dcomp_unittest.cc",
       "display_embedder/software_output_device_win_swapchain_unittest.cc",
       "display_embedder/software_output_device_win_unittest.cc",
       "display_embedder/test_support/dcomp_mocks.cc",
diff --git a/components/viz/service/display_embedder/skia_output_device.cc b/components/viz/service/display_embedder/skia_output_device.cc
index 03ec61b..15e4d30 100644
--- a/components/viz/service/display_embedder/skia_output_device.cc
+++ b/components/viz/service/display_embedder/skia_output_device.cc
@@ -104,11 +104,14 @@
     CHECK(!graphite_shared_context);
     capabilities_.max_render_target_size = gr_context->maxRenderTargetSize();
     capabilities_.max_texture_size = gr_context->maxTextureSize();
-  } else {
-    CHECK(graphite_shared_context);
+  } else if (graphite_shared_context) {
     capabilities_.max_render_target_size =
         graphite_shared_context->maxTextureSize();
     capabilities_.max_texture_size = graphite_shared_context->maxTextureSize();
+  } else {
+    // Unit tests may create SkiaOutputDevice without a GPU context.
+    capabilities_.max_render_target_size = 8192;
+    capabilities_.max_texture_size = 8192;
   }
 }
 
diff --git a/components/viz/service/display_embedder/skia_output_device_dcomp.cc b/components/viz/service/display_embedder/skia_output_device_dcomp.cc
index 140ec190..c21a5319 100644
--- a/components/viz/service/display_embedder/skia_output_device_dcomp.cc
+++ b/components/viz/service/display_embedder/skia_output_device_dcomp.cc
@@ -18,7 +18,6 @@
 #include "components/viz/common/switches.h"
 #include "components/viz/service/display_embedder/skia_output_surface_dependency.h"
 #include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/service/feature_info.h"
 #include "gpu/command_buffer/service/gl_utils.h"
 #include "gpu/command_buffer/service/shared_context_state.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
@@ -26,6 +25,7 @@
 #include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
 #include "gpu/command_buffer/service/skia_utils.h"
 #include "gpu/command_buffer/service/texture_manager.h"
+#include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
@@ -121,7 +121,7 @@
     gpu::SharedImageRepresentationFactory* shared_image_representation_factory,
     gpu::SharedContextState* context_state,
     scoped_refptr<gl::Presenter> presenter,
-    scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
+    const gpu::GpuDriverBugWorkarounds& workarounds,
     gpu::MemoryTracker* memory_tracker,
     DidSwapBufferCompleteCallback did_swap_buffer_complete_callback)
     : SkiaOutputDevice(context_state->gr_context(),
@@ -131,8 +131,7 @@
       shared_image_representation_factory_(shared_image_representation_factory),
       context_state_(context_state),
       presenter_(std::move(presenter)) {
-  DCHECK(!feature_info->workarounds()
-              .disable_post_sub_buffers_for_onscreen_surfaces);
+  DCHECK(!workarounds.disable_post_sub_buffers_for_onscreen_surfaces);
   capabilities_.uses_default_gl_framebuffer = true;
   capabilities_.output_surface_origin = gfx::SurfaceOrigin::kTopLeft;
   capabilities_.number_of_buffers =
@@ -143,7 +142,7 @@
     // when the feature |DCompTripleBufferRootSwapChain| is enabled.
     capabilities_.number_of_buffers = 2;
   }
-  if (feature_info->workarounds().supports_two_yuv_hardware_overlays) {
+  if (workarounds.supports_two_yuv_hardware_overlays) {
     capabilities_.allowed_yuv_overlay_count = 2;
   }
   if (base::FeatureList::IsEnabled(
@@ -169,9 +168,6 @@
       !IsBufferQueueSupportedAndEnabled(capabilities_.dc_support_level);
 
   DCHECK(context_state_);
-  DCHECK(context_state_->gr_context() ||
-         context_state_->graphite_shared_context());
-  DCHECK(context_state_->context());
   DCHECK(presenter_);
 
   // SRGB
@@ -320,6 +316,9 @@
     params.content_rect = gfx::ScaleRect(
         dc_layer.uv_rect, dc_layer.resource_size_in_pixels.width(),
         dc_layer.resource_size_in_pixels.height());
+    if (params.overlay_image) {
+      params.content_rect.Intersect(gfx::RectF(params.overlay_image->size()));
+    }
 
     params.quad_rect = gfx::ToRoundedRect(dc_layer.display_rect);
     CHECK(std::holds_alternative<gfx::Transform>(dc_layer.transform));
diff --git a/components/viz/service/display_embedder/skia_output_device_dcomp.h b/components/viz/service/display_embedder/skia_output_device_dcomp.h
index 6d9ef9e7..22dd6af7 100644
--- a/components/viz/service/display_embedder/skia_output_device_dcomp.h
+++ b/components/viz/service/display_embedder/skia_output_device_dcomp.h
@@ -12,6 +12,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "components/viz/service/display_embedder/skia_output_device.h"
+#include "components/viz/service/viz_service_export.h"
 #include "ui/gl/presenter.h"
 
 namespace gl {
@@ -21,23 +22,20 @@
 namespace gpu {
 class SharedContextState;
 class SharedImageRepresentationFactory;
-
-namespace gles2 {
-class FeatureInfo;
-}  // namespace gles2
+class GpuDriverBugWorkarounds;
 }  // namespace gpu
 
 namespace viz {
 
 // Base class for DComp-backed OutputDevices.
-class SkiaOutputDeviceDComp : public SkiaOutputDevice {
+class VIZ_SERVICE_EXPORT SkiaOutputDeviceDComp : public SkiaOutputDevice {
  public:
   SkiaOutputDeviceDComp(
       gpu::SharedImageRepresentationFactory*
           shared_image_representation_factory,
       gpu::SharedContextState* context_state,
       scoped_refptr<gl::Presenter> presenter,
-      scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
+      const gpu::GpuDriverBugWorkarounds& workarounds,
       gpu::MemoryTracker* memory_tracker,
       DidSwapBufferCompleteCallback did_swap_buffer_complete_callback);
 
@@ -56,12 +54,13 @@
       std::vector<GrBackendSemaphore>* end_semaphores) override;
   void EndPaint() override;
 
+ protected:
+  virtual std::optional<gl::DCLayerOverlayImage> BeginOverlayAccess(
+      const gpu::Mailbox& mailbox);
+
  private:
   class OverlayData;
 
-  std::optional<gl::DCLayerOverlayImage> BeginOverlayAccess(
-      const gpu::Mailbox& mailbox);
-
   void CreateSkSurface();
 
   // Mailboxes of overlays scheduled in the current frame.
diff --git a/components/viz/service/display_embedder/skia_output_device_dcomp_unittest.cc b/components/viz/service/display_embedder/skia_output_device_dcomp_unittest.cc
new file mode 100644
index 0000000..0db5ef1
--- /dev/null
+++ b/components/viz/service/display_embedder/skia_output_device_dcomp_unittest.cc
@@ -0,0 +1,178 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/skia_output_device_dcomp.h"
+
+#include <memory>
+#include <utility>
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/components/viz/service/display_embedder/skia_output_device_dcomp_unittest.cc b/components/viz/service/display_embedder/skia_output_device_dcomp_unittest.cc
new file mode 100644
index 0000000..0db5ef1
--- /dev/null
+++ b/components/viz/service/display_embedder/skia_output_device_dcomp_unittest.cc
@@ -0,0 +1,178 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/skia_output_device_dcomp.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/functional/callback_helpers.h"
+#include "base/memory/scoped_refptr.h"
+#include "components/viz/service/display/overlay_candidate.h"
+#include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "gpu/command_buffer/service/shared_context_state.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/dc_layer_overlay_image.h"
+#include "ui/gl/dc_layer_overlay_params.h"
+#include "ui/gl/presenter.h"
+#include "ui/gl/gl_context_stub.h"
+#include "ui/gl/gl_surface_stub.h"
+
+using ::testing::_;
+using ::testing::Invoke;
+
+namespace viz {
+namespace {
+
+class MockPresenter : public gl::Presenter {
+ public:
+  MockPresenter() = default;
+
+  void Present(SwapCompletionCallback completion_callback,
+               PresentationCallback presentation_callback,
+               gfx::FrameData data) override {
+    std::move(completion_callback)
+        .Run(gfx::SwapCompletionResult(gfx::SwapResult::SWAP_ACK));
+    std::move(presentation_callback).Run({});
+  }
+
+  bool ScheduleOverlayPlane(
+      gl::OverlayImage image,
+      std::unique_ptr<gfx::GpuFence> gpu_fence,
+      const gfx::OverlayPlaneData& overlay_plane_data) override {
+    return true;
+  }
+
+  MOCK_METHOD1(ScheduleDCLayers, void(std::vector<gl::DCLayerOverlayParams>));
+
+  bool SupportsDelegatedInk() override { return false; }
+  HWND GetWindow() const override { return nullptr; }
+  bool DestroyDCLayerTree() override { return true; }
+
+ protected:
+  ~MockPresenter() override = default;
+};
+
+class TestSkiaOutputDeviceDComp : public SkiaOutputDeviceDComp {
+ public:
+  TestSkiaOutputDeviceDComp(scoped_refptr<gl::Presenter> presenter,
+                            gpu::SharedContextState* context_state)
+      : SkiaOutputDeviceDComp(
+            /*shared_image_representation_factory=*/nullptr,
+            context_state,
+            std::move(presenter),
+            /*workarounds=*/gpu::GpuDriverBugWorkarounds(),
+            /*memory_tracker=*/nullptr,
+            /*did_swap_buffer_complete_callback=*/base::DoNothing()) {}
+
+  void SetOverlayImageSize(const gpu::Mailbox& mailbox, const gfx::Size& size) {
+    overlay_sizes_[mailbox] = size;
+  }
+
+ protected:
+  std::optional<gl::DCLayerOverlayImage> BeginOverlayAccess(
+      const gpu::Mailbox& mailbox) override {
+    auto it = overlay_sizes_.find(mailbox);
+    if (it != overlay_sizes_.end()) {
+      return gl::DCLayerOverlayImage(it->second,
+                                     Microsoft::WRL::ComPtr<IUnknown>());
+    }
+    return std::nullopt;
+  }
+
+ private:
+  base::flat_map<gpu::Mailbox, gfx::Size> overlay_sizes_;
+};
+
+class SkiaOutputDeviceDCompTest : public testing::Test {
+ public:
+  void SetUp() override {
+    auto presenter = base::MakeRefCounted<MockPresenter>();
+    presenter_ = presenter.get();
+
+    auto surface = base::MakeRefCounted<gl::GLSurfaceStub>();
+    auto context = base::MakeRefCounted<gl::GLContextStub>();
+    context->Initialize(surface.get(), gl::GLContextAttribs());
+    context_state_ = base::MakeRefCounted<gpu::SharedContextState>(
+        /*share_group=*/nullptr,
+        surface,
+        context,
+        /*use_virtualized_gl_contexts=*/false,
+        /*context_lost_callback=*/base::DoNothing(),
+        gpu::GrContextType::kGraphiteDawn);
+
+    output_device_ = std::make_unique<TestSkiaOutputDeviceDComp>(
+        std::move(presenter), context_state_.get());
+  }
+
+  void TearDown() override {
+    presenter_ = nullptr;
+    output_device_.reset();
+    context_state_.reset();
+  }
+
+ protected:
+  scoped_refptr<gpu::SharedContextState> context_state_;
+  std::unique_ptr<TestSkiaOutputDeviceDComp> output_device_;
+  raw_ptr<MockPresenter> presenter_ = nullptr;
+};
+
+TEST_F(SkiaOutputDeviceDCompTest, ClampsOutOfBoundsUVRect) {
+  gfx::Size image_size(100, 100);
+  gpu::Mailbox mailbox = gpu::Mailbox::Generate();
+  output_device_->SetOverlayImageSize(mailbox, image_size);
+
+  OverlayCandidate candidate;
+  candidate.mailbox = mailbox;
+  candidate.display_rect = gfx::RectF(0, 0, 100, 100);
+  candidate.uv_rect = gfx::RectF(-0.1f, -0.1f, 1.2f, 1.2f);  // OOB
+  candidate.resource_size_in_pixels = image_size;
+  candidate.transform = gfx::Transform();
+
+  SkiaOutputSurface::OverlayList overlays;
+  overlays.push_back(candidate);
+
+  EXPECT_CALL(*presenter_, ScheduleDCLayers(_))
+      .WillOnce([](std::vector<gl::DCLayerOverlayParams> params) {
+        ASSERT_EQ(params.size(), 1u);
+        // The uv_rect is [-0.1, -0.1, 1.2, 1.2].
+        // Content rect in pixels would be [-10, -10, 120, 120].
+        // Clamped content rect should be [0, 0, 100, 100].
+        EXPECT_EQ(params[0].content_rect, gfx::RectF(0, 0, 100, 100));
+      });
+
+  output_device_->ScheduleOverlays(std::move(overlays));
+}
+
+TEST_F(SkiaOutputDeviceDCompTest, ClampsOutOfBoundsResourceSize) {
+  gfx::Size image_size(100, 100);
+  gpu::Mailbox mailbox = gpu::Mailbox::Generate();
+  output_device_->SetOverlayImageSize(mailbox, image_size);
+
+  OverlayCandidate candidate;
+  candidate.mailbox = mailbox;
+  candidate.display_rect = gfx::RectF(0, 0, 100, 100);
+  candidate.uv_rect = gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f);
+  candidate.resource_size_in_pixels = gfx::Size(150, 150);
+  candidate.transform = gfx::Transform();
+
+  SkiaOutputSurface::OverlayList overlays;
+  overlays.push_back(candidate);
+
+  EXPECT_CALL(*presenter_, ScheduleDCLayers(_))
+      .WillOnce([](std::vector<gl::DCLayerOverlayParams> params) {
+        ASSERT_EQ(params.size(), 1u);
+        // ScaleRect gives [0, 0, 150, 150].
+        // Clamped to image size [100, 100] gives [0, 0, 100, 100].
+        EXPECT_EQ(params[0].content_rect, gfx::RectF(0, 0, 100, 100));
+      });
+
+  output_device_->ScheduleOverlays(std::move(overlays));
+}
+
+}  // namespace
+}  // namespace viz
Loading diff…

Original Bug Report

reported by vm...@google.com

Potential out-of-bounds D3D11 source rect via unvalidated DComp Overlay path

Project Fortify, an experimental security project, has identified the following potential security issue.

Overview: A compromised renderer can supply a CompositorFrame with a TextureDrawQuad and TransferableResource containing unvalidated, out-of-bounds coordinates and sizes. These values are passed through the DirectComposition overlay pipeline without validation against the actual GPU texture size. This results in D3D11 VideoProcessor APIs being called with an out-of-bounds source rectangle, potentially leading to cross-origin GPU memory disclosure or driver memory corruption.

Affected files:

  • components/viz/service/display_embedder/skia_output_device_dcomp.cc
  • ui/gl/swap_chain_presenter.cc
  • components/viz/service/display/dc_layer_overlay.cc
  • components/viz/common/quads/texture_draw_quad.h
  • components/viz/service/display/display_resource_provider.cc

Estimated timestamp from git blame: 2025-05-12

Summary

A potential vulnerability exists in the DirectComposition (DComp) video overlay path on Windows where unvalidated renderer-controlled data is passed to D3D11 APIs. A compromised renderer can submit a CompositorFrame containing a TextureDrawQuad with an out-of-bounds tex_coord_rect_ and a TransferableResource that reports an incorrect size. These values are used to compute a source rectangle for video processing without adequate validation against the actual GPU-backed texture dimensions.

Technical Analysis

The vulnerability stems from a lack of validation across multiple stages of the compositing pipeline, specifically in the hardware overlay path:

  1. Mojo Deserialization: The Mojo traits for TextureDrawQuad (in services/viz/public/cpp/compositing/quads_mojom_traits.cc) and TransferableResource (in services/viz/public/cpp/compositing/transferable_resource_mojom_traits.cc) deserialize fields like tex_coord_rect_, is_video_frame, and is_normalized_coords without validation against the actual resource being referenced.
  2. Texture Coordinate Handling: In components/viz/common/quads/texture_draw_quad.h, the GetNormalizedTexCoords method returns tex_coord_rect_ directly if is_normalized_coords is true, failing to clamp the values to the expected [0, 1] range.
  3. Resource Size Propagation: DisplayResourceProvider::GetResourceBackedSize in components/viz/service/display/display_resource_provider.cc returns the size claimed by the renderer in the TransferableResource metadata. This size is then used in DCLayerOverlayProcessor::FromDrawQuad to populate an OverlayCandidate.
  4. Unbounded Content Rect Calculation: In SkiaOutputDeviceDComp::ScheduleDCLayers (via ScheduleOverlays) in components/viz/service/display_embedder/skia_output_device_dcomp.cc, the params.content_rect is calculated by scaling the uv_rect by resource_size_in_pixels. Since both are renderer-controlled and unvalidated, the resulting content_rect can be arbitrarily large.
  5. Bypassing Validation: When BeginOverlayAccess is called, it retrieves the actual SharedImageBacking based on the mailbox via ProduceOverlay. While the standard rasterization ProduceSkia path contains size-mismatch checks (in components/viz/service/display_embedder/image_context_impl.cc), the ProduceOverlay path (in SharedImageManager::ProduceOverlay) does not validate that the backing texture’s actual dimensions match the TransferableResource’s claimed size.
  6. D3D11 API Sink: In ui/gl/swap_chain_presenter.cc, the massively out-of-bounds content_rect is converted to a RECT and passed directly as a source rectangle to D3D11 APIs, specifically VideoProcessorSetStreamSourceRect and IDXGIDecodeSwapChain::SetSourceRect, with no further clamping or intersection against the input texture’s true bounds.

Security Impact

Per Microsoft’s D3D11 documentation, the source rectangle must fall within the bounds of the input surface. Violating this constraint leads to driver-undefined behavior. Depending on the specific IHV GPU driver implementation, this can result in:

  • Information Disclosure: An out-of-bounds (OOB) read of adjacent GPU memory can occur, which is then blitted into the visible swap chain. This allows a compromised renderer to capture cross-origin pixels (e.g., via getDisplayMedia).
  • Memory Corruption: Driver state corruption may lead to memory corruption within the GPU process.
  • Denial of Service: The driver may crash or cause a GPU Timeout Detection and Recovery (TDR).

Potential Steps to Reproduce

Note: Our tooling agent does not yet have the capability to run code, so these are suggested steps to trigger the vulnerability based on static analysis.

  1. Compromise a renderer process.
  2. Construct a malicious CompositorFrame containing a valid video or canvas shared image Mailbox.
  3. Create a TransferableResource for this mailbox, but spoof its size metadata to be exceptionally large (e.g., gfx::Size(10000, 10000)).
  4. Create a TextureDrawQuad linking to this resource. Set is_normalized_coords to true and set tex_coord_rect_ to massive or negative values (e.g., gfx::RectF(-1000.0f, -1000.0f, 2000.0f, 2000.0f)).
  5. Ensure the quad meets the criteria for DirectComposition overlay promotion on Windows (e.g., large enough on screen, no complex clipping).
  6. Submit the frame to the Viz process via Mojo.
  7. If successful, observe driver instability or use getDisplayMedia to capture the resulting screen contents, looking for leaked GPU memory artifacts.

Suggested Fix

Validation should be added to ensure that the renderer cannot specify an overlay source rectangle that exceeds the bounds of the actual GPU-backed texture.

  1. Add Validation to ProduceOverlay: Similar to the checks in ImageContextImpl::ProduceSkia, SharedImageManager::ProduceOverlay (or a higher-level caller like SkiaOutputDeviceDComp::BeginOverlayAccess) should verify that the dimensions claimed in the TransferableResource (and thus dc_layer.resource_size_in_pixels) do not exceed the actual size() of the produced OverlayImageRepresentation.
  2. Clamp content_rect in SwapChainPresenter: As a defense-in-depth measure, ui/gl/swap_chain_presenter.cc should validate or intersect the content_rect against the input_texture’s actual bounds (retrieved via GetDesc) before passing it to VideoProcessorSetStreamSourceRect or SetSourceRect.

Evaluated with Chrome root at commit: a9cbf6e8b275fe4147435aa905f3b7f5a656f5f0


Results from 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. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker