Fix CFF subroutine recursion vulnerability (CVE-2024-XXXXX)#825
Merged
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
src/tables/cff.mjs: Added
MAX_CALL_DEPTHconstant (value: 10) and depth tracking to bothcallsubr(local subroutines) andcallgsubr(global subroutines) operators. When the depth limit is exceeded, the call is skipped with a warning instead of proceeding.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.
test/fonts/CFFRecursionTest.otf: Generated test font with recursive subroutine calls.
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?
test/tables/cff.spec.mjsthat loads the recursive CFF font and accesses glyph paths without throwing an errorTypes of changes
Checklist:
https://claude.ai/code/session_01DogWctecDJdRQqLAi17jm7