CVE-2025-27363 AI-generated analysis
platform/external/freetype, TrueType glyph loader (src/truetype/ttgload.c, GX variation support)
Restructures heap buffer allocation in external/freetype src/truetype/ttgload.c in two places. In the TrueType composite-glyph variation path (load_truetype_glyph), the temporary outline is now allocated directly into the FT_Outline fields with explicit sizes, and n_points/n_contours are set only after allocation succeeds. In TT_Process_Simple_Glyph, the unrounded array switches to a non-zeroing allocation.
Root cause
In load_truetype_glyph, a composite glyph loaded for a non-default variation instance (TT_CONFIG_OPTION_GX_VAR_SUPPORT) gets a temporary FT_Outline that passes the subglyph anchor points plus the 4 phantom points to TT_Vary_Apply_Glyph_Deltas. The old code did this in order: (1) set outline.n_contours = outline.n_points = limit (a short) before any allocation; (2) allocated four separate local arrays (points, tags, contours, unrounded), each of limit + 4 entries, with zeroing FT_NEW_ARRAY; (3) filled the locals; (4) only then attached them to the outline. The fix changes the buffer layout and sizing of this temporary outline. The material does not state what memory-safety fault the old layout caused.
How the fix works
- src/truetype/ttgload.c:load_truetype_glyph: the locals points/tags/contours are removed. The FT_Outline is zero-initialized ({ 0, 0, NULL, NULL, NULL, 0 }) and its points/tags/contours members are allocated directly with FT_QNEW_ARRAY. Sizes: points gets limit + 4 entries (limit anchor points plus pp1..pp4), tags and contours get limit entries each, and unrounded gets limit + 4.
- src/truetype/ttgload.c:load_truetype_glyph: outline.n_contours = outline.n_points = limit is now set only after all allocations succeed. If an allocation fails (goto Exit1), the outline has zero counts. Before, it could be left with non-zero counts and arrays not yet attached.
- src/truetype/ttgload.c:load_truetype_glyph: the fill loop writes outline.points[i], outline.tags[i] = ON_CURVE_POINT (was literal 1) and outline.contours[i] = i, then appends loader->pp1..pp4 at outline.points[limit..limit+3]. The readback after the deltas are applied uses outline.points[i].x/.y.
- src/truetype/ttgload.c:TT_Process_Simple_Glyph: FT_NEW_ARRAY(unrounded, n_points) becomes FT_QNEW_ARRAY, so the array is no longer zeroed.
Completeness
- Covers only the two allocation sites in ttgload.c: the composite-glyph temporary outline in load_truetype_glyph and the unrounded array in TT_Process_Simple_Glyph.
- No validation of limit (a short derived from the subglyph count) or of n_points is added. The fix relies on the allocation sizes now matching how the arrays are indexed in this function (points: limit + 4; tags/contours: limit).
- This commit does not change TT_Vary_Apply_Glyph_Deltas itself or its other callers.
- The diff is complete per the diffstat (18 insertions, 29 deletions) and does not modify the Exit1 cleanup. What Exit1 frees is not shown.
Behavior changes
- Allocated arrays are no longer zero-filled (FT_QNEW_ARRAY instead of FT_NEW_ARRAY).
- The tags and contours arrays of the temporary composite outline shrink from limit + 4 to limit entries.
- On allocation failure in the composite variation path, the temporary outline has n_points = n_contours = 0 (before, both were set to limit before allocation).
- No new error codes are introduced in the diff.
Per major
- Android 14: same fix: DO NOT MERGE cherry-pick f9c146bda91f in android-security-14.0.0_r20 (Change-Id I647f2145da6f0a7ab862e7b31632ad3199d9d2ad). At android-security-14.0.0_r29, 5/8 lines of the patched region are present, and the code context shows the FT_QNEW_ARRAY form at line 979.
- Android 15: not affected per the bulletin. 5/8 lines of the patched region are present at android-security-15.0.0_r17. The exact code state is not shown.
- Android 16: not affected per the bulletin. 5/8 lines of the patched region are present at android-security-16.0.0_r8. The exact code state is not shown.
- Android 17: not affected per the bulletin. 4/8 lines of the patched region are present at android-security-17.0.0_r1. The exact code state is not shown.
Unknowns
- The commit message and diff do not say what memory-safety fault the old allocation layout caused (which index exceeded which buffer). The commit is described as a cleanup.
- What the Exit1 cleanup frees (it is unchanged by this commit and not shown).
- Whether TT_Vary_Apply_Glyph_Deltas fully writes the unrounded array.
- Whether Android 13 received the same cherry-pick (the bulletin lists 13 as affected, but the material only shows the Android 14 commit).
- The exact code state on the Android 15/16/17 branches; only partial line-match counts are given.