Bugzilla – Bug 1092480
VUL-1: CVE-2018-10779: tiff: TIFFWriteScanline in tif_write.c has a heap-based buffer over-read
Last modified: 2018-10-29 23:45:56 UTC
CVE-2018-10779 TIFFWriteScanline in tif_write.c in LibTIFF 3.8.2 has a heap-based buffer over-read, as demonstrated by bmp2tiff. References: http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-10779 http://people.canonical.com/~ubuntu-security/cve/2018/CVE-2018-10779.html http://www.cvedetails.com/cve/CVE-2018-10779/ http://www.securityfocus.com/bid/104089 http://bugzilla.maptools.org/show_bug.cgi?id=2788
Could not reproduce (since no ASAN build): kbabioch@sle11sp4:~> bmp2tiff POC.bmp /dev/null /dev/null: Error writing data for field "BitsPerSample". But we have the same code as in the original report in place: if( td->td_stripbytecount[strip] > 0 ) { /* if we are writing over existing tiles, zero length */ td->td_stripbytecount[strip] = 0; /* this forces TIFFAppendToStrip() to do a seek */ tif->tif_curoff = 0; }
Affected codestreams (based on source): SUSE:SLE-10-SP3:Update SUSE:SLE-11:Update SUSE:SLE-12:Update
3.8.2/bmp2tiff (in contrast of 4.0.9/bmp2tiff we ship in sle12) does not check the read() of BMP header was successful (POC comes from bug 1092484): $ valgrind -q bmp2tiff POC out.tiff ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x401383: main (bmp2tiff.c:390) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x401460: main (bmp2tiff.c:410) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4014E3: main (bmp2tiff.c:419) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4E6FBE3: _TIFFmalloc (tif_unix.c:241) ==2094== by 0x40151B: main (bmp2tiff.c:426) ==2094== ==2094== Syscall param read(count) contains uninitialised byte(s) ==2094== at 0x57F0EB0: read (in /lib64/libc-2.9.so) ==2094== by 0x401571: main (bmp2tiff.c:435) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4016E7: main (bmp2tiff.c:462) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4E6DDB5: multiply (tif_strip.c:56) ==2094== by 0x4E6E515: TIFFScanlineSize (tif_strip.c:272) ==2094== by 0x4E6E2BE: _TIFFDefaultStripSize (tif_strip.c:219) ==2094== by 0x4E6E29D: TIFFDefaultStripSize (tif_strip.c:207) ==2094== by 0x4017E9: main (bmp2tiff.c:496) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4E6DDC7: multiply (tif_strip.c:56) ==2094== by 0x4E6E515: TIFFScanlineSize (tif_strip.c:272) ==2094== by 0x4E6E2BE: _TIFFDefaultStripSize (tif_strip.c:219) ==2094== by 0x4E6E29D: TIFFDefaultStripSize (tif_strip.c:207) ==2094== by 0x4017E9: main (bmp2tiff.c:496) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4E6DDB5: multiply (tif_strip.c:56) ==2094== by 0x4E6E53D: TIFFScanlineSize (tif_strip.c:272) ==2094== by 0x4E6E2BE: _TIFFDefaultStripSize (tif_strip.c:219) ==2094== by 0x4E6E29D: TIFFDefaultStripSize (tif_strip.c:207) ==2094== by 0x4017E9: main (bmp2tiff.c:496) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4E6DDC7: multiply (tif_strip.c:56) ==2094== by 0x4E6E53D: TIFFScanlineSize (tif_strip.c:272) ==2094== by 0x4E6E2BE: _TIFFDefaultStripSize (tif_strip.c:219) ==2094== by 0x4E6E29D: TIFFDefaultStripSize (tif_strip.c:207) ==2094== by 0x4017E9: main (bmp2tiff.c:496) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4E6E2C6: _TIFFDefaultStripSize (tif_strip.c:220) ==2094== by 0x4E6E29D: TIFFDefaultStripSize (tif_strip.c:207) ==2094== by 0x4017E9: main (bmp2tiff.c:496) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x4E6E2FC: _TIFFDefaultStripSize (tif_strip.c:221) ==2094== by 0x4E6E29D: TIFFDefaultStripSize (tif_strip.c:207) ==2094== by 0x4017E9: main (bmp2tiff.c:496) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x401922: main (bmp2tiff.c:526) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x401AFA: main (bmp2tiff.c:590) ==2094== ==2094== Conditional jump or move depends on uninitialised value(s) ==2094== at 0x401B05: main (bmp2tiff.c:590) ==2094== ==2094== Syscall param write(buf) points to uninitialised byte(s) ==2094== at 0x57F0F30: write (in /lib64/libc-2.9.so) ==2094== by 0x4E6F975: _tiffWriteProc (tif_unix.c:64) ==2094== by 0x4E439F5: TIFFWriteData (tif_dirwrite.c:1135) ==2094== by 0x4E42BF5: TIFFWriteShortTable (tif_dirwrite.c:777) ==2094== by 0x4E417B0: _TIFFWriteDirectory (tif_dirwrite.c:247) ==2094== by 0x4E41E77: TIFFWriteDirectory (tif_dirwrite.c:413) ==2094== by 0x402092: main (bmp2tiff.c:728) ==2094== Address 0x5a85148 is 0 bytes inside a block of size 4 alloc'd ==2094== at 0x4C256AE: malloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==2094== by 0x4E6FBF9: _TIFFmalloc (tif_unix.c:244) ==2094== by 0x4E35420: setByteArray (tif_dir.c:52) ==2094== by 0x4E354F8: _TIFFsetShortArray (tif_dir.c:64) ==2094== by 0x4E36AD4: _TIFFVSetField (tif_dir.c:285) ==2094== by 0x4E386B2: TIFFVSetField (tif_dir.c:672) ==2094== by 0x4E38669: TIFFSetField (tif_dir.c:658) ==2094== by 0x401841: main (bmp2tiff.c:500) ==2094== ==2094== Syscall param write(buf) points to uninitialised byte(s) ==2094== at 0x57F0F30: write (in /lib64/libc-2.9.so) ==2094== by 0x4E6F975: _tiffWriteProc (tif_unix.c:64) ==2094== by 0x4E41D4A: _TIFFWriteDirectory (tif_dirwrite.c:383) ==2094== by 0x4E41E77: TIFFWriteDirectory (tif_dirwrite.c:413) ==2094== by 0x402092: main (bmp2tiff.c:728) ==2094== Address 0x5a85211 is 33 bytes inside a block of size 120 alloc'd ==2094== at 0x4C256AE: malloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==2094== by 0x4E6FBF9: _TIFFmalloc (tif_unix.c:244) ==2094== by 0x4E413AD: _TIFFWriteDirectory (tif_dirwrite.c:143) ==2094== by 0x4E41E77: TIFFWriteDirectory (tif_dirwrite.c:413) ==2094== by 0x402092: main (bmp2tiff.c:728) $ $ valgrind -q bmp2tiff POC.bmp out.tiff ==2107== Conditional jump or move depends on uninitialised value(s) ==2107== at 0x401922: main (bmp2tiff.c:526) ==2107== ==2107== Conditional jump or move depends on uninitialised value(s) ==2107== at 0x401AFA: main (bmp2tiff.c:590) ==2107== ==2107== Conditional jump or move depends on uninitialised value(s) ==2107== at 0x401B05: main (bmp2tiff.c:590) $ The condition on line 526 also decides whether the reproduction of this bug will or will not happen. When I 526 if (info_hdr.iCompression == BMPC_RGB) { (gdb) set info_hdr.iCompression=BMPC_RGB later I get: Breakpoint 4, TIFFSetupStrips (tif=0x604010) at tif_write.c:464 464 td->td_stripbytecount = (uint32 *) (gdb) p td->td_nstrips $29 = 1073807351 (gdb) p td->td_nstrips * sizeof (uint32) $30 = 262108 My proposal is to start with the patch, that will ensure the BMP header was correctly read. That of course will invalidate the test case totally and I am not sure whether the int overflow can happen or not (also in 4.0.x potentially). I have asked tiff maintainer (Even) about his position.
------- Comment #4 From Even Rouault 2018-08-15 09:35:12 ------- Likely related fix https://gitlab.com/libtiff/libtiff/commit/981e43ecae83935625c86c9118c0778c942c7048
AFTER 3.8.2 and 4.0.9 $ valgrind -q bmp2tiff POC.bmp out.tif POC.bmp: Failed to read from file (Success). $ [but the code wich is changed by the fix is not reached]
Will submit for: TW,15,12,11,10sp3/tiff.
Packages submitted.
An update workflow for this issue was started. This issue was rated as low. Please submit fixed packages until 2018-09-24. When done, reassign the bug to security-team@suse.de. https://swamp.suse.de/webswamp/wf/64126
SUSE-SU-2018:2676-1: An update that fixes four vulnerabilities is now available. Category: security (moderate) Bug References: 1074186,1092480,960589,983440 CVE References: CVE-2015-8668,CVE-2016-5319,CVE-2017-17942,CVE-2018-10779 Sources used: SUSE Linux Enterprise Software Development Kit 11-SP4 (src): tiff-3.8.2-141.169.16.1 SUSE Linux Enterprise Server 11-SP4 (src): tiff-3.8.2-141.169.16.1 SUSE Linux Enterprise Debuginfo 11-SP4 (src): tiff-3.8.2-141.169.16.1
SUSE-SU-2018:2836-1: An update that fixes three vulnerabilities is now available. Category: security (moderate) Bug References: 1074186,1092480,983440 CVE References: CVE-2016-5319,CVE-2017-17942,CVE-2018-10779 Sources used: SUSE Linux Enterprise Software Development Kit 12-SP3 (src): tiff-4.0.9-44.21.1 SUSE Linux Enterprise Server 12-SP3 (src): tiff-4.0.9-44.21.1 SUSE Linux Enterprise Desktop 12-SP3 (src): tiff-4.0.9-44.21.1
openSUSE-SU-2018:2880-1: An update that fixes three vulnerabilities is now available. Category: security (moderate) Bug References: 1074186,1092480,983440 CVE References: CVE-2016-5319,CVE-2017-17942,CVE-2018-10779 Sources used: openSUSE Leap 42.3 (src): tiff-4.0.9-34.1
SUSE-SU-2018:3327-1: An update that fixes 5 vulnerabilities is now available. Category: security (moderate) Bug References: 1092480,1106853,1108627,1108637,1110358 CVE References: CVE-2018-10779,CVE-2018-16335,CVE-2018-17100,CVE-2018-17101,CVE-2018-17795 Sources used: SUSE Linux Enterprise Module for Desktop Applications 15 (src): tiff-4.0.9-5.14.1 SUSE Linux Enterprise Module for Basesystem 15 (src): tiff-4.0.9-5.14.1
openSUSE-SU-2018:3370-1: An update that fixes 5 vulnerabilities is now available. Category: security (moderate) Bug References: 1092480,1106853,1108627,1108637,1110358 CVE References: CVE-2018-10779,CVE-2018-16335,CVE-2018-17100,CVE-2018-17101,CVE-2018-17795 Sources used: openSUSE Leap 15.0 (src): tiff-4.0.9-lp150.4.6.1
released