diff options
author | Khushal <khushalsagar@chromium.org> | 2018-05-07 13:57:43 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-07 21:31:30 +0000 |
commit | cea8e3d1326df16f1eeb41233703bf469016025c (patch) | |
tree | 6f31f9e52a0f49043b216c816c2339bca70dc2ea | |
parent | 4e9e32572529ffc5bb442fe082206df2285261e3 (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.h | 5 | ||||
-rw-r--r-- | src/core/SkTextBlob.cpp | 23 |
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; } |