Compare commits

...

8 Commits
main ... 3.3.x

Author SHA1 Message Date
wiredfool
b28c176817 3.3.3 Release Version bump 2016-10-04 07:07:02 -07:00
wiredfool
3f73d9b680 Map.c check should be against PY_SSIZE_T_MAX (#2151) 2016-10-04 14:40:22 +01:00
wiredfool
98101c0463 Vulnerable map function is not called on windows 2016-10-03 07:52:05 -07:00
wiredfool
6ce889a573 IOError is also a valid error here 2016-10-03 07:52:05 -07:00
wiredfool
9cf752a697 3.3.2 version bump 2016-09-30 06:55:22 -07:00
wiredfool
58e7501998 Changes, Release notes 2016-09-30 06:55:22 -07:00
wiredfool
fe7b41b438 Map.c overflow fixes 2016-09-30 06:55:22 -07:00
wiredfool
d4663806a8 Memory error in Storage.c when accepting negative image size arguments 2016-09-30 06:55:22 -07:00
14 changed files with 116 additions and 5 deletions

View File

@ -1,6 +1,22 @@
Changelog (Pillow)
==================
3.3.3 (2016-10-04)
------------------
- Fix fix for map.c overflow #2151
[wiredfool]
3.3.2 (2016-10-03)
------------------
- Fix negative image sizes in Storage.c #2105
[wiredfool]
- Fix integer overflow in map.c #2105
[wiredfool]
3.3.1 (2016-08-18)
------------------

View File

@ -154,7 +154,7 @@ class ImageFile(Image.Image):
if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES:
try:
if hasattr(Image.core, "map"):
# use built-in mapper
# use built-in mapper WIN32 only
self.map = Image.core.map(self.filename)
self.map.seek(o)
self.im = self.map.readimage(

View File

@ -12,7 +12,7 @@
# ;-)
VERSION = '1.1.7' # PIL version
PILLOW_VERSION = '3.3.1' # Pillow
PILLOW_VERSION = '3.3.3' # Pillow
_plugins = ['BmpImagePlugin',
'BufrStubImagePlugin',

BIN
Tests/images/l2rgb_read.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 B

BIN
Tests/images/negative_size.ppm Executable file

Binary file not shown.

View File

@ -44,6 +44,18 @@ class TestFilePpm(PillowTestCase):
self.assertRaises(ValueError, lambda: Image.open(path))
def test_neg_ppm(self):
"""test_neg_ppm
Storage.c accepted negative values for xsize, ysize.
open_ppm is a core debugging item that doesn't check any parameters for
sanity.
"""
with self.assertRaises(ValueError):
Image.core.open_ppm('Tests/images/negative_size.ppm')
if __name__ == '__main__':
unittest.main()

28
Tests/test_map.py Normal file
View File

@ -0,0 +1,28 @@
from helper import PillowTestCase, unittest
import sys
from PIL import Image
@unittest.skipIf(sys.platform.startswith('win32'), "Win32 does not call map_buffer")
class TestMap(PillowTestCase):
def test_overflow(self):
# There is the potential to overflow comparisons in map.c
# if there are > SIZE_MAX bytes in the image or if
# the file encodes an offset that makes
# (offset + size(bytes)) > SIZE_MAX
# Note that this image triggers the decompression bomb warning:
max_pixels = Image.MAX_IMAGE_PIXELS
Image.MAX_IMAGE_PIXELS = None
# This image hits the offset test.
im = Image.open('Tests/images/l2rgb_read.bmp')
with self.assertRaises((ValueError, MemoryError, IOError)):
im.load()
Image.MAX_IMAGE_PIXELS = max_pixels
if __name__ == '__main__':
unittest.main()

View File

@ -71,7 +71,7 @@
* See the README file for information on usage and redistribution.
*/
#define PILLOW_VERSION "3.3.1"
#define PILLOW_VERSION "3.3.3"
#include "Python.h"

View File

@ -1,4 +1,4 @@
version: 3.3.1.{build}
version: 3.3.3.{build}
clone_folder: c:\pillow
init:
- ECHO %PYTHON%

View File

@ -0,0 +1,40 @@
3.3.2
=====
Integer overflow in Map.c
-------------------------
Pillow prior to 3.3.2 may experience integer overflow errors in map.c
when reading specially crafted image files. This may lead to memory
disclosure or corruption.
Specifically, when parameters from the image are passed into
``Image.core.map_buffer``, the size of the image was calculated with
``xsize``*``ysize``*``bytes_per_pixel``. This will overflow if the
result is larger than SIZE_MAX. This is possible on a 32-bit system.
Furthermore this ``size`` value was added to a potentially attacker
provided ``offset`` value and compared to the size of the buffer
without checking for overflow or negative values.
These values were then used for creating pointers, at which point
Pillow could read the memory and include it in other images. The image
was marked readonly, so Pillow would not ordinarily write to that
memory without duplicating the image first.
This issue was found by Cris Neckar at Divergent Security.
Sign Extension in Storage.c
---------------------------
Pillow prior to 3.3.2 and PIL 1.1.7 (at least) do not check for
negative image sizes in ``ImagingNew`` in ``Storage.c``. A negative
image size can lead to a smaller allocation than expected, leading to
arbitrary writes.
This issue was found by Cris Neckar at Divergent Security.

View File

@ -6,6 +6,7 @@ Release Notes
.. toctree::
:maxdepth: 2
3.3.2
3.3.0
3.2.0
3.1.2

View File

@ -406,6 +406,10 @@ ImagingNew(const char* mode, int xsize, int ysize)
} else
bytes = strlen(mode); /* close enough */
if (xsize < 0 || ysize < 0) {
return (Imaging) ImagingError_ValueError("bad image size");
}
if ((int64_t) xsize * (int64_t) ysize <= THRESHOLD / bytes) {
im = ImagingNewBlock(mode, xsize, ysize);
if (im)

10
map.c
View File

@ -342,8 +342,18 @@ PyImaging_MapBuffer(PyObject* self, PyObject* args)
stride = xsize * 4;
}
if (ysize > INT_MAX / stride) {
PyErr_SetString(PyExc_MemoryError, "Integer overflow in ysize");
return NULL;
}
size = (Py_ssize_t) ysize * stride;
if (offset > PY_SSIZE_T_MAX - size) {
PyErr_SetString(PyExc_MemoryError, "Integer overflow in offset");
return NULL;
}
/* check buffer size */
if (PyImaging_GetBuffer(target, &view) < 0)
return NULL;

View File

@ -110,7 +110,7 @@ except (ImportError, OSError):
_tkinter = None
NAME = 'Pillow'
PILLOW_VERSION = '3.3.1'
PILLOW_VERSION = '3.3.3'
JPEG_ROOT = None
JPEG2K_ROOT = None
ZLIB_ROOT = None