You need to log in before you can comment on or make changes to this bug.
Created an attachment (id=788) [details] the vulnerability is triggered by ./tiff2pdf $FILE The asan debug information is below: ==125927==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b00000aff8 at pc 0x0000004174c4 bp 0x7ffcb6eb6160 sp 0x7ffcb6eb6150 WRITE of size 4 at 0x60b00000aff8 thread T0 Xshell #0 0x4174c3 in t2p_write_pdf /home/company/real/libtiff-master-latest/tools/tiff2pdf.c:5481 #1 0x402151 in main /home/company/real/libtiff-master-latest/tools/tiff2pdf.c:808 #2 0x7f30f0d5fa3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f) #3 0x402e08 in _start (/home/company/real/libtiff-master-latest/install_asan/bin/tiff2pdf+0x402e08) 0x60b00000aff8 is located 0 bytes to the right of 104-byte region [0x60b00000af90,0x60b00000aff8) allocated by thread T0 here: #0 0x7f30f149f9aa in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x989aa) #1 0x415f27 in t2p_write_pdf /home/company/real/libtiff-master-latest/tools/tiff2pdf.c:5424 SUMMARY: AddressSanitizer: heap-buffer-overflow /home/company/real/libtiff-master-latest/tools/tiff2pdf.c:5481 t2p_write_pdf Shadow bytes around the buggy address: 0x0c167fff95a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c167fff95f0: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00[fa] 0x0c167fff9600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9630: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9640: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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 ==125927==ABORTING The function t2p_write_pdf(tiff2pdf.c:5424) allocated buffer t2p->pdf_xrefoffsets of size t2p->pdf_xrefcount*sizeof(uint32). The value of t2p->pdf_xrefcount is parsed from t2p_read_tiff_init(tiff2pdf.c:5422)at first, and assigned to 0 in line 5433 . An illegal TIFF document could have a big t2p->tiff_transferfunctioncount(tiff2pdf.c:5480) that cause heap overflow with operation t2p->pdf_xrefcount++. This heap overflow could lead to different damages. For example, a crafted TIFF document can lead to out of bound read in TIFFCleanup (trigger by POC1 in the attachment) , invalid free in TIFFClose (trigger by POC2 in attachment) or t2p_free(trigger by POC3 in attachment) , memory corruption in t2p_readwrite_pdf_image(trigger by POC4 in attachment), double free in t2p_free(trigger by POC5 in attachment). Given these possibilities, it probably could cause arbitrary code execution, although a more detail analysis of this vulnerability is required. 5415 tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){ ... 5422 t2p_read_tiff_init(t2p, input); 5423 if(t2p->t2p_error!=T2P_ERR_OK){return(0);} 5424 t2p->pdf_xrefoffsets= (uint32*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,t2p->pdf_xrefcount,sizeof(uint32)) );//allocate ... 5432 } 5433 t2p->pdf_xrefcount=0; ... 5478 written += t2p_write_pdf_transfer(t2p, output); 5479 written += t2p_write_pdf_obj_end(output); 5480 for(i=0; i < t2p->tiff_transferfunctioncount; i++){ 5481 t2p->pdf_xrefoffsets[t2p->pdf_xrefcount++]=written;//heap overflow 5482 written += t2p_write_pdf_obj_start(t2p->pdf_xrefcount, output); ... The gdb debug information for these five POC samples are as followings.Each one has different effects to the program. $gdb ./tiff2pdf (gdb) set args POC1 (gdb) r ... XshellProgram received signal SIGSEGV, Segmentation fault. TIFFCleanup (tif=tif@entry=0x60fc10) at tif_close.c:85 85 if (fld->field_bit == FIELD_CUSTOM && (gdb) bt #0 TIFFCleanup (tif=tif@entry=0x60fc10) at tif_close.c:85 #1 0x00007ffff7b77ba9 in TIFFClose (tif=tif@entry=0x60fc10) at tif_close.c:128 #2 0x00000000004019fb in main (argc=<optimized out>, argv=<optimized out>) at tiff2pdf.c:820 (gdb) set args POC2 (gdb) r ... Program received signal SIGABRT, Aborted. 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 55 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 #1 0x00007ffff77dbeca in __GI_abort () at abort.c:89 #2 0x00007ffff781dc53 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff79361a8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007ffff78299f8 in malloc_printerr (ptr=<optimized out>, str=0x7ffff79361d0 "munmap_chunk(): invalid pointer", action=<optimized out>) at malloc.c:4965 #4 munmap_chunk (p=<optimized out>) at malloc.c:2820 #5 __GI___libc_free (mem=<optimized out>) at malloc.c:2945 #6 0x00007ffff7b77b0c in TIFFCleanup (tif=tif@entry=0x60fc10) at tif_close.c:87 #7 0x00007ffff7b77ba9 in TIFFClose (tif=tif@entry=0x60fc10) at tif_close.c:128 #8 0x00000000004019fb in main (argc=<optimized out>, argv=<optimized out>) at tiff2pdf.c:820 (gdb) set args POC3 (gdb) r ... Program received signal SIGABRT, Aborted. 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 55 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 #1 0x00007ffff77dbeca in __GI_abort () at abort.c:89 #2 0x00007ffff781dc53 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff79361a8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007ffff7825c69 in malloc_printerr (ptr=<optimized out>, str=0x7ffff7936220 "free(): invalid next size (fast)", action=1) at malloc.c:4965 #4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3834 #5 0x00007ffff782989c in __GI___libc_free (mem=<optimized out>) at malloc.c:2950 #6 0x0000000000402a91 in t2p_free (t2p=t2p@entry=0x60f010) at tiff2pdf.c:969 #7 0x0000000000401c69 in main (argc=<optimized out>, argv=<optimized out>) at tiff2pdf.c:824 (gdb) set args POC4 (gdb) r ... Program received signal SIGABRT, Aborted. 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 55 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 #1 0x00007ffff77dbeca in __GI_abort () at abort.c:89 #2 0x00007ffff781dc53 in __libc_message (do_abort=1, fmt=fmt@entry=0x7ffff79361a8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007ffff7826e5e in malloc_printerr (ptr=0x614bb0, str=0x7ffff793237b "malloc(): memory corruption", action=<optimized out>) at malloc.c:4965 #4 _int_malloc (av=av@entry=0x7ffff7b69c00 <main_arena>, bytes=bytes@entry=3342336) at malloc.c:3441 #5 0x00007ffff782950e in __GI___libc_malloc (bytes=3342336) at malloc.c:2895 #6 0x0000000000403be1 in t2p_readwrite_pdf_image (t2p=t2p@entry=0x60f010, input=input@entry=0x60fc10, output=output@entry=0x610e60) at tiff2pdf.c:2445 #7 0x000000000040a410 in t2p_readwrite_pdf_image (output=0x610e60, input=0x60fc10, t2p=0x60f010) at tiff2pdf.c:5480 #8 t2p_write_pdf (t2p=0x60f010, input=0x60fc10, output=0x610e60) at tiff2pdf.c:5558 #9 0x00000000004019e8 in main (argc=<optimized out>, argv=<optimized out>) at tiff2pdf.c:808 (gdb) set args POC5 (gdb) r *** Error in `/home/company/real/libtiff-master-latest/install/bin/tiff2pdf': double free or corruption (!prev): 0x0000000000613640 *** Xshell Program received signal SIGABRT, Aborted. 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 55 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007ffff77da267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55 #1 0x00007ffff77dbeca in __GI_abort () at abort.c:89 #2 0x00007ffff781dc53 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff79361a8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007ffff7825c69 in malloc_printerr (ptr=<optimized out>, str=0x7ffff79362d8 "double free or corruption (!prev)", action=1) at malloc.c:4965 #4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3834 #5 0x00007ffff782989c in __GI___libc_free (mem=<optimized out>) at malloc.c:2950 #6 0x0000000000402a91 in t2p_free (t2p=t2p@entry=0x60f010) at tiff2pdf.c:969 #7 0x0000000000401c69 in main (argc=<optimized out>, argv=<optimized out>) at tiff2pdf.c:824 Affected version: the Latest version (4.0.8) 4.0.7 … 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.
CVE-2017-9935 has been assigned for this.
I'm unable to reproduce this issue with latest CVS version. Not sure which commit fixed this issue, but I believe the CVE is now duplicate and should be rejected. Could you retest against latest CVS?
(In reply to comment #2) > I'm unable to reproduce this issue with latest CVS version. Not sure which > commit fixed this issue, but I believe the CVE is now duplicate and should be > rejected. Could you retest against latest CVS? Yes, I have checked the latest CVS, all bugs in this vulnerability are triggered as crash both of asan and non-asan mode. In addition, the heap overflow is precise in t2p_write_pdf funtion as follows: #0 0x7fd56dcbf9aa in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x989aa) #1 0x415f17 in t2p_write_pdf /home/company/real/libtiff/tools/tiff2pdf.c:5424 SUMMARY: AddressSanitizer: heap-buffer-overflow /home/company/real/libtiff/tools/tiff2pdf.c:5481 t2p_write_pdf Shadow bytes around the buggy address: 0x0c167fff95a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff95e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c167fff95f0: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00[fa] 0x0c167fff9600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9630: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c167fff9640: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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
As I described, it's sure a very serious unknown vulnerability and not easy to repair.
Okay. Maybe there is something wrong with my own setup then. Which command did you use to fetch the latest version? I also tried with unofficial https://github.com/vadz/libtiff and no luck.
(In reply to comment #5) > Okay. Maybe there is something wrong with my own setup then. Which command did > you use to fetch the latest version? I also tried with unofficial > https://github.com/vadz/libtiff and no luck. company@ubuntu:~/real/libtiff$ export CVSROOT=:pserver:cvsanon@cvs.maptools.org:/cvs/maptools/cvsroot company@ubuntu:~/real/libtiff$ cvs login (empty passwd) company@ubuntu:~/real/libtiff$ cvs checkout libtiff
(In reply to comment #5) > Okay. Maybe there is something wrong with my own setup then. Which command did > you use to fetch the latest version? I also tried with unofficial > https://github.com/vadz/libtiff and no luck. It's sure the latest, the start of changlog is as follows: 2017-06-26 Even Rouault <even.rouault at spatialys.com> * libtiff/tif_jbig.c: fix memory leak in error code path of JBIGDecode() Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2706 Reported by team OWL337 2017-06-24 Even Rouault <even.rouault at spatialys.com> * libtiff/tif_jpeg.c: error out at decoding time if anticipated libjpeg memory allocation is above 100 MB. libjpeg in case of multiple scans, which is allowed even in baseline JPEG, if components are spread over several scans and not interleavedin a single one, needs to allocate memory (or backing store) for the whole strip/tile. See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf This limitation may be overriden by setting the LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, or recompiling libtiff with a custom value of TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro. ...
There is something wrong with my setup. Please ignore my recent comments. This has been verified by Debian security team member. I'll investigate and get back to you. Sorry for the noise.
(In reply to comment #8) > There is something wrong with my setup. Please ignore my recent comments. This > has been verified by Debian security team member. I'll investigate and get back > to you. Sorry for the noise. It doesn't matter. Debug need to be patient.
Looks like it might be similar to http://bugzilla.maptools.org/show_bug.cgi?id=2663 which also involves TransferFunction
(In reply to comment #11) > Looks like it might be similar to > http://bugzilla.maptools.org/show_bug.cgi?id=2663 which also involves > TransferFunction Hello, I wanna know if your team fix this bug?
> Hello, I wanna know if your team fix this bug? Be aware that libtiff is free software maintained mostly by volunteers in their free time, and few of the current active maintainers have direct interest in the utilities, but are more focused on the library itself. So if you're in position to contribute a patch to fix the issue, please do so.
note the terminology: the tiff spec talks about a tiff file containing multiple images; the tiff2pdf talks about pages instead; Here I will use the "image" term to refer to multiple images in a single tiff file. After studying this problem for a while, it appears that tiff2pdf assumes that every image in a multiple image tiff file will use the same transfer function. I don't see anywhere in the tiff specs that say this assumption is valid. Every image is allowed to have a different transfer function. As in I don't think there is anything wrong with the POC1 image that causes problems. tiff2pdf allocates memory for xref for each image (page) based on the transfer function it reads for that image (either 2 entries or 4 entries), but it only keeps track of the last transfer function for the last image it read. For the first exploit this means it allocates 2 entries for the first image, 2 entries for the second, and 4 entries for the last image. As the transfer function for the entire file has now been set from the last image, it assumes 4 entries have been allocated for every page, which is not correct, and buffer overflow occurs. I think the correct and proper solution is that we need to keep track of a transfer function for each and every image in the file. Two possible solutions to this security issue in the meantime however: 1. We always allocate 4 entries for every image. Will solve the buffer overflow problem, however, may not always give good results as we ignore the transfer function from earlier images and always use the transfer function from the last image. 2. We check the transfer function provided by each image matches the previous images and generate an error if it doesn't. At least this way it is clear to the user why the operation is not working instead of silently doing the wrong thing. I also discussed this on the debian-lts mailing list. https://lists.debian.org/debian-lts/2017/11/msg00049.html (note: I have only investigated the POC1 exploit in detail, not the others; for now I assume they are variations of the same bug)
At the moment, the option 2 I listed is my preferred way to solve the security issue.
What is the preferred way of contributing patches to fix this? As attachments to this bug report?
Somewhat puzzled here. I believe a transfer function is a table of 16 bit integer values. But tiff2pdf.c has: float* tiff_transferfunction[3]; Did I miss some sort of conversion from uint16 to float?
Created an attachment (id=826) [details] Patch to fix CVE-2017-9935.
Created an attachment (id=827) [details] Patch to fix transfer table type error Note this depends on the CVE-2017-9935 patch.
I have attached patches that I propose to fix the problems I mentioned.
Could you open pull requests against https://gitlab.com/libtiff/libtiff with your patches
(In reply to comment #21) > Could you open pull requests against https://gitlab.com/libtiff/libtiff with > your patches Ok, I will have a look.
https://gitlab.com/libtiff/libtiff/merge_requests/7
(In reply to comment #23) > https://gitlab.com/libtiff/libtiff/merge_requests/7 My pull request has been merged. Hopefully that means this bug can be closed. If not, please say so.