tif_dir: unset transferfunction field if necessary

The number of entries in the transfer table is determined as following:

(td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1

This means that whenever td->td_samplesperpixel or td->td_extrasamples are
modified we also need to make sure that the number of required entries in
the transfer table didn't change.

If it changed and the number of entries is higher than before we should
invalidate the transfer table field and free previously allocated values.
In the other case there's nothing to do, additional tf entries won't harm
and properly written code will just ignore them since spp - es < 1.

For instance this situation might happen when reading an OJPEG compressed
image with missing SamplesPerPixel tag. In this case the SamplesPerPixel
field might be updated after setting the transfer table.

see http://bugzilla.maptools.org/show_bug.cgi?id=2500

This commit addresses CVE-2018-19210.
This commit is contained in:
Hugo Lefeuvre 2018-11-21 18:50:34 +01:00
parent 4e3faaf6f5
commit d0a842c5db

View File

@ -285,6 +285,18 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFfree(td->td_smaxsamplevalue); _TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL; td->td_smaxsamplevalue = NULL;
} }
/* Test if 3 transfer functions instead of just one are now needed
See http://bugzilla.maptools.org/show_bug.cgi?id=2820 */
if( td->td_transferfunction[0] != NULL && (v - td->td_extrasamples > 1) &&
!(td->td_samplesperpixel - td->td_extrasamples > 1))
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
"but TransferFunction was read with a different value. Cancelling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
}
} }
td->td_samplesperpixel = (uint16) v; td->td_samplesperpixel = (uint16) v;
break; break;
@ -361,6 +373,16 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
break; break;
case TIFFTAG_EXTRASAMPLES: case TIFFTAG_EXTRASAMPLES:
if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel - v > 1) &&
!(td->td_samplesperpixel - td->td_extrasamples > 1))
{
TIFFWarningExt(tif->tif_clientdata,module,
"ExtraSamples tag value is changing, "
"but TransferFunction was read with a different value. Cancelling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
}
if (!setExtraSamples(td, ap, &v)) if (!setExtraSamples(td, ap, &v))
goto badvalue; goto badvalue;
break; break;