https://bugzilla.redhat.com/show_bug.cgi?id=2544965

            Bug ID: 2544965
           Summary: CVE-2026-95512 freetype: FreeType: Denial of Service
                    via repeated subroutine allocations in CID font loader
                    [fedora-all]
           Product: Fedora
           Version: rawhide
            Status: NEW
        Whiteboard: {"flaws": ["46e9cdce-fd3d-4569-afb0-d57cef67374c"]}
         Component: freetype
          Keywords: Security, SecurityTracking
          Severity: medium
          Priority: medium
          Assignee: [email protected]
          Reporter: [email protected]
        QA Contact: [email protected]
                CC: [email protected], [email protected],
                    [email protected], [email protected],
                    [email protected], [email protected]
            Blocks: 2462295 (CVE-2026-95512)
  Target Milestone: ---
    Classification: Fedora



Disclaimer: Community trackers are created by Red Hat Product Security team on
a best effort basis. Package maintainers are required to ascertain if the flaw
indeed affects their package, before starting the update process.

AI_ONLY_REPORT
package: freetype-2.13.2-8.el10
------
Summary: Denial of Service via Overlapping CID Subroutine Maps: crafted CID  
fonts can trigger repeated subroutine allocations and decryptions across  
many font dictionaries during face loading, causing severe memory and CPU  
exhaustion.
Requirements to exploit: An attacker must reach a build of  
`freetype-2.13.2-8.el10` that includes the CID loader and cause an  
application or service to load a crafted CID-keyed font. No privileges are  
required. In common client-side cases this means getting a user to open  
content that embeds or references the font.
Component affected: `freetype-2.13.2-8.el10`, CID loader in  
`src/cid/cidload.c` (`parse_fd_array`, `cid_face_open`, `cid_read_subrs`)
Version affected: `freetype-2.13.2-8.el10`
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: None established.
CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H - 6.5 (MEDIUM)
AV:N - The malicious font can be delivered through remotely supplied  
content before local parsing.
AC:L - The attacker needs only a syntactically valid CID font that  
reuses the same or overlapping subroutine regions across many dictionaries.
PR:N - No authentication or prior access is required.
UI:R - The demonstrated path requires the victim application to load  
attacker-controlled content that causes the font to be parsed.
S:U - The impact remains within the same security scope as the parsing  
process.
C:N - No confidentiality impact is established.
I:N - No integrity impact is established.
A:H - Face initialization can perform large repeated allocations and  
decryptions, potentially hanging or terminating the process.
Impact: Important. Red Hat classifies flaws that allow remote users to  
cause denial of service as Important when they can readily impact  
availability. In deployments that expose this CID parsing path to  
attacker-controlled fonts, a crafted input can drive high memory and CPU  
consumption and deny service to the parsing process. The issue does not  
rise to Critical because the available evidence shows availability impact  
only, and the common exploitation path still requires the crafted font to  
be loaded.
Embargo: no
Reason: The currently established impact is denial of service during  
font loading, with no evidence of code execution, privilege escalation, or  
data exposure. Operational mitigations are also available while a fix is  
prepared.
Acknowledgement: Aisle Research
Vulnerability Details: In the reviewed CID loader code, `cid_read_subrs`  
allocates, reads, and decrypts subroutine data independently for each font  
dictionary. If many dictionaries point at the same or overlapping  
`SubrMapOffset` region, the same underlying data can be copied and  
decrypted repeatedly.
```c
/* src/cid/cidload.c: cid_read_subrs */
for ( n = 0; n < cid->num_dicts; n+, subr+ )
{
CID_FaceDict  dict  = cid->font_dicts + n;
FT_UInt       count, num_subrs = dict->num_subrs;
...
data_len = offsets[num_subrs] - offsets[0];
if ( FT_QNEW_ARRAY( subr->code, num_subrs + 1 ) ||
FT_QALLOC( subr->code[0], data_len )       )
goto Fail;
if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) ||
FT_STREAM_READ( subr->code[0], data_len )       )
goto Fail;
if ( lenIV >= 0 )
for ( count = 0; count < num_subrs; count++ )
psaux->t1_decrypt( subr->code[count], len, 4330 );
}
```
The number of dictionaries can scale with the font size, and the validation  
in the reviewed path is per-dictionary rather than cumulative across the  
whole face:
```c
/* src/cid/cidload.c: parse_fd_array */
max_dicts = (FT_Long)( stream->size / 100 );
if ( num_dicts > max_dicts )
{
...
num_dicts = max_dicts;
}
/* src/cid/cidload.c: cid_face_open */
if ( dict->subrmap_offset > binary_length )
{
FT_ERROR(( "cid_face_open: Invalid `SubrMapOffset' value\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
/* the initial pre-check prevents the multiplication overflow */
if ( dict->num_subrs > FT_UINT_MAX / 4      ||
dict->num_subrs * dict->sd_bytes >
binary_length - dict->subrmap_offset )
{
FT_ERROR(( "cid_face_open: Invalid `SubrCount' value\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
```
These checks appear to prevent out-of-bounds access and integer overflow in  
the reviewed path, but they do not stop cross-dictionary resource  
amplification. A crafted CID font can therefore cause large repeated  
allocations, reads, and `t1_decrypt` work during face initialization alone;  
no glyph rendering is required.
Steps to reproduce:
1. Build a CID font with a large `FDArray`, for example near `stream_size /  
100` dictionaries.
2. Set many dictionaries to the same `SubrMapOffset` and the same  
`SubrCount` and `SDBytes` values.
3. Make the shared offset table valid and monotonic, with large `data_len =  
offsets[last] - offsets[0]`, still bounded by the binary section size.
4. Load the font through the affected package; face initialization is  
sufficient.
5. Observe repeated allocations, copies, and decryptions for each  
dictionary; resident memory and CPU usage rise roughly with the number of  
dictionaries until the process stalls or hits out-of-memory conditions.
Mitigation: Until a fix is available, avoid parsing attacker-controlled  
CID-keyed fonts in processes that cannot tolerate memory or CPU spikes. If  
untrusted font handling is required, isolate font parsing in a separate  
process or container and apply strict memory and CPU limits. If deployments  
can reject CID fonts before they reach FreeType, that removes this trigger  
path.
Proposed Fix: Add cumulative per-face limits in `cid_read_subrs` so one  
face load cannot multiply subroutine memory and work across many  
dictionaries without bound. A stronger follow-up would deduplicate  
identical subroutine regions across dictionaries.
```diff
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
@@ -531,6 +531,12 @@ cid_read_subrs( CID_Face  face )
FT_UInt        max_offsets = 0;
FT_ULong*      offsets = NULL;
PSAux_Service  psaux = (PSAux_Service)face->psaux;
+  FT_ULong       total_subr_bytes = 0;
+  FT_ULong       total_subr_count = 0;
+  FT_ULong       binary_len = stream->size - cid->data_offset;
+  FT_ULong       max_total_subr_bytes =
+                   ( binary_len <= FT_ULONG_MAX / 4 ) ? binary_len * 4 :  
FT_ULONG_MAX;
+  FT_ULong       max_total_subr_count = (FT_ULong)cid->num_dicts * 65535UL;
@@ -599,6 +605,19 @@ cid_read_subrs( CID_Face  face )
data_len = offsets[num_subrs] - offsets[0];
+      if ( total_subr_bytes > FT_ULONG_MAX - data_len ||
+           total_subr_count > FT_ULONG_MAX - num_subrs )
+      {
+        error = FT_THROW( Invalid_File_Format );
+        goto Fail;
+      }
+      total_subr_bytes += data_len;
+      total_subr_count += num_subrs;
+      if ( total_subr_bytes > max_total_subr_bytes ||
+           total_subr_count > max_total_subr_count )
+      {
+        error = FT_THROW( Invalid_File_Format );
+        goto Fail;
+      }
+
if ( FT_QNEW_ARRAY( subr->code, num_subrs + 1 ) ||
FT_QALLOC( subr->code[0], data_len )       )
goto Fail;
```
------
This report was generated using AI technology. Always review AI-generated  
content prior to use



Referenced Bugs:

https://bugzilla.redhat.com/show_bug.cgi?id=2462295
[Bug 2462295] CVE-2026-95512 freetype: FreeType: Denial of Service via repeated
subroutine allocations in CID font loader
-- 
You are receiving this mail because:
You are on the CC list for the bug.
https://bugzilla.redhat.com/show_bug.cgi?id=2544965

Report this comment as SPAM: 
https://bugzilla.redhat.com/enter_bug.cgi?product=Bugzilla&format=report-spam&short_desc=Report%20of%20Bug%202544965%23c0

-- 
_______________________________________________
fonts-bugs mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/[email protected]
Do not reply to spam, report it: 
https://forge.fedoraproject.org/infra/tickets/issues/new

Reply via email to