diff options
author | Mike Klein <mtklein@chromium.org> | 2018-05-31 13:16:59 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-01 20:15:46 +0000 |
commit | 804d0f28ba6de89b7e671c0e9192e16b7494944d (patch) | |
tree | 6dab092fe9ed6a138f95e3cc157a933d03b625ae | |
parent | 11203af095573b91dcf23398d8557d2963f802a1 (diff) |
turn on pointer-overflow on ASAN/UBSAN bots
I know SkRasterPipelineBlitter will add back offsets
to the mask pointer to make these fMaskPtr.pixels safe.
SkImageInfo wasn't making out-of-bounds pointers, but was moving
between two in-bounds pointers by subtracting large (negative)
size_t. Switching to explicit negate and add quiets this down.
Bug: chromium:836282
Change-Id: Ia65e380ec41dbfedce0659106830fbacb1a5cf4a
Reviewed-on: https://skia-review.googlesource.com/131147
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
-rw-r--r-- | gn/BUILD.gn | 2 | ||||
-rw-r--r-- | src/core/SkImageInfo.cpp | 6 | ||||
-rw-r--r-- | src/core/SkRasterPipelineBlitter.cpp | 10 |
3 files changed, 11 insertions, 7 deletions
diff --git a/gn/BUILD.gn b/gn/BUILD.gn index 9d65118c96..80b7f3f1bc 100644 --- a/gn/BUILD.gn +++ b/gn/BUILD.gn @@ -228,7 +228,7 @@ config("default") { fyi_sanitizers = fyi_sanitize if (sanitize == "ASAN" || sanitize == "UBSAN") { # ASAN implicitly runs all UBSAN checks also. - sanitizers = "bool,float-cast-overflow,integer-divide-by-zero,nonnull-attribute,null,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound" + sanitizers = "bool,float-cast-overflow,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound" if (fyi_sanitize == "" && !is_android) { fyi_sanitizers = "float-divide-by-zero" diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp index fd5e8087ba..7e08be2ab9 100644 --- a/src/core/SkImageInfo.cpp +++ b/src/core/SkImageInfo.cpp @@ -137,7 +137,8 @@ bool SkReadPixelsRec::trim(int srcWidth, int srcHeight) { y = 0; } // here x,y are either 0 or negative - fPixels = ((char*)fPixels - y * fRowBytes - x * fInfo.bytesPerPixel()); + // we negate and add them so UBSAN (pointer-overflow) doesn't get confused. + fPixels = ((char*)fPixels + -y*fRowBytes + -x*fInfo.bytesPerPixel()); // the intersect may have shrunk info's logical size fInfo = fInfo.makeWH(srcR.width(), srcR.height()); fX = srcR.x(); @@ -173,7 +174,8 @@ bool SkWritePixelsRec::trim(int dstWidth, int dstHeight) { y = 0; } // here x,y are either 0 or negative - fPixels = ((const char*)fPixels - y * fRowBytes - x * fInfo.bytesPerPixel()); + // we negate and add them so UBSAN (pointer-overflow) doesn't get confused. + fPixels = ((const char*)fPixels + -y*fRowBytes + -x*fInfo.bytesPerPixel()); // the intersect may have shrunk info's logical size fInfo = fInfo.makeWH(dstR.width(), dstR.height()); fX = dstR.x(); diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp index 0d45fa11b1..ae7661765a 100644 --- a/src/core/SkRasterPipelineBlitter.cpp +++ b/src/core/SkRasterPipelineBlitter.cpp @@ -472,19 +472,21 @@ void SkRasterPipelineBlitter::blitMask(const SkMask& mask, const SkIRect& clip) std::function<void(size_t,size_t,size_t,size_t)>* blitter = nullptr; // Update fMaskPtr to point "into" this current mask, but lined up with fDstPtr at (0,0). + // This sort of trickery upsets UBSAN (pointer-overflow) so we do our math in uintptr_t. + // mask.fRowBytes is a uint32_t, which would break our addressing math on 64-bit builds. size_t rowBytes = mask.fRowBytes; switch (effectiveMaskFormat) { case SkMask::kA8_Format: fMaskPtr.stride = rowBytes; - fMaskPtr.pixels = (uint8_t*)(mask.fImage - mask.fBounds.left() * (size_t)1 - - mask.fBounds.top() * rowBytes); + fMaskPtr.pixels = (void*)((uintptr_t)mask.fImage - mask.fBounds.left() * (size_t)1 + - mask.fBounds.top() * rowBytes); blitter = &fBlitMaskA8; break; case SkMask::kLCD16_Format: fMaskPtr.stride = rowBytes / 2; - fMaskPtr.pixels = (uint16_t*)(mask.fImage - mask.fBounds.left() * (size_t)2 - - mask.fBounds.top() * rowBytes); + fMaskPtr.pixels = (void*)((uintptr_t)mask.fImage - mask.fBounds.left() * (size_t)2 + - mask.fBounds.top() * rowBytes); blitter = &fBlitMaskLCD16; break; default: |