Bug 2728 - There is a reachable assertion abort in function TIFFWriteDirectoryTagSubifd() of libtiff. A crafted input will lead to remote denial of attack.
: There is a reachable assertion abort in function TIFFWriteDirectoryTagSubifd(...
Status: RESOLVED FIXED
: libtiff
default
: unspecified
: PC Windows NT
: P2 enhancement
: ---
Assigned To:
:
:
:
:
:
  Show dependency treegraph
 
Reported: 2017-08-21 06:23 by
Modified: 2017-08-23 08:34 (History)


Attachments
Triggered by "./tiffset POC8" (345 bytes, application/octet-stream)
2017-08-21 06:23, owl337
Details


Note

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


Description From 2017-08-21 06:23:36
Created an attachment (id=808) [details]
Triggered by "./tiffset POC8"

The output information is as follows:

$ ./tiffset POC8
TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not
sorted in ascending order.
TIFFReadDirectory: Warning, Unknown field with tag 27 (0x1b) encountered.
TIFFReadDirectory: Warning, Unknown field with tag 12316 (0x301c) encountered.
TIFFReadDirectory: Warning, Unknown field with tag 8192 (0x2000) encountered.
TIFFFetchNormalTag: Warning, Incompatible type for "FillOrder"; tag ignored.
TIFFFetchNormalTag: Warning, ASCII value for tag "DocumentName" contains null
byte in value; value incorrectly truncated during reading due to implementation
limitations.
TIFFFetchStripThing: Warning, Incorrect count for "StripOffsets"; tag ignored.
TIFFFetchStripThing: Warning, Incorrect count for "StripByteCounts"; tag
ignored.
tiffset: tif_dirwrite.c:1947: TIFFWriteDirectoryTagSubifd: Assertion `*pa <=
0xFFFFFFFFUL' failed.
Aborted

The gdb debugging information is listed below:
(gdb) set args POC8
(gdb) r
...
TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not
sorted in ascending order.
TIFFReadDirectory: Warning, Unknown field with tag 27 (0x1b) encountered.
TIFFReadDirectory: Warning, Unknown field with tag 12316 (0x301c) encountered.
TIFFReadDirectory: Warning, Unknown field with tag 8192 (0x2000) encountered.
TIFFFetchNormalTag: Warning, Incompatible type for "FillOrder"; tag ignored.
TIFFFetchNormalTag: Warning, ASCII value for tag "DocumentName" contains null
byte in value; value incorrectly truncated during reading due to implementation
limitations.
TIFFFetchStripThing: Warning, Incorrect count for "StripOffsets"; tag ignored.
TIFFFetchStripThing: Warning, Incorrect count for "StripByteCounts"; tag
ignored.

Breakpoint 1, TIFFWriteDirectoryTagSubifd (dir=0x61300000de80,
ndir=0x7fffffffe060, tif=0x61900000fa80) at tif_dirwrite.c:1947
1947                assert(*pa <= 0xFFFFFFFFUL);
(gdb) bt
#0  TIFFWriteDirectoryTagSubifd (dir=0x61300000de80, ndir=0x7fffffffe060,
tif=0x61900000fa80) at tif_dirwrite.c:1947
#1  TIFFWriteDirectorySec (tif=0x61900000fa80, isimage=<optimized out>,
imagedone=<optimized out>, pdiroff=<optimized out>)
    at tif_dirwrite.c:640
#2  0x00007ffff6bbbcb0 in TIFFRewriteDirectory (tif=tif@entry=0x61900000fa80)
at tif_dirwrite.c:360
#3  0x000000000040146a in main (argc=2, argv=0x7fffffffe588) at tiffset.c:344
(gdb) n
1948                *pb++=(uint32)(*pa++);
...
1946                            assert(pa != 0);
(gdb) 
1947                assert(*pa <= 0xFFFFFFFFUL);
(gdb) 
tiffset: tif_dirwrite.c:1947: TIFFWriteDirectoryTagSubifd: Assertion `*pa <=
0xFFFFFFFFUL' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff67d3267 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) 


Program terminated with signal SIGABRT, Aborted.
The program no longer exists.
Trigged in TIFFWriteDirectoryTagSubifd (dir=0x61300000de80,
ndir=0x7fffffffe060, tif=0x61900000fa80) at tif_dirwrite.c:1947
    at tif_dirwrite.c:824
(gdb) list 
1942            pa=tif->tif_dir.td_subifd;
1943            pb=o;
1944            for (p=0; p < tif->tif_dir.td_nsubifd; p++)
1945            {
1946                            assert(pa != 0);
1947                assert(*pa <= 0xFFFFFFFFUL);
1948                *pb++=(uint32)(*pa++);
1949            }
1950           
n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
1951            _TIFFfree(o);


[note]: Tiffset sets the value of a TIFF header to a specified value.It will
modify the raw POC file,so you'd better make a backup file every time you are
going to run.

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-08-23 08:34:00 -------
Fixed per

2017-08-23  Even Rouault <even.rouault at spatialys.com>

        * libtiff/tif_dirwrite.c: replace assertion to tag value not fitting
        on uint32 when selecting the value of SubIFD tag by runtime check
        (in TIFFWriteDirectoryTagSubifd()).
        Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2728
        Reported by team OWL337

/cvs/maptools/cvsroot/libtiff/ChangeLog,v  <--  ChangeLog
new revision: 1.1279; previous revision: 1.1278
/cvs/maptools/cvsroot/libtiff/libtiff/tif_dirwrite.c,v  <-- 
libtiff/tif_dirwrite.c
new revision: 1.89; previous revision: 1.88