Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught Exception(s) in Pillow Library #7876

Closed
fatihhcelik opened this issue Mar 13, 2024 · 3 comments · Fixed by #7883
Closed

Uncaught Exception(s) in Pillow Library #7876

fatihhcelik opened this issue Mar 13, 2024 · 3 comments · Fixed by #7883

Comments

@fatihhcelik
Copy link

What did you do?

We (@DogukanK, @esraercann) discovered a 3 crashes in Python Pillow library because of 'Uncaught Exception' via specially crafted input.

What did you expect to happen?

Exceptions should be handled properly in Pillow.

What actually happened?

Crash.

  • Here is the first crash log:
=== Uncaught Python exception: ===

error: argument out of range

Traceback (most recent call last):

 File "/home/ubuntu/targets/pillow/main.py", line 20, in TestOneInput

   pilfuzz(data)

 File "/home/ubuntu/targets/pillow/main.py", line 11, in pilfuzz

   out = im.transpose(Image.Transpose.FLIP_LEFT_RIGHT)

 File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 2807, in transpose

   def transpose(self, method):

 File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/ImageFile.py", line 266, in load

   err_code = decoder.decode(b"")[1]

 File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/PpmImagePlugin.py", line 273, in decode

   data = self._decode_blocks(maxval)

 File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/PpmImagePlugin.py", line 261, in _decode_blocks

   data += o32(value) if self.mode == "I" else o8(value)

 File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/_binary.py", line 93, in o32le

   def o32le(i: int) -> bytes:

error: argument out of range

Poc:

>>> from PIL import Image                                                                                                                                     

>>> im = Image.open("./crash-4148ce4324e2e54cc3c2c6aa369420ddbd9dee5e")

>>> im.transpose(Image.Transpose.FLIP_LEFT_RIGHT)                                                                                                             

Traceback (most recent call last):                                               

  File "<stdin>", line 1, in <module>                                                                                                                              

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 2818, in transpose                                                                    

    self.load()                                                                                                                                                    

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/ImageFile.py", line 266, in load                                                                      

    err_code = decoder.decode(b"")[1]                                            

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/PpmImagePlugin.py", line 273, in decode                                                               

    data = self._decode_blocks(maxval)                                           

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/PpmImagePlugin.py", line 261, in _decode_blocks

    data += o32(value) if self.mode == "I" else o8(value)                                                                                                          

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/_binary.py", line 94, in o32le                                                                        

    return pack("<I", i)                                                         

struct.error: argument out of range 
  • Here is the second crash:
>>> from PIL import Image, ImageFilter

>>> im = Image.open("./crash-73c3d4dca546775e83ea511a0fc882f3c5b6f60a")

>>> im.filter(ImageFilter.DETAIL)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 1281, in filter

    self.load()

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/GbrImagePlugin.py", line 94, in load

    self.frombytes(self.fp.read(self._data_size))

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 810, in frombytes

    d.setimage([self.im](http://self.im/))

MemoryError
  • Here is the third crash:
=== Uncaught Python exception: ===

OverflowError: Python int too large to convert to C ssize_t

Traceback (most recent call last):

  File "/home/ubuntu/targets/pillow/main.py", line 16, in TestOneInput

    pilfuzz(data)

  File "/home/ubuntu/targets/pillow/main.py", line 10, in pilfuzz

    with Image.open(io.BytesIO(data)) as im:

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 3258, in open

    preinit()

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 3273, in _open_core

    fp.seek(0)

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/TiffImagePlugin.py", line 1082, in __init__

    super().__init__(fp, filename)

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/ImageFile.py", line 137, in __init__

    self._open()

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/TiffImagePlugin.py", line 1109, in _open

    self._seek(0)

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/TiffImagePlugin.py", line 1150, in _seek

    self.fp.seek(self.__next)

OverflowError: Python int too large to convert to C ssize_t

PoC:

Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux                                                                                  

Type "help", "copyright", "credits" or "license" for more information.                                                                                          

>>> from PIL import Image                                                                                                                              

>>> im = Image.open("./crash-ecd6f7d1583338a2a2c4aaee944b0b3371f4f926")                                                                                

Traceback (most recent call last):                                              

  File "<stdin>", line 1, in <module>                                           

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 3293, in open                                                             

    im = _open_core(                    

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/Image.py", line 3274, in _open_core                                                       

    im = factory(fp, filename)          

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/TiffImagePlugin.py", line 1082, in __init__                                               

    super().__init__(fp, filename)                                              

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/ImageFile.py", line 137, in __init__                                                      

    self._open()                        

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/TiffImagePlugin.py", line 1109, in _open                                                  

    self._seek(0)                       

  File "/home/ubuntu/.local/lib/python3.10/site-packages/PIL/TiffImagePlugin.py", line 1150, in _seek                                                  

    self.fp.seek(self.__next)           

ValueError: cannot fit 'int' into an offset-sized integer

What are your OS, Python and Pillow versions?

  • Python3 Version: Python 3.10.12
  • PIL Version: 10.2.0
  • OS: Ubuntu 22.04.3 LTS 5.15.0-84-generic x86/64

Crash Files

Archive.zip

@radarhere
Copy link
Member

radarhere commented Mar 13, 2024

Looking at your second situation, I see it is hitting

Pillow/src/decode.c

Lines 194 to 198 in 9e3d1a7

/* Allocate memory buffer (if bits field is set) */
if (state->bits > 0) {
if (!state->bytes) {
if (state->xsize > ((INT_MAX / state->bits) - 7)) {
return ImagingError_MemoryError();

You are trying to create an image that is 134,217,792px wide, greater than the limit in that logic of 67,108,856px wide.

So that's not an unexpected exception, that's something we're deliberately raising.

@wiredfool
Copy link
Member

The first one was sent to security@. The error for that one is raised by python core, and isn't an issue unless valgrind finds memory corruption, and since that's directly in python core, it would be a bug for them.

@radarhere
Copy link
Member

radarhere commented Mar 16, 2024

I've created #7882 for the first situation, as that is similar to another error that we already catch.

I've created #7883 for the third situation. I'm not highly convinced of the need for this change, but it at least documents in our code that this may happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants