diff options
author | John Stiles <johnstiles@google.com> | 2023-08-03 13:33:52 -0400 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-09-14 09:47:36 +0000 |
commit | 419ccc596a8fe69b071067213efd19be0659e605 (patch) | |
tree | 59d67fb2974d2624ed18549e76aec03cd795e7d3 | |
parent | 5f69b708f88738aac4560590a47adb05ea7aff75 (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.cpp | 79 |
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; |