CVE-2026-45527 AI-generated analysis
platform/frameworks/av, media/module/extractors/mp4 (HEIF clean aperture handling, media.extractor)
In the MP4/HEIF extractor, convertCleanApertureToRect() now checks the crop rectangle bounds with int64_t arithmetic before computing right/bottom, so crafted CleanAperture values can no longer trigger a signed int32 overflow (IntSan abort) in media.extractor.
Root cause
In media/module/extractors/mp4/HeifCleanAperture.cpp:convertCleanApertureToRect(), *right = *left + clapW and *bottom = *top + clapH were computed as int32_t additions before any range check. *left/*top come from centerX/centerY (which include the file-supplied horizOff/vertOff) and clapW/clapH are the file-supplied clean aperture width/height. With large offsets the addition overflows int32_t, which aborts the process under IntSan. The check that followed (*left > (UINT32_MAX - clapW) || *right > imageW || ...) did not help: for a non-negative int32 left, the UINT32_MAX comparison is effectively never true, and the *right > imageW comparison ran after the overflow had already happened.
How the fix works
- media/module/extractors/mp4/HeifCleanAperture.cpp:convertCleanApertureToRect(): the two additions producing *right and *bottom now run after the bounds check instead of before it.
- The bounds check is rewritten as ((int64_t)*left + clapW > (int64_t)imageW || (int64_t)*top + clapH > (int64_t)imageH) -> return false. Earlier in the function, imageW and imageH are rejected if they are > INT32_MAX. So passing this check guarantees that left + clapW and top + clapH fit in int32_t, and the int32 additions that follow cannot overflow.
- media/module/extractors/mp4/tests/HeifCleanApertureUnitTest.cpp: two negative test vectors are added to kInvalidClapPropertyTestParams. Each uses a 2x2 image with horizOff or vertOff set to 0x7FFFFFFE and expects convertCleanApertureToRect() to return false.
Completeness
- Covers both the horizontal (left + clapW) and the vertical (top + clapH) addition in convertCleanApertureToRect().
- The other arithmetic in the function is already guarded in the shown code: denominators must be > 0, width/height numerators must be >= 0 and width/height non-zero, imageW/imageH must be <= INT32_MAX, the bool results of Fraction::add/subtract are checked, and centerX.n/centerY.n must be >= 0 and integer.
- Fraction::isInteger() and getInt32() (n % d, n / d) are only reached after the d <= 0 checks in this function. This fix does not change how safe they are when called from elsewhere.
- For inputs that do not overflow, the retained check behaves as before (reject if right > imageW or bottom > imageH). Only the overflow cases are newly rejected.
Behavior changes
- CleanAperture properties whose offset plus width/height exceeds the int32 range now make convertCleanApertureToRect() return false (invalid clap) instead of aborting the media.extractor process under IntSan.
- *right and *bottom are no longer written when the function returns false for an out-of-bounds rectangle. Before the fix they were assigned before the check.
Per major
- Android 14: not affected per the bulletin; HeifCleanAperture.cpp and its unit test are absent at android-security-14.0.0_r29 (code absent).
- Android 15: same fix: c92a92203957 in android-security-15.0.0_r17, identical diff (blob f0a086703e -> 7d78f0e869). The code context confirms that the int64_t check comes before the additions.
- Android 16: same fix: 9456667afa01 in android-security-16.0.0_r8, identical diff and blob hashes.
- Android 17: same fix: 1e00537f8f43 in android-security-17.0.0_r1, identical diff and blob hashes.
Unknowns
- The production caller of convertCleanApertureToRect() in the MP4 extractor is not shown in the material (the index search only returned the header, the implementation file and the unit test).
- Whether the Fraction(int32_t n, int32_t d) constructor or the clap box parser does any additional validation before this function is not shown.
- The implementations of calculateCenter() and Fraction::add/subtract/commonDenominator are not shown, so the material does not confirm that the resulting denominator is positive (and therefore that left/top are non-negative).