Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInformation leak in Skia
DescriptionInformation leak in Skia
ComponentSkia
Bug ClassLogic Error
Tracker513969378
Fix commite30d3d14a4c3 (skia) +62/-2
CISA KEVNot listed
CreditedGoogle
Disclosed2026-08-25

Changed Functions

FunctionChangeNotes
if
src/gpu/ganesh/GrFragmentProcessors.cpp
modified
for
tests/ProtectedTest.cpp
modified

Files Changed

  • src/gpu/ganesh/GrFragmentProcessors.cpp
  • tests/ProtectedTest.cpp
From e30d3d14a4c33a4d594fa1a71ab3d4f74b7aeebe Mon Sep 17 00:00:00 2001
From: Robert Phillips <robertphillips@google.com>
Date: Tue, 30 Jun 2026 17:35:01 +0000
Subject: [PATCH] Propagate protectedness to SkPictureShader draws

This change seems harmless and is more correct. Basically, the protected-ness of the backing surface is propagated to the internal image created for a PictureShader. This is relevant if the SkPicture contains protected content.

Bug: b/513969378
Change-Id: I9314aca6481850d098bab0515601cca51fb7a00a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1281217
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
---

diff --git a/src/gpu/ganesh/GrFragmentProcessors.cpp b/src/gpu/ganesh/GrFragmentProcessors.cpp
index 5de0327..bfb26ea 100644
--- a/src/gpu/ganesh/GrFragmentProcessors.cpp
+++ b/src/gpu/ganesh/GrFragmentProcessors.cpp
@@ -755,7 +755,9 @@
     } else {
         const int msaaSampleCount = 0;
         const bool createWithMips = false;
-        const bool kUnprotected = false;
+        const bool isProtected =
+                args.fSurfaceDrawContext->asSurfaceProxy()->isProtected() ==
+                GrProtected::kYes;
         auto image = info.makeImage(SkSurfaces::RenderTarget(ctx,
                                                              skgpu::Budgeted::kYes,
                                                              info.imageInfo,
@@ -763,7 +765,7 @@
                                                              kTopLeft_GrSurfaceOrigin,
                                                              &info.props,
                                                              createWithMips,
-                                                             kUnprotected),
+                                                             isProtected),
                                     shader->picture().get());
         if (!image) {
             return nullptr;
diff --git a/tests/ProtectedTest.cpp b/tests/ProtectedTest.cpp
index 9f779c6..e3499fb 100644
--- a/tests/ProtectedTest.cpp
+++ b/tests/ProtectedTest.cpp
@@ -13,6 +13,8 @@
 #include "include/core/SkCanvas.h"
 #include "include/core/SkColorSpace.h"
 #include "include/core/SkPaint.h"
+#include "include/core/SkPicture.h"
+#include "include/core/SkPictureRecorder.h"
 #include "include/core/SkSurface.h"
 #include "include/gpu/ganesh/GrBackendSurface.h"
 #include "include/gpu/ganesh/GrDirectContext.h"
@@ -230,4 +232,60 @@
     REPORTER_ASSERT(reporter, !cbContext.fResult);
 }
 
+DEF_GANESH_TEST_FOR_ALL_CONTEXTS(Protected_pictureShader, reporter,
+                                 ctxInfo, CtsEnforcement::kNever) {
+    auto dContext = ctxInfo.directContext();
+
+    if (!dContext->supportsProtectedContent()) {
+        // Protected content not supported
+        return;
+    }
+
+    sk_sp<SkImage> protectedImage = ProtectedUtils::CreateProtectedSkImage(dContext,
+                                                                           { kSize, kSize },
+                                                                           SkColors::kBlue,
+                                                                           /* isProtected= */ true);
+    dContext->flushAndSubmit(GrSyncCpu::kYes);
+
+    REPORTER_ASSERT(reporter, protectedImage);
+    REPORTER_ASSERT(reporter, protectedImage->isProtected());
+
+    sk_sp<SkPicture> protectedPicture;
+    {
+        SkPictureRecorder recorder;
+        recorder.beginRecording(100, 100)->drawImage(protectedImage.get(), 0, 0);
+        protectedPicture = recorder.finishRecordingAsPicture();
+        REPORTER_ASSERT(reporter, protectedPicture);
+    }
+
+    SkPaint protectedPaint;
+    protectedPaint.setShader(protectedPicture->makeShader(SkTileMode::kRepeat,
+                                                          SkTileMode::kRepeat,
+                                                          SkFilterMode::kNearest));
+
+    SkImageInfo ii = SkImageInfo::Make({ kSize, kSize },
+                                       kRGBA_8888_SkColorType,
+                                       kPremul_SkAlphaType);
+
+    for (bool isProtected : { true, false }) {
+        sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(dContext,
+                                                            skgpu::Budgeted::kNo,
+                                                            ii,
+                                                            /* sampleCount= */ 1,
+                                                            kBottomLeft_GrSurfaceOrigin,
+                                                            /* surfaceProps= */ nullptr,
+                                                            /* shouldCreateWithMips= */ false,
+                                                            isProtected);
+
+        REPORTER_ASSERT(reporter, surface);
+
+        // For the un-protected surface, drawing the SkPicture containing the protected
+        // image should cause the final draw of the generated image to the surface to fail
+        // while the generation of the internal (protected) image should succeed.
+        surface->getCanvas()->drawPaint(protectedPaint);
+    }
+
+    dContext->flushAndSubmit(GrSyncCpu::kYes);
+}
+
 #endif  // defined(SK_GANESH)
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.