diff options
author | Florin Malita <fmalita@chromium.org> | 2018-05-10 09:52:27 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-10 14:28:35 +0000 |
commit | f77db110e1c4d2b813ed40de0cf63f65f84b4b64 (patch) | |
tree | ebcf951baf445b5b45dda88d7cc33f12291ea47c /src/shaders | |
parent | ff6a7cd4d2da9a8c992a20da01cd439bfb008b5c (diff) |
Validate gradient DescriptorScope size during deserialization
Check that the reader has sufficient data before allocating buffers.
Bug: skia:7937
Change-Id: I2352d9a5cbace77b77c150a3a6439e8ac18b0dc5
Reviewed-on: https://skia-review.googlesource.com/127132
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Diffstat (limited to 'src/shaders')
-rw-r--r-- | src/shaders/gradients/SkGradientShader.cpp | 33 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShaderPriv.h | 11 |
2 files changed, 25 insertions, 19 deletions
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 60b9e34f79..f61bb7c2d4 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -17,6 +17,7 @@ #include "SkMallocPixelRef.h" #include "SkRadialGradient.h" #include "SkReadBuffer.h" +#include "SkSafeMath.h" #include "SkSweepGradient.h" #include "SkTwoPointConicalGradient.h" #include "SkWriteBuffer.h" @@ -71,6 +72,19 @@ void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const { } } +template <int N, typename T, bool MEM_MOVE> +static bool validate_array(SkReadBuffer& buffer, size_t count, SkSTArray<N, T, MEM_MOVE>* array) { + SkSafeMath safe; + const auto expectedSize = safe.mul(sizeof(T), count); + + if (!buffer.validate(safe && expectedSize <= buffer.available())) { + return false; + } + + array->resize_back(count); + return true; +} + bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) { // New gradient format. Includes floating point color, color space, densely packed flags uint32_t flags = buffer.readUInt(); @@ -79,18 +93,13 @@ bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) { fGradFlags = (flags >> kGradFlagsShift_GSF) & kGradFlagsMask_GSF; fCount = buffer.getArrayCount(); - if (fCount > kStorageCount) { - size_t allocSize = (sizeof(SkColor4f) + sizeof(SkScalar)) * fCount; - fDynamicStorage.reset(allocSize); - fColors = (SkColor4f*)fDynamicStorage.get(); - fPos = (SkScalar*)(fColors + fCount); - } else { - fColors = fColorStorage; - fPos = fPosStorage; - } - if (!buffer.readColor4fArray(mutableColors(), fCount)) { + + if (!(validate_array(buffer, fCount, &fColorStorage) && + buffer.readColor4fArray(fColorStorage.begin(), fCount))) { return false; } + fColors = fColorStorage.begin(); + if (SkToBool(flags & kHasColorSpace_GSF)) { sk_sp<SkData> data = buffer.readByteArrayAsData(); fColorSpace = SkColorSpace::Deserialize(data->data(), data->size()); @@ -98,9 +107,11 @@ bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) { fColorSpace = nullptr; } if (SkToBool(flags & kHasPosition_GSF)) { - if (!buffer.readScalarArray(mutablePos(), fCount)) { + if (!(validate_array(buffer, fCount, &fPosStorage) && + buffer.readScalarArray(fPosStorage.begin(), fCount))) { return false; } + fPos = fPosStorage.begin(); } else { fPos = nullptr; } diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h index f8f28e97d1..dccb4e70cb 100644 --- a/src/shaders/gradients/SkGradientShaderPriv.h +++ b/src/shaders/gradients/SkGradientShaderPriv.h @@ -11,7 +11,6 @@ #include "SkGradientShader.h" #include "SkArenaAlloc.h" -#include "SkAutoMalloc.h" #include "SkMatrix.h" #include "SkShaderBase.h" #include "SkTArray.h" @@ -54,13 +53,9 @@ public: SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); } private: - enum { - kStorageCount = 16 - }; - SkColor4f fColorStorage[kStorageCount]; - SkScalar fPosStorage[kStorageCount]; - SkMatrix fLocalMatrixStorage; - SkAutoMalloc fDynamicStorage; + SkSTArray<16, SkColor4f, true> fColorStorage; + SkSTArray<16, SkScalar , true> fPosStorage; + SkMatrix fLocalMatrixStorage; }; SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit); |