Skip to content

Commit 4e2def2

Browse files
committed
Overflow checks for realloc for tiff decoding
1 parent a79b65c commit 4e2def2

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

Diff for: Tests/images/tiff_overflow_rows_per_strip.tif

305 KB
Binary file not shown.

Diff for: Tests/test_file_libtiff.py

+10
Original file line numberDiff line numberDiff line change
@@ -870,3 +870,13 @@ def test_sampleformat_not_corrupted(self):
870870
out.seek(0)
871871
with Image.open(out) as im:
872872
im.load()
873+
874+
def test_realloc_overflow(self):
875+
TiffImagePlugin.READ_LIBTIFF = True
876+
with Image.open("Tests/images/tiff_overflow_rows_per_strip.tif") as im:
877+
with self.assertRaises(IOError) as e:
878+
im.load()
879+
880+
# Assert that the error code is IMAGING_CODEC_MEMORY
881+
self.assertEqual(str(e.exception), "-9")
882+
TiffImagePlugin.READ_LIBTIFF = False

Diff for: src/libImaging/TiffDecode.c

+14-3
Original file line numberDiff line numberDiff line change
@@ -353,16 +353,18 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
353353

354354
// We could use TIFFTileSize, but for YCbCr data it returns subsampled data size
355355
row_byte_size = (tile_width * state->bits + 7) / 8;
356-
state->bytes = row_byte_size * tile_length;
357356

358-
/* overflow check for malloc */
359-
if (state->bytes > INT_MAX - 1) {
357+
/* overflow check for realloc */
358+
if (INT_MAX / row_byte_size < tile_length) {
360359
state->errcode = IMAGING_CODEC_MEMORY;
361360
TIFFClose(tiff);
362361
return -1;
363362
}
363+
364+
state->bytes = row_byte_size * tile_length;
364365

365366
/* realloc to fit whole tile */
367+
/* malloc check above */
366368
new_data = realloc (state->buffer, state->bytes);
367369
if (!new_data) {
368370
state->errcode = IMAGING_CODEC_MEMORY;
@@ -415,11 +417,20 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_
415417

416418
// We could use TIFFStripSize, but for YCbCr data it returns subsampled data size
417419
row_byte_size = (state->xsize * state->bits + 7) / 8;
420+
421+
/* overflow check for realloc */
422+
if (INT_MAX / row_byte_size < rows_per_strip) {
423+
state->errcode = IMAGING_CODEC_MEMORY;
424+
TIFFClose(tiff);
425+
return -1;
426+
}
427+
418428
state->bytes = rows_per_strip * row_byte_size;
419429

420430
TRACE(("StripSize: %d \n", state->bytes));
421431

422432
/* realloc to fit whole strip */
433+
/* malloc check above */
423434
new_data = realloc (state->buffer, state->bytes);
424435
if (!new_data) {
425436
state->errcode = IMAGING_CODEC_MEMORY;

0 commit comments

Comments
 (0)