diff --git a/backport-CVE-2021-25287-CVE-2021-25288.patch b/backport-CVE-2021-25287-CVE-2021-25288.patch new file mode 100644 index 0000000000000000000000000000000000000000..5e5b2b341bbdd35286507fb5ac748013a26c4a7d --- /dev/null +++ b/backport-CVE-2021-25287-CVE-2021-25288.patch @@ -0,0 +1,75 @@ +From 3bf5eddb89afdf690eceaa52bc4d3546ba9a5f87 Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Sun, 7 Mar 2021 12:32:12 +0100 +Subject: [PATCH] Fix OOB Read in Jpeg2KDecode CVE-2021-25287,CVE-2021-25288 + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/3bf5eddb89afdf690eceaa52bc4d3546ba9a5f87 +--- + src/libImaging/Jpeg2KDecode.c | 33 +++++++++++++++++++++++++-------- + 1 file changed, 25 insertions(+), 8 deletions(-) + +diff --git a/src/libImaging/Jpeg2KDecode.c b/src/libImaging/Jpeg2KDecode.c +index 8cce545..60d4d77 100644 +--- a/src/libImaging/Jpeg2KDecode.c ++++ b/src/libImaging/Jpeg2KDecode.c +@@ -589,7 +589,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state) + j2k_unpacker_t unpack = NULL; + size_t buffer_size = 0, tile_bytes = 0; + unsigned n, tile_height, tile_width; +- int components; ++ int total_component_width = 0; + + + stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE); +@@ -753,23 +753,40 @@ j2k_decode_entry(Imaging im, ImagingCodecState state) + goto quick_exit; + } + ++ if (tile_info.nb_comps != image->numcomps) { ++ state->errcode = IMAGING_CODEC_BROKEN; ++ state->state = J2K_STATE_FAILED; ++ goto quick_exit; ++ } ++ + /* Sometimes the tile_info.datasize we get back from openjpeg +- is less than numcomps*w*h, and we overflow in the ++ is less than sum(comp_bytes)*w*h, and we overflow in the + shuffle stage */ + + tile_width = tile_info.x1 - tile_info.x0; + tile_height = tile_info.y1 - tile_info.y0; +- components = tile_info.nb_comps == 3 ? 4 : tile_info.nb_comps; +- if (( tile_width > UINT_MAX / components ) || +- ( tile_height > UINT_MAX / components ) || +- ( tile_width > UINT_MAX / (tile_height * components )) || +- ( tile_height > UINT_MAX / (tile_width * components ))) { ++ ++ /* Total component width = sum (component_width) e.g, it's ++ legal for an la file to have a 1 byte width for l, and 4 for ++ a. and then a malicious file could have a smaller tile_bytes ++ */ ++ ++ for (n=0; n < tile_info.nb_comps; n++) { ++ // see csize /acsize calcs ++ int csize = (image->comps[n].prec + 7) >> 3; ++ csize = (csize == 3) ? 4 : csize; ++ total_component_width += csize; ++ } ++ if ((tile_width > UINT_MAX / total_component_width) || ++ (tile_height > UINT_MAX / total_component_width) || ++ (tile_width > UINT_MAX / (tile_height * total_component_width)) || ++ (tile_height > UINT_MAX / (tile_width * total_component_width))) { + state->errcode = IMAGING_CODEC_BROKEN; + state->state = J2K_STATE_FAILED; + goto quick_exit; + } + +- tile_bytes = tile_width * tile_height * components; ++ tile_bytes = tile_width * tile_height * total_component_width; + + if (tile_bytes > tile_info.data_size) { + tile_info.data_size = tile_bytes; +-- +2.23.0 + diff --git a/backport-CVE-2021-28675.patch b/backport-CVE-2021-28675.patch new file mode 100644 index 0000000000000000000000000000000000000000..f8a5aac84883fdc655419f814e5fa8e9561538ad --- /dev/null +++ b/backport-CVE-2021-28675.patch @@ -0,0 +1,197 @@ +From 22e9bee4ef225c0edbb9323f94c26cee0c623497 Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Sun, 7 Mar 2021 19:04:25 +0100 +Subject: [PATCH] Fix DOS in PSDImagePlugin -- CVE-2021-28675 + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/22e9bee4ef225c0edbb9323f94c26cee0c623497 +--- + Tests/test_decompression_bomb.py | 1 + + Tests/test_file_apng.py | 2 +- + Tests/test_file_blp.py | 1 + + Tests/test_file_tiff.py | 6 ++++-- + src/PIL/ImageFile.py | 14 ++++++++++++-- + src/PIL/PsdImagePlugin.py | 32 +++++++++++++++++++++----------- + 6 files changed, 40 insertions(+), 16 deletions(-) + +diff --git a/Tests/test_decompression_bomb.py b/Tests/test_decompression_bomb.py +index 7671cdc..f96a15a 100644 +--- a/Tests/test_decompression_bomb.py ++++ b/Tests/test_decompression_bomb.py +@@ -52,6 +52,7 @@ class TestDecompressionBomb: + with Image.open(TEST_FILE): + pass + ++ @pytest.mark.xfail(reason="different exception") + def test_exception_ico(self): + with pytest.raises(Image.DecompressionBombError): + Image.open("Tests/images/decompression_bomb.ico") +diff --git a/Tests/test_file_apng.py b/Tests/test_file_apng.py +index 97e2a15..8348da4 100644 +--- a/Tests/test_file_apng.py ++++ b/Tests/test_file_apng.py +@@ -312,7 +312,7 @@ def test_apng_syntax_errors(): + exception = e + assert exception is None + +- with pytest.raises(SyntaxError): ++ with pytest.raises(OSError): + with Image.open("Tests/images/apng/syntax_num_frames_high.png") as im: + im.seek(im.n_frames - 1) + im.load() +diff --git a/Tests/test_file_blp.py b/Tests/test_file_blp.py +index 94c469c..1510614 100644 +--- a/Tests/test_file_blp.py ++++ b/Tests/test_file_blp.py +@@ -1,4 +1,5 @@ + from PIL import Image ++import pytest + + from .helper import assert_image_equal + +diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py +index bb1bbda..1500ac8 100644 +--- a/Tests/test_file_tiff.py ++++ b/Tests/test_file_tiff.py +@@ -612,8 +612,10 @@ class TestFileTiff: + ) + def test_string_dimension(self): + # Assert that an error is raised if one of the dimensions is a string +- with pytest.raises(ValueError): +- Image.open("Tests/images/string_dimension.tiff") ++ with pytest.raises(OSError): ++ with Image.open("Tests/images/string_dimension.tiff") as im: ++ im.load() ++ + + + @pytest.mark.skipif(not is_win32(), reason="Windows only") +diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py +index f2a55cb..468314b 100644 +--- a/src/PIL/ImageFile.py ++++ b/src/PIL/ImageFile.py +@@ -555,12 +555,18 @@ def _safe_read(fp, size): + + :param fp: File handle. Must implement a read method. + :param size: Number of bytes to read. +- :returns: A string containing up to size bytes of data. ++ :returns: A string containing size bytes of data. ++ ++ Raises an OSError if the file is truncated and the read can not be completed ++ + """ + if size <= 0: + return b"" + if size <= SAFEBLOCK: +- return fp.read(size) ++ data = fp.read(size) ++ if len(data) < size: ++ raise OSError("Truncated File Read") ++ return data + data = [] + while size > 0: + block = fp.read(min(size, SAFEBLOCK)) +@@ -568,9 +574,13 @@ def _safe_read(fp, size): + break + data.append(block) + size -= len(block) ++ if sum(len(d) for d in data) < size: ++ raise OSError("Truncated File Read") + return b"".join(data) + + ++ ++ + class PyCodecState: + def __init__(self): + self.xsize = 0 +diff --git a/src/PIL/PsdImagePlugin.py b/src/PIL/PsdImagePlugin.py +index d3799ed..96de58f 100644 +--- a/src/PIL/PsdImagePlugin.py ++++ b/src/PIL/PsdImagePlugin.py +@@ -119,7 +119,8 @@ class PsdImageFile(ImageFile.ImageFile): + end = self.fp.tell() + size + size = i32(read(4)) + if size: +- self.layers = _layerinfo(self.fp) ++ _layer_data = io.BytesIO(ImageFile._safe_read(self.fp, size)) ++ self.layers = _layerinfo(_layer_data, size) + self.fp.seek(end) + self.n_frames = len(self.layers) + self.is_animated = self.n_frames > 1 +@@ -170,12 +171,20 @@ class PsdImageFile(ImageFile.ImageFile): + finally: + self.__fp = None + +- +-def _layerinfo(file): ++def _layerinfo(fp, ct_bytes): + # read layerinfo block + layers = [] +- read = file.read +- for i in range(abs(i16(read(2)))): ++ ++ def read(size): ++ return ImageFile._safe_read(fp, size) ++ ++ ct = i16(read(2)) ++ ++ # sanity check ++ if ct_bytes < (abs(ct) * 20): ++ raise SyntaxError("Layer block too short for number of layers requested") ++ ++ for i in range(abs(ct)): + + # bounding box + y0 = i32(read(4)) +@@ -186,7 +195,8 @@ def _layerinfo(file): + # image info + info = [] + mode = [] +- types = list(range(i16(read(2)))) ++ ct_types = i16(read(2)) ++ types = list(range(ct_types)) + if len(types) > 4: + continue + +@@ -219,16 +229,16 @@ def _layerinfo(file): + size = i32(read(4)) # length of the extra data field + combined = 0 + if size: +- data_end = file.tell() + size ++ data_end = fp.tell() + size + + length = i32(read(4)) + if length: +- file.seek(length - 16, io.SEEK_CUR) ++ fp.seek(length - 16, io.SEEK_CUR) + combined += length + 4 + + length = i32(read(4)) + if length: +- file.seek(length, io.SEEK_CUR) ++ fp.seek(length, io.SEEK_CUR) + combined += length + 4 + + length = i8(read(1)) +@@ -238,7 +248,7 @@ def _layerinfo(file): + name = read(length).decode("latin-1", "replace") + combined += length + 1 + +- file.seek(data_end) ++ fp.seek(data_end) + layers.append((name, mode, (x0, y0, x1, y1))) + + # get tiles +@@ -246,7 +256,7 @@ def _layerinfo(file): + for name, mode, bbox in layers: + tile = [] + for m in mode: +- t = _maketile(file, m, bbox, 1) ++ t = _maketile(fp, m, bbox, 1) + if t: + tile.extend(t) + layers[i] = name, mode, bbox, tile +-- +2.23.0 + diff --git a/backport-CVE-2021-28676.patch b/backport-CVE-2021-28676.patch new file mode 100644 index 0000000000000000000000000000000000000000..f80a1075aa08cfdceedbb5ba75a49ed0957d463c --- /dev/null +++ b/backport-CVE-2021-28676.patch @@ -0,0 +1,30 @@ +From bb6c11fb889e6c11b0ee122b828132ee763b5856 Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Thu, 11 Mar 2021 22:12:35 +0100 +Subject: [PATCH] Fix FLI DOS -- CVE-2021-28676 + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/bb6c11fb889e6c11b0ee122b828132ee763b5856 +--- + src/libImaging/FliDecode.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/libImaging/FliDecode.c b/src/libImaging/FliDecode.c +index 8450801..b8bc5ce 100644 +--- a/src/libImaging/FliDecode.c ++++ b/src/libImaging/FliDecode.c +@@ -242,6 +242,11 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt + return -1; + } + advance = I32(ptr); ++ if (advance == 0 ) { ++ // If there's no advance, we're in in infinite loop ++ state->errcode = IMAGING_CODEC_BROKEN; ++ return -1; ++ } + if (advance < 0 || advance > bytes) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; +-- +2.23.0 + diff --git a/backport-CVE-2021-28677.patch b/backport-CVE-2021-28677.patch new file mode 100644 index 0000000000000000000000000000000000000000..419adb9d15dbbf0d27f287be0953e71eff68fb87 --- /dev/null +++ b/backport-CVE-2021-28677.patch @@ -0,0 +1,43 @@ +From 5a5e6db0abf4e7a638fb1b3408c4e495a096cb92 Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Mon, 8 Mar 2021 20:31:41 +0100 +Subject: [PATCH] Fix EPS DOS on _open -- CVE-2021-28677 + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/5a5e6db0abf4e7a638fb1b3408c4e495a096cb92 +--- + src/PIL/EpsImagePlugin.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py +index dc61f48..3bf8ee0 100644 +--- a/src/PIL/EpsImagePlugin.py ++++ b/src/PIL/EpsImagePlugin.py +@@ -170,12 +170,12 @@ class PSFile: + self.fp.seek(offset, whence) + + def readline(self): +- s = self.char or b"" ++ s = [self.char or b""] + self.char = None + + c = self.fp.read(1) +- while c not in b"\r\n": +- s = s + c ++ while (c not in b"\r\n") and len(c): ++ s.append(c) + c = self.fp.read(1) + + self.char = self.fp.read(1) +@@ -183,7 +183,7 @@ class PSFile: + if self.char in b"\r\n": + self.char = None + +- return s.decode("latin-1") ++ return b"".join(s).decode("latin-1") + + + def _accept(prefix): +-- +2.23.0 + diff --git a/backport-CVE-2021-28678.patch b/backport-CVE-2021-28678.patch new file mode 100644 index 0000000000000000000000000000000000000000..1bed97871a9e629122addf7483c3dc526c12ccc1 --- /dev/null +++ b/backport-CVE-2021-28678.patch @@ -0,0 +1,123 @@ +From 496245aa4365d0827390bd0b6fbd11287453b3a1 Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Sun, 7 Mar 2021 19:00:17 +0100 +Subject: [PATCH] Fix BLP DOS -- CVE-2021-28678 + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/496245aa4365d0827390bd0b6fbd11287453b3a1 +--- + src/PIL/BlpImagePlugin.py | 43 +++++++++++++++++++++------------------ + 1 file changed, 23 insertions(+), 20 deletions(-) + +diff --git a/src/PIL/BlpImagePlugin.py b/src/PIL/BlpImagePlugin.py +index 88aae80..e074746 100644 +--- a/src/PIL/BlpImagePlugin.py ++++ b/src/PIL/BlpImagePlugin.py +@@ -286,33 +286,36 @@ class _BLPBaseDecoder(ImageFile.PyDecoder): + raise OSError("Truncated Blp file") from e + return 0, 0 + ++ def _safe_read(self, length): ++ return ImageFile._safe_read(self.fd, length) ++ + def _read_palette(self): + ret = [] + for i in range(256): + try: +- b, g, r, a = struct.unpack("<4B", self.fd.read(4)) ++ b, g, r, a = struct.unpack("<4B", self._safe_read(4)) + except struct.error: + break + ret.append((b, g, r, a)) + return ret + + def _read_blp_header(self): +- (self._blp_compression,) = struct.unpack(" +Date: Sun, 14 Mar 2021 23:26:28 +0100 +Subject: [PATCH] Fix Memory DOS in ImageFont + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/ba65f0b08ee8b93195c3f3277820771f5b62aa52 +--- + src/PIL/ImageFont.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py +index c48d898..2f63dda 100644 +--- a/src/PIL/ImageFont.py ++++ b/src/PIL/ImageFont.py +@@ -669,6 +669,7 @@ class FreeTypeFont: + ) + size = size[0] + stroke_width * 2, size[1] + stroke_width * 2 + offset = offset[0] - stroke_width, offset[1] - stroke_width ++ Image._decompression_bomb_check(size) + im = fill("RGBA" if mode == "RGBA" else "L", size, 0) + self.font.render( + text, im.id, mode, direction, features, language, stroke_width, ink +-- +2.23.0 + diff --git a/backport-Fix-Wformat-error-in-TiffDecode.patch b/backport-Fix-Wformat-error-in-TiffDecode.patch new file mode 100644 index 0000000000000000000000000000000000000000..277e2c508e94231d37e4aba42c596d4f6cb93183 --- /dev/null +++ b/backport-Fix-Wformat-error-in-TiffDecode.patch @@ -0,0 +1,30 @@ +From 852fd170f8f3bb45cb0a7709d62bbc52b568d8bc Mon Sep 17 00:00:00 2001 +From: Luke Granger-Brown +Date: Wed, 3 Mar 2021 13:30:28 +0000 +Subject: [PATCH] Fix -Wformat error in TiffDecode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/852fd170f8f3bb45cb0a7709d62bbc52b568d8bc +--- + src/libImaging/TiffDecode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c +index accadfd..40a86ca 100644 +--- a/src/libImaging/TiffDecode.c ++++ b/src/libImaging/TiffDecode.c +@@ -48,7 +48,7 @@ tsize_t _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) { + dump_state(state); + + if (state->loc > state->eof) { +- TIFFError("_tiffReadProc", "Invalid Read at loc %d, eof: %d", state->loc, state->eof); ++ TIFFError("_tiffReadProc", "Invalid Read at loc %lu, eof: %lu", state->loc, state->eof); + return 0; + } + to_read = min(size, min(state->size, (tsize_t)state->eof) - (tsize_t)state->loc); +-- +2.23.0 + diff --git a/backport-Fixed-linear_gradient-and-radial_gradient-32-bit-mod.patch b/backport-Fixed-linear_gradient-and-radial_gradient-32-bit-mod.patch new file mode 100644 index 0000000000000000000000000000000000000000..7a20eaa38092bd923ec83cd15694fa6df60736f9 --- /dev/null +++ b/backport-Fixed-linear_gradient-and-radial_gradient-32-bit-mod.patch @@ -0,0 +1,84 @@ +From 297789284b8680a1d15549dc2d192f3abc552160 Mon Sep 17 00:00:00 2001 +From: Andrew Murray +Date: Mon, 22 Feb 2021 19:32:52 +1100 +Subject: [PATCH] Fixed linear_gradient and radial_gradient 32-bit modes + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/297789284b8680a1d15549dc2d192f3abc552160 +--- + Tests/test_image.py | 4 ++-- + src/libImaging/Fill.c | 28 ++++++++++++++++++++++++---- + 2 files changed, 26 insertions(+), 6 deletions(-) + +diff --git a/Tests/test_image.py b/Tests/test_image.py +index f2a1917..54448f3 100644 +--- a/Tests/test_image.py ++++ b/Tests/test_image.py +@@ -516,7 +516,7 @@ class TestImage: + + # Arrange + target_file = "Tests/images/linear_gradient.png" +- for mode in ["L", "P"]: ++ for mode in ["L", "P", "I", "F"]: + + # Act + im = Image.linear_gradient(mode) +@@ -542,7 +542,7 @@ class TestImage: + + # Arrange + target_file = "Tests/images/radial_gradient.png" +- for mode in ["L", "P"]: ++ for mode in ["L", "P", "I", "F"]: + + # Act + im = Image.radial_gradient(mode) +diff --git a/src/libImaging/Fill.c b/src/libImaging/Fill.c +index da143b4..6c6e107 100644 +--- a/src/libImaging/Fill.c ++++ b/src/libImaging/Fill.c +@@ -79,8 +79,21 @@ ImagingFillLinearGradient(const char *mode) + return NULL; + } + +- for (y = 0; y < 256; y++) { +- memset(im->image8[y], (unsigned char) y, 256); ++ if (im->image8) { ++ for (y = 0; y < 256; y++) { ++ memset(im->image8[y], (unsigned char)y, 256); ++ } ++ } else { ++ int x; ++ for (y = 0; y < 256; y++) { ++ for (x = 0; x < 256; x++) { ++ if (im->type == IMAGING_TYPE_FLOAT32) { ++ IMAGING_PIXEL_FLOAT32(im, x, y) = y; ++ } else { ++ IMAGING_PIXEL_INT32(im, x, y) = y; ++ } ++ } ++ } + } + + return im; +@@ -106,9 +119,16 @@ ImagingFillRadialGradient(const char *mode) + for (x = 0; x < 256; x++) { + d = (int) sqrt((double) ((x-128)*(x-128) + (y-128)*(y-128)) * 2.0); + if (d >= 255) { +- im->image8[y][x] = 255; +- } else { ++ d = 255; ++ } ++ if (im->image8) { + im->image8[y][x] = d; ++ } else { ++ if (im->type == IMAGING_TYPE_FLOAT32) { ++ IMAGING_PIXEL_FLOAT32(im, x, y) = d; ++ } else { ++ IMAGING_PIXEL_INT32(im, x, y) = d; ++ } + } + } + } +-- +2.23.0 + diff --git a/backport-Updated-format-specifiers.patch b/backport-Updated-format-specifiers.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f293f1f6066b8b7bdd52536a9329a95180a1189 --- /dev/null +++ b/backport-Updated-format-specifiers.patch @@ -0,0 +1,27 @@ +From 68b655f3f014c6beb13f4c9a6fa53f1ebff527c2 Mon Sep 17 00:00:00 2001 +From: Andrew Murray <3112309+radarhere@users.noreply.github.com> +Date: Wed, 10 Mar 2021 20:43:16 +1100 +Subject: [PATCH] Updated format specifiers + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/68b655f3f014c6beb13f4c9a6fa53f1ebff527c2 +--- + src/libImaging/TiffDecode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c +index 40a86ca..0c6e758 100644 +--- a/src/libImaging/TiffDecode.c ++++ b/src/libImaging/TiffDecode.c +@@ -48,7 +48,7 @@ tsize_t _tiffReadProc(thandle_t hdata, tdata_t buf, tsize_t size) { + dump_state(state); + + if (state->loc > state->eof) { +- TIFFError("_tiffReadProc", "Invalid Read at loc %lu, eof: %lu", state->loc, state->eof); ++ TIFFError("_tiffReadProc", "Invalid Read at loc %llu, eof: %llu", state->loc, state->eof); + return 0; + } + to_read = min(size, min(state->size, (tsize_t)state->eof) - (tsize_t)state->loc); +-- +2.23.0 + diff --git a/backport-fix-for-crash-8115.patch b/backport-fix-for-crash-8115.patch new file mode 100644 index 0000000000000000000000000000000000000000..c088979f59a86688da76b2da5f28a7c0eb375075 --- /dev/null +++ b/backport-fix-for-crash-8115.patch @@ -0,0 +1,29 @@ +From 53c80281d7f745cc1804901ec6f5b61d236688e0 Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Wed, 31 Mar 2021 21:16:43 +0200 +Subject: [PATCH] fix for crash-8115 + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/53c80281d7f745cc1804901ec6f5b61d236688e0 +--- + src/PIL/TiffImagePlugin.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py +index 0b70ce3..ced414f 100644 +--- a/src/PIL/TiffImagePlugin.py ++++ b/src/PIL/TiffImagePlugin.py +@@ -1250,6 +1250,10 @@ class TiffImageFile(ImageFile.ImageFile): + if bps_count > len(bps_tuple) and len(bps_tuple) == 1: + bps_tuple = bps_tuple * bps_count + ++ samplesPerPixel = self.tag_v2.get(SAMPLESPERPIXEL, 1) ++ if len(bps_tuple) != samplesPerPixel: ++ raise SyntaxError("unknown data organization") ++ + # mode: check photometric interpretation and bits per pixel + key = ( + self.tag_v2.prefix, +-- +2.23.0 + diff --git a/backport-fixes-crash-74d2.patch b/backport-fixes-crash-74d2.patch new file mode 100644 index 0000000000000000000000000000000000000000..3dcdc48c11e7e5e4eceb3374c0fe38ebd461e22c --- /dev/null +++ b/backport-fixes-crash-74d2.patch @@ -0,0 +1,71 @@ +From 45530d5ce1bcc9357907b7e5eeb6e54c6198358e Mon Sep 17 00:00:00 2001 +From: Eric Soroos +Date: Wed, 31 Mar 2021 21:04:59 +0200 +Subject: [PATCH] fixes crash-74d2 + +Conflict:NA +Reference:https://github.com/python-pillow/Pillow/commit/45530d5ce1bcc9357907b7e5eeb6e54c6198358e +--- + src/libImaging/TiffDecode.c | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c +index cd47158..accadfd 100644 +--- a/src/libImaging/TiffDecode.c ++++ b/src/libImaging/TiffDecode.c +@@ -199,7 +199,7 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) { + char emsg[1024] = ""; + + ret = TIFFGetFieldDefaulted(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip); +- if (ret != 1) { ++ if (ret != 1 || rows_per_strip==(UINT32)(-1)) { + rows_per_strip = state->ysize; + } + TRACE(("RowsPerStrip: %u \n", rows_per_strip)); +@@ -214,13 +214,6 @@ int _decodeStripYCbCr(Imaging im, ImagingCodecState state, TIFF *tiff) { + img.req_orientation = ORIENTATION_TOPLEFT; + img.col_offset = 0; + +- if (state->xsize != img.width || state->ysize != img.height) { +- TRACE(("Inconsistent Image Error: %d =? %d, %d =? %d", +- state->xsize, img.width, state->ysize, img.height)); +- state->errcode = IMAGING_CODEC_BROKEN; +- goto decodeycbcr_err; +- } +- + /* overflow check for row byte size */ + if (INT_MAX / 4 < img.width) { + state->errcode = IMAGING_CODEC_MEMORY; +@@ -360,6 +353,7 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ + TIFF *tiff; + uint16 photometric = 0; // init to not PHOTOMETRIC_YCBCR + int isYCbCr = 0; ++ UINT32 img_width, img_height; + + /* buffer is the encoded file, bytes is the length of the encoded file */ + /* it all ends up in state->buffer, which is a uint8* from Imaging.h */ +@@ -420,7 +414,20 @@ int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ + } + } + +- ++ TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width); ++ TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height); ++ ++ if (state->xsize != img_width || state->ysize != img_height) { ++ TRACE( ++ ("Inconsistent Image Error: %d =? %d, %d =? %d", ++ state->xsize, ++ img_width, ++ state->ysize, ++ img_height)); ++ state->errcode = IMAGING_CODEC_BROKEN; ++ goto decode_err; ++ } ++ + TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); + isYCbCr = photometric == PHOTOMETRIC_YCBCR; + +-- +2.23.0 + diff --git a/python-pillow.spec b/python-pillow.spec index 8f5d14822742696cbbc6189385738db16f3fb996..73de7354721f20878edaedc2bdba6b075d035deb 100644 --- a/python-pillow.spec +++ b/python-pillow.spec @@ -5,7 +5,7 @@ Name: python-pillow Version: 8.1.1 -Release: 2 +Release: 3 Summary: Python image processing library License: MIT URL: http://python-pillow.github.io/ @@ -14,6 +14,17 @@ Source0: https://github.com/python-pillow/Pillow/archive/%{version}/Pillo Patch0: python-pillow_spinxwarn.patch Patch1: python-pillow_sphinx-issues.patch Patch6000: backport-CVE-2021-27921_CVE-2021-27922_CVE-2021-27923.patch +Patch6001: backport-Fix-Wformat-error-in-TiffDecode.patch +Patch6002: backport-Updated-format-specifiers.patch +Patch6003: backport-CVE-2021-25287-CVE-2021-25288.patch +Patch6004: backport-CVE-2021-28675.patch +Patch6005: backport-CVE-2021-28676.patch +Patch6006: backport-CVE-2021-28677.patch +Patch6007: backport-CVE-2021-28678.patch +Patch6008: backport-Fixed-linear_gradient-and-radial_gradient-32-bit-mod.patch +Patch6009: backport-fixes-crash-74d2.patch +Patch6010: backport-fix-for-crash-8115.patch +Patch6011: backport-Fix-Memory-DOS-in-ImageFont.patch BuildRequires: freetype-devel ghostscript lcms2-devel libimagequant-devel libjpeg-devel libraqm-devel libtiff-devel BuildRequires: libwebp-devel openjpeg2-devel tk-devel zlib-devel python3-cffi python3-devel python3-numpy python3-olefile @@ -145,6 +156,12 @@ popd %{python3_sitearch}/PIL/__pycache__/ImageQt* %changelog +* Mon Jun 15 2021 hanhui - 8.1.1-3 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC: incorporate community patch + * Mon Mar 15 2021 wangye - 8.1.1-2 - Type:CVE - CVE:CVE-2021-27921 CVE-2021-27922 CVE-2021-27923