summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Stiles <johnstiles@google.com>2023-08-03 13:33:52 -0400
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-09-14 09:47:36 +0000
commit419ccc596a8fe69b071067213efd19be0659e605 (patch)
tree59d67fb2974d2624ed18549e76aec03cd795e7d3
parent5f69b708f88738aac4560590a47adb05ea7aff75 (diff)
[Backport] CVE-2023-4354: Heap buffer overflow in Skia
Manual backport of patch originallt reviewed on https://skia-review.googlesource.com/c/skia/+/736359: Enforce an upper limit of 715 million path verbs in SkPath. Bug: chromium:1464215 Change-Id: I264d248f78b9991e2d49d9e42dcffe706e961518 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/736359 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/503195 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/third_party/skia/src/core/SkPath.cpp79
1 files changed, 45 insertions, 34 deletions
diff --git a/chromium/third_party/skia/src/core/SkPath.cpp b/chromium/third_party/skia/src/core/SkPath.cpp
index 00da5e02a50..c5677a5aab1 100644
--- a/chromium/third_party/skia/src/core/SkPath.cpp
+++ b/chromium/third_party/skia/src/core/SkPath.cpp
@@ -27,6 +27,7 @@
#include "src/pathops/SkPathOpsPoint.h"
#include <cmath>
+#include <limits>
#include <utility>
struct SkPath_Storage_Equivalent {
@@ -3345,40 +3346,50 @@ static PathInfo validate_verbs(const uint8_t vbs[], int verbCount) {
bool needMove = true;
bool invalid = false;
- for (int i = 0; i < verbCount; ++i) {
- switch ((SkPathVerb)vbs[i]) {
- case SkPathVerb::kMove:
- needMove = false;
- info.points += 1;
- break;
- case SkPathVerb::kLine:
- invalid |= needMove;
- info.segmentMask |= kLine_SkPathSegmentMask;
- info.points += 1;
- break;
- case SkPathVerb::kQuad:
- invalid |= needMove;
- info.segmentMask |= kQuad_SkPathSegmentMask;
- info.points += 2;
- break;
- case SkPathVerb::kConic:
- invalid |= needMove;
- info.segmentMask |= kConic_SkPathSegmentMask;
- info.points += 2;
- info.weights += 1;
- break;
- case SkPathVerb::kCubic:
- invalid |= needMove;
- info.segmentMask |= kCubic_SkPathSegmentMask;
- info.points += 3;
- break;
- case SkPathVerb::kClose:
- invalid |= needMove;
- needMove = true;
- break;
- default:
- invalid = true;
- break;
+
+ if (verbCount >= (INT_MAX / 3)) {
+ // A path with an extremely high number of quad, conic or cubic verbs could cause
+ // `info.points` to overflow. To prevent against this, we reject extremely large paths. This
+ // check is conservative and assumes the worst case (in particular, it assumes that every
+ // verb consumes 3 points, which would only happen for a path composed entirely of cubics).
+ // This limits us to 700 million verbs, which is large enough for any reasonable use case.
+ invalid = true;
+ } else {
+ for (int i = 0; i < verbCount; ++i) {
+ switch ((SkPathVerb)vbs[i]) {
+ case SkPathVerb::kMove:
+ needMove = false;
+ info.points += 1;
+ break;
+ case SkPathVerb::kLine:
+ invalid |= needMove;
+ info.segmentMask |= kLine_SkPathSegmentMask;
+ info.points += 1;
+ break;
+ case SkPathVerb::kQuad:
+ invalid |= needMove;
+ info.segmentMask |= kQuad_SkPathSegmentMask;
+ info.points += 2;
+ break;
+ case SkPathVerb::kConic:
+ invalid |= needMove;
+ info.segmentMask |= kConic_SkPathSegmentMask;
+ info.points += 2;
+ info.weights += 1;
+ break;
+ case SkPathVerb::kCubic:
+ invalid |= needMove;
+ info.segmentMask |= kCubic_SkPathSegmentMask;
+ info.points += 3;
+ break;
+ case SkPathVerb::kClose:
+ invalid |= needMove;
+ needMove = true;
+ break;
+ default:
+ invalid = true;
+ break;
+ }
}
}
info.valid = !invalid;