mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	Merge pull request #6700 from hugovk/security-samples_per_pixel-sec
This commit is contained in:
		
						commit
						2444cddab2
					
				
							
								
								
									
										
											BIN
										
									
								
								Tests/images/oom-225817ca0f8c663be7ab4b9e717b02c661e66834.tif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/oom-225817ca0f8c663be7ab4b9e717b02c661e66834.tif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -4,7 +4,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 (
 | 
			
		||||
| 
						 | 
				
			
			@ -858,6 +858,19 @@ 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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,15 @@ decode the data in its natural CMYK mode, then convert it to RGB and rearrange
 | 
			
		|||
the channels afterwards. Trying to load the data in an incorrect mode could
 | 
			
		||||
result in a segmentation fault. This issue was introduced in Pillow 9.1.0.
 | 
			
		||||
 | 
			
		||||
Limit SAMPLESPERPIXEL to avoid runtime DOS
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
This was introduced in Pillow 9.2.0, found with `OSS-Fuzz`_ and fixed by limiting
 | 
			
		||||
``SAMPLESPERPIXEL`` to the number of planes that we can decode.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Other Changes
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -88,3 +97,5 @@ Show all frames with ImageShow
 | 
			
		|||
 | 
			
		||||
When calling :py:meth:`~PIL.Image.Image.show` or using
 | 
			
		||||
:py:mod:`~PIL.ImageShow`, all frames will now be shown.
 | 
			
		||||
 | 
			
		||||
.. _OSS-Fuzz: https://github.com/google/oss-fuzz
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -257,6 +257,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1396,6 +1398,14 @@ class TiffImageFile(ImageFile.ImageFile):
 | 
			
		|||
            SAMPLESPERPIXEL,
 | 
			
		||||
            3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if samples_per_pixel > MAX_SAMPLESPERPIXEL:
 | 
			
		||||
            # DOS check, samples_per_pixel can be a Long, and we extend the tuple below
 | 
			
		||||
            logger.error(
 | 
			
		||||
                "More samples per pixel than can be decoded: %s", samples_per_pixel
 | 
			
		||||
            )
 | 
			
		||||
            raise SyntaxError("Invalid value for samples per pixel")
 | 
			
		||||
 | 
			
		||||
        if samples_per_pixel < bps_actual_count:
 | 
			
		||||
            # If a file has more values in bps_tuple than expected,
 | 
			
		||||
            # remove the excess.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user