Skip to content

Fix CFF subroutine recursion vulnerability (CVE-2024-XXXXX)#825

Merged
fdb merged 2 commits intomasterfrom
claude/fix-cff-recursion-cve-GQhzx
Apr 3, 2026
Merged

Fix CFF subroutine recursion vulnerability (CVE-2024-XXXXX)#825
fdb merged 2 commits intomasterfrom
claude/fix-cff-recursion-cve-GQhzx

Conversation

@fdb
Copy link
Copy Markdown
Contributor

@fdb fdb commented Apr 3, 2026

Description

This PR fixes a critical vulnerability in CFF charstring parsing that allows unbounded subroutine recursion, which can cause stack overflow and denial of service. The fix implements a maximum call depth limit of 10, as defined by the CFF/Type 2 specification (section 4.7) and enforced by conforming implementations like FreeType.

Changes Made:

  1. src/tables/cff.mjs: Added MAX_CALL_DEPTH constant (value: 10) and depth tracking to both callsubr (local subroutines) and callgsubr (global subroutines) operators. When the depth limit is exceeded, the call is skipped with a warning instead of proceeding.

  2. test/generate-recursive-cff-font.mjs: Added a proof-of-concept font generator that creates a minimal CFF OpenType font with a self-referencing subroutine. This demonstrates the vulnerability and serves as a test case.

  3. test/fonts/CFFRecursionTest.otf: Generated test font with recursive subroutine calls.

  4. test/tables/cff.spec.mjs: Added regression test that verifies the parser handles recursive subroutines without crashing.

Motivation and Context

This addresses a CFF charstring VM unbounded subroutine recursion vulnerability (CWE-674). Malicious or malformed CFF fonts could exploit this to cause stack overflow by creating circular subroutine references. The fix enforces the specification-defined recursion limit to prevent this attack vector.

How Has This Been Tested?

  • Added regression test in test/tables/cff.spec.mjs that loads the recursive CFF font and accesses glyph paths without throwing an error
  • The test verifies that charstring parsing completes safely despite the recursive subroutine structure
  • All existing tests continue to pass with the depth limit in place (legitimate fonts stay well below the limit)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • I have added tests to cover my changes (regression test for recursive subroutines)
  • Tests pass with the changes applied

https://claude.ai/code/session_01DogWctecDJdRQqLAi17jm7

claude added 2 commits March 16, 2026 17:05
Enforce the CFF/Type 2 spec maximum subroutine call depth of 10 for
both callsubr and callgsubr operators, preventing stack overflow from
malicious fonts with circular subroutine references.

Includes a POC font generator and regression test.

https://claude.ai/code/session_01DogWctecDJdRQqLAi17jm7
Replace the over-engineered 5-iteration convergence loop with a clean
2-pass approach. The generated font is byte-identical.

https://claude.ai/code/session_01DogWctecDJdRQqLAi17jm7
@fdb fdb merged commit 599f6c1 into master Apr 3, 2026
1 check passed
@fdb fdb deleted the claude/fix-cff-recursion-cve-GQhzx branch April 3, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants