Talos Vulnerability Report

TALOS-2024-1946

Adobe Acrobat Reader Font gvar GlyphVariationData out-of-bounds read vulnerability

May 15, 2024
CVE Number

CVE-2024-30311

SUMMARY

An out-of-bounds read vulnerability exists in the Font functionality of Adobe Acrobat Reader 2023.008.20470.A specially crafted font file embedded into a PDF can trigger this vulnerability which can lead to disclosure of sensitive information. An attacker needs to trick the user into opening the malicious file to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Adobe Acrobat Reader 2023.008.20470

PRODUCT URLS

Acrobat Reader - https://acrobat.adobe.com/us/en/acrobat/pdf-reader.html

CVSSv3 SCORE

6.5 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N

CWE

CWE-125 - Out-of-bounds Read

DETAILS

Adobe Acrobat Reader is one of the most popular and feature-rich PDF readers on the market. It has a large user base and is usually a default PDF reader on systems. It also integrates into web browsers as a plugin for rendering PDFs.

Adobe acrobat supports parsing of embedded font files in the PDF. This vulnerability is related to OpenType font format. An OpenType font file starts with a table directory (TableDirectory ) followed by one or more table record (TableRecord) entries. The structure of TableDirectory is as follows:

Offset Size   Name
------ ----- --------------------------------------
0x00    0x04  sfntVersion (0x00010000 or 0x4F54544F  )
0x04    0x02  numTables
0x06    0x02  searchRange
0x08    0x02  entrySelector
0x0c    0x02  rangeShift

If the value of the sfntVersion field is 0x00010000, the font contains TrueType data. The CFF data will be present if the value of sfntVersion is 0x4F54544F (‘OTTO). The numTables field specifies the number of TableRecord entries present in the font file. The structure of a TableRecord entry is as follows:

Offset Size   Name
------ ----- ----------------------------------
0x00    0x04  tableTag
0x04    0x04  tableChecksum
0x08    0x04  tableOffset
0x0C    0x04  tableLength

tableTag is the name of TableRecord. The tableOffset field specifies the offset of the table from the beginning of the file. The tableLength indicates the length of the table. The structure of each TableRecord depends on the type table, which is defined by the tableTag. This vulnerability occurs when the the value of the tableTag field is the string gvar, which indicates the table type is an glyph variations (gvar) table.

The gvar table contains a header followed by shared tuple records (sharedTuples) and glyph variation data tables (GlyphVariationDataTables). The structure of the gvar table header is as follows:

Offset Size   Name
------ ----- --------------------------------------
0x00    0x02             gvar_majorVersion
0x02    0x02             gvar_minorVersion
0x04    0x02             gvar_axisCount
0x06    0x02             sharedTupleCount
0x08    0x04             sharedTuplesOffset
0x0c    0x02             gvar_glyphCount (gc)
0x0e    0x02             gvar_flags (gc_size = 4 if flags else 2)
0x10    0x04             glyphVariationDataArrayOffset
0x14    gc+1 * gc_size   glyphVariationDataOffsets 

The gvar_axisCount field gives the number of variation axes for this font. gvar_glyphCount indicates the number of glyphs present in the font. glyphVariationDataArrayOffset defines the byte offset from the beginning of this table to GlyphVariationDataTables.

The glyphVariationDataOffsets is an array that contains 2-byte or 4-byte offsets. If gvar_flags is 0, the offsets in glyphVariationDataOffsets are 2 bytes each; otherwise, they are 4 bytes. Note that if the offset size is 2 bytes, the stored value represents half of the actual offset value. Therefore, when gvar_flags is 0, the true offset value is obtained by doubling the offset value. The number of offsets present in glyphVariationDataOffsets is gvar_glyphCount + 1. Here, gc indicates gvar_glyphCount.

GlyphVariationDataTables is an array that contains GlyphVariationData tables.

For simplicity, consider the scenario where gvar_flags is 0, gvar_glyphCount is 3, and the values of glyphVariationDataOffsets are as follows:

glyphVariationDataOffsets = [0x04,  0x08, 0x0A, 0x0F]

In this example, the offset from the beginning of this table to the first GlyphVariationData is glyphVariationDataArrayOffset+ 0x04 * 2 and the size of the first GlyphVariationData (namely GlyphVariationData_size) is 0x08 (0x08*2- 0x04*2= 0x08 ). Here, GlyphVariationData_size indicates the size of GlyphVariationData calculated by subtracting two consecutive offsets from the glyphVariationDataOffsets array.

The structure of the GlyphVariationData table is comprised of a header followed by serialized data. The structure of the GlyphVariationData header is as follows:

Offset Size   Name
------ ----- --------------------------------------
0x00    0x02                 tupleVariationCount (tc = tupleVariationCount & 0xfff )
0x02    0x02                 dataOffset
0x04    total_tvh_size       TupleVariationHeaders

The low 12 bits of tupleVariationCount indicates the number of tuple variation tables for this glyph. The TupleVariationHeaders contains an array of TupleVariationHeader. The total number of TupleVariationHeader present in TupleVariationHeaders is indicated by tc. Here, total_tvh_size is the sum of the size of each TupleVariationHeader like (total_tvh_size = tvh_size_1 + tvh_size_2 + ... + tvh_size_tc ). tvh_size_1 is size of the first TupleVariationHeader, tvh_size_2 is size of the second TupleVariationHeader and so on.

The structure of TupleVariationHeader is as follows:

Offset Size   Name
------ ----- --------------------------------------
0x00    0x02             tvh_variationDataSize
0x02    0x02             tvh_tupleIndex

Note that TupleVariationHeader contains other optional fields which are omitted here for brevity.

tvh_variationDataSize indicates the size of serialized data. The TupleVariationHeader size (tvh_size) is variable. It can calculated using the following python pseudo code:

def get_TupleVariationHeader_size(tvh_tupleIndex, gvar_axisCount):
    size = 4
    if (tvh_tupleIndex & 0x8000) != 0:
        size += axisCount * 2
    if (tvh_tupleIndex & 0x4000) != 0:
        size += axisCount * 4
    return size

This vulnerability occurs when the value of GlyphVariationData_size is smaller than 4 + total_tvh_size. The application performs some additional checks which narrow down the range of the vulnerable condition so the vulnerability occurs when the following statement is true:

GlyphVariationData_size < tableLength && GlyphVariationData_size >= (4 * tc) && GlyphVariationData_size < (4 + total_tvh_size)  

In our Poc, the vulnerability occurs when reading the 0xd0 GlyphVariationData table. We can observe the following in the debugger (with PageHeap enabled):

0:000> g                                                                               
Breakpoint 0 hit
eax=000000e1 ebx=d30e6fb0 ecx=b8806d54 edx=c5fd00cf esi=6c524f10 edi=000000cf
eip=6c5dee47 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x4ea37:
6c5dee47 8d3c7d14000000  lea     edi,[edi*2+14h]                                 ; <------------- (1)
0:000> p
eax=000000e1 ebx=d30e6fb0 ecx=b8806d54 edx=c5fd00cf esi=6c524f10 edi=000001b2
eip=6c5dee4e esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x4ea3e:
6c5dee4e 57              push    edi
0:000> pc
eax=000000e1 ebx=d30e6fb0 ecx=6c524f10 edx=c5fd00cf esi=6c524f10 edi=000001b2
eip=6c5dee55 esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x4ea45:
6c5dee55 ff1530e6746c    call    dword ptr [CoolType!CTGetVersion+0x1529a0 (6c74e630)] ds:002b:6c74e630={ntdll!LdrpValidateUserCallTarget (777888f0)}
0:000> p
eax=0d8a49e2 ebx=d30e6fb0 ecx=6c524f10 edx=04000005 esi=6c524f10 edi=000001b2
eip=6c5dee5b esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000247
CoolType!CTCleanup+0x4ea4b:
6c5dee5b ffd6            call    esi {CoolType!CTInit+0x218b0 (6c524f10)}          ; <---------------- (2)
0:000> p
eax=00000000 ebx=d30e6fb0 ecx=00000000 edx=000001b2 esi=6c524f10 edi=000001b2
eip=6c5dee5d esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x4ea4d:
6c5dee5d 8b730c          mov     esi,dword ptr [ebx+0Ch] ds:002b:d30e6fbc=6c524f10 ; <---------------- (3)
0:000> pc
eax=000001b4 ebx=d30e6fb0 ecx=6c524f10 edx=000001b2 esi=6c524f10 edi=000001b2
eip=6c5dee72 esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x4ea62:
6c5dee72 ff1530e6746c    call    dword ptr [CoolType!CTGetVersion+0x1529a0 (6c74e630)] ds:002b:6c74e630={ntdll!LdrpValidateUserCallTarget (777888f0)}
0:000> p
eax=0d8a49e2 ebx=d30e6fb0 ecx=6c524f10 edx=04000005 esi=6c524f10 edi=000001b2
eip=6c5dee78 esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000247
CoolType!CTCleanup+0x4ea68:
6c5dee78 ffd6            call    esi {CoolType!CTInit+0x218b0 (6c524f10)}
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c524f10 edi=000001b2
eip=6c5dee7a esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea6a:
6c5dee7a 8bf8            mov     edi,eax                                        ; <---------------- (4)
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c524f10 edi=00000004
eip=6c5dee7c esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea6c:
6c5dee7c 83c40c          add     esp,0Ch
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c524f10 edi=00000004
eip=6c5dee7f esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
CoolType!CTCleanup+0x4ea6f:
6c5dee7f 03ff            add     edi,edi                                       ; <---------------- (5)  
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c524f10 edi=00000008
eip=6c5dee81 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea71:
6c5dee81 2b7dfc          sub     edi,dword ptr [ebp-4] ss:002b:00f0c528=00000000  ; <---------------- (6) 
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c524f10 edi=00000008
eip=6c5dee84 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea74:
6c5dee84 897df8          mov     dword ptr [ebp-8],edi ss:002b:00f0c524=6c8209e4
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c524f10 edi=00000008
eip=6c5dee87 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea77:
6c5dee87 0f8471010000    je      CoolType!CTCleanup+0x4ebee (6c5deffe)   [br=0]
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c524f10 edi=00000008
eip=6c5dee8d esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea7d:
6c5dee8d 8b732c          mov     esi,dword ptr [ebx+2Ch] ds:002b:d30e6fdc=6c7159d0
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=00000004 edx=000001b4 esi=6c7159d0 edi=00000008
eip=6c5dee90 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea80:
6c5dee90 8bce            mov     ecx,esi
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=6c7159d0 edx=000001b4 esi=6c7159d0 edi=00000008
eip=6c5dee92 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea82:
6c5dee92 53              push    ebx
0:000> p
eax=00000004 ebx=d30e6fb0 ecx=6c7159d0 edx=000001b4 esi=6c7159d0 edi=00000008
eip=6c5dee93 esp=00f0c4ec ebp=00f0c52c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x4ea83:
6c5dee93 ff1530e6746c    call    dword ptr [CoolType!CTGetVersion+0x1529a0 (6c74e630)] ds:002b:6c74e630={ntdll!LdrpValidateUserCallTarget (777888f0)}
0:000> p
eax=0d8e2b3a ebx=d30e6fb0 ecx=6c7159d0 edx=04004000 esi=6c7159d0 edi=00000008
eip=6c5dee99 esp=00f0c4ec ebp=00f0c52c iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000247
CoolType!CTCleanup+0x4ea89:
6c5dee99 ffd6            call    esi {CoolType!CTGetVersion+0x119d40 (6c7159d0)}
0:000> p
eax=000003e6 ebx=d30e6fb0 ecx=6c7159d0 edx=04004000 esi=6c7159d0 edi=00000008
eip=6c5dee9b esp=00f0c4ec ebp=00f0c52c iopl=0         nv up ei pl nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000217
CoolType!CTCleanup+0x4ea8b:
6c5dee9b 59              pop     ecx
0:000> p
eax=000003e6 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c7159d0 edi=00000008
eip=6c5dee9c esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei pl nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000217
CoolType!CTCleanup+0x4ea8c:
6c5dee9c 3bf8            cmp     edi,eax                                              ; <---------------- (7) 
0:000> p
eax=000003e6 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c7159d0 edi=00000008
eip=6c5dee9e esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4ea8e:
6c5dee9e 0f875a010000    ja      CoolType!CTCleanup+0x4ebee (6c5deffe)   [br=0]
0:000> p
eax=000003e6 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c7159d0 edi=00000008
eip=6c5deea4 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4ea94:
6c5deea4 8b7d14          mov     edi,dword ptr [ebp+14h] ss:002b:00f0c540=b8806d54

At (1), the value of edi serves as an index, determining which entry of the GlyphVariationData table will be accessed (the index values start at 0). The method is called at (2) to read the offsets from the glyphVariationDataOffsets. eax at (3) and (4) contains 2 consecutive offset values. Here, gvar_flags is 0, so the actual offset value is obtained by doubling the offset value as shown at (5). GlyphVariationData_size is calculated at (6). At (7), a check is performed to ensure GlyphVariationData_size is smaller than tableLength.

0:000> p
eax=00000008 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c8209e4 edi=b8806d54
eip=6c5deead esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4ea9d:
6c5deead 50              push    eax                                            ; <---------------------- (8)
0:000> p
eax=00000008 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c8209e4 edi=b8806d54
eip=6c5deeae esp=00f0c4ec ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4ea9e:
6c5deeae 894708          mov     dword ptr [edi+8],eax ds:002b:b8806d5c=00000000
0:000> p
eax=00000008 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c8209e4 edi=b8806d54
eip=6c5deeb1 esp=00f0c4ec ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4eaa1:
6c5deeb1 56              push    esi
0:000> p
eax=00000008 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c8209e4 edi=b8806d54
eip=6c5deeb2 esp=00f0c4e8 ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4eaa2:
6c5deeb2 8b36            mov     esi,dword ptr [esi]  ds:002b:6c8209e4=6c521480
0:000> p
eax=00000008 ebx=d30e6fb0 ecx=d30e6fb0 edx=04004000 esi=6c521480 edi=b8806d54
eip=6c5deeb4 esp=00f0c4e8 ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4eaa4:
6c5deeb4 8bce            mov     ecx,esi
0:000> p
eax=00000008 ebx=d30e6fb0 ecx=6c521480 edx=04004000 esi=6c521480 edi=b8806d54
eip=6c5deeb6 esp=00f0c4e8 ebp=00f0c52c iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
CoolType!CTCleanup+0x4eaa6:
6c5deeb6 ff1530e6746c    call    dword ptr [CoolType!CTGetVersion+0x1529a0 (6c74e630)] ds:002b:6c74e630={ntdll!LdrpValidateUserCallTarget (777888f0)}
0:000> p
eax=0d8a4290 ebx=d30e6fb0 ecx=6c521480 edx=10010400 esi=6c521480 edi=b8806d54
eip=6c5deebc esp=00f0c4e8 ebp=00f0c52c iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000247
CoolType!CTCleanup+0x4eaac:
6c5deebc ffd6            call    esi {CoolType!CTInit+0x1de20 (6c521480)}                  ; <---------------------- (9)
0:000> p
eax=d42d5ff8 ebx=d30e6fb0 ecx=00000008 edx=00000000 esi=6c521480 edi=b8806d54
eip=6c5deebe esp=00f0c4e8 ebp=00f0c52c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
CoolType!CTCleanup+0x4eaae:
6c5deebe 894704          mov     dword ptr [edi+4],eax ds:002b:b8806d58=00000000
0:000> dd eax                                                                              ; <---------------------- (10)
d42d5ff8  c0c0c0c0 c0c0c0c0 ???????? ????????
d42d6008  ???????? ???????? ???????? ????????

[...]

0:000> p
eax=c5fdac18 ebx=d30e6fb0 ecx=0000020a edx=10010400 esi=6c5214e0 edi=b8806d54
eip=6c5def10 esp=00f0c4f0 ebp=00f0c52c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
CoolType!CTCleanup+0x4eb00:
6c5def10 ff75d4          push    dword ptr [ebp-2Ch]  ss:002b:00f0c500=00000008
0:000> p
eax=c5fdac18 ebx=d30e6fb0 ecx=0000020a edx=10010400 esi=6c5214e0 edi=b8806d54
eip=6c5def13 esp=00f0c4ec ebp=00f0c52c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
CoolType!CTCleanup+0x4eb03:
6c5def13 ff75d0          push    dword ptr [ebp-30h]  ss:002b:00f0c4fc=c5fdadf4
0:000> p
eax=c5fdac18 ebx=d30e6fb0 ecx=0000020a edx=10010400 esi=6c5214e0 edi=b8806d54
eip=6c5def16 esp=00f0c4e8 ebp=00f0c52c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
CoolType!CTCleanup+0x4eb06:
6c5def16 ff75f8          push    dword ptr [ebp-8]    ss:002b:00f0c524=00000008
0:000> p
eax=c5fdac18 ebx=d30e6fb0 ecx=0000020a edx=10010400 esi=6c5214e0 edi=b8806d54
eip=6c5def19 esp=00f0c4e4 ebp=00f0c52c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
CoolType!CTCleanup+0x4eb09:
6c5def19 ff7704          push    dword ptr [edi+4]    ds:002b:b8806d58=d42d5ff8
0:000> p
eax=c5fdac18 ebx=d30e6fb0 ecx=0000020a edx=10010400 esi=6c5214e0 edi=b8806d54
eip=6c5def1c esp=00f0c4e0 ebp=00f0c52c iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
CoolType!CTCleanup+0x4eb0c:
6c5def1c e8bd120000      call    CoolType!CTCleanup+0x4fdce (6c5e01de)             ; <---------------------- (11)
0:000> p
eax=00000000 ebx=d30e6fb0 ecx=00000000 edx=00000000 esi=6c5214e0 edi=b8806d54
eip=6c5def21 esp=00f0c4e0 ebp=00f0c52c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x4eb11:
6c5def21 8b7324          mov     esi,dword ptr [ebx+24h] ds:002b:d30e6fd4=6c521cb0
0:000> dd d42d5ff8                                                                 ; <---------------------- (12)
d42d5ff8  01000200 00000000 ???????? ????????
d42d6008  ???????? ???????? ???????? ????????

The malloc function is called at (9) and the size argument of malloc comes from eax at (8), which is equal to GlyphVariationData_size. This malloc called creates the vulnerable buffer. The memcpy is called at (11) to copy GlyphVariationData to the vulnerable buffer. The vulnerable buffer content can be observed at (12).

0:000> p
eax=6c829938 ebx=00000004 ecx=00000000 edx=00f0c494 esi=00000004 edi=00f0c494
eip=6c5bb9df esp=00f0c3b0 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b5cf:
6c5bb9df 8b5730          mov     edx,dword ptr [edi+30h] ds:002b:00f0c4c4=d42d5ff8
0:000> p
eax=6c829938 ebx=00000004 ecx=00000000 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9e2 esp=00f0c3b0 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b5d2:
6c5bb9e2 83c424          add     esp,24h
0:000> p
eax=6c829938 ebx=00000004 ecx=00000000 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9e5 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTCleanup+0x2b5d5:
6c5bb9e5 8955a0          mov     dword ptr [ebp-60h],edx ss:002b:00f0c408=00f0cb1c
0:000> p
eax=6c829938 ebx=00000004 ecx=00000000 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9e8 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTCleanup+0x2b5d8:
6c5bb9e8 668b02          mov     ax,word ptr [edx]        ds:002b:d42d5ff8=0200  ;<-------------------- (13)
0:000> p
eax=6c820200 ebx=00000004 ecx=00000000 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9eb esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTCleanup+0x2b5db:
6c5bb9eb 0fb64a01        movzx   ecx,byte ptr [edx+1]       ds:002b:d42d5ff9=02  ;<-------------------- (14)
0:000> p
eax=6c820200 ebx=00000004 ecx=00000002 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9ef esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTCleanup+0x2b5df:
6c5bb9ef 66c1e008        shl     ax,8
0:000> p
eax=6c820000 ebx=00000004 ecx=00000002 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9f3 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b5e3:
6c5bb9f3 6633c8          xor     cx,ax
0:000> p
eax=6c820000 ebx=00000004 ecx=00000002 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9f6 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b5e6:
6c5bb9f6 668b4202        mov     ax,word ptr [edx+2]      ds:002b:d42d5ffa=0100  ;<------------------- (15)
0:000> p
eax=6c820100 ebx=00000004 ecx=00000002 edx=d42d5ff8 esi=00000004 edi=00f0c494
eip=6c5bb9fa esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b5ea:
6c5bb9fa 0fb7f1          movzx   esi,cx
0:000> p
eax=6c820100 ebx=00000004 ecx=00000002 edx=d42d5ff8 esi=00000002 edi=00f0c494
eip=6c5bb9fd esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b5ed:
6c5bb9fd 0fb64a03        movzx   ecx,byte ptr [edx+3]       ds:002b:d42d5ffb=01 ;<--------------------- (16)
0:000> p
eax=6c820100 ebx=00000004 ecx=00000001 edx=d42d5ff8 esi=00000002 edi=00f0c494
eip=6c5bba01 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b5f1:
6c5bba01 83c204          add     edx,4                                         ;<--------------------- (17)
0:000> p
eax=6c820100 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba04 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000286
CoolType!CTCleanup+0x2b5f4:
6c5bba04 66c1e008        shl     ax,8
0:000> dd edx L8
d42d5ffc  00000000 ???????? ???????? ????????
d42d600c  ???????? ???????? ???????? ????????
0:000> p
eax=6c820000 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba08 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000247
CoolType!CTCleanup+0x2b5f8:
6c5bba08 6633c8          xor     cx,ax
0:000> p
eax=6c820000 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba0b esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b5fb:
6c5bba0b 8955e8          mov     dword ptr [ebp-18h],edx ss:002b:00f0c450=6c8284e0

0:000> p
eax=6c820000 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba0e esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b5fe:
6c5bba0e 8b4510          mov     eax,dword ptr [ebp+10h] ss:002b:00f0c478=b8806bf8
0:000> p
eax=b8806bf8 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba11 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b601:
6c5bba11 0fb7c9          movzx   ecx,cx
0:000> p
eax=b8806bf8 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba14 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b604:
6c5bba14 894dd0          mov     dword ptr [ebp-30h],ecx ss:002b:00f0c438=00000020
0:000> p
eax=b8806bf8 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba17 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b607:
6c5bba17 0fb7c9          movzx   ecx,cx
0:000> p
eax=b8806bf8 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba1a esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b60a:
6c5bba1a 8b8064010000    mov     eax,dword ptr [eax+164h] ds:002b:b8806d5c=00000008
0:000> p
eax=00000008 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba20 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b610:
6c5bba20 8945e4          mov     dword ptr [ebp-1Ch],eax ss:002b:00f0c44c=cddc4ed0
0:000> p
eax=00000008 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba23 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b613:
6c5bba23 3bc8            cmp     ecx,eax
0:000> p
eax=00000008 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba25 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CoolType!CTCleanup+0x2b615:
6c5bba25 0f8fea030000    jg      CoolType!CTCleanup+0x2ba05 (6c5bbe15)   [br=0]
0:000> p
eax=00000008 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba2b esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CoolType!CTCleanup+0x2b61b:
6c5bba2b 8bc6            mov     eax,esi
0:000> p
eax=00000002 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba2d esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CoolType!CTCleanup+0x2b61d:
6c5bba2d c745a8ff0f0000  mov     dword ptr [ebp-58h],0FFFh ss:002b:00f0c410=47cef144
0:000> p
eax=00000002 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba34 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CoolType!CTCleanup+0x2b624:
6c5bba34 25ff0f0000      and     eax,0FFFh
0:000> p
eax=00000002 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba39 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b629:
6c5bba39 894584          mov     dword ptr [ebp-7Ch],eax ss:002b:00f0c3ec=01000002
0:000> p
eax=00000002 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba3c esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b62c:
6c5bba3c c1e002          shl     eax,2                                         <------------------- (18)
0:000> p
eax=00000008 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba3f esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b62f:
6c5bba3f 3b45e4          cmp     eax,dword ptr [ebp-1Ch] ss:002b:00f0c44c=00000008 ; <------------------- (19)
0:000> p
eax=00000008 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba42 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b632:
6c5bba42 0f8fcd030000    jg      CoolType!CTCleanup+0x2ba05 (6c5bbe15)   [br=0]
0:000> p
eax=00000008 ebx=00000004 ecx=00000001 edx=d42d5ffc esi=00000002 edi=00f0c494
eip=6c5bba48 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b638:
6c5bba48 6685f6          test    si,si

The above method is called to parse GlyphVariationData. The tupleVariationCount field is read at (13) and (14) and dataOffset is read at (15) and (16). The pointer is moved by 4 bytes at (17) to point to the beginning of TupleVariationHeaders. A check is performed at (19) to ensure 4*tupleVariationCount is less than or equal to GlyphVariationData_size.

0:000> p
eax=6c8298f0 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbac8 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b6b8:
6c5bbac8 668b02          mov     ax,word ptr [edx]        ds:002b:d42d5ffc=0000 <--------------------- (20)
0:000> p
eax=6c820000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbacb esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b6bb:
6c5bbacb 0fb64a01        movzx   ecx,byte ptr [edx+1]       ds:002b:d42d5ffd=00
0:000> p
eax=6c820000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbacf esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b6bf:
6c5bbacf 66c1e008        shl     ax,8
0:000> p
eax=6c820000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbad3 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b6c3:
6c5bbad3 6633c8          xor     cx,ax
0:000> p
eax=6c820000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbad6 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b6c6:
6c5bbad6 0fb7c1          movzx   eax,cx
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbad9 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b6c9:
6c5bbad9 898578ffffff    mov     dword ptr [ebp-88h],eax ss:002b:00f0c3e0={ntdll!_except_handler4 (7777af30)}
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbadf esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b6cf:
6c5bbadf 0fb7c1          movzx   eax,cx
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbae2 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b6d2:
6c5bbae2 89458c          mov     dword ptr [ebp-74h],eax ss:002b:00f0c3f4=00000050
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbae5 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTCleanup+0x2b6d5:
6c5bbae5 3b45e4          cmp     eax,dword ptr [ebp-1Ch] ss:002b:00f0c44c=00000008
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbae8 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000293
CoolType!CTCleanup+0x2b6d8:
6c5bbae8 0f8f27030000    jg      CoolType!CTCleanup+0x2ba05 (6c5bbe15)   [br=0]
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbaee esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000293
CoolType!CTCleanup+0x2b6de:
6c5bbaee 668b4202        mov     ax,word ptr [edx+2]      ds:002b:d42d5ffe=0000
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbaf2 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000293
CoolType!CTCleanup+0x2b6e2:
6c5bbaf2 0fb64a03        movzx   ecx,byte ptr [edx+3]       ds:002b:d42d5fff=00
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d5ffc esi=00000004 edi=00f0c494
eip=6c5bbaf6 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000293
CoolType!CTCleanup+0x2b6e6:
6c5bbaf6 83c204          add     edx,4                                            ; <------------ (21)
0:000> p
eax=00000000 ebx=00000004 ecx=00000000 edx=d42d6000 esi=00000004 edi=00f0c494
eip=6c5bbaf9 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000296
CoolType!CTCleanup+0x2b6e9:
6c5bbaf9 8b7510          mov     esi,dword ptr [ebp+10h] ss:002b:00f0c478=b8806bf8
0:000> dd edx L4
d42d6000  ???????? ???????? ???????? ????????
[...]
:000> p
eax=00000000 ebx=00000004 ecx=00000400 edx=00000000 esi=00000001 edi=00000000
eip=6c5bbe03 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b9f3:
6c5bbe03 0145d0          add     dword ptr [ebp-30h],eax ss:002b:00f0c438=00000001
0:000> p
eax=00000000 ebx=00000004 ecx=00000400 edx=00000000 esi=00000001 edi=00000000
eip=6c5bbe06 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b9f6:
6c5bbe06 8b55e8          mov     edx,dword ptr [ebp-18h] ss:002b:00f0c450=d42d6000
0:000> p
eax=00000000 ebx=00000004 ecx=00000400 edx=d42d6000 esi=00000001 edi=00000000
eip=6c5bbe09 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b9f9:
6c5bbe09 897588          mov     dword ptr [ebp-78h],esi ss:002b:00f0c3f0=00000000
0:000> p
eax=00000000 ebx=00000004 ecx=00000400 edx=d42d6000 esi=00000001 edi=00000000
eip=6c5bbe0c esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTCleanup+0x2b9fc:
6c5bbe0c 3b7584          cmp     esi,dword ptr [ebp-7Ch] ss:002b:00f0c3ec=00000002
0:000> p
eax=00000000 ebx=00000004 ecx=00000400 edx=d42d6000 esi=00000001 edi=00000000
eip=6c5bbe0f esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CoolType!CTCleanup+0x2b9ff:
6c5bbe0f 0f8cb3fcffff    jl      CoolType!CTCleanup+0x2b6b8 (6c5bbac8)   [br=1]  <---------- (22)

The loop starts at (20) and ends at (22) to read the TupleVariationHeader elements present in the TupleVariationHeadersarray. After reading the first TupleVariationHeader, the vulnerable buffer has already reached its end, which can be observed at (21). The out-of-bounds read occurs when the loop tries to read the second TupleVariationHeader. This can be observed at the time of the crash:

0:000> g
(778.1554): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000004 ecx=00000400 edx=d42d6000 esi=00000001 edi=00000000
eip=6c5bbac8 esp=00f0c3d4 ebp=00f0c468 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010297
CoolType!CTCleanup+0x2b6b8:
6c5bbac8 668b02          mov     ax,word ptr [edx]        ds:002b:d42d6000=????
0:000> u
CoolType!CTCleanup+0x2b6b8:
6c5bbac8 668b02          mov     ax,word ptr [edx]
6c5bbacb 0fb64a01        movzx   ecx,byte ptr [edx+1]
6c5bbacf 66c1e008        shl     ax,8
6c5bbad3 6633c8          xor     cx,ax
6c5bbad6 0fb7c1          movzx   eax,cx
6c5bbad9 898578ffffff    mov     dword ptr [ebp-88h],eax
6c5bbadf 0fb7c1          movzx   eax,cx
6c5bbae2 89458c          mov     dword ptr [ebp-74h],eax
0:000> kb
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 00f0c468 6c54e2ab     33390db4 00f0c494 b8806bf8 CoolType!CTCleanup+0x2b6b8
01 00f0c52c 6c54cff8     b8806bf8 33390db4 b8806d68 CoolType!CTInit+0x4ac4b
02 00f0c628 6c54c946     33390c18 33390d88 33390d48 CoolType!CTInit+0x49998
03 00f0c68c 6c54c74b     33390c18 33390d88 33390d48 CoolType!CTInit+0x492e6
04 00f0c6e8 6c5471d3     33390c18 33390d88 33390d48 CoolType!CTInit+0x490eb
05 00f0c758 6c547016     00f0c8a8 00f0c7d8 00000001 CoolType!CTInit+0x43b73
06 00f0c774 6c543db7     00f0c8a8 00f0c7d8 cddc4ed0 CoolType!CTInit+0x439b6
07 00f0c8fc 6c5435f0     cddc4ed0 6c82f950 00f0cae8 CoolType!CTInit+0x40757
08 00f0cb28 6c53caa0     00f0d5e4 00f0cbb0 00000000 CoolType!CTInit+0x3ff90
09 00f0d630 6c53a8fb     000000cf 00000000 00000000 CoolType!CTInit+0x39440
0a 00f0d704 6c5393bf     00f0d98c 00000001 00f0d768 CoolType!CTInit+0x3729b
0b 00f0da70 6c538e7c     cdd88bdc cdd88bc4 c1e84c4e CoolType!CTInit+0x35d5f
0c 00f0daac 6c8ac1e1     b79baf64 cdd88bdc cdd88bc4 CoolType!CTInit+0x3581c
0d 00f0dac0 6c8a373e     cdd88bc4 6c8a3570 3fef6250 AGM!AGMInitialize+0x22be1
0e 00f0dad4 6c89efb7     3fef625c 6cd22a68 00000001 AGM!AGMInitialize+0x1a13e
0f 00f0daf8 6c8aafea     00f0db5c 00f0db78 00f0dc08 AGM!AGMInitialize+0x159b7
10 00f0db0c 6c8ab03b     00000001 eec9d8ec 00000000 AGM!AGMInitialize+0x219ea
11 00f0db34 777e9323     decbd236 3f800000 00000000 AGM!AGMInitialize+0x21a3b
12 00f0dbd8 00000000     c6468448 01f216cc 00f0dc10 ntdll!RtlStdLogStackTrace+0x43

Using this vulnerability, it is possible to read arbitrary memory of the process. Because of complex interactions between PDF reader and font subcomponents, especially in the presence of a JavaScript engine, it is possible that sensitive contents of arbitrary memory could be disclosed, which could aid in further exploitation and exploit mitigation bypass.

VENDOR RESPONSE

Adobe released updated software which can be found linked from the advisory: https://helpx.adobe.com/security/products/acrobat/apsb24-29.html

TIMELINE

2024-02-20 - Vendor Disclosure
2024-05-14 - Vendor Patch Release
2024-05-15 - Public Release

Credit

Discovered by KPC of Cisco Talos.