Bug 2820 - There is a Segmentation fault at tif_dirwrite.c:1896 in tiffset (CVE-2018-19210)
: There is a Segmentation fault at tif_dirwrite.c:1896 in tiffset (CVE-2018-19210)
Status: RESOLVED FIXED
: libtiff
default
: unspecified
: PC All
: P2 critical
: ---
Assigned To:
:
:
:
:
:
  Show dependency treegraph
 
Reported: 2018-10-28 07:11 by
Modified: 2019-02-02 09:49 (History)


Attachments
Trigger by "tiffset poc0" (880 bytes, application/octet-stream)
2018-10-28 07:11, ganshuitao
Details


Note

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


Description From 2018-10-28 07:11:07
Created an attachment (id=873) [details]
Trigger by "tiffset poc0"

version: libtiff 4.0.9
Summary: 

There is a Segmentation fault at tif_dirwrite.c:1896 in tiffset. 

Description:

The asan debug is as follows:

$./tiffset POC0

=================================================================
==62110==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc
0x7fd46e2c3233 sp 0x7fff581e7218 bp 0x7fff581e7270 T0)
==62110==WARNING: Trying to symbolize code, but external symbolizer is not
initialized!
    #0 0x7fd46e2c3232 (/lib/x86_64-linux-gnu/libc.so.6+0x16f232)
    #1 0x4581b0
(/home/company/real_sanitize/poc_check/tiffset/tiffset_addr+0x4581b0)
    #2 0x4fce5b
(/home/company/real_sanitize/poc_check/tiffset/tiffset_addr+0x4fce5b)
    #3 0x4f2761
(/home/company/real_sanitize/poc_check/tiffset/tiffset_addr+0x4f2761)
    #4 0x5eb0d1
(/home/company/real_sanitize/poc_check/tiffset/tiffset_addr+0x5eb0d1)
    #5 0x7fd46e174a3f (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
    #6 0x47e738
(/home/company/real_sanitize/poc_check/tiffset/tiffset_addr+0x47e738)


$./tiffset POC0
Segmentation fault

The GDB debugging information is as follow


(gdb) set args POC0
(gdb) r

Program received signal SIGSEGV, Segmentation fault.
__memcmp_avx2_movbe () at ../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:67
67    ../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S: No such file or
directory.
(gdb) bt
#0  __memcmp_avx2_movbe () at
../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:67
#1  0x000000000046f7ee in TIFFWriteDirectorySec (tif=0x746260, isimage=1,
imagedone=1, 
    pdiroff=0x0) at tif_dirwrite.c:1896
#2  0x0000000000469cec in TIFFWriteDirectory (tif=0x746260) at
tif_dirwrite.c:182
#3  TIFFRewriteDirectory (tif=0x746260) at tif_dirwrite.c:358
#4  0x000000000050a557 in main (argc=<optimized out>, argv=<optimized out>)
    at tiffset.c:361
------- Comment #1 From 2018-11-13 17:15:44 -------
The issue seems still to be present in v4.0.10 and in current HEAD
(2f79874c30f2d0f3a140a8b041c1c75fb359e6a9).
------- Comment #2 From 2018-11-19 06:53:45 -------
In _TIFFVSetField, there is:

        case TIFFTAG_TRANSFERFUNCTION:
                v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
                for (i = 0; i < v; i++)
                        _TIFFsetShortArray(&td->td_transferfunction[i],
                            va_arg(ap, uint16*), 1U<<td->td_bitspersample);
                break;

Therefore, in some cases td->td_transferfunction[1] and
td->td_transferfunction[2] can remain NULL (it is initialized in
TIFFDefaultDirectory() by memset on td, but perhaps _TIFFVSetField could set it
explicitely to NULL). Program control for given test case then gives:
(gdb) l
449            td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
450            td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
451            break;
452        case TIFFTAG_TRANSFERFUNCTION:
453            v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
454            for (i = 0; i < v; i++)
455                _TIFFsetShortArray(&td->td_transferfunction[i],
456                    va_arg(ap, uint16*), 1U<<td->td_bitspersample);
457            break;
458        case TIFFTAG_REFERENCEBLACKWHITE:
(gdb) p td->td_samplesperpixel
$8 = 1
(gdb) p td->td_extrasamples
$9 = 0

Only td->td_transferfunction[0] is initialized.

When I continue, libtiff throws following warning:

TIFFReadDirectory: Warning, SamplesPerPixel tag is missing, applying correct
SamplesPerPixel value of 3.

So now in the TIFFWriteDirectoryTagTransferfunction()

Breakpoint 3, TIFFWriteDirectoryTagTransferfunction (tif=0x55555555a010,
ndir=0x7fffffffe5d0, dir=0x55555555aa30) at tif_dirwrite.c:1885
1885        n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
(gdb) p tif->tif_dir.td_samplesperpixel
$10 = 3
(gdb) p tif->tif_dir.td_extrasamples
$11 = 0
(gdb)

hence the invalid access.
------- Comment #3 From 2018-11-21 11:21:31 -------
Looks like http://bugzilla.maptools.org/show_bug.cgi?id=2500. Patch should be
similar. I'll MR once ready.
------- Comment #4 From 2018-11-21 16:40:52 -------
see https://gitlab.com/libtiff/libtiff/merge_requests/47