Skip to content

font/sfnt: add bounds checks in GPOS parsing to prevent OOM#26

Open
ZephrFish wants to merge 1 commit into
golang:masterfrom
ZephrFish:fix/font-sfnt-gpos-oom
Open

font/sfnt: add bounds checks in GPOS parsing to prevent OOM#26
ZephrFish wants to merge 1 commit into
golang:masterfrom
ZephrFish:fix/font-sfnt-gpos-oom

Conversation

@ZephrFish
Copy link
Copy Markdown
Contributor

A crafted font file can trigger a multi-gigabyte allocation when
parsing GPOS PairPos tables. In parsePairPosFormat2, numClass1 and
numClass2 are read as uint16 from the font and their product is
passed unchecked to source.view. With both values at 65535, the
product times 2 reaches ~8 GiB, OOM-killing the process.

Only the io.ReaderAt path is affected (the []byte path is bounded
by the slice length).

This was previously reported to the Go security team via
security@golang.org and has been designated for the PUBLIC track.

Changes:

  • Validate the class count product against maxTableLength before
    allocating in parsePairPosFormat2
  • Add bounds checks in makeCachedPairPosGlyph to verify pair count
    does not exceed buffer
  • Add bounds checks in makeCachedPairPosClass to verify class
    indices fall within the parsed buffer before indexing
  • Add an overflow check in source.varLenView for the computed
    total length
  • Add fuzz test for Parse exercising GPOS kerning paths

Fixes golang/go#78382

@ZephrFish ZephrFish force-pushed the fix/font-sfnt-gpos-oom branch from 8f0ca81 to 2a64e6d Compare March 26, 2026 08:51
A crafted font file can trigger a multi-gigabyte allocation when
parsing GPOS PairPos tables. In parsePairPosFormat2, numClass1 and
numClass2 are read as uint16 from the font and their product is
passed unchecked to source.view. With both values at 65535, the
product times 2 reaches ~8 GiB, OOM-killing the process.

Validate the class count product against maxTableLength before
allocating. Also add bounds checks in makeCachedPairPosGlyph and
makeCachedPairPosClass to verify that indices derived from the font
file do not exceed the parsed buffer, and add an overflow check in
source.varLenView for the computed total length.

Fixes golang/go#78382
@ZephrFish ZephrFish force-pushed the fix/font-sfnt-gpos-oom branch from 2a64e6d to a03464d Compare March 26, 2026 08:54
@gopherbot
Copy link
Copy Markdown
Contributor

This PR (HEAD: a03464d) has been imported to Gerrit for code review.

Please visit Gerrit at https://go-review.googlesource.com/c/image/+/759520.

Important tips:

  • Don't comment on this PR. All discussion takes place in Gerrit.
  • You need a Gmail or other Google account to log in to Gerrit.
  • To change your code in response to feedback:
    • Push a new commit to the branch used by your GitHub PR.
    • A new "patch set" will then appear in Gerrit.
    • Respond to each comment by marking as Done in Gerrit if implemented as suggested. You can alternatively write a reply.
    • Critical: you must click the blue Reply button near the top to publish your Gerrit responses.
    • Multiple commits in the PR will be squashed by GerritBot.
  • The title and description of the GitHub PR are used to construct the final commit message.
    • Edit these as needed via the GitHub web interface (not via Gerrit or git).
    • You should word wrap the PR description at ~76 characters unless you need longer lines (e.g., for tables or URLs).
  • See the Sending a change via GitHub and Reviews sections of the Contribution Guide as well as the FAQ for details.

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.

x/image/font/sfnt: crafted GPOS table causes OOM via unchecked class count product

2 participants