Bug 2811 - A null pointer deference in function _TIFFmemcmp at tif_unix.c:352 in libtiff4.0.9 (CVE-2018-17000)
: A null pointer deference in function _TIFFmemcmp at tif_unix.c:352 in libtiff...
Status: RESOLVED LATER
: libtiff
default
: unspecified
: PC Linux
: P2 enhancement
: ---
Assigned To:
:
:
: migrated_to_gitlab
:
:
  Show dependency treegraph
 
Reported: 2018-09-07 08:47 by
Modified: 2019-10-01 14:21 (History)


Attachments
poc to reproduce the crash (430 bytes, application/octet-stream)
2018-09-07 08:47, rookie
Details


Note

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


Description From 2018-09-07 08:47:27
Created an attachment (id=869) [details]
poc to reproduce the crash

A null pointer deference in function _TIFFmemcmp at tif_unix.c:352 when
using tiffcp tool in the latest libtiff4.0.9 by a created tiff file.

the master branch(981e43ec) of source code in
https://gitlab.com/libtiff/libtiff

tiffcp -i $FILE /tmp/foo

gdb debug output:

EAX: 0x8054300 --> 0x0 
EBX: 0xb7ed8bfc (mov    ecx,DWORD PTR [eax-0x8])
ECX: 0xffff0000 
EDX: 0x8 
ESI: 0x8 
EDI: 0x4 
EBP: 0x8053178 --> 0x8053428 ("/tmp/foo")
ESP: 0xbfffeec8 --> 0xb7fd9ff4 --> 0x76e84 
EIP: 0xb7ed8bff (mov    ebx,DWORD PTR [edx-0x8])
EFLAGS: 0x210287 (CARRY PARITY adjust zero SIGN trap INTERRUPT direction
overflow)
[-------------------------------------code-------------------------------------]
   0xb7ed8bf4:    cmp    ecx,ebx
   0xb7ed8bf6:    jne    0xb7ed95e0
   0xb7ed8bfc:    mov    ecx,DWORD PTR [eax-0x8]
=> 0xb7ed8bff:    mov    ebx,DWORD PTR [edx-0x8]
   0xb7ed8c02:    cmp    ecx,ebx
   0xb7ed8c04:    jne    0xb7ed95e0
   0xb7ed8c0a:    mov    ecx,DWORD PTR [eax-0x4]
   0xb7ed8c0d:    mov    ebx,DWORD PTR [edx-0x4]
[------------------------------------stack-------------------------------------]
0000| 0xbfffeec8 --> 0xb7fd9ff4 --> 0x76e84 
0004| 0xbfffeecc --> 0xb7fab80b (<_TIFFmemcmp+43>:    add    esp,0x18)
0008| 0xbfffeed0 --> 0x80542f8 --> 0xffff0000 
0012| 0xbfffeed4 --> 0x0 
0016| 0xbfffeed8 --> 0x8 
0020| 0xbfffeedc --> 0xb7fab7e0 (<_TIFFmemcmp>:    push   ebx)
0024| 0xbfffeee0 --> 0x80542f8 --> 0xffff0000 
0028| 0xbfffeee4 --> 0xb7fdc920 --> 0xb7f63000 --> 0x464c457f 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0xb7ed8bff in ?? () from /lib/i386-linux-gnu/libc.so.6
gdb-peda$ bt
#0  0xb7ed8bff in ?? () from /lib/i386-linux-gnu/libc.so.6
#1  0xb7fab80b in _TIFFmemcmp (p1=0x80542f8, p2=0x0, c=0x8) at tif_unix.c:352
#2  0xb7f7a407 in TIFFWriteDirectoryTagTransferfunction (dir=0x8053c10,
ndir=0xbfffef7c, tif=0x8053178) at tif_dirwrite.c:1901
#3  TIFFWriteDirectorySec (tif=0x8053178, isimage=0x1, imagedone=0x1,
pdiroff=0x0) at tif_dirwrite.c:628
#4  0xb7f7b61e in TIFFWriteDirectorySec (pdiroff=0x0, imagedone=0x1,
isimage=0x1, tif=0x8053178) at tif_dirwrite.c:370
#5  TIFFWriteDirectory (tif=0x8053178) at tif_dirwrite.c:182
#6  0xb7f7ba1f in TIFFRewriteDirectory (tif=0x8053178) at tif_dirwrite.c:358
#7  0xb7f82f2d in TIFFFlush (tif=0x8053178) at tif_flush.c:81
#8  0xb7f695d0 in TIFFCleanup (tif=0x8053178) at tif_close.c:51
#9  0xb7f69622 in TIFFClose (tif=0x8053178) at tif_close.c:126
#10 0x08049d9d in main (argc=0x4, argv=0xbffff264) at tiffcp.c:303
#11 0xb7dc04d3 in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
#12 0x0804a9d1 in _start ()
------- Comment #1 From 2018-09-13 15:20:59 -------
This issue was assigned CVE-2018-17000.
------- Comment #2 From 2018-10-17 03:25:30 -------
Hi,

with 183102bc I get:

$ tiffcp poc  out
TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not
sorted in ascending order.
TIFFReadDirectory: Warning, Unknown field with tag 466 (0x1d2) encountered.
poc: Warning, Nonstandard tile width 1, convert file.
TIFFFetchStripThing: Warning, Incorrect count for "StripOffsets"; tag ignored.
TIFFFetchStripThing: Warning, Incorrect count for "StripByteCounts"; tag
ignored.
TIFFReadDirectory: Warning, Sum of Photometric type-related color channels and
ExtraSamples doesn't match SamplesPerPixel. Defining non-color channels as
ExtraSamples..
poc: Error, cannot handle BitsPerSample that is not a multiple of 8.
Segmentation fault (core dumped)
$

GDB backtrace

#0  _TIFFVGetField (tif=0x55555555f940, tag=301, ap=0x7fffffffe550) at
tif_dir.c:1071
#1  0x00007ffff7fb38c2 in PredictorVGetField (tif=0x55555555f940, tag=301,
ap=0x7fffffffe550) at tif_predict.c:793
#2  0x00007ffff7f6be52 in TIFFVGetField (tif=0x55555555f940, tag=301,
ap=0x7fffffffe550) at tif_dir.c:1239
#3  0x00007ffff7f6bd98 in TIFFGetField (tif=0x55555555f940, tag=301) at
tif_dir.c:1223
#4  0x0000555555557322 in cpTag (in=0x55555555f940, out=0x55555555f010,
tag=301, count=4, type=TIFF_SHORT) at tiffcp.c:500
#5  0x0000555555557c14 in tiffcp (in=0x55555555f940, out=0x55555555f010) at
tiffcp.c:718
#6  0x0000555555556c02 in main (argc=3, argv=0x7fffffffe858) at tiffcp.c:303


It think this relates to fix for CVE-2017-9935

https://gitlab.com/libtiff/libtiff/commit/3dd8f6a357981a4090f126ab9025056c938b6940

From what I can tell, 4.0.9 without this fix does not segfault, with this fix
does.

Guesses follows. There seem to be discrepancy in td->td_extrasamples in
GetField and SetField:

Breakpoint 1, _TIFFVGetField (tif=0x55555555f940, tag=301, ap=0x7fffffffe550)
at tif_dir.c:1066
1066                *va_arg(ap, uint16**) = td->td_transferfunction[0];
(gdb) l
1061            case TIFFTAG_YCBCRSUBSAMPLING:
1062                *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
1063                *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
1064                break;
1065            case TIFFTAG_TRANSFERFUNCTION:
1066                *va_arg(ap, uint16**) = td->td_transferfunction[0];
1067                if (td->td_samplesperpixel - td->td_extrasamples > 1) {
1068                    *va_arg(ap, uint16**) = td->td_transferfunction[1];
1069                    *va_arg(ap, uint16**) = td->td_transferfunction[2];
1070                } else {
(gdb) p td->td_samplesperpixel
$15 = 2
(gdb) p td->td_extrasamples
$16 = 1
(gdb)

Here td->td_samplesperpixel - td->td_extrasamples > 1 is not true and thus 
NULL is returned as second and third transferfunction field. However, later in
TIFFWriteDirectoryTagTransferfunction()

Breakpoint 7, TIFFWriteDirectoryTagTransferfunction (tif=0x55555555f010,
ndir=0x7fffffffe550, dir=0x555555560690) at tif_dirwrite.c:1894
1894        if (n>3)
(gdb) p tif_dir.td_samplesperpixel
No symbol "tif_dir" in current context.
(gdb) p tif->tif_dir.td_samplesperpixel
$17 = 2
(gdb) p tif->tif_dir.td_extrasamples
$18 = 0
(gdb) n
1896        if (n==3)
(gdb) 
1901        if (n==2)
(gdb) 
1903            if
(!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
(gdb) p tif->tif_dir.td_transferfunction[1]
$19 = (uint16 *) 0x0
(gdb)
------- Comment #3 From 2018-10-17 03:27:43 -------
(The gdb output is over 4.0.9 plus certain CVE patches, so line numbers will
not exactly match 183102bc.)
------- Comment #4 From 2018-10-17 04:34:03 -------
(In reply to comment #2)
> Guesses follows. There seem to be discrepancy in td->td_extrasamples in
> GetField and SetField:

This should have been: discrepancy in td->td_extrasamples between
TIFFGetField and TIFFWriteDirectoryTagTransferfunction:
------- Comment #5 From 2019-01-29 05:53:38 -------
According to my tests, the following patch fixes the bug :
https://gitlab.com/libtiff/libtiff/merge_requests/54
------- Comment #6 From 2019-02-13 05:37:03 -------
can you confirm the bug is fixed in master ? commit
ae0bed1fe530a82faf2e9ea1775109dbf301a971

this commit fixed the bug :
https://gitlab.com/libtiff/libtiff/commit/802d3cbf3043be5dce5317e140ccb1c17a6a2d39
------- Comment #7 From 2019-02-13 06:26:29 -------
I have tested 4.0.10 plus your change and that worked.
------- Comment #8 From 2019-10-01 14:21:23 -------
Bugzilla is no longer used for tracking libtiff issues. Remaining open tickets,
such as this one, have been migrated to the libtiff GitLab instance at
https://gitlab.com/libtiff/libtiff/issues .

The migrated tickets have their summary prefixed with [BZ#XXXX] where XXXX is
the initial Bugzilla issue number.