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>
This commit is contained in:
parent
ff6a7cd4d2
commit
f77db110e1
@ -17,6 +17,7 @@
|
|||||||
#include "SkMallocPixelRef.h"
|
#include "SkMallocPixelRef.h"
|
||||||
#include "SkRadialGradient.h"
|
#include "SkRadialGradient.h"
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
|
#include "SkSafeMath.h"
|
||||||
#include "SkSweepGradient.h"
|
#include "SkSweepGradient.h"
|
||||||
#include "SkTwoPointConicalGradient.h"
|
#include "SkTwoPointConicalGradient.h"
|
||||||
#include "SkWriteBuffer.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) {
|
bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) {
|
||||||
// New gradient format. Includes floating point color, color space, densely packed flags
|
// New gradient format. Includes floating point color, color space, densely packed flags
|
||||||
uint32_t flags = buffer.readUInt();
|
uint32_t flags = buffer.readUInt();
|
||||||
@ -79,18 +93,13 @@ bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) {
|
|||||||
fGradFlags = (flags >> kGradFlagsShift_GSF) & kGradFlagsMask_GSF;
|
fGradFlags = (flags >> kGradFlagsShift_GSF) & kGradFlagsMask_GSF;
|
||||||
|
|
||||||
fCount = buffer.getArrayCount();
|
fCount = buffer.getArrayCount();
|
||||||
if (fCount > kStorageCount) {
|
|
||||||
size_t allocSize = (sizeof(SkColor4f) + sizeof(SkScalar)) * fCount;
|
if (!(validate_array(buffer, fCount, &fColorStorage) &&
|
||||||
fDynamicStorage.reset(allocSize);
|
buffer.readColor4fArray(fColorStorage.begin(), fCount))) {
|
||||||
fColors = (SkColor4f*)fDynamicStorage.get();
|
|
||||||
fPos = (SkScalar*)(fColors + fCount);
|
|
||||||
} else {
|
|
||||||
fColors = fColorStorage;
|
|
||||||
fPos = fPosStorage;
|
|
||||||
}
|
|
||||||
if (!buffer.readColor4fArray(mutableColors(), fCount)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
fColors = fColorStorage.begin();
|
||||||
|
|
||||||
if (SkToBool(flags & kHasColorSpace_GSF)) {
|
if (SkToBool(flags & kHasColorSpace_GSF)) {
|
||||||
sk_sp<SkData> data = buffer.readByteArrayAsData();
|
sk_sp<SkData> data = buffer.readByteArrayAsData();
|
||||||
fColorSpace = SkColorSpace::Deserialize(data->data(), data->size());
|
fColorSpace = SkColorSpace::Deserialize(data->data(), data->size());
|
||||||
@ -98,9 +107,11 @@ bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) {
|
|||||||
fColorSpace = nullptr;
|
fColorSpace = nullptr;
|
||||||
}
|
}
|
||||||
if (SkToBool(flags & kHasPosition_GSF)) {
|
if (SkToBool(flags & kHasPosition_GSF)) {
|
||||||
if (!buffer.readScalarArray(mutablePos(), fCount)) {
|
if (!(validate_array(buffer, fCount, &fPosStorage) &&
|
||||||
|
buffer.readScalarArray(fPosStorage.begin(), fCount))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
fPos = fPosStorage.begin();
|
||||||
} else {
|
} else {
|
||||||
fPos = nullptr;
|
fPos = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "SkGradientShader.h"
|
#include "SkGradientShader.h"
|
||||||
|
|
||||||
#include "SkArenaAlloc.h"
|
#include "SkArenaAlloc.h"
|
||||||
#include "SkAutoMalloc.h"
|
|
||||||
#include "SkMatrix.h"
|
#include "SkMatrix.h"
|
||||||
#include "SkShaderBase.h"
|
#include "SkShaderBase.h"
|
||||||
#include "SkTArray.h"
|
#include "SkTArray.h"
|
||||||
@ -54,13 +53,9 @@ public:
|
|||||||
SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
|
SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
SkSTArray<16, SkColor4f, true> fColorStorage;
|
||||||
kStorageCount = 16
|
SkSTArray<16, SkScalar , true> fPosStorage;
|
||||||
};
|
|
||||||
SkColor4f fColorStorage[kStorageCount];
|
|
||||||
SkScalar fPosStorage[kStorageCount];
|
|
||||||
SkMatrix fLocalMatrixStorage;
|
SkMatrix fLocalMatrixStorage;
|
||||||
SkAutoMalloc fDynamicStorage;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
|
SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
|
||||||
|
Loading…
Reference in New Issue
Block a user