CVE-2024-43767 AI-generated analysis
platform/external/skia, core blur mask filter (src/core/SkBlurMF.cpp)
Adds a check in SkBlurMF.cpp prepare_to_draw_into_mask() so it returns false when SkMask::computeImageSize() returns 0 (the size overflow signal, per the commit title), so no SkMask image is allocated with that size.
Root cause
prepare_to_draw_into_mask() sets mask->fBounds from bounds.roundOut(), sets fRowBytes = SkAlign4(width) and fFormat = kA8_Format, then calls mask->computeImageSize() and passes the result straight to SkMask::AllocImage(), checking only for a nullptr return. The commit title ("Check for size overflow before allocating SkMask data") and the added size == 0 check indicate that computeImageSize() returns 0 when the size overflows, and the code did not test for this. The caller draw_rrect_into_mask() then installs the mask pixels into an SkBitmap and draws into it with an SkCanvas positioned by mask->fBounds. The authors describe the fix as speculative and the issue as not reproducible.
How the fix works
- src/core/SkBlurMF.cpp:prepare_to_draw_into_mask(): the fix inserts `if (size == 0) { return false; }` after `const size_t size = mask->computeImageSize();` and before `SkMask::AllocImage(size, SkMask::kZeroInit_Alloc)`.
- draw_rrect_into_mask() already returns false when prepare_to_draw_into_mask() fails, so the new early return stops it before installMaskPixels() and canvas drawing.
- Single commit with 3 added lines: a RESTRICT AUTOMERGE cherry-pick (Change-Id I74c081a7b849f13194ec7807b7a748d1919c1bb2), reviewed upstream at skia-review 894478.
Completeness
- Covers the allocation in prepare_to_draw_into_mask(), which draw_rrect_into_mask() calls. The FIXME comment says draw_rrect_into_mask duplicates code in draw_rects_into_mask, but the material does not show whether draw_rects_into_mask uses this helper.
- The fix relies on computeImageSize() returning 0 on overflow. It does not validate the fBounds dimensions itself, and the body of computeImageSize() is not in the material.
- The commit does not touch SkBlurMask::BoxBlur/BlurRect/BlurRRect (called from filterMask/filterRectMask/filterRRectMask). The material does not show their allocation logic.
- The bulletin lists Android 12, 12L and 13 as affected, but the material only shows the Android 14 cherry-pick.
Behavior changes
- prepare_to_draw_into_mask() now returns false whenever computeImageSize() returns 0, and draw_rrect_into_mask() then returns false instead of allocating and drawing. Whether non-overflow cases (such as empty bounds) also produce 0, and how higher-level callers handle the failure, is not shown.
- No API change; this is an internal early return.
Per major
- Android 14: same fix: RESTRICT AUTOMERGE cherry-pick 796c2040f641 in android-security-14.0.0_r15. At android-security-14.0.0_r29, all 5 lines of the patched region are present.
- Android 15: not affected per bulletin. src/core/SkBlurMF.cpp is absent at android-security-15.0.0_r17.
- Android 16: not affected per bulletin. src/core/SkBlurMF.cpp is absent at android-security-16.0.0_r8.
- Android 17: not affected per bulletin. src/core/SkBlurMF.cpp is absent at android-security-17.0.0_r1.
Unknowns
- The implementations of SkMask::computeImageSize() and SkMask::AllocImage() are not in the material. That computeImageSize() returns 0 on overflow is inferred from the commit title and the check, not shown.
- Whether draw_rects_into_mask() also uses prepare_to_draw_into_mask() is not shown.
- Which Android-side callers (e.g. HWUI/RenderEngine blur paths) reach this path with attacker-influenced geometry is not shown.
- Whether and how the fix was applied to Android 12, 12L and 13, and what the code looks like there, is not in the material.
- The commit states the issue was not reproducible and the fix is speculative. The concrete memory-safety consequence is not demonstrated in the material.
- The reason SkBlurMF.cpp is absent on Android 15 and later is not shown.