Bugzilla – Bug 960341
VUL-0: CVE-2015-7554: tiff: libtiff: invalid write in tiffsplit / _TIFFVGetField
Last modified: 2018-05-29 11:34:47 UTC
CVE-2015-7554 `_TIFFVGetField()' in libtiff-4.0.6 may write field data for certain extension tags to invalid or possibly arbitrary memory. Each tag has a `field_passcount' variable in their TIFFField struct: tiff-4.0.6/libtiff/tif_dir.h #276..289: ,---- | struct _TIFFField { | uint32 field_tag; /* field's tag */ | short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ | short field_writecount; /* write count/TIFF_VARIABLE */ | TIFFDataType field_type; /* type of associated data */ | uint32 reserved; /* reserved for future extension */ | TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */ | TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */ | unsigned short field_bit; /* bit in fieldsset bit vector */ | unsigned char field_oktochange; /* if true, can change while writing */ | unsigned char field_passcount; /* if true, pass dir count on set */ | char* field_name; /* ASCII name */ | TIFFFieldArray* field_subfields; /* if field points to child ifds, child ifd field definition array */ | }; `---- For example: tiff-4.0.6/libtiff/tif_fax3.c #1139..1141: ,---- | static const TIFFField fax3Fields[] = { | { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL }, | }; `---- However, `field_passcount' is always assigned TRUE if the tag is processed by `_TIFFCreateAnonField()'. This happens on unsuccessful invocations of `TIFFReadDirectoryFindFieldInfo()': tiff-4.0.6/libtiff/tif_dirread.c #3396..4076: ,---- | int | TIFFReadDirectory(TIFF* tif) | { | [...] | TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); | if (fii == FAILED_FII) | { | TIFFWarningExt(tif->tif_clientdata, module, | "Unknown field with tag %d (0x%x) encountered", | dp->tdir_tag,dp->tdir_tag); | /* the following knowingly leaks the | anonymous field structure */ | if (!_TIFFMergeFields(tif, | _TIFFCreateAnonField(tif, | dp->tdir_tag, | (TIFFDataType) dp->tdir_type), | 1)) { | [...] | } `---- tiff-4.0.6/libtiff/tif_dirinfo.c #627..719: ,---- | TIFFField* | _TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type) | { | [...] | fld->field_bit = FIELD_CUSTOM; | [...] | fld->field_passcount = TRUE; | [...] | } `---- If the field for a 1-count extension tag whose `field_passcount' has been overridden is later read by `_TIFFVGetField()', this happens: tiff-4.0.6/libtiff/tif_dir.c #823..1145: ,---- | static int | _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) | { | [...] | uint32 standard_tag = tag; | [...] | if (fip->field_bit == FIELD_CUSTOM) { | standard_tag = 0; | } | | switch (standard_tag) { | [...] | default: | { | [...] | for (i = 0; i < td->td_customValueCount; i++) { | [...] | if (fip->field_passcount) { | if (fip->field_readcount == TIFF_VARIABLE2) | *va_arg(ap, uint32*) = (uint32)tv->count; | else /* Assume TIFF_VARIABLE */ | *va_arg(ap, uint16*) = (uint16)tv->count; | *va_arg(ap, void **) = tv->value; | ret_val = 1; | } | [...] | } | } | } | [...] | } `---- With an invocation of `TIFFGetField()' such as: ,---- | TIFFGetField(tif, TIFFTAG_GROUP3OPTIONS, &dst); `---- for a TIFFTAG_GROUP3OPTIONS specified as: ,---- | 0x24, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x41 | ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ | tag type count offset/value `---- the count is written to `dst', whereas 0x41414141 is written to invalid/arbitrary memory. Using the included tiffsplit utility as an example: tiff-4.0.6/tools/tiffsplit.c #157..228: ,---- | static int | tiffcp(TIFF* in, TIFF* out) | { | [...] | CopyField(TIFFTAG_YRESOLUTION, floatv); | CopyField(TIFFTAG_GROUP3OPTIONS, longv); | [...] | } `---- ,---- | $ gdb -q --args tiffsplit tag.tiff | Reading symbols from tiffsplit...done. | (gdb) r | TIFFReadDirectory: Warning, Unknown field with tag 292 (0x124) encountered. | | Program received signal SIGSEGV, Segmentation fault. | 0xb7f68155 in _TIFFVGetField (tif=0x804d008, tag=292, ap=0xbffff660 "\024\367\377\277\210\366\377\277\200\366\377\277\067\206\004\b0\371\377\267") at tif_dir.c:1056 | 1056 *va_arg(ap, void **) = tv->value; | (gdb) x/i $eip | => 0xb7f68155 <_TIFFVGetField+2229 at tif_dir.c:1056>: mov %edx,(%eax) | (gdb) x/x $edx | 0x804d670: 0x41414141 | (gdb) x/x $eax | 0x41410000: Cannot access memory at address 0x41410000 | (gdb) `---- tag.tiff: ,---- | unsigned char tiff[] = { | /* little-endian */ | 0x49, 0x49, | | /* version */ | 0x2a, 0x00, | | /* tif->tif_diroff */ | 0x09, 0x00, 0x00, 0x00, | 0x00, | | /* tag count */ | 0x07, 0x00, | | /* tag | type | count | offset/value */ | /* TIFFTAG_IMAGEWIDTH */ | 0x00, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | /* TIFFTAG_IMAGELENGTH */ | 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | /* TIFFTAG_BITSPERSAMPLE */ | 0x02, 0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, | /* TIFFTAG_STRIPOFFSETS */ | 0x11, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | /* TIFFTAG_STRIPBYTECOUNTS */ | 0x17, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | /* TIFFTAG_YRESOLUTION */ | 0x1b, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, | /* TIFFTAG_GROUP3OPTIONS */ | 0x24, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x41, | | /* tif->tif_nextdiroff */ | 0x00, 0x00, 0x00, 0x00, | | /* bits per sample */ | 0x08, 0x00, | 0x08, 0x00, | 0x08, 0x00, | }; `---- This issue has been assigned CVE-2015-7554 and it has yet to be fixed. References: http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-7554 http://seclists.org/oss-sec/2015/q4/590
Looks like SLE-12 isn't affected. Factory however it is.
bugbot adjusting priority
I contacted the maintainers of libtiff. They currently don't know how they will fix this. I will update the bug if I receive more information from them
This is an autogenerated message for OBS integration: This bug (960341) was mentioned in https://build.opensuse.org/request/show/353436 13.1 / tiff https://build.opensuse.org/request/show/353444 13.1 / tiff
This is an autogenerated message for OBS integration: This bug (960341) was mentioned in https://build.opensuse.org/request/show/353690 13.1 / tiff
This is an autogenerated message for OBS integration: This bug (960341) was mentioned in https://build.opensuse.org/request/show/353699 13.2 / tiff
SUSE-SU-2016:0160-1: An update that solves one vulnerability and has one errata is now available. Category: security (moderate) Bug References: 942690,960341 CVE References: CVE-2015-7554 Sources used: SUSE Linux Enterprise Software Development Kit 12-SP1 (src): tiff-4.0.6-19.1 SUSE Linux Enterprise Software Development Kit 12 (src): tiff-4.0.6-19.1 SUSE Linux Enterprise Server 12-SP1 (src): tiff-4.0.6-19.1 SUSE Linux Enterprise Server 12 (src): tiff-4.0.6-19.1 SUSE Linux Enterprise Desktop 12-SP1 (src): tiff-4.0.6-19.1 SUSE Linux Enterprise Desktop 12 (src): tiff-4.0.6-19.1
openSUSE-SU-2016:0212-1: An update that solves one vulnerability and has one errata is now available. Category: security (moderate) Bug References: 942690,960341 CVE References: CVE-2015-7554 Sources used: openSUSE 13.2 (src): tiff-4.0.6-10.17.1
openSUSE-SU-2016:0215-1: An update that solves one vulnerability and has one errata is now available. Category: security (moderate) Bug References: 942690,960341 CVE References: CVE-2015-7554 Sources used: openSUSE 13.1 (src): tiff-4.0.6-8.13.1
Release openSUSE Leap 42.1 update, all done
openSUSE-SU-2016:0252-1: An update that solves one vulnerability and has one errata is now available. Category: security (moderate) Bug References: 942690,960341 CVE References: CVE-2015-7554 Sources used: openSUSE Leap 42.1 (src): tiff-4.0.6-3.1
SUSE-SU-2016:0353-1: An update that fixes four vulnerabilities is now available. Category: security (moderate) Bug References: 960341,964225 CVE References: CVE-2015-7554,CVE-2015-8781,CVE-2015-8782,CVE-2015-8783 Sources used: SUSE Linux Enterprise Software Development Kit 11-SP4 (src): tiff-3.8.2-141.163.1 SUSE Linux Enterprise Server 11-SP4 (src): tiff-3.8.2-141.163.1 SUSE Linux Enterprise Desktop 11-SP4 (src): tiff-3.8.2-141.163.1 SUSE Linux Enterprise Debuginfo 11-SP4 (src): tiff-3.8.2-141.163.1
Created attachment 665388 [details] tiff-3.8.2-CVE-2015-7554.patch tiff-3.8.2-CVE-2015-7554.patch we used to fix this bug
Created attachment 665389 [details] tag.tiff tag.tiff generated from comment #c0
On SLE12 GA with this update: rpm -q tiff libtiff5 tiff-4.0.6-19.1.x86_64 libtiff5-4.0.6-19.1.x86_64 gdb tiffsplit (gdb) r xx.tiff Starting program: /usr/bin/tiffsplit xx.tiff [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". TIFFReadDirectory: Warning, Unknown field with tag 292 (0x124) encountered. Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7b7364f in ?? () from /usr/lib64/libtiff.so.5
I do not think the patch fixes this problem.
(In reply to Marcus Meissner from comment #27) adjusted tracking in SMASH so we request this with the next update
I have a customer who uses Sysscan to scan their servers for security vulnerabilities. It recently started reporting that SLES 12 SP2 server with the latest channel patches as of yesterday were vulnerable to this exploit. Is there a fix coming and if yes, when will it be in the public channels? Thanks, Sean
Fridrich, please submit for this issue so we can include it in the currently running update. Sean, we have a tiff update in the working in SUSE:Maintenance:5049, so once we have a submit that includes this issue it'll be fixed for your customer soon.
ping. we still waiting for this submission.
SUSE-SU-2018:0073-1: An update that fixes 5 vulnerabilities is now available. Category: security (important) Bug References: 1017690,1069213,960341,969783,983436 CVE References: CVE-2014-8128,CVE-2015-7554,CVE-2016-10095,CVE-2016-5318,CVE-2017-16232 Sources used: SUSE Linux Enterprise Software Development Kit 12-SP3 (src): tiff-4.0.9-44.7.1 SUSE Linux Enterprise Software Development Kit 12-SP2 (src): tiff-4.0.9-44.7.1 SUSE Linux Enterprise Server for Raspberry Pi 12-SP2 (src): tiff-4.0.9-44.7.1 SUSE Linux Enterprise Server 12-SP3 (src): tiff-4.0.9-44.7.1 SUSE Linux Enterprise Server 12-SP2 (src): tiff-4.0.9-44.7.1 SUSE Linux Enterprise Desktop 12-SP3 (src): tiff-4.0.9-44.7.1 SUSE Linux Enterprise Desktop 12-SP2 (src): tiff-4.0.9-44.7.1
openSUSE-SU-2018:0097-1: An update that fixes 5 vulnerabilities is now available. Category: security (important) Bug References: 1017690,1069213,960341,969783,983436 CVE References: CVE-2014-8128,CVE-2015-7554,CVE-2016-10095,CVE-2016-5318,CVE-2017-16232 Sources used: openSUSE Leap 42.3 (src): tiff-4.0.9-24.1 openSUSE Leap 42.2 (src): tiff-4.0.9-17.9.1
It was solved for SLE12 by bumping the version to 4.0.9. For the other codestreams this needs to be fixed/backported. Original upstream bug: http://bugzilla.maptools.org/show_bug.cgi?id=2561. It has been fixed upstream (along with several other CVEs) in the following upstream commit: https://gitlab.com/libtiff/libtiff/commit/6281927e03aed3fdaac4c25e1cd1a5ff7232bcd8 According to the commit message this fixes: - CVE-2016-10095 - CVE-2015-7554 - CVE-2016-5318 - CVE-2014-8128
Michael, feel free to look at sr#162930 and sr#162931.
I think adding functions should not break the abi, but of course _TIFFCheckFieldIsValidForCodec() can also be added as static into tif_dirread.c.
I see, there is a testcase. I will test tomorrow.
BEFORE 11/tiff $ valgrind -q tiffsplit xx.tiff TIFFReadDirectory: Warning, xx.tiff: wrong data type 4 for "YResolution"; tag ignored. TIFFReadDirectory: Warning, xx.tiff: unknown field with tag 292 (0x124) encountered. xx.tiff: Warning, incorrect count for field "BitsPerSample" (3, expecting 1); tag trimmed. ==16218== Invalid write of size 8 ==16218== at 0x4E3585A: _TIFFVGetField (tif_dir.c:868) ==16218== by 0x4E35C97: TIFFGetField (tif_dir.c:946) ==16218== by 0x4012E2: main (tiffsplit.c:176) ==16218== Address 0x3 is not stack'd, malloc'd or (recently) free'd ==16218== ==16218== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==16218== Access not within mapped region at address 0x3 ==16218== at 0x4E3585A: _TIFFVGetField (tif_dir.c:868) ==16218== by 0x4E35C97: TIFFGetField (tif_dir.c:946) ==16218== by 0x4012E2: main (tiffsplit.c:176) /root/bin/vgq: line 3: 16218 Segmentation fault (core dumped) valgrind -q $@ $ 12/tiff $ valgrind -q tiffsplit xx.tiff TIFFReadDirectory: Warning, Unknown field with tag 292 (0x124) encountered. $ PATCH see comment 35 12/ImageMagick: have the fix in 11,10sp3/ImageMagick: needs to be fixed AFTER 11/tiff $ valgrind -q tiffsplit xx.tiff TIFFReadDirectory: Warning, xx.tiff: wrong data type 4 for "YResolution"; tag ignored. TIFFReadDirectory: Warning, xx.tiff: unknown field with tag 292 (0x124) encountered. xx.tiff: Warning, incorrect count for field "BitsPerSample" (3, expecting 1); tag trimmed. $
Note that tiff-3.8.2-CVE-2015-7554.patch was amended to contain proper fix.
I will now go trough the rest of CVEs stated in comment 35 and see if they are fixed by the patch.
I do not see CVE-2014-8128[*] between opened bugs; I see it already fixed in change log but the fix was probably not complete. To verify: [*] bound to: http://bugzilla.maptools.org/show_bug.cgi?id=2499 BEFORE (I mean: tiff-3.8.2-CVE-2015-7554.patch completely disabled) 12/tiff $ valgrind -q tiffcmp 00_basefile.tiff 18_tiffcmp.tiff TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not sorted in ascending order. TIFFReadDirectory: Warning, Unknown field with tag 317 (0x13d) encountered. XResolution: 1 0 $ [no issues observed] $ valgrind -q thumbnail 17_thumbnail.tiff out.tiff TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not sorted in ascending order. TIFFReadDirectory: Warning, Unknown field with tag 328 (0x148) encountered. rastersize=1 TIFFFillStrip: Read error on strip 0; got 18446744073709551603 bytes, expected 1. bpr=1, sy=0, bpr*sy=0 ==16904== Use of uninitialised value of size 8 ==16904== at 0x10A17D: setrow (thumbnail.c:525) ==16904== by 0x10A17D: setImage1 (thumbnail.c:581) ==16904== by 0x109985: setImage (thumbnail.c:591) ==16904== by 0x109985: generateThumbnail (thumbnail.c:633) ==16904== by 0x109985: main (thumbnail.c:122) ==16904== bpr=1, sy=0, bpr*sy=0 [..] bpr=1, sy=0, bpr*sy=0 TIFFReadRawStrip: Read error at scanline 4294967295, strip 0; got 0 bytes, expected 1. $ [no segfault or invalid access observed] 11/tiff $ valgrind -q thumbnail 17_thumbnail.tiff out.tiff TIFFReadDirectory: Warning, 17_thumbnail.tiff: unknown field with tag 328 (0x148) encountered. TIFFReadDirectory: Warning, 17_thumbnail.tiff: invalid TIFF directory; tags are not sorted in ascending order. rastersize=1 TIFFFillStrip: 17_thumbnail.tiff: Read error on strip 0; got 18446744073709551603 bytes, expected 1. bpr=1, sy=0, bpr*sy=0 ==16917== Invalid read of size 1 ==16917== at 0x401532: setImage1 (thumbnail.c:519) ==16917== by 0x4020E1: main (thumbnail.c:569) ==16917== Address 0x5a81ab9 is 0 bytes after a block of size 1 alloc'd ==16917== at 0x4C256AE: malloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==16917== by 0x401DF5: main (thumbnail.c:593) ==16917== ==16917== Use of uninitialised value of size 8 ==16917== at 0x401474: setImage1 (thumbnail.c:503) ==16917== by 0x4020E1: main (thumbnail.c:569) bpr=1, sy=0, bpr*sy=0 bpr=1, sy=0, bpr*sy=0 [..] bpr=1, sy=0, bpr*sy=0 bpr=1, sy=0, bpr*sy=0 bpr=1, sy=0, bpr*sy=0 ==16917== ==16917== Invalid write of size 8 ==16917== at 0x4E3585A: _TIFFVGetField (tif_dir.c:868) ==16917== by 0x4E35C97: TIFFGetField (tif_dir.c:946) ==16917== by 0x401720: cpTag (thumbnail.c:159) ==16917== by 0x402295: main (thumbnail.c:275) ==16917== Address 0x1 is not stack'd, malloc'd or (recently) free'd ==16917== ==16917== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==16917== Access not within mapped region at address 0x1 ==16917== at 0x4E3585A: _TIFFVGetField (tif_dir.c:868) ==16917== by 0x4E35C97: TIFFGetField (tif_dir.c:946) ==16917== by 0x401720: cpTag (thumbnail.c:159) ==16917== by 0x402295: main (thumbnail.c:275) /root/bin/vgq: line 3: 16917 Segmentation fault (core dumped) valgrind -q $@ $ $ tiffcmp 00_basefile.tiff 18_tiffcmp.tiff TIFFReadDirectory: Warning, 18_tiffcmp.tiff: unknown field with tag 317 (0x13d) encountered. TIFFReadDirectory: Warning, 18_tiffcmp.tiff: invalid TIFF directory; tags are not sorted in ascending order. Segmentation fault (core dumped) $ PATCH see comment 35 12/ImageMagick: have the fix in 11,10sp3/ImageMagick: needs to be fixed AFTER (patch from comment 35 applied) 11/tiff $ valgrind -q thumbnail 17_thumbnail.tiff out.tiff TIFFReadDirectory: Warning, 17_thumbnail.tiff: unknown field with tag 328 (0x148) encountered. TIFFReadDirectory: Warning, 17_thumbnail.tiff: invalid TIFF directory; tags are not sorted in ascending order. rastersize=1 TIFFFillStrip: 17_thumbnail.tiff: Read error on strip 0; got 18446744073709551603 bytes, expected 1. bpr=1, sy=0, bpr*sy=0 ==5816== Invalid read of size 1 ==5816== at 0x401532: setImage1 (thumbnail.c:519) ==5816== by 0x4020E1: main (thumbnail.c:569) ==5816== Address 0x5a81a21 is 0 bytes after a block of size 1 alloc'd ==5816== at 0x4C256AE: malloc (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so) ==5816== by 0x401DF5: main (thumbnail.c:593) ==5816== ==5816== Use of uninitialised value of size 8 ==5816== at 0x401474: setImage1 (thumbnail.c:503) ==5816== by 0x4020E1: main (thumbnail.c:569) bpr=1, sy=0, bpr*sy=0 bpr=1, sy=0, bpr*sy=0 [..] pr=1, sy=0, bpr*sy=0 bpr=1, sy=0, bpr*sy=0 TIFFReadRawStrip: 17_thumbnail.tiff: Read error at scanline 4294967295, strip 0; got 18446744073709551603 bytes, expected 1. $ $ valgrind -q tiffcmp 00_basefile.tiff 18_tiffcmp.tiff TIFFReadDirectory: Warning, 18_tiffcmp.tiff: unknown field with tag 317 (0x13d) encountered. TIFFReadDirectory: Warning, 18_tiffcmp.tiff: invalid TIFF directory; tags are not sorted in ascending order. XResolution: 1 0 $ [segfault gone] The invalid read I will try fix with tiff-thumbnail-invalid-read.patch (inspired in 4.0.9). After that patch, setrow() still uses uninitialized value.
Will be submitted for 11/tiff and 10sp3/tiff.
I believe this is fixed in sr#162981 and sr#162982. Michael, after you review my changes and statements here, feel free to accept these submit requests and resubmit as maintenance request. In the same moment such maintenance request is created, bug can be assigned to security team immediately.
SR#164509 SLE-10-SP3 SR#164510 SLE-11
released
SUSE-SU-2018:1179-1: An update that solves 11 vulnerabilities and has two fixes is now available. Category: security (moderate) Bug References: 1007280,1011107,1011845,1017688,1017690,1017691,1017692,1031255,1046077,1048937,1074318,960341,983436 CVE References: CVE-2015-7554,CVE-2016-10095,CVE-2016-10268,CVE-2016-3945,CVE-2016-5318,CVE-2016-5652,CVE-2016-9453,CVE-2016-9536,CVE-2017-11335,CVE-2017-17973,CVE-2017-9935 Sources used: SUSE Linux Enterprise Software Development Kit 11-SP4 (src): tiff-3.8.2-141.169.3.1 SUSE Linux Enterprise Server 11-SP4 (src): tiff-3.8.2-141.169.3.1 SUSE Linux Enterprise Debuginfo 11-SP4 (src): tiff-3.8.2-141.169.3.1
An update workflow for this issue was started. This issue was rated as important. Please submit fixed packages until 2018-05-18. When done, reassign the bug to security-team@suse.de. https://swamp.suse.de/webswamp/wf/64038