Bug 2715 - tiff2pdf: heap based buffer write overflow
: tiff2pdf: heap based buffer write overflow
Status: RESOLVED FIXED
: libtiff
default
: unspecified
: PC All
: P2 blocker
: ---
Assigned To:
:
:
:
:
:
  Show dependency treegraph
 
Reported: 2017-07-14 02:52 by
Modified: 2017-07-15 21:07 (History)


Attachments
Triggered by "./tiff2pdf $POC" (318 bytes, application/octet-stream)
2017-07-14 02:52, owl337
Details


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2017-07-14 02:52:27
Created an attachment (id=797) [details]
Triggered by  "./tiff2pdf $POC"

The debugging information is as follows:

$ ./tiff2pdf POC1
=================================================================
==13268==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x60d00000c8a4 at pc 0x7f247a6c0d64 bp 0x7ffdf0bd4650 sp 0x7ffdf0bd3df8
WRITE of size 132 at 0x60d00000c8a4 thread T0
    #0 0x7f247a6c0d63 in __asan_memcpy
(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x8cd63)
    #1 0x7f24794195ca in inflate (/lib/x86_64-linux-gnu/libz.so.1+0xa5ca)
    #2 0x7f247a3e3205 in ZIPDecode
/home/company/real/libtiff-cvs/libtiff/libtiff/tif_zip.c:177
    #3 0x7f247a3dacdd in TIFFReadEncodedTile
/home/company/real/libtiff-cvs/libtiff/libtiff/tif_read.c:1009
    #4 0x4097d0 in t2p_readwrite_pdf_image_tile
/home/company/real/libtiff-cvs/libtiff/tools/tiff2pdf.c:2990
    #5 0x416988 in t2p_readwrite_pdf_image_tile
/home/company/real/libtiff-cvs/libtiff/tools/tiff2pdf.c:2782
    #6 0x416988 in t2p_write_pdf
/home/company/real/libtiff-cvs/libtiff/tools/tiff2pdf.c:5535
    #7 0x402151 in main
/home/company/real/libtiff-cvs/libtiff/tools/tiff2pdf.c:808
    #8 0x7f2479f8aa3f in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
    #9 0x402e08 in _start
(/home/company/real/libtiff-cvs/libtiff/install_asan/bin/tiff2pdf+0x402e08)

0x60d00000c8a4 is located 0 bytes to the right of 132-byte region
[0x60d00000c820,0x60d00000c8a4)
allocated by thread T0 here:
    #0 0x7f247a6cc9aa in malloc
(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x989aa)
    #1 0x4096e6 in t2p_readwrite_pdf_image_tile
/home/company/real/libtiff-cvs/libtiff/tools/tiff2pdf.c:2978

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 __asan_memcpy
Shadow bytes around the buggy address:
  0x0c1a7fff98c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1a7fff98d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1a7fff98e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1a7fff98f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1a7fff9900: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c1a7fff9910: 00 00 00 00[04]fa fa fa fa fa fa fa fa fa 00 00
  0x0c1a7fff9920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 fa
  0x0c1a7fff9930: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c1a7fff9940: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa
  0x0c1a7fff9950: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1a7fff9960: 00 00 00 00 fa fa fa fa fa fa fa fa fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==13268==ABORTING
The out of write point is marked by "//" as follows:
...
152 static int
153 ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
154 {
155         static const char module[] = "ZIPDecode";
156         ZIPState* sp = DecoderState(tif);
157 
158         (void) s;
159         assert(sp != NULL);
160         assert(sp->state == ZSTATE_INIT_DECODE);
161 
162         sp->stream.next_in = tif->tif_rawcp;
163         sp->stream.avail_in = (uInt) tif->tif_rawcc;
164 
165         sp->stream.next_out = op;
166         assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets
raised,
167             we need to simplify this code to reflect a ZLib that is likely
updated
168             to deal with 8byte memory sizes, though this code will respond
169             appropriately even before we simplify it */
170         sp->stream.avail_out = (uInt) occ;
171         if ((tmsize_t)sp->stream.avail_out != occ)
172         {
173                 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal
with buffers this size");
174                 return (0);
175         }
176         do {
177                 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);//out of 
                    bound write
178                 if (state == Z_STREAM_END)
179                         break;
180                 if (state == Z_DATA_ERROR) {
181                         TIFFErrorExt(tif->tif_clientdata, module,
182                             "Decoding error at scanline %lu, %s",
183                              (unsigned long) tif->tif_row, SAFE_MSG(sp));
184                         if (inflateSync(&sp->stream) != Z_OK)
185                                 return (0);
186                         continue;
187                 }
188                 if (state != Z_OK) {
189                         TIFFErrorExt(tif->tif_clientdata, module,
190                                      "ZLib error: %s", SAFE_MSG(sp));
...

The gdb debug info is as follows:


Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7828892 in __GI___libc_free (mem=0x610dc0) at malloc.c:2949
2949    malloc.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7828892 in __GI___libc_free (mem=0x610dc0) at malloc.c:2949
#1  0x0000000000404965 in t2p_readwrite_pdf_image_tile (t2p=t2p@entry=0x60f010,
input=input@entry=0x60fc10, output=output@entry=0x610e50, tile=tile@entry=0) at
tiff2pdf.c:3013
#2  0x0000000000409f31 in t2p_readwrite_pdf_image_tile (tile=0,
output=0x610e50, input=0x60fc10, t2p=0x60f010) at tiff2pdf.c:2782
#3  t2p_write_pdf (t2p=0x60f010, input=0x60fc10, output=0x610e50) at
tiff2pdf.c:5535
#4  0x00000000004019e8 in main (argc=<optimized out>, argv=<optimized out>) at
tiff2pdf.c:808


Credits:

This vulnerability is detected by team OWL337, with our custom fuzzer collAFL.
Please contact ganshuitao@gmail.com   and chaoz@tsinghua.edu.cn if you need
more info about the team, the tool or the vulnerability.
------- Comment #1 From 2017-07-14 02:57:22 -------
I have reproduced this vulnerability successfully in verison 4.0.7, 4.0.8 and
CVS. It's a very serious vulnerability, please fix it as soon as possible.
------- Comment #2 From 2017-07-15 06:15:11 -------
The flow was in tiff2pdf, not in libtiff

Fixed per

2017-07-15  Even Rouault <even.rouault at spatialys.com>

        * tools/tiff2pdf.c: prevent heap buffer overflow write in "Raw"
        mode on PlanarConfig=Contig input images.
        Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2715
        Reported by team OWL337

/cvs/maptools/cvsroot/libtiff/ChangeLog,v  <--  ChangeLog
new revision: 1.1270; previous revision: 1.1269
/cvs/maptools/cvsroot/libtiff/tools/tiff2pdf.c,v  <--  tools/tiff2pdf.c
new revision: 1.102; previous revision: 1.101
------- Comment #3 From 2017-07-15 21:07:39 -------
(In reply to comment #2)
> The flow was in tiff2pdf, not in libtiff
> 
> Fixed per
> 
> 2017-07-15  Even Rouault <even.rouault at spatialys.com>
> 
>         * tools/tiff2pdf.c: prevent heap buffer overflow write in "Raw"
>         mode on PlanarConfig=Contig input images.
>         Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2715
>         Reported by team OWL337
> 
> /cvs/maptools/cvsroot/libtiff/ChangeLog,v  <--  ChangeLog
> new revision: 1.1270; previous revision: 1.1269
> /cvs/maptools/cvsroot/libtiff/tools/tiff2pdf.c,v  <--  tools/tiff2pdf.c
> new revision: 1.102; previous revision: 1.101

Ok, the overflowed heap was in the tiff2pdf, but the overflow operator was in
libtiff, wasn't it?