aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-05-10 09:52:27 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-10 14:28:35 +0000
commitf77db110e1c4d2b813ed40de0cf63f65f84b4b64 (patch)
treeebcf951baf445b5b45dda88d7cc33f12291ea47c
parentff6a7cd4d2da9a8c992a20da01cd439bfb008b5c (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>
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp33
-rw-r--r--src/shaders/gradients/SkGradientShaderPriv.h11
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);