Talos Vulnerability Report

TALOS-2024-2070

Adobe Acrobat Reader Font Private Point Numbers Out-Of-Bounds Read Vulnerability

December 11, 2024
CVE Number

CVE-2024-49533

SUMMARY

An out-of-bounds read vulnerability exists in font handling code of Adobe Acrobat Reader 2024.002.21005. A font file with a specially crafted Private Point Numbers table embedded into a PDF can trigger an out of bounds memory read which can lead to disclosure of sensitive information and aid further exploitation. 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 2024.002.21005

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, including OpenType fonts. 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 or 0x74727565, 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                 tvs_dataOffset
0x04    total_tvh_size       TupleVariationHeaders 

The low 12 bits of tupleVariationCount indicates the number of tuple variation tables for this glyph. tvs_dataOffset indicates the offset from the start of the GlyphVariationData table to the serialized data. The TupleVariationHeaders contains an array of TupleVariationHeader.

In our case, the vulnerable GlyphVariationData contains the following data:

8f10ef50  00 02 00 4c 00 50 20 01-00 4e 20 00 1a 19 01 01  ...L.P ..N .....
8f10ef60  03 01 02 01 01 01 21 01-01 01 01 01 02 02 02 03  ......!.........
8f10ef70  02 02 01 01 02 04 01 01-00 ff 82 13 fe fe fc fc  ................
8f10ef80  fc 06 07 fe fe 05 0c 05-f8 f0 06 0b 0a 02 fc fb  ................
8f10ef90  81 15 06 05 04 02 02 02-02 04 04 0d 09 06 f5 f5  ................
8f10efa0  04 12 12 fe 09 04 00 04-81 01 02 f8 19 18 01 01  ................
8f10efb0  01 02 02 02 03 01 01 01-01 01 03 01 02 03 02 01  ................
8f10efc0  01 01 01 02 04 01 01 01-03 01 81 12 03 04 06 f8  ................
8f10efd0  f6 02 03 fb ee fb 0c 18-fa f7 f1 f2 fe 06 02 81  ................
8f10efe0  14 f8 f8 fb fc fe fe fb-ed f3 f8 0f 0f f2 e6 e6  ................
8f10eff0  04 f4 f4 fb 00 fb 81 01-fe 0c d0       

Here, the value of tupleVariationCount is 0x02. But the low 12 bits of tupleVariationCount indicates the number of tuple variation tables for this glyph. It means TupleVariationHeaders contains two TupleVariationHeader and the values of each TupleVariationHeader are as follows:

TupleVariationHeader_1 
    tvh_variationDataSize_1 = 0x050
    tvh_tupleIndex_1 =  0x2001
    tvh_size_1    =  4

TupleVariationHeader_2
    tvh_variationDataSize_2 = 0x4e
    tvh_tupleIndex_2 =  0x2000
    tvh_size_2    =  4

Here, total_tvh_size is 0x08 (tvh_size_1 + tvh_size_2). The value of tvh_size_1 and tvh_size_2 is calculated using the function get_TupleVariationHeader_size.

After the GlyphVariationData table header, a block of serialized data is present. A serialized data block begins with the optional shared point number data (shared-point-numbers), followed by the variation data for the tuple variation tables (per-tuple-variation-table). The optional shared-point-numbers data is included when (tupleVariationCount & 0x8000) is non-zero. Here (tupleVariationCount & 0x8000) is zero so no shared-point-numbers are present.

The per-tuple-variation-table data begins with the optional private-point-numbers if (tvh_tupleIndex & 0x2000) is non-zero. The private-point-numbers data is represented as packed point numbers.

private_point_number begins with a count followed by one or more runs of point number data. The total count of point numbers can be calculated using the following python pseudo-code:

def get_total_count_of_pn(private_point_number: bytes):
    total_count = 0

    if private_point_number[0] & 0x80:
        total_count =  (private_point_number[1] | ((private_point_number[0] & 0x7F) << 8) ) 
    else:
        total_count =  private_point_number[0]

    return total_count

The application fails to properly validate all fields before processing private_point_number. This vulnerability occurs when the size of GlyphVariationData is samller than (tvs_dataOffset + tvh_variationDataSize_1 + tvh_variationDataSize_2 + ... + tvh_variationDataSize_n) . Here, tvh_variationDataSize_1 is the size of the first serialized block, tvh_variationDataSize_2 is the size of the second serialized block, and so on.

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

0:002> p
Time Travel Position: 2E6D36:10D2
eax=eba01720 ebx=73958fb0 ecx=00000003 edx=001d0002 esi=6b0ecaa0 edi=00000002
eip=6b1a69fa esp=00cfbe98 ebp=00cfbed4 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+0xd11ea:
6b1a69fa 8d3c7d14000000  lea     edi,[edi*2+14h]                  ;<---------------------------- (1)     
0:002> p
Time Travel Position: 2E6D36:10D3
eax=eba01720 ebx=73958fb0 ecx=00000003 edx=001d0002 esi=6b0ecaa0 edi=00000018
eip=6b1a6a01 esp=00cfbe98 ebp=00cfbed4 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+0xd11f1:
6b1a6a01 57              push    edi
0:002> p
Time Travel Position: 2E6D36:10D4
eax=eba01720 ebx=73958fb0 ecx=00000003 edx=001d0002 esi=6b0ecaa0 edi=00000018
eip=6b1a6a02 esp=00cfbe94 ebp=00cfbed4 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+0xd11f2:
6b1a6a02 ff750c          push    dword ptr [ebp+0Ch]  ss:002b:00cfbee0=00cfbf00
0:002> pc
Time Travel Position: 2E6D36:10D7
eax=eba01720 ebx=73958fb0 ecx=6b0ecaa0 edx=001d0002 esi=6b0ecaa0 edi=00000018
eip=6b1a6a08 esp=00cfbe8c ebp=00cfbed4 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+0xd11f8:
6b1a6a08 ff15ac26316b    call    dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:10E3
eax=0d61d954 ebx=73958fb0 ecx=6b0ecaa0 edx=00100000 esi=6b0ecaa0 edi=00000018
eip=6b1a6a0e esp=00cfbe8c ebp=00cfbed4 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+0xd11fe:
6b1a6a0e ffd6            call    esi {CoolType!CTCleanup+0x17290 (6b0ecaa0)}  ; <---------------- (2)
0:002> p
Time Travel Position: 2E6D36:10FA
eax=00000056 ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a10 esp=00cfbe8c ebp=00cfbed4 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+0xd1200:
6b1a6a10 8b730c          mov     esi,dword ptr [ebx+0Ch] ds:002b:73958fbc=6b0ecaa0 ; <---------------- (3)
0:002> p
Time Travel Position: 2E6D36:10FB
eax=00000056 ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a13 esp=00cfbe8c ebp=00cfbed4 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+0xd1203:
6b1a6a13 83c40c          add     esp,0Ch
0:002> p
Time Travel Position: 2E6D36:10FC
eax=00000056 ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a16 esp=00cfbe98 ebp=00cfbed4 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212
CoolType!CTCleanup+0xd1206:
6b1a6a16 03c0            add     eax,eax
0:002> p
Time Travel Position: 2E6D36:10FD
eax=000000ac ebx=73958fb0 ecx=00000056 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a18 esp=00cfbe98 ebp=00cfbed4 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+0xd1208:
6b1a6a18 8bce            mov     ecx,esi
0:002> pc
Time Travel Position: 2E6D36:1103
eax=0000001a ebx=73958fb0 ecx=6b0ecaa0 edx=00000018 esi=6b0ecaa0 edi=00000018
eip=6b1a6a25 esp=00cfbe8c ebp=00cfbed4 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+0xd1215:
6b1a6a25 ff15ac26316b    call    dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:110F
eax=0d61d954 ebx=73958fb0 ecx=6b0ecaa0 edx=00100000 esi=6b0ecaa0 edi=00000018
eip=6b1a6a2b esp=00cfbe8c ebp=00cfbed4 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+0xd121b:
6b1a6a2b ffd6            call    esi {CoolType!CTCleanup+0x17290 (6b0ecaa0)}
0:002> p
Time Travel Position: 2E6D36:1126
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=00000018
eip=6b1a6a2d esp=00cfbe8c ebp=00cfbed4 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+0xd121d:
6b1a6a2d 8bf8            mov     edi,eax                                      ; <---------------- (4)
0:002> p
Time Travel Position: 2E6D36:1127
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000ab
eip=6b1a6a2f esp=00cfbe8c ebp=00cfbed4 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+0xd121f:
6b1a6a2f 83c40c          add     esp,0Ch
0:002> p
Time Travel Position: 2E6D36:1128
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000ab
eip=6b1a6a32 esp=00cfbe98 ebp=00cfbed4 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212
CoolType!CTCleanup+0xd1222:
6b1a6a32 03ff            add     edi,edi                                      ;<--------------------- (5)
0:002> p
Time Travel Position: 2E6D36:1129
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=00000156
eip=6b1a6a34 esp=00cfbe98 ebp=00cfbed4 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+0xd1224:
6b1a6a34 2b7df8          sub     edi,dword ptr [ebp-8] ss:002b:00cfbecc=000000ac   ;<----------------- (6)
0:002> p
Time Travel Position: 2E6D36:112A
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000aa
eip=6b1a6a37 esp=00cfbe98 ebp=00cfbed4 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+0xd1227:
6b1a6a37 897df4          mov     dword ptr [ebp-0Ch],edi ss:002b:00cfbec8=00000050
0:002> p
Time Travel Position: 2E6D36:112B
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000aa
eip=6b1a6a3a esp=00cfbe98 ebp=00cfbed4 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+0xd122a:
6b1a6a3a 0f846e010000    je      CoolType!CTCleanup+0xd139e (6b1a6bae)   [br=0]
0:002> p
Time Travel Position: 2E6D36:112C
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b0ecaa0 edi=000000aa
eip=6b1a6a40 esp=00cfbe98 ebp=00cfbed4 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+0xd1230:
6b1a6a40 8b732c          mov     esi,dword ptr [ebx+2Ch] ds:002b:73958fdc=6b2d4880
0:002> p
Time Travel Position: 2E6D36:112D
eax=000000ab ebx=73958fb0 ecx=000000ab edx=0000001a esi=6b2d4880 edi=000000aa
eip=6b1a6a43 esp=00cfbe98 ebp=00cfbed4 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+0xd1233:
6b1a6a43 8bce            mov     ecx,esi
0:002> p
Time Travel Position: 2E6D36:112E
eax=000000ab ebx=73958fb0 ecx=6b2d4880 edx=0000001a esi=6b2d4880 edi=000000aa
eip=6b1a6a45 esp=00cfbe98 ebp=00cfbed4 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+0xd1235:
6b1a6a45 53              push    ebx
0:002> p
Time Travel Position: 2E6D36:112F
eax=000000ab ebx=73958fb0 ecx=6b2d4880 edx=0000001a esi=6b2d4880 edi=000000aa
eip=6b1a6a46 esp=00cfbe94 ebp=00cfbed4 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+0xd1236:
6b1a6a46 ff15ac26316b    call    dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:113B
eax=0d65a910 ebx=73958fb0 ecx=6b2d4880 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a4c esp=00cfbe94 ebp=00cfbed4 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+0xd123c:
6b1a6a4c ffd6            call    esi {CoolType!CTGetVersion+0x111c80 (6b2d4880)}
0:002> p
Time Travel Position: 2E6D36:1147
eax=00000176 ebx=73958fb0 ecx=6b2d4880 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a4e esp=00cfbe94 ebp=00cfbed4 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+0xd123e:
6b1a6a4e 59              pop     ecx
0:002> p
Time Travel Position: 2E6D36:1148
eax=00000176 ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a4f esp=00cfbe98 ebp=00cfbed4 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+0xd123f:
6b1a6a4f 3bf8            cmp     edi,eax                                   ;<------------------(7)
0:002> p
Time Travel Position: 2E6D36:1149
eax=00000176 ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b2d4880 edi=000000aa
eip=6b1a6a51 esp=00cfbe98 ebp=00cfbed4 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xd1241:
6b1a6a51 0f8757010000    ja      CoolType!CTCleanup+0xd139e (6b1a6bae)   [br=0]

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, called at (2), reads the offsets from the glyphVariationDataOffsets. eax at (3) and (4) contains two 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) and its value is 0xaa. At (7), a check is performed to ensure GlyphVariationData_size is smaller than tableLength.

0:002> p
Time Travel Position: 2E6D36:114D
eax=000000aa ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b3e59fc edi=eba01720
eip=6b1a6a60 esp=00cfbe98 ebp=00cfbed4 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xd1250:
6b1a6a60 50              push    eax                                          ;<---------------------------- (8)
0:002> p
Time Travel Position: 2E6D36:114E
eax=000000aa ebx=73958fb0 ecx=73958fb0 edx=01010010 esi=6b3e59fc edi=eba01720
eip=6b1a6a61 esp=00cfbe94 ebp=00cfbed4 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xd1251:
6b1a6a61 894708          mov     dword ptr [edi+8],eax ds:002b:eba01728=00000000
0:002> pc
Time Travel Position: 2E6D36:1152
eax=000000aa ebx=73958fb0 ecx=6b0e7eb0 edx=01010010 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a69 esp=00cfbe90 ebp=00cfbed4 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xd1259:
6b1a6a69 ff15ac26316b    call    dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D36:115E
eax=0d61cfd6 ebx=73958fb0 ecx=6b0e7eb0 edx=01440000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a6f esp=00cfbe90 ebp=00cfbed4 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+0xd125f:
6b1a6a6f ffd6            call    esi {CoolType!CTCleanup+0x126a0 (6b0e7eb0)}   ;<---------------------------- (9)
0:002> p
Time Travel Position: 2E6D3A:F0D
eax=8f10ef50 ebx=73958fb0 ecx=000000aa edx=00000000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a71 esp=00cfbe90 ebp=00cfbed4 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+0xd1261:
6b1a6a71 894704          mov     dword ptr [edi+4],eax ds:002b:eba01724=00000000
0:002> dd eax                                                                  ;<---------------------------- (10) 
8f10ef50  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef60  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef70  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef80  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10ef90  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10efa0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10efb0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
8f10efc0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0:002> p
Time Travel Position: 2E6D3A:F0E
eax=8f10ef50 ebx=73958fb0 ecx=000000aa edx=00000000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a74 esp=00cfbe90 ebp=00cfbed4 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+0xd1264:
6b1a6a74 59              pop     ecx
0:002> p
Time Travel Position: 2E6D3A:F0F
eax=8f10ef50 ebx=73958fb0 ecx=6b3e59fc edx=00000000 esi=6b0e7eb0 edi=eba01720
eip=6b1a6a75 esp=00cfbe94 ebp=00cfbed4 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+0xd1265:
6b1a6a75 59              pop     ecx
0:002> pc
Time Travel Position: 2E6D3A:F1F
eax=00cfbea4 ebx=73958fb0 ecx=6b0e7f80 edx=00000000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aa2 esp=00cfbe8c ebp=00cfbed4 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+0xd1292:
6b1a6aa2 ff15ac26316b    call    dword ptr [CoolType!CTGetVersion+0x14faac (6b3126ac)] ds:002b:6b3126ac=77ed8e70
0:002> p
Time Travel Position: 2E6D3A:F2B
eax=0d61cff0 ebx=73958fb0 ecx=6b0e7f80 edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aa8 esp=00cfbe8c ebp=00cfbed4 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+0xd1298:
6b1a6aa8 ffd6            call    esi {CoolType!CTCleanup+0x12770 (6b0e7f80)}
0:002> p
Time Travel Position: 2E6D3A:F4F
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aaa esp=00cfbe8c ebp=00cfbed4 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+0xd129a:
6b1a6aaa 83c40c          add     esp,0Ch
0:002> p
Time Travel Position: 2E6D3A:F50
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6aad esp=00cfbe98 ebp=00cfbed4 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212
CoolType!CTCleanup+0xd129d:
6b1a6aad 837dd000        cmp     dword ptr [ebp-30h],0 ss:002b:00cfbea4=001d4f54
0:002> p
Time Travel Position: 2E6D3A:F51
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ab1 esp=00cfbe98 ebp=00cfbed4 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+0xd12a1:
6b1a6ab1 7510            jne     CoolType!CTCleanup+0xd12b3 (6b1a6ac3)   [br=1]
0:002> p
Time Travel Position: 2E6D3A:F52
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ac3 esp=00cfbe98 ebp=00cfbed4 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+0xd12b3:
6b1a6ac3 ff75d4          push    dword ptr [ebp-2Ch]  ss:002b:00cfbea8=000000aa
0:002> p
Time Travel Position: 2E6D3A:F53
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ac6 esp=00cfbe94 ebp=00cfbed4 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+0xd12b6:
6b1a6ac6 ff75d0          push    dword ptr [ebp-30h]  ss:002b:00cfbea4=001d4f54
0:002> p
Time Travel Position: 2E6D3A:F54
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6ac9 esp=00cfbe90 ebp=00cfbed4 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+0xd12b9:
6b1a6ac9 ff75f4          push    dword ptr [ebp-0Ch]  ss:002b:00cfbec8=000000aa
0:002> p
Time Travel Position: 2E6D3A:F55
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6acc esp=00cfbe8c ebp=00cfbed4 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+0xd12bc:
6b1a6acc ff7704          push    dword ptr [edi+4]    ds:002b:eba01724=8f10ef50
0:002> p
Time Travel Position: 2E6D3A:F56
eax=001d4e88 ebx=73958fb0 ecx=000000aa edx=00014000 esi=6b0e7f80 edi=eba01720
eip=6b1a6acf esp=00cfbe88 ebp=00cfbed4 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+0xd12bf:
6b1a6acf e8ca120000      call    CoolType!CTCleanup+0xd258e (6b1a7d9e)             ; <----------------------- (11)
0:002> p
Time Travel Position: 2E6D3A:1029
eax=00000000 ebx=73958fb0 ecx=00000000 edx=000000aa esi=6b0e7f80 edi=eba01720
eip=6b1a6ad4 esp=00cfbe88 ebp=00cfbed4 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+0xd12c4:
6b1a6ad4 8b7324          mov     esi,dword ptr [ebx+24h] ds:002b:73958fd4=6b0e8fa0
0:002> dd 8f10ef50                                                                 ;<----------------------- (12)
8f10ef50  4c000200 01205000 00204e00 0101191a
8f10ef60  01020103 01210101 01010101 03020202
8f10ef70  01010202 01010402 1382ff00 fcfcfefe
8f10ef80  fe0706fc 050c05fe 0b06f0f8 fbfc020a
8f10ef90  05061581 02020204 0d040402 f5f50609
8f10efa0  fe121204 04000409 f8020181 01011819
8f10efb0  02020201 01010103 01030101 01020302
8f10efc0  02010101 01010104 12810103 f8060403

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 creates the vulnerable buffer and its value is examined at (10). The memcpy is called at (11) to copy GlyphVariationData to the vulnerable buffer. The vulnerable buffer content can be observed at (12).

0:002>
Time Travel Position: 2E6D44:D95
eax=00010000 ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846d2 esp=00cfbd74 ebp=00cfbe10 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+0xaeec2:
6b1846d2 8b45d8          mov     eax,dword ptr [ebp-28h] ss:002b:00cfbde8=0000009c  ;<----------------------- (13)
0:002> p
Time Travel Position: 2E6D44:D96
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846d5 esp=00cfbd74 ebp=00cfbe10 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+0xaeec5:
6b1846d5 0fb7c0          movzx   eax,ax
0:002> p
Time Travel Position: 2E6D44:D97
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846d8 esp=00cfbd74 ebp=00cfbe10 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+0xaeec8:
6b1846d8 3bc7            cmp     eax,edi
0:002> p
Time Travel Position: 2E6D44:D98
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846da esp=00cfbd74 ebp=00cfbe10 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xaeeca:
6b1846da 0f8d6f020000    jge     CoolType!CTCleanup+0xaf13f (6b18494f)   [br=0]
0:002> p
Time Travel Position: 2E6D44:D99
eax=0000009c ebx=00000029 ecx=00000001 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846e0 esp=00cfbd74 ebp=00cfbe10 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xaeed0:
6b1846e0 8b4dbc          mov     ecx,dword ptr [ebp-44h] ss:002b:00cfbdcc=8f10ef50
0:002> p
Time Travel Position: 2E6D44:D9A
eax=0000009c ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846e3 esp=00cfbd74 ebp=00cfbe10 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xaeed3:
6b1846e3 03c1            add     eax,ecx                                        ;<----------------------- (14)
0:002> p
Time Travel Position: 2E6D44:D9B
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846e5 esp=00cfbd74 ebp=00cfbe10 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+0xaeed5:
6b1846e5 f745f000200000  test    dword ptr [ebp-10h],2000h ss:002b:00cfbe00=00002000 ;<----------------------- (15)
0:002> dd eax                                                                  
8f10efec  e6e6f20f fbf4f404 0181fb00 d0d00cfe
8f10effc  d0d0d0d0 ???????? ???????? ????????
8f10f00c  ???????? ???????? ???????? ????????
8f10f01c  ???????? ???????? ???????? ????????
8f10f02c  ???????? ???????? ???????? ????????

0:002> p
Time Travel Position: 2E6D44:D9C
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846ec esp=00cfbd74 ebp=00cfbe10 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+0xaeedc:
6b1846ec 8945ec          mov     dword ptr [ebp-14h],eax ss:002b:00cfbdfc=8f10efa8
0:002> p
Time Travel Position: 2E6D44:D9D
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846ef esp=00cfbd74 ebp=00cfbe10 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+0xaeedf:
6b1846ef 0f84a7000000    je      CoolType!CTCleanup+0xaef8c (6b18479c)   [br=0]
0:002> p
Time Travel Position: 2E6D44:D9E
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846f5 esp=00cfbd74 ebp=00cfbe10 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+0xaeee5:
6b1846f5 803800          cmp     byte ptr [eax],0           ds:002b:8f10efec=0f
0:002> p
Time Travel Position: 2E6D44:D9F
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b1846f8 esp=00cfbd74 ebp=00cfbe10 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+0xaeee8:
6b1846f8 7570            jne     CoolType!CTCleanup+0xaef5a (6b18476a)   [br=1]
0:002> p
Time Travel Position: 2E6D44:DA0
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b18476a esp=00cfbd74 ebp=00cfbe10 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+0xaef5a:
6b18476a ff75b0          push    dword ptr [ebp-50h]  ss:002b:00cfbdc0=0000004e
0:002> p
Time Travel Position: 2E6D44:DA1
eax=8f10efec ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b18476d esp=00cfbd70 ebp=00cfbe10 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+0xaef5d:
6b18476d 8d040f          lea     eax,[edi+ecx]
0:002> pc
Time Travel Position: 2E6D44:DAA
eax=00cfbdfc ebx=00000029 ecx=8f10ef50 edx=80225fcc esi=8f10ef5c edi=000000aa
eip=6b18477e esp=00cfbd58 ebp=00cfbe10 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+0xaef6e:
6b18477e e8fc330000      call    CoolType!CTCleanup+0xb236f (6b187b7f)    ;<----------------------- (16)

The above code shows the processing of the second tuple variation table. At (13), the offset of the second tuple variation table is 0x9c calculated by adding tvs_dataOffset and tvh_variationDataSize of the first table. The value of GlyphVariationData_size is 0xaa, which means the size of the second table (tvh_variationDataSize_2) can’t be greater than (0xaa-0x9c) 0x0e bytes. As observed earlier, the value of tvh_variationDataSize_2 is 0x4e. Ideally, a check should be performed here to verify the correct size, and the code should continue only if sufficient bytes are present.

Next, at (14), the offset is added to the vulnerable buffer to get the  serialized data block of the second tuple variation table . A check is performed at (15) to see whether per-tuple-variation-table contains the private-point-numbers data. In this case, per-tuple-variation-table contains private-point-numbers.

At (16), a method is called to parse private-point-numbers. The following code show parsing of private-point-numbers by the method:

0:002> p
Time Travel Position: 2E6D44:DBB
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=000000aa
eip=6b187ba5 esp=00cfbd30 ebp=00cfbd50 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+0xb2395:
6b187ba5 0f8449010000    je      CoolType!CTCleanup+0xb24e4 (6b187cf4)   [br=0]  
0:002> db edx                                                   <-------------------------------- (17)
8f10efec  0f f2 e6 e6 04 f4 f4 fb-00 fb 81 01 fe 0c d0 d0  ................
8f10effc  d0 d0 d0 d0 ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ....????????????
8f10f00c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
8f10f01c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
8f10f02c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
8f10f03c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
8f10f04c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
8f10f05c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
0:002> p
Time Travel Position: 2E6D44:DBC
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=000000aa
eip=6b187bab esp=00cfbd30 ebp=00cfbd50 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+0xb239b:
6b187bab 33ff            xor     edi,edi
0:002> p
Time Travel Position: 2E6D44:DBD
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000000
eip=6b187bad esp=00cfbd30 ebp=00cfbd50 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+0xb239d:
6b187bad 47              inc     edi
0:002> p
Time Travel Position: 2E6D44:DBE
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000001
eip=6b187bae esp=00cfbd30 ebp=00cfbd50 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+0xb239e:
6b187bae 397d20          cmp     dword ptr [ebp+20h],edi ss:002b:00cfbd70=0000004e; <-------------------------------- (18)
0:002> p
Time Travel Position: 2E6D44:DBF
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000001
eip=6b187bb1 esp=00cfbd30 ebp=00cfbd50 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+0xb23a1:
6b187bb1 0f8236010000    jb      CoolType!CTCleanup+0xb24dd (6b187ced)   [br=0]
0:002> p
Time Travel Position: 2E6D44:DC0
eax=00cfbda4 ebx=00cfbdfc ecx=8f10ef50 edx=8f10efec esi=00000000 edi=00000001
eip=6b187bb7 esp=00cfbd30 ebp=00cfbd50 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+0xb23a7:
6b187bb7 0fb60a          movzx   ecx,byte ptr [edx]         ds:002b:8f10efec=0f  ;<-------------------------------- (19)
0:002> p
Time Travel Position: 2E6D44:DC1
eax=00cfbda4 ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bba esp=00cfbd30 ebp=00cfbd50 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+0xb23aa:
6b187bba 8d4201          lea     eax,[edx+1]
0:002> p
Time Travel Position: 2E6D44:DC2
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bbd esp=00cfbd30 ebp=00cfbd50 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+0xb23ad:
6b187bbd 8903            mov     dword ptr [ebx],eax  ds:002b:00cfbdfc=8f10efec
0:002> p
Time Travel Position: 2E6D44:DC3
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bbf esp=00cfbd30 ebp=00cfbd50 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+0xb23af:
6b187bbf 84c9            test    cl,cl
0:002> p
Time Travel Position: 2E6D44:DC4
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bc1 esp=00cfbd30 ebp=00cfbd50 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+0xb23b1:
6b187bc1 791d            jns     CoolType!CTCleanup+0xb23d0 (6b187be0)   [br=1]
0:002> p
Time Travel Position: 2E6D44:DC5
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187be0 esp=00cfbd30 ebp=00cfbd50 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+0xb23d0:
6b187be0 3b4d10          cmp     ecx,dword ptr [ebp+10h] ss:002b:00cfbd60=000000aa ;<-------------------------------- (20)
0:002> p
Time Travel Position: 2E6D44:DC6
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187be3 esp=00cfbd30 ebp=00cfbd50 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+0xb23d3:
6b187be3 0f8704010000    ja      CoolType!CTCleanup+0xb24dd (6b187ced)   [br=0]
0:002> p
Time Travel Position: 2E6D44:DC7
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187be9 esp=00cfbd30 ebp=00cfbd50 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+0xb23d9:
6b187be9 3b4d18          cmp     ecx,dword ptr [ebp+18h] ss:002b:00cfbd68=00000029 ;<-------------------------------- (21)
0:002> p
Time Travel Position: 2E6D44:DC8
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bec esp=00cfbd30 ebp=00cfbd50 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xb23dc:
6b187bec 0f87fb000000    ja      CoolType!CTCleanup+0xb24dd (6b187ced)   [br=0]
0:002> p
Time Travel Position: 2E6D44:DC9
eax=8f10efed ebx=00cfbdfc ecx=0000000f edx=8f10efec esi=00000000 edi=00000001
eip=6b187bf2 esp=00cfbd30 ebp=00cfbd50 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000283
CoolType!CTCleanup+0xb23e2:
6b187bf2 8b5514          mov     edx,dword ptr [ebp+14h] ss:002b:00cfbd64=00cfbda4
[...]
0:002> p
Time Travel Position: 2E6D44:DCF
eax=8f100000 ebx=00cfbdfc ecx=0000000f edx=00cfbda4 esi=00000000 edi=00000001
eip=6b187c07 esp=00cfbd30 ebp=00cfbd50 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+0xb23f7:
6b187c07 8b0b            mov     ecx,dword ptr [ebx]  ds:002b:00cfbdfc=8f10efed
0:002> p
Time Travel Position: 2E6D44:DD0
eax=8f100000 ebx=00cfbdfc ecx=8f10efed edx=00cfbda4 esi=00000000 edi=00000001
eip=6b187c09 esp=00cfbd30 ebp=00cfbd50 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+0xb23f9:
6b187c09 3b4d1c          cmp     ecx,dword ptr [ebp+1Ch] ss:002b:00cfbd6c=8f10effa ;<------------------------- (22)

At (17), the content of the per-tuple-variation-table is examined. At (18), edi contains the offset to read the per-tuple-variation-table. Here, it is compared against tvh_variationDataSize_2. As we learned, the number of bytes present in the per-tuple-variation-table is 0x0e, so this check fails to prevent the out-of-bounds read.

At (19), the count field of private-point-numbers is read, and its value is greater than 0x0e. Several other validations occur at (20), (21), and (22), but these are not sufficient to prevent the out-of-bounds read. If the parsing of private-point-numbers continues, a crash can be observed.

0:002> g
(1a0c.1984): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: 2E6D45:0
eax=00000100 ebx=00cfbdfc ecx=00000016 edx=00cfbda4 esi=8f10f000 edi=00000016
eip=6b187c57 esp=00cfbd30 ebp=00cfbd50 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+0xb2447:
6b187c57 0fb70e          movzx   ecx,word ptr [esi]       ds:002b:8f10f000=????
0:002> u
CoolType!CTCleanup+0xb2447:
6b187c57 0fb70e          movzx   ecx,word ptr [esi]
6b187c5a 0fb65601        movzx   edx,byte ptr [esi+1]
6b187c5e 0fafc8          imul    ecx,eax
6b187c61 8d4602          lea     eax,[esi+2]
6b187c64 8b75f4          mov     esi,dword ptr [ebp-0Ch]
6b187c67 8903            mov     dword ptr [ebx],eax
6b187c69 6603d1          add     dx,cx
6b187c6c 8b4dec          mov     ecx,dword ptr [ebp-14h]
0:002> kb
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 00cfbd50 6b184783     6b3eeb82 00cfbdfc 000000aa CoolType!CTCleanup+0xb2447
01 00cfbe10 6b121a53     3fd2adb4 6b3ed550 eba015c4 CoolType!CTCleanup+0xaef73
02 00cfbed4 6b11fb28     eba015c4 3fd2adb4 eba02614 CoolType!CTCleanup+0x4c243
03 00cfbfc4 6b11efa3     3fd2ac18 3fd2ad88 3fd2ad48 CoolType!CTCleanup+0x4a318
04 00cfc028 6b11edce     3fd2ac18 3fd2ad88 3fd2ad48 CoolType!CTCleanup+0x49793
05 00cfc084 6b117238     3fd2ac18 3fd2ad88 3fd2ad48 CoolType!CTCleanup+0x495be
06 00cfc0f8 6b117077     00cfc248 00cfc178 00000001 CoolType!CTCleanup+0x41a28
07 00cfc114 6b113097     00cfc248 00cfc178 eb614ed0 CoolType!CTCleanup+0x41867
08 00cfc29c 6b112922     eb614ed0 6b3f4a18 00cfc488 CoolType!CTCleanup+0x3d887
09 00cfc4c8 6b10b49b     00cfcf88 00cfc554 00000000 CoolType!CTCleanup+0x3d112
0a 00cfcfd4 6b10928a     00000002 00000000 00000000 CoolType!CTCleanup+0x35c8b
0b 00cfd0a8 6b107d7d     88bf8da8 00000032 00cfd17c CoolType!CTCleanup+0x33a7a
0c 00cfda08 6b107418     eaa8e8fc 00cfda3c 7ed3db91 CoolType!CTCleanup+0x3256d
0d 00cfdd64 6b10733c     eaa8e8fc eaa8e8e4 7ed3db55 CoolType!CTCleanup+0x31c08
0e 00cfdda0 6b4803d1     57509d5c eaa8e8fc eaa8e8e4 CoolType!CTCleanup+0x31b2c
0f 00cfddb4 6b475b3e     eaa8e8e4 6b475aa0 1fdd2c10 AGM!AGMTerminate+0xa2f1
10 00cfddc8 6b470087     1fdd2c1c 6b8f0a50 00000001 AGM!AGMInitialize+0x1c37e
11 00cfddec 6b47f1c8     00cfde18 00cfde34 00cfde54 AGM!AGMInitialize+0x168c7
12 00cfde00 6b47f1f4     00000001 ba03296a 00000000 AGM!AGMTerminate+0x90e8
13 00cfdebc 6eacab2f     09b01000 3f800000 00000000 AGM!AGMTerminate+0x9114
14 00cfded4 00000000     00000000 00000000 eaa80ff0 verifier!AVrfDebugPageHeapFree+0xef

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.

TIMELINE

2024-09-10 - Vendor Disclosure
2024-12-10 - Vendor Patch Release
2024-12-11 - Public Release

Credit

Discovered by KPC of Cisco Talos.