Skip to content

Commit 13f2c5a

Browse files
wiredfoolhugovk
authored andcommitted
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.
1 parent e055ef0 commit 13f2c5a

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed
Binary file not shown.

Tests/test_file_tiff.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import pytest
66

7-
from PIL import Image, ImageFile, TiffImagePlugin
7+
from PIL import Image, ImageFile, TiffImagePlugin, UnidentifiedImageError
88
from PIL.TiffImagePlugin import RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION
99

1010
from .helper import (
@@ -858,6 +858,19 @@ def test_timeout(self):
858858
im.load()
859859
ImageFile.LOAD_TRUNCATED_IMAGES = False
860860

861+
@pytest.mark.parametrize(
862+
"test_file",
863+
[
864+
"Tests/images/oom-225817ca0f8c663be7ab4b9e717b02c661e66834.tif",
865+
],
866+
)
867+
@pytest.mark.timeout(2)
868+
def test_oom(self, test_file):
869+
with pytest.raises(UnidentifiedImageError):
870+
with Image.open(test_file) as im:
871+
im.load()
872+
873+
861874

862875
@pytest.mark.skipif(not is_win32(), reason="Windows only")
863876
class TestFileTiffW32:

src/PIL/TiffImagePlugin.py

+8
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@
257257
(MM, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"),
258258
}
259259

260+
MAX_SAMPLESPERPIXEL = max(len(key_tp[4]) for key_tp in OPEN_INFO.keys())
261+
260262
PREFIXES = [
261263
b"MM\x00\x2A", # Valid TIFF header with big-endian byte order
262264
b"II\x2A\x00", # Valid TIFF header with little-endian byte order
@@ -1396,6 +1398,12 @@ def _setup(self):
13961398
SAMPLESPERPIXEL,
13971399
3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1,
13981400
)
1401+
1402+
if samples_per_pixel > MAX_SAMPLESPERPIXEL:
1403+
# DOS check, samples_per_pixel can be a Long, and we extend the tuple below
1404+
logger.error("More samples per pixel than can be decoded: %s", samples_per_pixel)
1405+
raise SyntaxError("Invalid value for samples per pixel")
1406+
13991407
if samples_per_pixel < bps_actual_count:
14001408
# If a file has more values in bps_tuple than expected,
14011409
# remove the excess.

0 commit comments

Comments
 (0)