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

Segmentation Fault on a PCD image #568

Closed
lehins opened this issue Mar 25, 2014 · 17 comments
Closed

Segmentation Fault on a PCD image #568

lehins opened this issue Mar 25, 2014 · 17 comments
Labels
Bug Any unexpected behavior, until confirmed feature.
Milestone

Comments

@lehins
Copy link

lehins commented Mar 25, 2014

Here is a link to the file that causes the problem: http://526ddd950476442e0e6c-adab491b4c7746bcac4e5a193c3c94e6.r70.cf1.rackcdn.com/golden.pcd
This file was created using 'convert', so it might not have proper formatting/header or whatever else, but it most definitely shouldn't cause a seg fault.

i = Image.open('golden.pcd') 
i.resize(new_dim) # crashes here or upon any other operation

Let me know if any other info is needed.
A fix for this error is not crucial for me, just want to help make this library even better.

@wiredfool
Copy link
Member

Ok, that's weird. The backtrace I'm getting is entirely python code.

(vpy32-dbg)erics:~/pcd$ gdb python
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/erics/vpy32-dbg/bin/python...done.
(gdb) r test.py
Starting program: /home/erics/vpy32-dbg/bin/python test.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
* ob
object  : <refcnt 0 at 0xec4588>
type    : builtin_function_or_method
refcount: 0
address : 0xec4588
* op->_ob_prev->_ob_next
object  : <refcnt 0 at 0xec4588>
type    : builtin_function_or_method
refcount: 0
address : 0xec4588
* op->_ob_next->_ob_prev
object  : 
Program received signal SIGSEGV, Segmentation fault.
0x000000000041ba96 in PyObject_Print (op=0xad846700ad8461, fp=0x7ffff6a3a180, flags=0) at ../Objects/object.c:279
279 ../Objects/object.c: No such file or directory.
(gdb) bt
#0  0x000000000041ba96 in PyObject_Print (op=0xad846700ad8461, fp=0x7ffff6a3a180, flags=0) at ../Objects/object.c:279
#1  0x000000000041bec7 in _PyObject_Dump (op=0xad846700ad8461) at ../Objects/object.c:351
#2  0x000000000041f437 in _Py_ForgetReference (op=0xec4588) at ../Objects/object.c:1676
#3  0x000000000041f494 in _Py_Dealloc (op=0xec4588) at ../Objects/object.c:1697
#4  0x000000000048ebb6 in call_function (pp_stack=0x7fffffffbcf0, oparg=1) at ../Python/ceval.c:3955
#5  0x0000000000488f43 in PyEval_EvalFrameEx (f=0xf36230, throwflag=0) at ../Python/ceval.c:2692
#6  0x000000000048ed7f in fast_function (func=0xc4ff78, pp_stack=0x7fffffffc880, n=1, na=1, nk=0) at ../Python/ceval.c:4009
#7  0x000000000048ea74 in call_function (pp_stack=0x7fffffffc880, oparg=0) at ../Python/ceval.c:3942
#8  0x0000000000488f43 in PyEval_EvalFrameEx (f=0xf35fe0, throwflag=0) at ../Python/ceval.c:2692
#9  0x000000000048c99f in PyEval_EvalCodeEx (_co=0x7ffff61096b8, globals=0xb4cf80, locals=0x0, args=0xaad858, argcount=2, 
    kws=0xaad868, kwcount=0, defs=0xc391d8, defcount=1, kwdefs=0x0, closure=0x0) at ../Python/ceval.c:3350
#10 0x000000000048eea9 in fast_function (func=0xc3a3f8, pp_stack=0x7fffffffd580, n=2, na=2, nk=0) at ../Python/ceval.c:4019
#11 0x000000000048ea74 in call_function (pp_stack=0x7fffffffd580, oparg=1) at ../Python/ceval.c:3942
#12 0x0000000000488f43 in PyEval_EvalFrameEx (f=0xaad6d0, throwflag=0) at ../Python/ceval.c:2692
#13 0x000000000048c99f in PyEval_EvalCodeEx (_co=0x7ffff7e64b08, globals=0xa251d0, locals=0xa251d0, args=0x0, argcount=0, kws=0x0, 
    kwcount=0, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0) at ../Python/ceval.c:3350
#14 0x000000000047c937 in PyEval_EvalCode (co=0x7ffff7e64b08, globals=0xa251d0, locals=0xa251d0) at ../Python/ceval.c:767
#15 0x00000000004c2bea in run_mod (mod=0xb4f178, filename=0x7ffff7f17800 "test.py", globals=0xa251d0, locals=0xa251d0, 
    flags=0x7fffffffe460, arena=0xa30da0) at ../Python/pythonrun.c:1810
#16 0x00000000004c29dc in PyRun_FileExFlags (fp=0xaabf30, filename=0x7ffff7f17800 "test.py", start=257, globals=0xa251d0, 
    locals=0xa251d0, closeit=1, flags=0x7fffffffe460) at ../Python/pythonrun.c:1767
#17 0x00000000004c0e39 in PyRun_SimpleFileExFlags (fp=0xaabf30, filename=0x7ffff7f17800 "test.py", closeit=1, flags=0x7fffffffe460)
    at ../Python/pythonrun.c:1292
#18 0x00000000004c020f in PyRun_AnyFileExFlags (fp=0xaabf30, filename=0x7ffff7f17800 "test.py", closeit=1, flags=0x7fffffffe460)
    at ../Python/pythonrun.c:1061
#19 0x00000000004dc309 in run_file (fp=0xaabf30, filename=0x7ffff7fa5040 L"test.py", p_cf=0x7fffffffe460) at ../Modules/main.c:307
#20 0x00000000004dcfca in Py_Main (argc=2, argv=0x7ffff7fa3040) at ../Modules/main.c:733
#21 0x000000000041b640 in main (argc=2, argv=0x7fffffffe5d8) at ../Modules/python.c:63
(gdb) 

I'm seeing it on multiple python versions, multiple versions of Pillow.

@wiredfool wiredfool added the bug label Mar 25, 2014
@aclark4life aclark4life added this to the 2.4.0 milestone Mar 25, 2014
@aclark4life
Copy link
Member

@lehins Thanks for reporting

@aclark4life
Copy link
Member

I'm currently targeting 2.4.0 for this, though I expect we may not get to it.

@aclark4life aclark4life modified the milestones: Future, 2.4.0 Mar 30, 2014
@wiredfool
Copy link
Member

Ok. This is still weird. I've thrown this at Fedora 20, where GDB is better integrated with the python runtime. It's failing in ImageFile.load:

                    b = b + s
                    n, e = d.decode(b)
                    if n < 0:
                        break
                    # UNDONE gdb locals, just for yucks.                                
                    lb = len(b) #dbg
                    ls = len(s) #dbg
                    assert(n<lb) #added for dbg
                    b = b[n:]  #Fails here. 
                    t = t + n

n = 64512, len(b) == 66560. It's the second time through, so b == ~1k from the first round, and 64k from this read, and we're indexing for the last 2k. This seems entirely reasonable to me. The only thing that I can think of is that the decode must be messing with the buffer, but that doesn't seem to be the case.

Detailed traces &c follow.

Py-bt is really short:

(gdb) py-bt
Traceback (most recent call first):
  File "/home/erics/vpy33-dbg/lib/python3.3/site-packages/Pillow-2.3.0-py3.3-linux-x86_64.egg/PIL/ImageFile.py", line 228, in load
  File "/home/erics/vpy33-dbg/lib/python3.3/site-packages/Pillow-2.3.0-py3.3-linux-x86_64.egg/PIL/Image.py", line 1347, in resize
  File "test.py", line 3, in <module>
    im.resize((512,384))

The locals from the current python frame:

(gdb) py-locals
self = <PcdImageFile(decodermaxblock=65536, map=None, pyaccess=None, category=0, filename='golden.pcd', im=<ImagingCore at remote 0x7fffefbf6db0>, mode='RGB', tile=[('pcd', (0, 0, 768, 512), 196608, None)], decoderconfig=(), palette=None, info={}, size=(768, 512), readonly=1, fp=<_io.BufferedReader at remote 0x7fffefd567a0>) at remote 0x7ffff0335a70>
pixel = None
readonly = 0
d = <ImagingDecoder at remote 0x7fffedca19e0>
e = 0
o = 196608
a = None
read = <built-in method read of _io.BufferedReader object at remote 0x7fffefd567a0>
seek = <built-in method seek of _io.BufferedReader object at remote 0x7fffefd567a0>
prefix = b''
b = b']]aaaaaa```_abbbbbbaabacddddcddeefeffffgfhihhhhhhhhhiiiiiikllllmnmmmmmmmmmlmmmmmnnnnnnoqrrrrrrqqqqsssstttstttstutuvutuvuuuuvvvwwwwwwwxyyyyyyyyyz{{||}}}}}}~~}~}~\x7f~~~~\x81\x81\x81\x82\x81\x81\x81\x82\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x80\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x80\x80\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x81\x83\x81\x80\x80\x80~\x7f\x7f\x7f\x80\x82\x89\x8e\x90\x8f\x8f\x91\x93\x92\x8e\x8c\x88\x85\x85\x8a\x90\x93\x93\x8f\x8b\x88\x8d\x8f\x8c\x89\x88\x88\x87\x88\x85\x80\x83\x82{yzz|\x82\x84\x87\x8b\x95\xa1\xac\xbb\xbe\xbb\xb7\xb5\xb1\xae\xaf\xab\xa1\xa2\xa8\xa4\x9b\x91\x91\x93\x95\x98\xa4\xab\xac\xae\xb3\xb8\xbc\xc2\xc6\xc6\xc2\xc1\xbf\xba\xb8\xb5\xb2\xad\xa8\xa4\xa4\xa4\xa0\x9f\xa0\x9f\x95\x8d\x8b\x88\x85\x82\x81\x88\x8a\x89\x86\x87\x99\xac\xaa\x9f\x9a\x95\x97\x9f\xa1\x9d...(truncated)
t = 64512
s = b'\x7f\x7f\x7f~\x7f\x80\x7f~\x7f\x80~~\x7f~~\x7f\x86\x8c\x8f\x90\x92\x99\x9a\x92\x8e\x8c\x8b\x87\x86\x8a\x8e\x8e\x8f\x90\x8b\x85\x84\x87\x8a\x8b\x87\x89\x84\x80~|~~}yvwz\x82\x85\x88\x90\x9c\xb0\xbf\xc8\xc6\xbf\xbc\xbe\xbb\xb9\xaf\xa8\xac\xb5\xba\xaf\xa0\x90\x8b\x8a\x91\x99\xa2\xa5\xa6\xac\xb2\xba\xc2\xc6\xc6\xc4\xc6\xc4\xc2\xbe\xbc\xbb\xb7\xb5\xb3\xae\xae\xab\xa2\x9f\x9d\x9b\x95\x8f\x8d\x90\x8f\x91\x96\x9b\x9d\x8f\x85\x80\x91\xa1\xa8\xa2\x8e\x8b\x93\x9c\x9f\x9b\x9b\xae\xbb\xbd\xc1\xc0\xc0\xca\xd2\xd3\xd4\xd4\xd3\xcd\xc8\xc1\xc1\xc6\xcc\xc8\xc1\xb6\xae\xad\xae\xb1\xb4\xb6\xbb\xc1\xc9\xcf\xd6\xda\xde\xdd\xda\xd7\xd7\xdb\xe0\xe4\xe3\xe3\xe2\xe1\xe1\xe3\xe6\xe8\xe6\xe5\xe3\xe3\xe6\xe9\xea\xea\xea\xea\xea\xea\xea\xeb\xeb\xea\xe7\xe6\xe5\xe4\xe3\xe1\xdf\xde\xe0\xe2\xe6\xe8\xe8\xe9\xea\xea\xea\xea\xe9\xe7\xe7\xe7\xe7\xe8\xe8\xe8\xe7\xe7\xe8\xea\xea\xea\xea\xe9\xea\xe8\xe6\xe1\xde\xda\xd7\xd8\xd3\xcf\xd0\xd2\xd6\xd9\xd8\xd7\xd7\xd3\xcf\xd2\xd2\xc9\xc8\xcc\xc7\xbe\xbd\xb7\xac\xae\xaf\xa1\x98\x93\x8a\x84\x81}{yzyy{zz{z...(truncated)
n = 64512
lb = 66560
ls = 65536
(gdb) 

Full bt, truncated to the call to Image.resize

(gdb) bt
#0  _int_malloc (av=0x7ffff6fab760 <main_arena>, bytes=2129) at malloc.c:3645
#1  0x00007ffff6c72f6c in __GI___libc_malloc (bytes=2129) at malloc.c:2859
#2  0x00007ffff799a3e4 in PyObject_Malloc (nbytes=nbytes@entry=2129)
    at /usr/src/debug/Python-3.3.2/Objects/obmalloc.c:961
#3  0x00007ffff799ab54 in _PyObject_DebugMallocApi (id=id@entry=111 'o', 
    nbytes=nbytes@entry=2097) at /usr/src/debug/Python-3.3.2/Objects/obmalloc.c:1467
#4  0x00007ffff799ac1d in _PyObject_DebugMalloc (nbytes=nbytes@entry=2097)
    at /usr/src/debug/Python-3.3.2/Objects/obmalloc.c:1434
#5  0x00007ffff79513f2 in PyBytes_FromStringAndSize (
    str=0x7f1330 "giiiiiiiijjjjkkjkjjjjllklmlkmnmlllmmmnnnnoopqqrsrrrrrssrrrstttuuuuuuuv", 'w' <repeats 14 times>, "xxx", 'y' <repeats 11 times>, "zzzzzzzyyyz{{{{|}|{{{~\200\201\201\201\201\201\201\201\201\201", '\202' <repeats 14 times>, "\205\205\205\204\204\204\205\205", '\206' <repeats 11 times>, "\205\206\210\210\211\210\210\207\207\210\215\223\226\234\236\235\240\233\230\232\234\233\230\226\221\216\226\233\226\226\233\235\233\236\241\244\247"..., size=2048) at /usr/src/debug/Python-3.3.2/Objects/bytesobject.c:98
#6  0x00007ffff79553a1 in bytes_subscript (self=0x7e1700, item=<optimized out>)
    at /usr/src/debug/Python-3.3.2/Objects/bytesobject.c:914
#7  0x00007ffff7a28e50 in PyEval_EvalFrameEx (
    f=f@entry=Frame 0x841d10, for file /home/erics/vpy33-dbg/lib/python3.3/site-packages/Pillow-2.3.0-py3.3-linux-x86_64.egg/PIL/ImageFile.py, line 228, in load (self=<PcdImageFile(decodermaxblock=65536, map=None, pyaccess=None, category=0, filename='golden.pcd', im=<ImagingCore at remote 0x7fffefbf6db0>, mode='RGB', tile=[('pcd', (0, 0, 768, 512), 196608, None)], decoderconfig=(), palette=None, info={}, size=(768, 512), readonly=1, fp=<_io.BufferedReader at remote 0x7fffefd567a0>) at remote 0x7ffff0335a70>, pixel=None, readonly=0, d=<ImagingDecoder at remote 0x7fffedca19e0>, e=0, o=196608, a=None, read=<built-in method read of _io.BufferedReader object at remote 0x7fffefd567a0>, seek=<built-in method seek of _io.BufferedReader object at remote 0x7fffefd567a0>, prefix=b'', b=b']]aaaaaa```_abbbbbbaabacddddcddeefeffffgfhihhhhhhhhhiiiiiikllllmnmmmmmmmmmlmmmmmnnnnnnoqrrrrrrqqqqsssstttstttstutuvutuvuuuuvvvwwwwwwwxyyyyyyyyyz{{||}}}}}}~~}~}~\x7f~~~~\x81\x81\x81\x82\x81\x81\x81\x82\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x...(truncated), 
    throwflag=throwflag@entry=0) at /usr/src/debug/Python-3.3.2/Python/ceval.c:1572
#8  0x00007ffff7a30bbd in fast_function (nk=<optimized out>, na=<optimized out>, 
    n=<optimized out>, pp_stack=0x7fffffffdcc0, func=<optimized out>)
    at /usr/src/debug/Python-3.3.2/Python/ceval.c:4180
#9  call_function (pintr1=0x7fffffffdcb8, pintr0=0x7fffffffdcb0, 
    oparg=<optimized out>, pp_stack=0x7fffffffdcc0)
    at /usr/src/debug/Python-3.3.2/Python/ceval.c:4113
#10 PyEval_EvalFrameEx (
    f=f@entry=Frame 0x83d390, for file /home/erics/vpy33-dbg/lib/python3.3/site-packages/Pillow-2.3.0-py3.3-linux-x86_64.egg/PIL/Image.py, line 1347, in resize (self=<PcdImageFile(decodermaxblock=65536, map=None, pyaccess=None, category=0, filename='golden.pcd', im=<ImagingCore at remote 0x7fffefbf6db0>, mode='RGB', tile=[('pcd', (0, 0, 768, 512), 196608, None)], decoderconfig=(), palette=None, info={}, size=(768, 512), readonly=1, fp=<_io.BufferedReader at remote 0x7fffefd567a0>) at remote 0x7ffff0335a70>, size=(512, 384), resample=0), throwflag=throwflag@entry=0)
    at /usr/src/debug/Python-3.3.2/Python/ceval.c:2701
...

@wiredfool wiredfool modified the milestones: 2.5.0, Future Mar 31, 2014
@aclark4life aclark4life modified the milestones: Future, 2.5.0 Jun 1, 2014
@dfandrich
Copy link

I'm getting a suspicious memory error when run under glibc 2.20 with Pillow 2.5.3 on an authentic PhotoCD image:

Python 2.7.8 (default, Oct 16 2014, 08:50:33) 
[GCC 4.9.2 20141001 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from PIL import Image
>>> i=Image.open('/tmp/img0039.pcd')
>>> i.copy()
*** Error in `/usr/bin/python': free(): invalid next size (normal): 0x00000000006cfb10 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x731be)[0x7ffff74b81be]
/lib64/libc.so.6(+0x7aef8)[0x7ffff74bfef8]
/lib64/libc.so.6(cfree+0x48)[0x7ffff74c35c8]
/usr/lib64/python2.7/site-packages/PIL/_imaging.so(+0x1621d)[0x7ffff5ee421d]
/lib64/libpython2.7.so.1.0(+0x6cf79)[0x7ffff7a7ff79]
/lib64/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x5543)[0x7ffff7af1493]
/lib64/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x830)[0x7ffff7af28f0]
/lib64/libpython2.7.so.1.0(PyEval_EvalFrameEx+0x541e)[0x7ffff7af136e]
/lib64/libpython2.7.so.1.0(PyEval_EvalCodeEx+0x830)[0x7ffff7af28f0]
/lib64/libpython2.7.so.1.0(PyEval_EvalCode+0x19)[0x7ffff7af29e9]
/lib64/libpython2.7.so.1.0(+0xf85df)[0x7ffff7b0b5df]
/lib64/libpython2.7.so.1.0(PyRun_InteractiveOneFlags+0x13a)[0x7ffff7b0d4fa]
/lib64/libpython2.7.so.1.0(PyRun_InteractiveLoopFlags+0x4e)[0x7ffff7b0d6de]
/lib64/libpython2.7.so.1.0(PyRun_AnyFileExFlags+0x3e)[0x7ffff7b0dd3e]
/lib64/libpython2.7.so.1.0(Py_Main+0xc3a)[0x7ffff7b1e79a]
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7ffff7464fd0]
/usr/bin/python[0x40077e]
======= Memory map: ========
…

Curiously, the free(): invalid next size error doesn't appear when debug symbols are available.

Valgrind gives even more useful messages; here is a selection:

==12856== Invalid write of size 1
==12856==    at 0x6A73BD5: ImagingPcdDecode (PcdDecode.c:47)
==12856==    by 0x6A571EE: _decode (decode.c:121)
==12856==    by 0x4F11F47: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)
==12856==  Address 0xab4b270 is 0 bytes after a block of size 2,304 alloc'd
==12856==    at 0x4C27F3F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12856==    by 0x6A570DA: _setimage (decode.c:186)
==12856== 
==12856== Invalid write of size 1
==12856==    at 0x6A73BF0: ImagingPcdDecode (PcdDecode.c:48)
==12856==    by 0x6A571EE: _decode (decode.c:121)
==12856== 
==12856== Invalid write of size 1
==12856==    at 0x6A73C11: ImagingPcdDecode (PcdDecode.c:49)
==12856==    by 0x6A571EE: _decode (decode.c:121)
==12856== 
==12856== Use of uninitialised value of size 8
==12856==    at 0x6A77F54: ImagingUnpackYCC (UnpackYCC.c:140)
==12856==    by 0x6A73C34: ImagingPcdDecode (PcdDecode.c:53)
==12856==    by 0x6A571EE: _decode (decode.c:121)
==12856== 
==12856== Invalid write of size 1
==12856==    at 0x6A73C6E: ImagingPcdDecode (PcdDecode.c:62)
==12856==    by 0x6A571EE: _decode (decode.c:121)
==12856== 
==12856== Use of uninitialised value of size 8
==12856==    at 0x6A77F5D: ImagingUnpackYCC (UnpackYCC.c:140)
==12856==    by 0x6A73CCA: ImagingPcdDecode (PcdDecode.c:68)
==12856==    by 0x6A571EE: _decode (decode.c:121)
==12856== 
==12856== Invalid read of size 8
==12856==    at 0x4F0D61A: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F11479: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F128EF: PyEval_EvalCodeEx (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F1136D: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F128EF: PyEval_EvalCodeEx (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F129E8: PyEval_EvalCode (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F2B5DE: ??? (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F2C751: PyRun_FileExFlags (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F2D856: PyRun_SimpleFileExFlags (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x4F3E799: Py_Main (in /usr/lib64/libpython2.7.so.1.0)
==12856==    by 0x5438FCF: (below main) (in /usr/lib64/libc-2.20.so)
==12856==  Address 0x8499350584999d is not stack'd, malloc'd or (recently) free'd
==12856== 
==12856== 
==12856== Process terminating with default action of signal 11 (SIGSEGV)
==12856==  General Protection Fault
==12856==    at 0x4F0D61A: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)

@aclark4life
Copy link
Member

@dfandrich can you please try with 2.7.0 and confirm the same issue still exists? Thanks

@dfandrich
Copy link

I just tried with git HEAD with seemingly identical results. The line numbers were slightly different, e.g.

==5395== Invalid write of size 1
==5395== at 0x72AA605: ImagingPcdDecode (PcdDecode.c:47)
==5395== by 0x728D1EE: _decode (decode.c:123)
==5395== Address 0xb09d480 is 0 bytes after a block of size 2,304 alloc'd
==5395== at 0x4C27F3F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5395== by 0x728D0DA: _setimage (decode.c:188)
==5395== Use of uninitialised value of size 8
==5395== at 0x72AE9A4: ImagingUnpackYCC (UnpackYCC.c:140)
==5395== by 0x72AA664: ImagingPcdDecode (PcdDecode.c:53)
==5395== by 0x728D1EE: _decode (decode.c:123)
==5395== Invalid write of size 1
==5395== at 0x72AA69E: ImagingPcdDecode (PcdDecode.c:62)
==5395== by 0x728D1EE: _decode (decode.c:123)
--5395-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--5395-- si_code=80; Faulting address: 0x0; sp: 0x802b99dd0

@wiredfool
Copy link
Member

If it's an invalid write, then our output buffer for decoding the image is bad:

out = state->buffer;
for (x = 0; x < state->xsize; x++) {
    out[0] = ptr[x];  /* <<< First invalid write PcdDecode.c:47 */
    out[1] = ptr[(x+4*state->xsize)/2];
    out[2] = ptr[(x+5*state->xsize)/2];
    out += 4;
}

That's a strange error, but this is a strange format.

It looks like there's a project that claims to decode all the sizes in a .pcd, with color mangement: http://pcdtojpeg.sourceforge.net/Home.html That may be a better approach than Pillow, since we don't even pretend to do the compressed higher res images.

@radarhere
Copy link
Member

The link to the problem file no longer works. Can anyone provide a file to demonstrate the problem?

@lehins
Copy link
Author

lehins commented Feb 2, 2016

Here is another file, that causes segmentation fault on resize:

http://7d64cbc4e99ce9788059-a127be7d9507d6d1187c85a377fe1ae1.r77.cf1.rackcdn.com/permanent/blackandwhite768.pcd

@radarhere
Copy link
Member

Thanks for that. I will note that it's not just resize, it would be any function that calls load, in the same way that the original image did according to other comments in this issue.

@wiredfool
Copy link
Member

Ok, I got it.

The shuffle/state buffer is malloc'd at 24bpp, and the filling of it is at 32 bpp.

Now, what's really lovely is that the original image (which I still have hanging around) comes up with color issues in pillow, but works in imagemagick. And the one posted today has color issues in imagemagick but works on pillow. But that's an issue for another PR.

wiredfool added a commit that referenced this issue Feb 4, 2016
PCD decoder overruns the shuffle buffer, Fixes #568
@dfandrich
Copy link

Could this buffer overflow have security implications? Can it overflow by more than a single byte (which isn't necessary safe either)?

@wiredfool
Copy link
Member

It overflows 768 bytes. The pattern is writing the first three bytes of the word, then leaves the next untouched.

I'd recommend updating to 3.1.1, which includes this fix.

@dfandrich
Copy link

In that case, it sounds very strongly like this is a potentially exploitable security problem. Are you planning on applying for a CVE number?

@dfandrich
Copy link

I found the CVE request—http://openwall.com/lists/oss-security/2016/02/02/5

@wiredfool
Copy link
Member

Yep. The release notes may be helpful as well: https://github.com/python-pillow/Pillow/blob/3.1.x/docs/releasenotes/3.1.1.rst

uqs pushed a commit to freebsd/freebsd-ports that referenced this issue Feb 13, 2016
Backport security fixes from 3.1.1 release, resolving the following
vulnerabilities:

 * CVE-2016-0775: Buffer overflow in FLI decoding code
 * CVE-2016-0740: Buffer overflow in TIFF decoding code
 * Integer overflow in Resample.c [1]
 * Buffer overflow in PCD decoder [2]

[1] python-pillow/Pillow#1710
[2] python-pillow/Pillow#568

PR:		207053
Submitted by:	rakuco
MFH:		2016Q1
Security:	a8de962a-cf15-11e5-805c-5453ed2e2b49


git-svn-id: svn+ssh://svn.freebsd.org/ports/head@408782 35697150-7ecd-e111-bb59-0022644237b5
uqs pushed a commit to freebsd/freebsd-ports that referenced this issue Feb 13, 2016
Backport security fixes from 3.1.1 release, resolving the following
vulnerabilities:

 * CVE-2016-0775: Buffer overflow in FLI decoding code
 * CVE-2016-0740: Buffer overflow in TIFF decoding code
 * Integer overflow in Resample.c [1]
 * Buffer overflow in PCD decoder [2]

[1] python-pillow/Pillow#1710
[2] python-pillow/Pillow#568

PR:		207053
Submitted by:	rakuco
MFH:		2016Q1
Security:	a8de962a-cf15-11e5-805c-5453ed2e2b49
uqs pushed a commit to freebsd/freebsd-ports that referenced this issue Feb 13, 2016
Backport security fixes from 3.1.1 release, resolving the following
vulnerabilities:

 * CVE-2016-0775: Buffer overflow in FLI decoding code
 * CVE-2016-0740: Buffer overflow in TIFF decoding code
 * Integer overflow in Resample.c [1]
 * Buffer overflow in PCD decoder [2]

[1] python-pillow/Pillow#1710
[2] python-pillow/Pillow#568

PR:		207053
Submitted by:	rakuco
Security:	a8de962a-cf15-11e5-805c-5453ed2e2b49

Approved by:	ports-secteam (security)
tota pushed a commit to tota/freebsd-ports that referenced this issue Feb 20, 2016
Backport security fixes from 3.1.1 release, resolving the following
vulnerabilities:

 * CVE-2016-0775: Buffer overflow in FLI decoding code
 * CVE-2016-0740: Buffer overflow in TIFF decoding code
 * Integer overflow in Resample.c [1]
 * Buffer overflow in PCD decoder [2]

[1] python-pillow/Pillow#1710
[2] python-pillow/Pillow#568

PR:		207053
Submitted by:	rakuco
MFH:		2016Q1
Security:	a8de962a-cf15-11e5-805c-5453ed2e2b49


git-svn-id: svn+ssh://svn.freebsd.org/ports/head@408782 35697150-7ecd-e111-bb59-0022644237b5
uqs pushed a commit to freebsd/freebsd-ports that referenced this issue Dec 2, 2016
Backport security fixes from 3.1.1 release, resolving the following
vulnerabilities:

 * CVE-2016-0775: Buffer overflow in FLI decoding code
 * CVE-2016-0740: Buffer overflow in TIFF decoding code
 * Integer overflow in Resample.c [1]
 * Buffer overflow in PCD decoder [2]

[1] python-pillow/Pillow#1710
[2] python-pillow/Pillow#568

PR:		207053
Submitted by:	rakuco
Security:	a8de962a-cf15-11e5-805c-5453ed2e2b49

Approved by:	ports-secteam (security)
uqs pushed a commit to freebsd/freebsd-ports that referenced this issue Apr 1, 2021
Backport security fixes from 3.1.1 release, resolving the following
vulnerabilities:

 * CVE-2016-0775: Buffer overflow in FLI decoding code
 * CVE-2016-0740: Buffer overflow in TIFF decoding code
 * Integer overflow in Resample.c [1]
 * Buffer overflow in PCD decoder [2]

[1] python-pillow/Pillow#1710
[2] python-pillow/Pillow#568

PR:		207053
Submitted by:	rakuco
Security:	a8de962a-cf15-11e5-805c-5453ed2e2b49

Approved by:	ports-secteam (security)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Any unexpected behavior, until confirmed feature.
Projects
None yet
Development

No branches or pull requests

5 participants