A crash when dereferencing unallocated internal structure in CFF and CID parsers
Migrated from: [SAVANNAH-58621]
Sebastian Rasmussen reported:
A crash was found in FreeType 2.10.0 using gcc 9.3.0 ASAN and a custom allocator that lets me control when/where it will return NULL.
This is the gdb backtrace (relevant for Freetype) where the allocator returns NULL:
#1 (closed) 0x0000555555b1b26e in ft_mem_qalloc (memory=0x621000002918, size=80, p_error=0x7fffffff8de0)
at freetype/src/base/ftutil.c:76
#2 (closed) 0x0000555555b1b0f3 in ft_mem_alloc (memory=0x621000002918, size=80, p_error=0x7fffffff8e80)
at freetype/src/base/ftutil.c:55
#3 (closed) 0x0000555555afba98 in ft_glyphslot_init (slot=0x613000000c88) at freetype/src/base/ftobjs.c:309
#4 (closed) 0x0000555555afd590 in FT_New_GlyphSlot (face=0x61a000000c88, aslot=0x0) at freetype/src/base/ftobjs.c:621
#5 (closed) 0x0000555555b01602 in ft_open_face_internal (library=0x614000000448, args=0x7fffffff9120, face_index=0, aface=0x7fffffff9230,
test_mac_fonts=1 '\001') at freetype/src/base/ftobjs.c:2564
#6 (closed) 0x0000555555b00b76 in FT_New_Memory_Face (library=0x614000000448, file_base=0x62e000000408 "\001", file_size=20486,
face_index=0, aface=0x7fffffff9230) at freetype/src/base/ftobjs.c:1493
This is the corresponding backtrace where the crash occurs due to dereferencing NULL:
#0 0x55da8ac9d134 in cff_slot_done freetype/src/cff/cffobjs.c:352
#1 (closed) 0x55da8ac541a3 in ft_glyphslot_done freetype/src/base/ftobjs.c:573
#2 (closed) 0x55da8ac545dc in FT_New_GlyphSlot freetype/src/base/ftobjs.c:624
#3 (closed) 0x55da8ac58601 in ft_open_face_internal freetype/src/base/ftobjs.c:2564
#4 (closed) 0x55da8ac57b75 in FT_New_Memory_Face freetype/src/base/ftobjs.c:1493
Looking at the source code (https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/base/ftobjs.c#n308)
it is evident why this happens: ft_glyphslot_init() again fails to allocate the internal structure,
which means that when ft_glyphslot_done() (https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/base/ftobjs.c#n571)
calls the class' done_slot() callback it must not conditionally dereference the empty internal pointer,
yet both cff_slot_done() (https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/cff/cffobjs.c#n352)
and cid_slot_done() (https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/cid/cidobjs.c#n49)
do so. I have taken the liberty of fixing both of these occurrences in the two patches I shall attach shortly.
Testing these two did not reveal any other problems according to gcc ASAN.