electron/patches/skia/ganesh_avoid_int_overflow_i...

159 lines
5.9 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: James Godfrey-Kittle <jamesgk@google.com>
Date: Wed, 28 Aug 2024 10:48:21 -0400
Subject: [ganesh] Avoid int overflow in PatternHelper
The callers of PatternHelper which are not updated here pass in a TArray
size as repeatCount, which already prevents overflow:
https://crsrc.org/c/third_party/skia/include/private/base/SkTArray.h?q=kMaxCapacity
Bug: b/361461526
Change-Id: I86c494cb00223f0bb8d68540d33d7230b60c9486
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/893916
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: James Godfrey-Kittle <jamesgk@google.com>
(cherry picked from commit 07fcb9a00233cace0b6cc19ed4bcec6770e0315f)
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/896478
diff --git a/src/gpu/ganesh/ops/DashOp.cpp b/src/gpu/ganesh/ops/DashOp.cpp
index 6f12cc38aa36fb779375b187ea72138397adcf43..56303cd9e87d56973b00dd0c81b803e48a7d8479 100644
--- a/src/gpu/ganesh/ops/DashOp.cpp
+++ b/src/gpu/ganesh/ops/DashOp.cpp
@@ -8,6 +8,7 @@
#include "src/gpu/ganesh/ops/DashOp.h"
#include "include/gpu/GrRecordingContext.h"
+#include "src/base/SkSafeMath.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkPointPriv.h"
#include "src/gpu/BufferWriter.h"
@@ -354,6 +355,7 @@ private:
STArray<kNumStackDashes, SkRect, true> rects;
STArray<kNumStackDashes, DashDraw, true> draws;
+ SkSafeMath safeMath;
int totalRectCount = 0;
int rectOffset = 0;
rects.push_back_n(3 * instanceCount);
@@ -520,9 +522,9 @@ private:
devIntervals[0] = lineLength;
}
- totalRectCount += !lineDone ? 1 : 0;
- totalRectCount += hasStartRect ? 1 : 0;
- totalRectCount += hasEndRect ? 1 : 0;
+ totalRectCount = safeMath.addInt(totalRectCount, !lineDone ? 1 : 0);
+ totalRectCount = safeMath.addInt(totalRectCount, hasStartRect ? 1 : 0);
+ totalRectCount = safeMath.addInt(totalRectCount, hasEndRect ? 1 : 0);
if (SkPaint::kRound_Cap == cap && 0 != args.fSrcStrokeWidth) {
// need to adjust this for round caps to correctly set the dashPos attrib on
@@ -562,7 +564,7 @@ private:
draw.fHasEndRect = hasEndRect;
}
- if (!totalRectCount) {
+ if (!totalRectCount || !safeMath) {
return;
}
diff --git a/src/gpu/ganesh/ops/DrawAtlasOp.cpp b/src/gpu/ganesh/ops/DrawAtlasOp.cpp
index 065011699f755b3c87f6cf9a9b19e4d5d42e91df..a3d7e4ddabb1a29ec50b5e1aab88cabcf1445104 100644
--- a/src/gpu/ganesh/ops/DrawAtlasOp.cpp
+++ b/src/gpu/ganesh/ops/DrawAtlasOp.cpp
@@ -10,6 +10,7 @@
#include "include/core/SkRSXform.h"
#include "include/gpu/GrRecordingContext.h"
#include "src/base/SkRandom.h"
+#include "src/base/SkSafeMath.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkRectPriv.h"
#include "src/gpu/ganesh/GrCaps.h"
@@ -280,8 +281,14 @@ GrOp::CombineResult DrawAtlasOpImpl::onCombineIfPossible(GrOp* t,
return CombineResult::kCannotCombine;
}
+ SkSafeMath safeMath;
+ int newQuadCount = safeMath.addInt(fQuadCount, that->quadCount());
+ if (!safeMath) {
+ return CombineResult::kCannotCombine;
+ }
+
fGeoData.push_back_n(that->fGeoData.size(), that->fGeoData.begin());
- fQuadCount += that->quadCount();
+ fQuadCount = newQuadCount;
return CombineResult::kMerged;
}
diff --git a/src/gpu/ganesh/ops/GrMeshDrawOp.cpp b/src/gpu/ganesh/ops/GrMeshDrawOp.cpp
index 4fdf90b0381996609773e952674aad149b29b98d..5b885f0fd1cae6602d7f0982b91cc2a0af7a8b3b 100644
--- a/src/gpu/ganesh/ops/GrMeshDrawOp.cpp
+++ b/src/gpu/ganesh/ops/GrMeshDrawOp.cpp
@@ -7,6 +7,7 @@
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
+#include "include/private/base/SkMath.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrOpsRenderPass.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
@@ -81,6 +82,12 @@ void GrMeshDrawOp::PatternHelper::init(GrMeshDrawTarget* target, GrPrimitiveType
if (!indexBuffer) {
return;
}
+
+ // Bail out when we get overflow from really large draws.
+ if (repeatCount < 0 || repeatCount > SK_MaxS32 / verticesPerRepetition) {
+ return;
+ }
+
sk_sp<const GrBuffer> vertexBuffer;
int firstVertex;
int vertexCount = verticesPerRepetition * repeatCount;
diff --git a/src/gpu/ganesh/ops/LatticeOp.cpp b/src/gpu/ganesh/ops/LatticeOp.cpp
index d1ae7ad1fa8e06f5fd862867118bd7688ccf209b..ce9d08ac89ee801177fbf7d8fb1466dd68713915 100644
--- a/src/gpu/ganesh/ops/LatticeOp.cpp
+++ b/src/gpu/ganesh/ops/LatticeOp.cpp
@@ -9,6 +9,7 @@
#include "include/core/SkBitmap.h"
#include "include/core/SkRect.h"
+#include "src/base/SkSafeMath.h"
#include "src/core/SkLatticeIter.h"
#include "src/core/SkMatrixPriv.h"
#include "src/gpu/BufferWriter.h"
@@ -240,11 +241,13 @@ private:
int patchCnt = fPatches.size();
int numRects = 0;
+
+ SkSafeMath safeMath;
for (int i = 0; i < patchCnt; i++) {
- numRects += fPatches[i].fIter->numRectsToDraw();
+ numRects = safeMath.addInt(numRects, fPatches[i].fIter->numRectsToDraw());
}
- if (!numRects) {
+ if (!numRects || !safeMath) {
return;
}
diff --git a/src/gpu/ganesh/ops/RegionOp.cpp b/src/gpu/ganesh/ops/RegionOp.cpp
index 58383775bc8bdd0e98125df01c538e03ef1ebc69..2ff9d648db32ad9b115c39c7321d3491fb13ae04 100644
--- a/src/gpu/ganesh/ops/RegionOp.cpp
+++ b/src/gpu/ganesh/ops/RegionOp.cpp
@@ -122,12 +122,8 @@ private:
for (int i = 0; i < numRegions; i++) {
numRects = safeMath.addInt(numRects, fRegions[i].fRegion.computeRegionComplexity());
}
- if (!safeMath) {
- // This is a nonsensical draw, so we can just drop it.
- return;
- }
- if (!numRects) {
+ if (!numRects || !safeMath) {
return;
}