Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
7d421ad058
!168 [sync] PR-160: Fix CVE-2024-28219
From: @openeuler-sync-bot 
Reviewed-by: @cherry530 
Signed-off-by: @cherry530
2024-04-08 01:01:38 +00:00
wk333
8caca229e5 Fix CVE-2024-28219
(cherry picked from commit 153d5e6d363befe4ac93a207597edd0e4288f12c)
2024-04-07 16:44:55 +08:00
openeuler-ci-bot
36c56d68e9
!156 [sync] PR-151: Fix CVE-2023-50447
From: @openeuler-sync-bot 
Reviewed-by: @cherry530 
Signed-off-by: @cherry530
2024-01-24 03:20:47 +00:00
wk333
56dd14ace3 Fix CVE-2023-50447
(cherry picked from commit 1b3993805bb1fe3c73e374ca064730cb99be1b55)
2024-01-24 10:28:59 +08:00
openeuler-ci-bot
08c18cb0d9
!139 Fix CVE-2022-45198
From: @wk333 
Reviewed-by: @cherry530 
Signed-off-by: @cherry530
2023-12-08 08:47:07 +00:00
wk333
9c3b0840d6 Fix CVE-2022-45198 2023-12-08 15:39:35 +08:00
openeuler-ci-bot
b12a8f7b77
!133 [sync] PR-130: fix CVE-2023-44271
From: @openeuler-sync-bot 
Reviewed-by: @caodongxia 
Signed-off-by: @caodongxia
2023-11-14 08:41:26 +00:00
hanhuihui
a2a58337f3 fix CVE-2023-44271
(cherry picked from commit 171428d0d5e4bae2efc281d0c12aaab800db65c7)
2023-11-14 16:03:45 +08:00
openeuler-ci-bot
58d504085b
!118 [sync] PR-115: fix:CVE-2022-45199
From: @openeuler-sync-bot 
Reviewed-by: @myeuler 
Signed-off-by: @myeuler
2022-11-22 14:28:11 +00:00
qz_cx
8ec3d992f5 fix:CVE-2022-45199
(cherry picked from commit 079e6a29ad5759ecb26c2fe282595ec143730c9f)
2022-11-22 20:42:54 +08:00
9 changed files with 493 additions and 5 deletions

41
CVE-2022-45198.patch Normal file
View File

@ -0,0 +1,41 @@
From 20c10c81927790c700480a67dc48aebe2228d6e2 Mon Sep 17 00:00:00 2001
From: zhangshaoning <zhangshaoning@uniontech.com>
Date: Sat, 6 May 2023 15:06:22 +0800
Subject: [PATCH] CVE-2022-45198
---
Tests/test_decompression_bomb.py | 5 +++++
src/PIL/GifImagePlugin.py | 1 +
2 files changed, 6 insertions(+)
diff --git a/Tests/test_decompression_bomb.py b/Tests/test_decompression_bomb.py
index d918ef9..18fed06 100644
--- a/Tests/test_decompression_bomb.py
+++ b/Tests/test_decompression_bomb.py
@@ -62,6 +62,11 @@ class TestDecompressionBomb:
with Image.open("Tests/images/decompression_bomb.gif"):
pass
+ def test_exception_gif_extents(self):
+ with Image.open("Tests/images/decompression_bomb_extents.gif") as im:
+ with pytest.raises(Image.DecompressionBombError):
+ im.seek(1)
+
def test_exception_bmp(self):
with pytest.raises(Image.DecompressionBombError):
with Image.open("Tests/images/bmp/b/reallybig.bmp"):
diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py
index 8c2180b..04b567a 100644
--- a/src/PIL/GifImagePlugin.py
+++ b/src/PIL/GifImagePlugin.py
@@ -247,6 +247,7 @@ class GifImageFile(ImageFile.ImageFile):
x1, y1 = x0 + i16(s, 4), y0 + i16(s, 6)
if x1 > self.size[0] or y1 > self.size[1]:
self._size = max(x1, self.size[0]), max(y1, self.size[1])
+ Image._decompression_bomb_check(self._size)
self.dispose_extent = x0, y0, x1, y1
flags = s[8]
--
2.20.1

79
CVE-2022-45199.patch Normal file
View File

@ -0,0 +1,79 @@
From 9ae8f6b7aa8ea4638cb675267cd20c5425dcfafc Mon Sep 17 00:00:00 2001
From: qz_cx <wangqingzheng@kylinos.cn>
Date: Thu, 17 Nov 2022 10:28:59 +0800
Subject: [PATCH] Merge pull request #6700 from
hugovk/security-samples_per_pixel-sec
hugovk committed
Prevent DOS with large SAMPLESPERPIXEL in Tiff IFD
A large value in the SAMPLESPERPIXEL tag could lead to a memory and
runtime DOS in TiffImagePlugin.py when setting up the context for
image decoding.
---
Tests/test_file_tiff.py | 14 +++++++++++++-
src/PIL/TiffImagePlugin.py | 10 ++++++++++
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py
index 5801e17..57fabfa 100644
--- a/Tests/test_file_tiff.py
+++ b/Tests/test_file_tiff.py
@@ -3,7 +3,7 @@ from io import BytesIO
import pytest
-from PIL import Image, ImageFile, TiffImagePlugin
+from PIL import Image, ImageFile, TiffImagePlugin, UnidentifiedImageError
from PIL.TiffImagePlugin import RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION
from .helper import (
@@ -734,6 +734,18 @@ class TestFileTiff:
im.load()
ImageFile.LOAD_TRUNCATED_IMAGES = False
+ @pytest.mark.parametrize(
+ "test_file",
+ [
+ "Tests/images/oom-225817ca0f8c663be7ab4b9e717b02c661e66834.tif",
+ ],
+ )
+ @pytest.mark.timeout(2)
+ def test_oom(self, test_file):
+ with pytest.raises(UnidentifiedImageError):
+ with pytest.warns(UserWarning):
+ with Image.open(test_file):
+ pass
@pytest.mark.skipif(not is_win32(), reason="Windows only")
class TestFileTiffW32:
diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py
index 5df5c4f..f2afe63 100644
--- a/src/PIL/TiffImagePlugin.py
+++ b/src/PIL/TiffImagePlugin.py
@@ -252,6 +252,8 @@ OPEN_INFO = {
(MM, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"),
}
+MAX_SAMPLESPERPIXEL = max(len(key_tp[4]) for key_tp in OPEN_INFO.keys())
+
PREFIXES = [
b"MM\x00\x2A", # Valid TIFF header with big-endian byte order
b"II\x2A\x00", # Valid TIFF header with little-endian byte order
@@ -1310,6 +1312,14 @@ class TiffImageFile(ImageFile.ImageFile):
SAMPLESPERPIXEL,
3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1,
)
+
+ if samplesPerPixel > MAX_SAMPLESPERPIXEL:
+ # DOS check, samplesPerPixel can be a Long, and we extend the tuple below
+ logger.error(
+ "More samples per pixel than can be decoded: %s", samplesPerPixel
+ )
+ raise SyntaxError("Invalid value for samples per pixel")
+
if len(bps_tuple) != samplesPerPixel:
raise SyntaxError("unknown data organization")
--
2.33.0

161
CVE-2023-44271.patch Normal file
View File

@ -0,0 +1,161 @@
From 1fe1bb49c452b0318cad12ea9d97c3bef188e9a7 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Fri, 30 Jun 2023 23:32:26 +1000
Subject: [PATCH] Added ImageFont.MAX_STRING_LENGTH
---
Tests/test_imagefont.py | 21 +++++++++++++++++++++
docs/reference/ImageFont.rst | 18 ++++++++++++++++++
src/PIL/ImageFont.py | 16 ++++++++++++++++
3 files changed, 55 insertions(+)
diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py
index 0d423aa..5afa0bc 100644
--- a/Tests/test_imagefont.py
+++ b/Tests/test_imagefont.py
@@ -990,6 +990,27 @@ class TestImageFont:
assert_image_similar_tofile(im, "Tests/images/colr_bungee_mask.png", 22)
+ def test_too_many_characters(self):
+ font = self.get_font()
+ with pytest.raises(ValueError):
+ font.getlength("A" * 1000001)
+ with pytest.raises(ValueError):
+ font.getbbox("A" * 1000001)
+ with pytest.raises(ValueError):
+ font.getsize("A" * 1000001)
+ with pytest.raises(ValueError):
+ font.getoffset("A" * 1000001)
+ with pytest.raises(ValueError):
+ font.getmask2("A" * 1000001)
+
+ transposed_font = ImageFont.TransposedFont(font)
+ with pytest.raises(ValueError):
+ transposed_font.getsize("A" * 1000001)
+
+ default_font = ImageFont.load_default()
+ with pytest.raises(ValueError):
+ default_font.getsize("A" * 1000001)
+
@skip_unless_feature("raqm")
class TestImageFont_RaqmLayout(TestImageFont):
diff --git a/docs/reference/ImageFont.rst b/docs/reference/ImageFont.rst
index 5f718ce..12edaf9 100644
--- a/docs/reference/ImageFont.rst
+++ b/docs/reference/ImageFont.rst
@@ -18,6 +18,15 @@ OpenType fonts (as well as other font formats supported by the FreeType
library). For earlier versions, TrueType support is only available as part of
the imToolkit package.
+.. warning::
+ To protect against potential DOS attacks when using arbitrary strings as
+ text input, Pillow will raise a ``ValueError`` if the number of characters
+ is over a certain limit, :py:data:`MAX_STRING_LENGTH`.
+
+ This threshold can be changed by setting
+ :py:data:`MAX_STRING_LENGTH`. It can be disabled by setting
+ ``ImageFont.MAX_STRING_LENGTH = None``.
+
Example
-------
@@ -72,3 +81,12 @@ Constants
Requires Raqm, you can check support using
:py:func:`PIL.features.check_feature` with ``feature="raqm"``.
+
+Constants
+---------
+
+.. data:: MAX_STRING_LENGTH
+
+ Set to 1,000,000, to protect against potential DOS attacks. Pillow will
+ raise a ``ValueError`` if the number of characters is over this limit. The
+ check can be disabled by setting ``ImageFont.MAX_STRING_LENGTH = None``.
diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py
index 805c8ff..e0b7167 100644
--- a/src/PIL/ImageFont.py
+++ b/src/PIL/ImageFont.py
@@ -43,12 +43,21 @@ class _imagingft_not_installed:
raise ImportError("The _imagingft C module is not installed")
+MAX_STRING_LENGTH = 1000000
+
+
try:
from . import _imagingft as core
except ImportError:
core = _imagingft_not_installed()
+def _string_length_check(text):
+ if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
+ msg = "too many characters in string"
+ raise ValueError(msg)
+
+
# FIXME: add support for pilfont2 format (see FontFile.py)
# --------------------------------------------------------------------
@@ -125,6 +134,7 @@ class ImageFont:
:return: (width, height)
"""
+ _string_length_check(text)
return self.font.getsize(text)
def getmask(self, text, mode="", *args, **kwargs):
@@ -297,6 +307,7 @@ class FreeTypeFont:
:return: Width for horizontal, height for vertical text.
"""
+ _string_length_check(text)
return self.font.getlength(text, mode, direction, features, language) / 64
def getbbox(
@@ -356,6 +367,7 @@ class FreeTypeFont:
:return: ``(left, top, right, bottom)`` bounding box
"""
+ _string_length_check(text)
size, offset = self.font.getsize(
text, mode, direction, features, language, anchor
)
@@ -418,6 +430,7 @@ class FreeTypeFont:
"""
# vertical offset is added for historical reasons
# see https://github.com/python-pillow/Pillow/pull/4910#discussion_r486682929
+ _string_length_check(text)
size, offset = self.font.getsize(text, "L", direction, features, language)
return (
size[0] + stroke_width * 2,
@@ -494,6 +507,7 @@ class FreeTypeFont:
:return: A tuple of the x and y offset
"""
+ _string_length_check(text)
return self.font.getsize(text)[1]
def getmask(
@@ -655,6 +669,7 @@ class FreeTypeFont:
:py:mod:`PIL.Image.core` interface module, and the text offset, the
gap between the starting coordinate and the first marking
"""
+ _string_length_check(text)
size, offset = self.font.getsize(
text, mode, direction, features, language, anchor
)
@@ -758,6 +773,7 @@ class TransposedFont:
self.orientation = orientation # any 'transpose' argument, or None
def getsize(self, text, *args, **kwargs):
+ _string_length_check(text)
w, h = self.font.getsize(text)
if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
return h, w
--
2.33.0

119
CVE-2023-50447.patch Normal file
View File

@ -0,0 +1,119 @@
Origin: https://github.com/python-pillow/Pillow/pull/7655
From 45c726fd4daa63236a8f3653530f297dc87b160a Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Fri, 27 Oct 2023 11:21:18 +0200
Subject: [PATCH 1/3] Don't allow __ or builtins in env dictionarys for
ImageMath.eval
---
src/PIL/ImageMath.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/PIL/ImageMath.py b/src/PIL/ImageMath.py
index 7ca512e7568..cf108e2586f 100644
--- a/src/PIL/ImageMath.py
+++ b/src/PIL/ImageMath.py
@@ -237,6 +237,10 @@ def eval(expression, _dict={}, **kw):
args.update(_dict)
args.update(kw)
- for k, v in list(args.items()):
+ for k, v in args.items():
+ if '__' in k or hasattr(__builtins__, k):
+ msg = f"'{k}' not allowed"
+ raise ValueError(msg)
+
if hasattr(v, "im"):
args[k] = _Operand(v)
From 0ca3c33c59927e1c7e0c14dbc1eea1dfb2431a80 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Sat, 28 Oct 2023 15:58:52 +1100
Subject: [PATCH 2/3] Allow ops
---
Tests/test_imagemath.py | 5 +++++
src/PIL/ImageMath.py | 9 +++++----
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/Tests/test_imagemath.py b/Tests/test_imagemath.py
index 22de86c7cab..9a0326ece3b 100644
--- a/Tests/test_imagemath.py
+++ b/Tests/test_imagemath.py
@@ -64,6 +64,11 @@ def test_prevent_exec(expression):
ImageMath.eval(expression)
+def test_prevent_double_underscores():
+ with pytest.raises(ValueError):
+ ImageMath.eval("1", {"__": None})
+
+
def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2"
diff --git a/src/PIL/ImageMath.py b/src/PIL/ImageMath.py
index cf108e2586f..fd7d78d4583 100644
--- a/src/PIL/ImageMath.py
+++ b/src/PIL/ImageMath.py
@@ -234,13 +234,14 @@ def eval(expression, _dict={}, **kw):
# build execution namespace
args = ops.copy()
- args.update(_dict)
- args.update(kw)
- for k, v in args.items():
- if '__' in k or hasattr(__builtins__, k):
+ for k in list(_dict.keys()) + list(kw.keys()):
+ if "__" in k or hasattr(__builtins__, k):
msg = f"'{k}' not allowed"
raise ValueError(msg)
+ args.update(_dict)
+ args.update(kw)
+ for k, v in args.items():
if hasattr(v, "im"):
args[k] = _Operand(v)
From 557ba59d13de919d04b3fd4cdef8634f7d4b3348 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Sat, 30 Dec 2023 09:30:12 +1100
Subject: [PATCH 3/3] Include further builtins
---
Tests/test_imagemath.py | 5 +++++
docs/releasenotes/10.2.0.rst | 9 ++++++---
src/PIL/ImageMath.py | 2 +-
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/Tests/test_imagemath.py b/Tests/test_imagemath.py
index 9a0326ece3b..9281de6f66a 100644
--- a/Tests/test_imagemath.py
+++ b/Tests/test_imagemath.py
@@ -69,6 +69,11 @@ def test_prevent_double_underscores():
ImageMath.eval("1", {"__": None})
+def test_prevent_builtins():
+ with pytest.raises(ValueError):
+ ImageMath.eval("(lambda: exec('exit()'))()", {"exec": None})
+
+
def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2"
diff --git a/src/PIL/ImageMath.py b/src/PIL/ImageMath.py
index fd7d78d4583..b77f4bce567 100644
--- a/src/PIL/ImageMath.py
+++ b/src/PIL/ImageMath.py
@@ -235,7 +235,7 @@ def eval(expression, _dict={}, **kw):
# build execution namespace
args = ops.copy()
for k in list(_dict.keys()) + list(kw.keys()):
- if "__" in k or hasattr(__builtins__, k):
+ if "__" in k or hasattr(builtins, k):
msg = f"'{k}' not allowed"
raise ValueError(msg)

55
CVE-2024-28219.patch Normal file
View File

@ -0,0 +1,55 @@
From 2a93aba5cfcf6e241ab4f9392c13e3b74032c061 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Thu, 22 Feb 2024 18:56:26 +1100
Subject: [PATCH] Use strncpy to avoid buffer overflow
Origin: https://github.com/python-pillow/Pillow/commit/2a93aba5cfcf6e241ab4f9392c13e3b74032c061
---
Tests/icc/sGrey-v2-nano.icc | Bin 0 -> 290 bytes
Tests/test_imagecms.py | 5 +++++
src/_imagingcms.c | 9 ++++-----
3 files changed, 9 insertions(+), 5 deletions(-)
create mode 100644 Tests/icc/sGrey-v2-nano.icc
diff --git a/Tests/test_imagecms.py b/Tests/test_imagecms.py
index c80fab75b67..fbd78032e59 100644
--- a/Tests/test_imagecms.py
+++ b/Tests/test_imagecms.py
@@ -593,3 +593,8 @@
)
assert_image_equal(test_image.convert(dst_format[2]), reference_image)
+
+
+def test_long_modes() -> None:
+ p = ImageCms.getOpenProfile("Tests/icc/sGrey-v2-nano.icc")
+ ImageCms.buildTransform(p, p, "ABCDEFGHI", "ABCDEFGHI")
diff --git a/src/_imagingcms.c b/src/_imagingcms.c
index 4d66dcc1085..84b8a7e71f9 100644
--- a/src/_imagingcms.c
+++ b/src/_imagingcms.c
@@ -201,8 +201,8 @@ cms_transform_new(cmsHTRANSFORM transform, char *mode_in, char *mode_out) {
self->transform = transform;
- strcpy(self->mode_in, mode_in);
- strcpy(self->mode_out, mode_out);
+ strncpy(self->mode_in, mode_in, 8);
+ strncpy(self->mode_out, mode_out, 8);
return (PyObject *)self;
}
@@ -242,10 +242,9 @@ findLCMStype(char *PILmode) {
// LabX equivalent like ALab, but not reversed -- no #define in lcms2
return (COLORSPACE_SH(PT_LabV2) | CHANNELS_SH(3) | BYTES_SH(1) | EXTRA_SH(1));
}
-
else {
- /* take a wild guess... but you probably should fail instead. */
- return TYPE_GRAY_8; /* so there's no buffer overrun... */
+ /* take a wild guess... */
+ return TYPE_GRAY_8;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

View File

@ -5,16 +5,25 @@
Name: python-pillow
Version: 9.0.1
Release: 2
Release: 7
Summary: Python image processing library
License: MIT
URL: http://python-pillow.github.io/
Source0: https://github.com/python-pillow/Pillow/archive/%{version}/Pillow-%{version}.tar.gz
Source1: oom-225817ca0f8c663be7ab4b9e717b02c661e66834.tif
# https://github.com/python-pillow/Pillow/blob/c9f1b35/Tests/images/decompression_bomb_extents.gif
Source2: decompression_bomb_extents.gif
# https://github.com/python-pillow/Pillow/blob/2a93aba/Tests/icc/sGrey-v2-nano.icc
Source3: sGrey-v2-nano.icc
Patch0: python-pillow_spinxwarn.patch
Patch1: python-pillow_sphinx-issues.patch
Patch6000: backport-Corrected-memory-allocation.patch
Patch0000: python-pillow_spinxwarn.patch
Patch0001: python-pillow_sphinx-issues.patch
Patch0002: backport-Corrected-memory-allocation.patch
Patch0003: CVE-2022-45199.patch
Patch0004: CVE-2023-44271.patch
Patch0005: CVE-2022-45198.patch
Patch0006: CVE-2023-50447.patch
Patch0007: CVE-2024-28219.patch
BuildRequires: freetype-devel ghostscript lcms2-devel libimagequant-devel libjpeg-devel libtiff-devel
BuildRequires: libwebp-devel openjpeg2-devel tk-devel zlib-devel python3-cffi python3-devel python3-numpy python3-olefile
@ -96,6 +105,9 @@ Qt pillow image wrapper.
%autosetup -p1 -n Pillow-%{version}
%build
cp %{SOURCE1} Tests/images/
cp %{SOURCE2} Tests/images/
cp %{SOURCE3} Tests/icc/
%py3_build
@ -152,6 +164,27 @@ pytest --ignore=_build.python2 --ignore=_build.python3 --ignore=_build.pypy3 -v
%{python3_sitearch}/PIL/__pycache__/ImageQt*
%changelog
* Sun Apr 07 2024 wangkai <13474090681@163.com> - 9.0.1-7
- Fix CVE-2024-28219
* Wed Jan 24 2024 wangkai <13474090681@163.com> - 9.0.1-6
- Fix CVE-2023-50447
* Thu Dec 07 2023 wangkai <13474090681@163.com> - 9.0.1-5
- Fix CVE-2022-45198
* Tue Nov 14 2023 hanhuihui <hanhuihui5@huawei.com> - 9.0.1-4
- Type:CVE
- ID:NA
- SUG:NA
- DESC: fix CVE-2023-44271
* Thu Nov 17 2022 qz_cx <wangqingzheng@kylinos.cn> - 9.0.1-3
- Type:CVE
- ID:NA
- SUG:NA
- DESC: fix CVE-2022-45199
* Wed Apr 20 2022 dongyuzhen <dongyuzhen@h-partners.com> - 9.0.1-2
- correct memory allocation in alloc_array (this is the rear patch of CVE-2022-22815,CVE-2022-22816)

BIN
sGrey-v2-nano.icc Normal file

Binary file not shown.