Fix fuzzer-found deserialization bugs

This fixes deserialization bugs found by fuzzing SkPaintImageFilter.

BUG=576908,576910
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1589533002

Review URL: https://codereview.chromium.org/1589533002
This commit is contained in:
ajuma 2016-01-13 13:46:31 -08:00 committed by Commit bot
parent 97c40072b0
commit f8aec588bf
4 changed files with 16 additions and 13 deletions

View File

@ -35,7 +35,7 @@ size_t SkRBuffer::skipToAlign4()
} }
bool SkRBufferWithSizeCheck::read(void* buffer, size_t size) { bool SkRBufferWithSizeCheck::read(void* buffer, size_t size) {
fError = fError || (fPos + size > fStop); fError = fError || (size > static_cast<size_t>(fStop - fPos));
if (!fError && (size > 0)) { if (!fError && (size > 0)) {
readNoSizeCheck(buffer, size); readNoSizeCheck(buffer, size);
} }

View File

@ -1946,6 +1946,9 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const {
void SkPaint::unflatten(SkReadBuffer& buffer) { void SkPaint::unflatten(SkReadBuffer& buffer) {
SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
if (!buffer.validateAvailable(kPODPaintSize)) {
return;
}
const void* podData = buffer.skip(kPODPaintSize); const void* podData = buffer.skip(kPODPaintSize);
const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);

View File

@ -1909,6 +1909,13 @@ size_t SkPath::readFromMemory(const void* storage, size_t length) {
uint8_t dir = (packed >> kDirection_SerializationShift) & 0x3; uint8_t dir = (packed >> kDirection_SerializationShift) & 0x3;
fIsVolatile = (packed >> kIsVolatile_SerializationShift) & 0x1; fIsVolatile = (packed >> kIsVolatile_SerializationShift) & 0x1;
SkPathRef* pathRef = SkPathRef::CreateFromBuffer(&buffer); SkPathRef* pathRef = SkPathRef::CreateFromBuffer(&buffer);
if (!pathRef) {
return 0;
}
fPathRef.reset(pathRef);
SkDEBUGCODE(this->validate();)
buffer.skipToAlign4();
// compatibility check // compatibility check
if (version < kPathPrivFirstDirection_Version) { if (version < kPathPrivFirstDirection_Version) {
@ -1929,17 +1936,7 @@ size_t SkPath::readFromMemory(const void* storage, size_t length) {
fFirstDirection = dir; fFirstDirection = dir;
} }
size_t sizeRead = 0; return buffer.pos();
if (buffer.isValid()) {
fPathRef.reset(pathRef);
SkDEBUGCODE(this->validate();)
buffer.skipToAlign4();
sizeRead = buffer.pos();
} else if (pathRef) {
// If the buffer is not valid, pathRef should be nullptr
sk_throw();
}
return sizeRead;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -138,8 +138,11 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
int32_t verbCount, pointCount, conicCount; int32_t verbCount, pointCount, conicCount;
if (!buffer->readU32(&(ref->fGenerationID)) || if (!buffer->readU32(&(ref->fGenerationID)) ||
!buffer->readS32(&verbCount) || !buffer->readS32(&verbCount) ||
verbCount < 0 ||
!buffer->readS32(&pointCount) || !buffer->readS32(&pointCount) ||
!buffer->readS32(&conicCount)) { pointCount < 0 ||
!buffer->readS32(&conicCount) ||
conicCount < 0) {
delete ref; delete ref;
return nullptr; return nullptr;
} }