Skip to content

Commit

Permalink
Overflow checks for realloc for tiff decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jan 2, 2020
1 parent a79b65c commit 4e2def2
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
Binary file added Tests/images/tiff_overflow_rows_per_strip.tif
Binary file not shown.
10 changes: 10 additions & 0 deletions Tests/test_file_libtiff.py
Expand Up @@ -870,3 +870,13 @@ def test_sampleformat_not_corrupted(self):
out.seek(0)
with Image.open(out) as im:
im.load()

def test_realloc_overflow(self):
TiffImagePlugin.READ_LIBTIFF = True
with Image.open("Tests/images/tiff_overflow_rows_per_strip.tif") as im:
with self.assertRaises(IOError) as e:
im.load()

# Assert that the error code is IMAGING_CODEC_MEMORY
self.assertEqual(str(e.exception), "-9")
TiffImagePlugin.READ_LIBTIFF = False
17 changes: 14 additions & 3 deletions src/libImaging/TiffDecode.c
Expand Up @@ -353,16 +353,18 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_

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

/* overflow check for malloc */
if (state->bytes > INT_MAX - 1) {
/* overflow check for realloc */
if (INT_MAX / row_byte_size < tile_length) {
state->errcode = IMAGING_CODEC_MEMORY;
TIFFClose(tiff);
return -1;
}

state->bytes = row_byte_size * tile_length;

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

// We could use TIFFStripSize, but for YCbCr data it returns subsampled data size
row_byte_size = (state->xsize * state->bits + 7) / 8;

/* overflow check for realloc */
if (INT_MAX / row_byte_size < rows_per_strip) {
state->errcode = IMAGING_CODEC_MEMORY;
TIFFClose(tiff);
return -1;
}

state->bytes = rows_per_strip * row_byte_size;

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

/* realloc to fit whole strip */
/* malloc check above */
new_data = realloc (state->buffer, state->bytes);
if (!new_data) {
state->errcode = IMAGING_CODEC_MEMORY;
Expand Down

1 comment on commit 4e2def2

@NicoleG25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that it appears that CVE-2020-5310 was assigned to this issue.

Please sign in to comment.