CESA-2004-006: libtiff
http://scary.beasts.org/security/CESA-2004-006.txt
CESA-2004-006 - rev 3
libtiff-3.8.1 image decoder parsing flaws
=========================================
Programs: libtiff, and users of libtiff such as GNOME and KDE
(konqueror and mail clients are of particular concern).
Severity: Compromise of account used to browse malicious TIFF file.
CAN identifier(s): CAN-2004-0803
This advisory lists code flaws discovered by inspection of the libtiff code.
Specifically, libtiff-3.8.1 was investigated. Unfortunately, due to the size
of libtiff, only a limited scan for flaws was possible. These flaws are
likely to typify others present.
Very brief libtiff summary: libtiff is an encoder / decoder for the TIFF image
format. The TIFF image format is an incredibly rich format featuring multiple
possible encodings and formats. The encodings include JPEG, LZW, ZIP, log-based
encodings and many more - from many different companies such as NeXT, SGI and
Pixar.
Flaw 1. Heap-based overflow during RLE decoding in tif_next.c
off = (bp[0] * 256) + bp[1];
n = (bp[2] * 256) + bp[3];
if (cc < 4+n)
goto bad;
_TIFFmemcpy(row+off, bp+4, n);
Here, off and n are arbitrary values from the TIFF. Bounds checking is
performed on the data source buffer, but not the data destination buffer.
Demo TIFF: http://scary.beasts.org/misc/bad_next.tiff
(note that memory is subtly corrupted but may not result in an immediate
crash)
Flaw 2. Heap-based overflow during RLE decoding in tif_thunder.c
case THUNDER_RUN: /* pixel run */
/*
* Replicate the last pixel n times,
* where n is the lower-order 6 bits.
*/
if (npixels & 1) {
op[0] |= lastpixel;
lastpixel = *op++; npixels++; n--;
} else
lastpixel |= lastpixel << 4;
npixels += n;
for (; n > 0; n -= 2)
*op++ = (tidataval_t) lastpixel;
Here, n is an arbitrary value from the TIFF, and is used to drive a copy count
into the output without bounds checking.
Demo TIFF: http://scary.beasts.org/misc/bad_thunder.tiff
(note that memory is subtly corrupted but may not result in an immediate
crash)
Flaw 3. Possible overflow in tif_luv.c
A TIFF file to confirm this has not been crafted - but it appears that there
may be heap-based overflows when doing RLE decoding:
for (shft = 2*8; (shft -= 8) >= 0; ) {
for (i = 0; i < npixels && cc > 0; )
if (*bp >= 128) { /* run */
rc = *bp++ + (2-128);
b = (int16)(*bp++ << shft);
cc -= 2;
while (rc--)
[*] tp[i++] |= b;
} else { /* non-run */
rc = *bp++; /* nul is noop */
while (--cc && rc--)
[*] tp[i++] |= (int16)*bp++ << shft;
Lines marked with a [*] exhibit a suspicious lack of checking on the size of
the output buffer. Note that tif_luv.c contains multiple versions of the RLE
decoder for different image depths, and all look similarly dangerous.
CESA-2004-006 - rev 3
Chris Evans
chris@xxxxxxxxxxxxxxxx