REDHAT-BUG-2492871: High severity LibTIFF libtiff vulnerability
The issue happens when decoding Pixarlog codec images with PIXARLOGDATAFMT8BITABGR output format and stride = 3 . The decoder writes 4 output bytes per 3 decoded samples (synthetic alpha byte) but advances the output cursor by 3 bytes. This mismatch causes a linear heap based buffer-overflow of approx. width bytes per scan line. For every 4-bytes in the overflow, the first is always 0x00 while the others are controlled. The overflow happens on a user allocated buffer, but according to the docs (TIFFReadScnaline.rst) the user is supposed to allocate a buffer of this TIFFScanlineSize(t) , which will return the incorrect size. The bug can be pinpointed to two locations in libtiff/tifpixarlog.c - the horizontalAccumulate8abgr function (3->4 byte expansion), and PixarLogDecode which updates the output pointer. RCA PixarLogDecode dispatches on sp->userdatafmt: case PIXARLOGDATAFMT8BITABGR: horizontalAccumulate8abgr(up, llen, sp->stride, (unsigned char )op, sp->ToLinear8); op += llen sizeof(unsigned char); // <-- WRONG for stride=3 break; horizontalAccumulate8abgr with stride == 3 emits 4 bytes per input triplet: if (stride == 3) { op[0] = 0; op[1] = t1; op[2] = t2; op[3] = t3; / 4 bytes written / n -= 3; while (n > 0) { n -= 3; wp += 3; op += 4; / advance 4 per triplet / op[0] = 0; op[1] = …; op[2] = …; op[3] = …; } } So for llen = stride width = 3 W input samples the function writes (llen / 3) 4 = 4 W bytes. PixarLogDecode then advances op by only llen = 3 W. The next iteration starts W bytes before the position where the previous write ended, and on the final iteration the writes extend W bytes past the end of the buffer the caller allocated from TIFFScanlineSize (which is W stride 1 = 3 W bytes for this configuration). Reachability Any application that selects PIXARLOGDATAFMT8BITABGR via TIFFSetField(tif, TIFFTAGPIXARLOGDATAFMT, PIXARLOGDATAFMT8BITABGR) and then reads a PixarLog-compressed TIFF with SamplesPerPixel == 3 is affected. The standard format picker in TIFFRGBAImageBegin does not select 8BITABGR (it picks 8BIT, 16BIT or FLOAT), so TIFFReadRGBAImage is not directly affected. PoC I attached a c program, that when executed produces a file that will overflow a heap buffer by 64 bytes. To verify I compiled it along with ASan-enabled libtiff, and got: $ gcc -fsanitize=address -g -O1 pixarlogheapoverflowpoc.c \ -I$LIBTIFF/libtiff -I$BUILD/libtiff \ -L$BUILD/libtiff -ltiff -Wl,-rpath,$BUILD/libtiff -o poc $ ./poc ================================================================= ==...==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x… at pc 0x… WRITE of size 1 at 0x… thread T0 #0 horizontalAccumulate8abgr libtiff/tifpixarlog.c:470 #1 PixarLogDecode libtiff/tifpixarlog.c:980 #2 TIFFReadScanline libtiff/tifread.c:465 #3 main pocpixarlog8bitabgr.c:31 0 bytes to the right of 192-byte region The 192-byte region is the caller's TIFFScanlineSize-sized buffer (W 3 = 192). The decoder writes 256 bytes ((W 3 / 3) 4 = 256) per row, producing a 64-byte overflow per row. pixarlogheapoverflowpoc.c Fix I didn't open a PR for this fix, since I'm not sure how to make it confidential and I wanted the maintainer to review this issue first. If you want me to open the PR, lmk and I'll do it as instructed. I think that in order to fix, we need to correct the output pointer advancement in PixarLogDecode: case PIXARLOGDATAFMT8BITABGR: horizontalAccumulate8abgr(up, llen, sp->stride, (unsigned char )op, sp->ToLinear8); if (sp->stride == 3) op += (sizet)(llen / 3) 4; / 4 output bytes per triplet / else op += (sizet)llen sizeof(unsigned char); break; And also to somehow make TIFFScanlineSize return the correct size. We can maybe do this with introducing a codec ScanLinesize override that is checked in the function: / tifstrip.c — TIFFScanlineSize64 / if (tif->tifscanlinesizeoverride) return tif->tifscanlinesizeoverride(tif); // ...
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
libtiffto a version that resolves this vulnerability.Patch tif_pixarlog.c - Configuration
Do not select PIXARLOGDATAFMT_8BITABGR for PixarLog-compressed TIFFs with SamplesPerPixel == 3 until the decoder pointer advancement/output sizing bug in libtiff/tif_pixarlog.c is fixed.
libtiff (PixarLog decoding) TIFFTAG_PIXARLOGDATAFMT via TIFFSetField = PIXARLOGDATAFMT_8BITABGR
Event History
Frequently Asked Questions
What is the severity of REDHAT-BUG-2492871?
The severity of REDHAT-BUG-2492871 is classified as high with a score of 7.
What causes the vulnerability in REDHAT-BUG-2492871?
The vulnerability occurs due to a mismatch in the number of output bytes written and the cursor advancement during Pixarlog codec image decoding.
How do I fix REDHAT-BUG-2492871?
To fix REDHAT-BUG-2492871, update to the latest version of LibTIFF that addresses this vulnerability.
What type of vulnerability is REDHAT-BUG-2492871?
REDHAT-BUG-2492871 is a heap-based buffer overflow vulnerability.
Which software is affected by REDHAT-BUG-2492871?
The affected software is LibTIFF, specifically the libtiff library.