aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Khushal <khushalsagar@chromium.org>2018-05-07 13:57:43 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-07 21:31:30 +0000
commitcea8e3d1326df16f1eeb41233703bf469016025c (patch)
tree6f31f9e52a0f49043b216c816c2339bca70dc2ea
parent4e9e32572529ffc5bb442fe082206df2285261e3 (diff)
text-blob: Fix OOM issues during blob deserialization.
Limit the number of glyphs allowed during blob deserialization. Allocating for an arbitrary number can lead to OOM issues. Bug: 840096 Change-Id: I1673fd312438b99ff76dadcfdc9f9427acdca13b R=bsalomon@chromium.org Reviewed-on: https://skia-review.googlesource.com/126603 Commit-Queue: Khusal Sagar <khushalsagar@chromium.org> Reviewed-by: Florin Malita <fmalita@chromium.org>
-rw-r--r--src/core/SkReadBuffer.h5
-rw-r--r--src/core/SkTextBlob.cpp23
2 files changed, 19 insertions, 9 deletions
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index b5666cc39c..ec64e8a0b2 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -96,11 +96,12 @@ public:
fVersion = version;
}
- size_t size() { return fReader.size(); }
- size_t offset() { return fReader.offset(); }
+ size_t size() const { return fReader.size(); }
+ size_t offset() const { return fReader.offset(); }
bool eof() { return fReader.eof(); }
const void* skip(size_t size);
const void* skip(size_t count, size_t size); // does safe multiply
+ size_t available() const { return fReader.available(); }
template <typename T> const T* skipT() {
return static_cast<const T*>(this->skip(sizeof(T)));
diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
index e2d3be4518..556e090104 100644
--- a/src/core/SkTextBlob.cpp
+++ b/src/core/SkTextBlob.cpp
@@ -793,6 +793,7 @@ sk_sp<SkTextBlob> SkTextBlob::MakeFromBuffer(SkReadBuffer& reader) {
reader.readRect(&bounds);
SkTextBlobBuilder blobBuilder;
+ SkSafeMath safe;
for (;;) {
int glyphCount = reader.read32();
if (glyphCount == 0) {
@@ -807,7 +808,7 @@ sk_sp<SkTextBlob> SkTextBlob::MakeFromBuffer(SkReadBuffer& reader) {
return nullptr;
}
int textSize = pe.extended ? reader.read32() : 0;
- if (textSize < 0 || static_cast<size_t>(textSize) > reader.size()) {
+ if (textSize < 0) {
return nullptr;
}
@@ -816,7 +817,16 @@ sk_sp<SkTextBlob> SkTextBlob::MakeFromBuffer(SkReadBuffer& reader) {
SkPaint font;
reader.readPaint(&font);
- if (!reader.isValid()) {
+ // Compute the expected size of the buffer and ensure we have enough to deserialize
+ // a run before allocating it.
+ const size_t glyphSize = safe.mul(glyphCount, sizeof(uint16_t)),
+ posSize =
+ safe.mul(glyphCount, safe.mul(sizeof(SkScalar), ScalarsPerGlyph(pos))),
+ clusterSize = pe.extended ? safe.mul(glyphCount, sizeof(uint32_t)) : 0;
+ const size_t totalSize =
+ safe.add(safe.add(glyphSize, posSize), safe.add(clusterSize, textSize));
+
+ if (!reader.isValid() || !safe || totalSize > reader.available()) {
return nullptr;
}
@@ -843,14 +853,13 @@ sk_sp<SkTextBlob> SkTextBlob::MakeFromBuffer(SkReadBuffer& reader) {
return nullptr;
}
- if (!reader.readByteArray(buf->glyphs, glyphCount * sizeof(uint16_t)) ||
- !reader.readByteArray(buf->pos,
- glyphCount * sizeof(SkScalar) * ScalarsPerGlyph(pos))) {
- return nullptr;
+ if (!reader.readByteArray(buf->glyphs, glyphSize) ||
+ !reader.readByteArray(buf->pos, posSize)) {
+ return nullptr;
}
if (pe.extended) {
- if (!reader.readByteArray(buf->clusters, glyphCount * sizeof(uint32_t)) ||
+ if (!reader.readByteArray(buf->clusters, clusterSize) ||
!reader.readByteArray(buf->utf8text, textSize)) {
return nullptr;
}