Talos Vulnerability Report


LibTIFF TIFF2PDF TIFFTAG_JPEGTABLES Remote Code Execution Vulnerability

October 25, 2016

Report ID



An exploitable heap based buffer overflow exists in the handling of TIFF images in LibTIFF’s TIFF2PDF tool. A crafted TIFF document can lead to a heap based buffer overflow resulting in remote code execution. Vulnerability can be triggered via a saved TIFF file delivered by other means.

Tested Versions

LibTiff - 4.0.6

Product URLs


CVSSv3 Score

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


This vulnerability is present in the Tiff2PDF tool that is bundled with LibTIFF. this tool is installed by default in the standard build process.

There exists a vulnerability in the parsing and handling of TIFF images. A specially crafted TIFF image file can lead to an out of bounds write and ultimately to remote code execution.

Tiff offers support for multiple compression algorithms inside of the image itself. One such algorithm is the JPEG compression. Looking at an information dump of the attached trigger we can see this is the compression algorithm used.

TIFF Directory at offset 0x13a (314)
    Image Width: 32 Image Length: 16
    Tile Width: 32 Tile Length: 1 [0]
    Bits/Sample: 4
    Compression Scheme: JPEG
    Photometric Interpretation: min-is-black
    Rows/Strip: 1
    Planar Configuration: single image plane
    JPEG Tables: (114 bytes)

Note also this is a tiled tiff [0], and the crash that happens when running the trigger is shown below.

rax = 0x0000000100b07f90
rbx = 0x0000000100993b60
rcx = 0x0000000000000010
rdx = 0xffffffffffffffe2
rdi = 0x0000000100b07fa0
rsi = 0x0000000100a72fd0
rbp = 0x00007fff5fbff830
rsp = 0x00007fff5fbff830
r8 = 0x0000000000000040
r9 = 0x00007fff7ae01110  __sFX + 240
r10 = 0xffffffffffffffff
r11 = 0x0000000000095010
r12 = 0x0000000100b07f90
r13 = 0x0000000000000000

->  0x7fff939be09a <+378>: vmovups ymmword ptr [rdi + rdx + 0x60], ymm4
    0x7fff939be0a0 <+384>: pop    rbp
    0x7fff939be0a1 <+385>: vzeroupper
    0x7fff939be0a4 <+388>: ret
    0x7fff939be0a5 <+389>: nop    word ptr cs:[rax + rax]
    0x7fff939be0b0 <+400>: sub    rsi, 0x8
    0x7fff939be0b4 <+404>: mov    rcx, qword ptr [rsi]
    0x7fff939be0b7 <+407>: sub    rdi, 0x8

* thread #1: tid = 0x16c8c4, 0x00007fff939be09a libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 378, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x100b08000)
  * frame #0: 0x00007fff939be09a libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 378
    frame #1: 0x00000001001614f1 libtiff.5.dylib`_TIFFmemcpy(d=<unavailable>, s=<unavailable>, c=<unavailable>) + 65 at tif_unix.c:340
    frame #2: 0x000000010001b1f8 llop`t2p_readwrite_pdf_image_tile(t2p=<unavailable>, input=0x0000000100993b60, output=0x00000001009b5bc0, tile=1) + 4840 at tiff2pdf.c:2951
    frame #3: 0x000000010000681f llop`t2p_write_pdf(t2p=0x00000001009913f0, input=0x0000000100993b60, output=0x00000001009b5bc0) + 8143 at tiff2pdf.c:5553
    frame #4: 0x00000001000037f7 llop`main(argc=<unavailable>, argv=<unavailable>) + 8439 at tiff2pdf.c:808
    frame #5: 0x00007fff909705ad libdyld.dylib`start + 1

The vulnerability arises in the calculating of the images tile size. The code uses a separate size reading function called t2p_read_tiff_size_tile. The relevant code is shown below:

if(t2p->tiff_compression==COMPRESSION_JPEG) {
uint32 count = 0;
if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt)!=0){
  if(count > 4){
    k = checkAdd64(k, count, t2p);
    k -= 2; /* don't use EOI of header or SOI of tile */

Our files compression is indeed jpeg so this code block is hit. The vulnerability comes when the size variable, k, is decremented by 2. Above we see that the JPEG tables of our image are 114 bytes and by decrementing by 2 it is moving it to 112. Due to malloc rounding on OS X, 112 will not be rounded and a buffer of exact size is used. Relevant code to when the jpeg is read in is below.

buffer= (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); [0]
    "Can't allocate " TIFF_SIZE_FORMAT " bytes of memory "
                                  "for t2p_readwrite_pdf_image_tile, %s",
                                    (TIFF_SIZE_T) t2p->tiff_datasize,
  t2p->t2p_error = T2P_ERR_ERROR;
if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0)  {    [1]
  if (count > 0) {
    printf("COUNT:[%d]", count);
    _TIFFmemcpy(buffer, jpt, count);    [2]
    bufferoffset += count - 2;
    table_end[0] = buffer[bufferoffset-2];
    table_end[1] = buffer[bufferoffset-1];

The vulnerable buffer is allocated based on the data size in the structure which is 112 as shown above [1]. When the call to get field is made for jpeg tables [2], it will return 114 as previously noted thus resulting in a 2 byte buffer overflow. This overwrite happens to be adjacent to another freed object thus corrupting the chunk but could also be used to turn this into full remote code execution.

Crash Information

Crashed thread log =
: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib          0x00007fff8c9e8f06 __pthread_kill + 10
1   libsystem_pthread.dylib         0x00007fff9018b4ec pthread_kill + 90
2   libsystem_c.dylib               0x00007fff8f4cb6e7 abort + 129
3   libsystem_malloc.dylib          0x00007fff8a22b396 szone_error + 626
4   libsystem_malloc.dylib          0x00007fff8a2215f4 tiny_free_list_remove_ptr + 289
5   libsystem_malloc.dylib          0x00007fff8a21ff94 szone_free_definite_size + 3094
6   libtiff.5.dylib                 0x000000010e3c7120 TIFFWriteDirectorySec + 52432 (tif_dirwrite.c:896)
7   tiff2pdf                        0x000000010e33883c t2p_write_pdf + 8172 (tiff2pdf.c:3648)
8   tiff2pdf                        0x000000010e3357f7 main + 8439 (tiff2pdf.c:808)
9   libdyld.dylib                   0x00007fff909705ad start + 1

log name is: ./crashlogs/_Users_t_Desktop_tiled-tiff-afl_tiff2pdfcrash_id:000022,sig:06,src:000675,op:havoc,rep:4.crashlog.txt
exception=EXC_CRASH:signal=6:is_exploitable=yes:instruction_disassembly=jae CONSTANT:instruction_address=0x00007fff8c9e8f06:access_type=:access_address=0x0000000000000000:
The crash is suspected to be an exploitable issue due to the suspicious function in the stack trace of the crashing thread: ' szone_error '


Tyler Bohan


2016-06-15 - Vendor Disclosure
2016-10-25 - Public Release