Bug 2460423 (CVE-2026-49919) - CVE-2026-49919 freetype: Integer overflow in FreeType tt_face_colr_blend_layer() leads to heap buffer overflow during COLR font rendering
Summary: CVE-2026-49919 freetype: Integer overflow in FreeType tt_face_colr_blend_laye...
Keywords:
Status: NEW
Alias: CVE-2026-49919
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On: 2545196 2545197 2545198 2545199 2545200 2545201 2545202 2545203 2545204 2545205 2545206 2545207 2545208 2545209
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-04-21 23:19 UTC by OSIDB Bzimport
Modified: 2026-10-02 14:07 UTC (History)
20 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-04-21 23:19:37 UTC
AI_ONLY_REPORT
package: freetype-2.14.1-3.1.hum1
------
Summary: Integer Overflow leading to Heap Buffer Overflow in tt_face_colr_blend_layer: Integer overflow in font-controlled bitmap size calculations during COLR layer blending can produce undersized heap allocations followed by heap out-of-bounds writes while rendering a malicious color font.
Requirements to exploit: Attacker must be able to supply a malicious COLR font, directly or through content that embeds or loads it, and cause a vulnerable application using FreeType to render a color glyph with `FT_Load_Glyph(..., FT_LOAD_RENDER | FT_LOAD_COLOR)`. The source analysis describes size-wrap conditions on 32-bit intermediates, while reviewer validation reported reproduction only on 64-bit systems, so exploitability appears architecture-dependent.
Component affected: FreeType (`src/sfnt/ttcolr.c`, `tt_face_colr_blend_layer()`)
Version affected: `2.14.1` confirmed; likely other versions containing `tt_face_colr_blend_layer` before a fix. The exact introducing version was not confirmed from the available source tarball.
Patch available: Proposed fix pattern included in this report; upstream release status unknown.
Version fixed (if any already): unknown
Upstream coordination: Not yet notified. This report is the initial triage.
CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - 7.8 (HIGH)
AV:L - This is a local parser/rendering flaw triggered when an application loads a malicious font.
AC:L - Once the vulnerable COLR rendering path is reached, no race or unusual runtime condition is required beyond crafted glyph geometry.
PR:N - The attacker needs no privileges to supply the font.
UI:R - A victim must open content or otherwise trigger rendering of the attacker-controlled color font.
S:U - The vulnerable and impacted component are within the same rendering process.
C:H - Heap corruption may expose sensitive process memory in the consuming application.
I:H - Heap corruption can alter application state or potentially enable code execution in the process context.
A:H - The application may crash or become unstable during font rendering.
Impact: Likely Important. This is a heap-memory corruption flaw in a widely used font rendering library. Exploitation requires rendering an attacker-controlled COLR font and current validation suggests architecture-dependent behavior, but successful exploitation could still compromise the confidentiality, integrity, or availability of the consuming process. The current evidence shows heap out-of-bounds writes rather than demonstrated arbitrary code execution.
Embargo: yes
Reason: This is a memory-corruption issue in a broadly deployed library and no upstream fix is confirmed. Coordinated disclosure is appropriate so a fix can be prepared before detailed exploit guidance for malicious fonts is public.
Suggested public date: 15-Jul-2026
Acknowledgement: Aisle Research
Steps to reproduce:
1. Build FreeType in an environment where the relevant size calculations can wrap, preferably with AddressSanitizer enabled.
2. Create or use a malicious COLR font whose layered glyph rendering produces very large `width` and `rows` values in `tt_face_colr_blend_layer` while still passing parser checks.
3. Load the font and render a color glyph with `FT_Load_Glyph(..., FT_LOAD_RENDER | FT_LOAD_COLOR)`.
4. Observe wraparound in the allocation size and subsequent heap out-of-bounds writes during `FT_MEM_COPY` or the blend loop.
Mitigation:
Avoid loading or rendering untrusted COLR fonts until a fix is available.




Vulnerability Details






In `tt_face_colr_blend_layer()`, font-controlled glyph geometry influences bitmap dimensions that are then used in unchecked multiplication for allocation sizes:
```c
/* first-layer allocation path */
dstSlot->bitmap.pitch = (int)dstSlot->bitmap.width * 4;
size = dstSlot->bitmap.rows * (unsigned int)dstSlot->bitmap.pitch;
error = ft_glyphslot_alloc_bitmap( dstSlot, size );
```
```c
/* resize path */
FT_UInt width = (FT_UInt)( x_max - x_min );
FT_UInt rows = (FT_UInt)( y_max - y_min );
FT_UInt pitch = width * 4;
size = rows * pitch;
if ( FT_ALLOC( buf, size ) )
return error;
...
FT_MEM_COPY( q, p, dstSlot->bitmap.width * 4 );
```
If `rows * pitch` wraps, the allocation can be smaller than the logical bitmap dimensions later used by `FT_MEM_COPY()` and the blend operations, leading to heap corruption while processing a malicious color font.
Most relevant CWEs:
`CWE-190` (Integer Overflow or Wraparound): unchecked `width * 4` and `rows * pitch`.

`CWE-122` / `CWE-787` (Heap-based Buffer Overflow / Out-of-bounds Write): writes after an undersized allocation.




Proposed Fix






Suggested patch pattern: add overflow checks before multiplying bitmap dimensions and before allocating the destination buffers.
```diff
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
— a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -1764,8 +1764,16 @@ tt_face_colr_blend_layer( TT_Face face,
dstSlot->bitmap.width = srcSlot->bitmap.width;
dstSlot->bitmap.rows = srcSlot->bitmap.rows;
dstSlot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
dstSlot->bitmap.pitch = (int)dstSlot->bitmap.width * 4;
+ if ( dstSlot->bitmap.width > FT_ULONG_MAX / 4 )
+ return FT_THROW( Array_Too_Large );
+ dstSlot->bitmap.pitch = (int)( dstSlot->bitmap.width * 4 );
 dstSlot->bitmap.num_grays = 256;


 
size = dstSlot->bitmap.rows * (unsigned int)dstSlot->bitmap.pitch;
+ if ( dstSlot->bitmap.pitch < 0 )
+ return FT_THROW( Array_Too_Large );
+ if ( dstSlot->bitmap.rows >
+ FT_ULONG_MAX / (FT_ULong)(unsigned int)dstSlot->bitmap.pitch )
+ return FT_THROW( Array_Too_Large );
+ size = dstSlot->bitmap.rows *
+ (FT_ULong)(unsigned int)dstSlot->bitmap.pitch;
@@ -1798,13 +1806,20 @@ tt_face_colr_blend_layer( TT_Face face,
 FT_UInt width = (FT_UInt)( x_max - x_min );
 FT_UInt rows = (FT_UInt)( y_max - y_min );

FT_UInt pitch = width * 4;
+ FT_UInt pitch;
@@
+ if ( width > FT_ULONG_MAX / 4 )
+ return FT_THROW( Array_Too_Large );
+ pitch = width * 4;
+ if ( rows > FT_ULONG_MAX / (FT_ULong)pitch )
+ return FT_THROW( Array_Too_Large );
 size = rows * pitch;
 if ( FT_ALLOC( buf, size ) )
 return error;
```


------
This report was generated using AI technology. Always review AI-generated content prior to use

Comment 2 Christopher Lusk 2026-06-26 17:43:45 UTC
Tracker filed for rhel-10.3: https://issues.redhat.com/browse/RHEL-189210


Note You need to log in before you can comment on or make changes to this bug.