Fix fuzzer-found deserialization bugs
authorajuma <ajuma@chromium.org>
Wed, 13 Jan 2016 21:46:31 +0000 (13:46 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 13 Jan 2016 21:46:32 +0000 (13:46 -0800)
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

src/core/SkBuffer.cpp
src/core/SkPaint.cpp
src/core/SkPath.cpp
src/core/SkPathRef.cpp

index 86c3bed..df8dc69 100644 (file)
@@ -35,7 +35,7 @@ size_t SkRBuffer::skipToAlign4()
 }
 
 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)) {
         readNoSizeCheck(buffer, size);
     }
index c0e552a..e5fe975 100644 (file)
@@ -1946,6 +1946,9 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const {
 
 void SkPaint::unflatten(SkReadBuffer& buffer) {
     SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
+    if (!buffer.validateAvailable(kPODPaintSize)) {
+        return;
+    }
     const void* podData = buffer.skip(kPODPaintSize);
     const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
 
index ab8d735..4af2dad 100644 (file)
@@ -1909,6 +1909,13 @@ size_t SkPath::readFromMemory(const void* storage, size_t length) {
     uint8_t dir = (packed >> kDirection_SerializationShift) & 0x3;
     fIsVolatile = (packed >> kIsVolatile_SerializationShift) & 0x1;
     SkPathRef* pathRef = SkPathRef::CreateFromBuffer(&buffer);
+    if (!pathRef) {
+        return 0;
+    }
+
+    fPathRef.reset(pathRef);
+    SkDEBUGCODE(this->validate();)
+    buffer.skipToAlign4();
 
     // compatibility check
     if (version < kPathPrivFirstDirection_Version) {
@@ -1929,17 +1936,7 @@ size_t SkPath::readFromMemory(const void* storage, size_t length) {
         fFirstDirection = dir;
     }
 
-    size_t sizeRead = 0;
-    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;
+    return buffer.pos();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index 28bffcb..cf4e8ff 100644 (file)
@@ -138,8 +138,11 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer) {
     int32_t verbCount, pointCount, conicCount;
     if (!buffer->readU32(&(ref->fGenerationID)) ||
         !buffer->readS32(&verbCount) ||
+        verbCount < 0 ||
         !buffer->readS32(&pointCount) ||
-        !buffer->readS32(&conicCount)) {
+        pointCount < 0 ||
+        !buffer->readS32(&conicCount) ||
+        conicCount < 0) {
         delete ref;
         return nullptr;
     }