diff --git a/CHANGES.rst b/CHANGES.rst index fd8eca6ef..d774aa963 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,9 @@ Changelog (Pillow) - Catch SGI out-of-bounds reads. CVE 2020-11538 [ucodery] +- Catch TiffDecode heap-based buffer overflow. CVE 2021-25289 + [ucodery] + 6.2.2 (2020-01-02) ------------------ diff --git a/Tests/images/crash-63b1dffefc8c075ddc606c0a2f5fdc15ece78863.tif b/Tests/images/crash-63b1dffefc8c075ddc606c0a2f5fdc15ece78863.tif new file mode 100644 index 000000000..b89203f75 Binary files /dev/null and b/Tests/images/crash-63b1dffefc8c075ddc606c0a2f5fdc15ece78863.tif differ diff --git a/Tests/test_tiff_crashes.py b/Tests/test_tiff_crashes.py new file mode 100644 index 000000000..655dc0b3a --- /dev/null +++ b/Tests/test_tiff_crashes.py @@ -0,0 +1,11 @@ +import pytest + +from PIL import Image + +@pytest.mark.filterwarnings("ignore:Possibly corrupt EXIF data") +@pytest.mark.filterwarnings("ignore:Metadata warning") +def test_tiff_crashes(): + test_file = "Tests/images/crash-63b1dffefc8c075ddc606c0a2f5fdc15ece78863.tif" + with pytest.raises(IOError): + with Image.open(test_file) as im: + im.load() diff --git a/docs/releasenotes/6.2.2.1.rst b/docs/releasenotes/6.2.2.1.rst index 8912fb798..16e4785cf 100644 --- a/docs/releasenotes/6.2.2.1.rst +++ b/docs/releasenotes/6.2.2.1.rst @@ -6,5 +6,8 @@ Security This release addresses CVE-2020-11538. -CVE-2019-11538 is regarding SGI images. An out-of-bounds read can occur in the +CVE-2020-11538 is regarding SGI images. An out-of-bounds read can occur in the parsing of SGI image files. + +CVE-2021-25289 is regarding Tiff images. A heap-based buffer overflow can occur +when decoding crafted YCbCr files. diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c index c3df1174e..df5ba3fa4 100644 --- a/src/libImaging/TiffDecode.c +++ b/src/libImaging/TiffDecode.c @@ -378,6 +378,12 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ for (y = state->yoff; y < state->ysize; y += tile_length) { for (x = state->xoff; x < state->xsize; x += tile_width) { + if (!TIFFCheckTile(tiff, x, y, 0, 0)) { + TRACE(("Check Tile Error, Tile at %dx%d\n", x, y)); + state->errcode = IMAGING_CODEC_BROKEN; + TIFFClose(tiff); + return -1; + } if (ReadTile(tiff, x, y, (UINT32*) state->buffer) == -1) { TRACE(("Decode Error, Tile at %dx%d\n", x, y)); state->errcode = IMAGING_CODEC_BROKEN;