CESA-2004-006 - rev 5 [See all my vulnerabilities at http://scary.beasts.org/security] libtiff-3.6.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.6.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 5 Chris Evans chris@scary.beasts.org