aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2018-05-31 13:16:59 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-01 20:15:46 +0000
commit804d0f28ba6de89b7e671c0e9192e16b7494944d (patch)
tree6dab092fe9ed6a138f95e3cc157a933d03b625ae
parent11203af095573b91dcf23398d8557d2963f802a1 (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.gn2
-rw-r--r--src/core/SkImageInfo.cpp6
-rw-r--r--src/core/SkRasterPipelineBlitter.cpp10
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: