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));
}