Skip to content

Heap buffer overflow when reading TTF file #5322

@vimpostor

Description

@vimpostor

In

v->tuples[i].coords = malloc(axiscount*sizeof(float));
fontforge allocates an array assuming it has size n * sizeof(float). But in reality the coords member has type real, see
real *coords; /* Location along axes array[axis_count] */

This does not match float if fontforge is configured to use double as real.

This will immediately write out of bounds in the line below it when it iterates over the array, because it may iterate over it with real=double but it only allocated enough space for it assuming real=float:

    for ( j=0; j<axiscount; ++j )
	    v->tuples[i].coords[j] = ((short) getushort(ttf))/16384.0;

The fix is extremely simple, just change sizeof(float) to sizeof(real) and I can confirm that this fixes fontforge crashing immediately on startup for me:

diff --git a/fontforge/parsettfvar.c b/fontforge/parsettfvar.c
index 18c6a2f13..fc3bcf9ae 100644
--- a/fontforge/parsettfvar.c
+++ b/fontforge/parsettfvar.c
@@ -579,7 +579,7 @@ return;
     v->tuples = calloc(globaltc,sizeof(struct tuples));
     fseek(ttf,tupoff,SEEK_SET);
     for ( i=0; i<globaltc; ++i ) {
-	v->tuples[i].coords = malloc(axiscount*sizeof(float));
+	v->tuples[i].coords = malloc(axiscount*sizeof(real));
 	for ( j=0; j<axiscount; ++j )
 	    v->tuples[i].coords[j] = ((short) getushort(ttf))/16384.0;
 	v->tuples[i].chars = InfoCopyGlyphs(info);

I didn't bother with creating a pull request, because I don't know if the project is still maintained - there has not been a commit since a year now. However, I thought I'd still share my findings.

Without this patch, fontforge crashes with the following glibc assert as a sideeffect of memory being corrupted:

Fatal glibc error: malloc.c:2594 (sysmalloc): assertion failed: (old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)

An example font that triggers this crash on startup is: https://github.com/google/material-design-icons/raw/a90037f80d7db37279a7c1d863559e247ed81b05/variablefont/MaterialSymbolsOutlined%5BFILL,GRAD,opsz,wght%5D.ttf

P.S.: I am well aware of https://github.com/fontforge/fontforge/wiki/Community-guidelines#D1, but this is not a fuzzy testing experiment, but a real bug inside fontforge that prevents real fonts (the above font is a trusted font) from being loaded.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions