Merge tag 'android-security-13.0.0_r24' into int/13/fp3

Android Security 13.0.0 Release 24 (12496786)

* tag 'android-security-13.0.0_r24':
  Prevent overflow when growing an SkRegion's RunArray
  RESTRICT AUTOMERGE: Check for size overflow before allocating SkMask data
  [pdf] Bounds check in skia_alloc_func

Change-Id: Iefa75ca4f21bc78b8930dfb77c4786e6c042a507
diff --git a/src/core/SkBlurMF.cpp b/src/core/SkBlurMF.cpp
index 5421697..5c3b94b 100644
--- a/src/core/SkBlurMF.cpp
+++ b/src/core/SkBlurMF.cpp
@@ -178,6 +178,9 @@
     mask->fRowBytes = SkAlign4(mask->fBounds.width());
     mask->fFormat = SkMask::kA8_Format;
     const size_t size = mask->computeImageSize();
+    if (size == 0) {
+        return false;
+    }
     mask->fImage = SkMask::AllocImage(size, SkMask::kZeroInit_Alloc);
     if (nullptr == mask->fImage) {
         return false;
diff --git a/src/core/SkRegion.cpp b/src/core/SkRegion.cpp
index 86c38bd..b1ec9f4 100644
--- a/src/core/SkRegion.cpp
+++ b/src/core/SkRegion.cpp
@@ -52,8 +52,10 @@
     /** Resize the array to a size greater-than-or-equal-to count. */
     void resizeToAtLeast(int count) {
         if (count > fCount) {
-            // leave at least 50% extra space for future growth.
-            count += count >> 1;
+            // leave at least 50% extra space for future growth (unless adding would overflow)
+            SkSafeMath safe;
+            int newCount = safe.addInt(count, count >> 1);
+            count = safe ? newCount : SK_MaxS32;
             fMalloc.realloc(count);
             if (fPtr == fStack) {
                 memcpy(fMalloc.get(), fStack, fCount * sizeof(SkRegionPriv::RunType));
diff --git a/src/pdf/SkDeflate.cpp b/src/pdf/SkDeflate.cpp
index a8bd667..f243f94 100644
--- a/src/pdf/SkDeflate.cpp
+++ b/src/pdf/SkDeflate.cpp
@@ -9,6 +9,7 @@
 
 #include "include/core/SkData.h"
 #include "include/private/SkMalloc.h"
+#include "include/private/SkTFitsIn.h"
 #include "include/private/SkTo.h"
 #include "src/core/SkTraceEvent.h"
 
@@ -21,6 +22,13 @@
 // Different zlib implementations use different T.
 // We've seen size_t and unsigned.
 template <typename T> void* skia_alloc_func(void*, T items, T size) {
+    if (!SkTFitsIn<size_t>(size)) {
+        return nullptr;
+    }
+    const size_t maxItems = SIZE_MAX / size;
+    if (maxItems < items) {
+        return nullptr;
+    }
     return sk_calloc_throw(SkToSizeT(items) * SkToSizeT(size));
 }