CVE-2016-2533: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: Buffer overflow in the ImagingPcdDecode function in PcdDecode.c in Pillow before 3.1.1 and Python Imaging Library (PIL) 1.1.7 and earlier allows remote attackers to cause a denial of service (crash) via a crafted PhotoCD file.
CWE description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
CVSS v3 base score: 6.5
Published: 2016-04-13T16:59Z
Repository: https://github.com/python-pillow/Pillow
Language: C
Files changed: Tests/test_file_pcd.py, libImaging/PcdDecode.c
Commit date: 2016-02-02 05:46:26 -0800
Commit message: PCD decoder overruns the shuffle buffer, Fixes #568

Diff: diff --git a/Tests/images/hopper.pcd b/Tests/images/hopper.pcd
new file mode 100644
index 00000000..8ffaf717
Binary files /dev/null and b/Tests/images/hopper.pcd differ
diff --git a/Tests/test_file_pcd.py b/Tests/test_file_pcd.py
new file mode 100644
index 00000000..2401e70c
--- /dev/null
+++ b/Tests/test_file_pcd.py
@@ -0,0 +1,18 @@
+from helper import unittest, PillowTestCase, hopper
+from PIL import Image
+
+class TestFilePcd(PillowTestCase):
+
+    def test_load_raw(self):
+        im = Image.open('Tests/images/hopper.pcd')
+        im.load() # should not segfault.
+
+        # Note that this image was created with a resized hopper
+        # image, which was then converted to pcd with imagemagick
+        # and the colors are wonky in Pillow.  It's unclear if this
+        # is a pillow or a convert issue, as other images not generated
+        # from convert look find on pillow and not imagemagick.
+        
+        #target = hopper().resize((768,512))
+        #self.assert_image_similar(im, target, 10)
+
diff --git a/libImaging/PcdDecode.c b/libImaging/PcdDecode.c
index fb6adc68..f9234389 100644
--- a/libImaging/PcdDecode.c
+++ b/libImaging/PcdDecode.c
@@ -45,11 +45,11 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
 	out = state->buffer;
 	for (x = 0; x < state->xsize; x++) {
 	    out[0] = ptr[x];
 	    out[1] = ptr[(x+4*state->xsize)/2];
 	    out[2] = ptr[(x+5*state->xsize)/2];
-	    out += 4;
+	    out += 3;
 	}
 
 	state->shuffle((UINT8*) im->image[state->y],
 		       state->buffer, state->xsize);
 
@@ -60,11 +60,11 @@ ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
 	out = state->buffer;
 	for (x = 0; x < state->xsize; x++) {
 	    out[0] = ptr[x+state->xsize];
 	    out[1] = ptr[(x+4*state->xsize)/2];
 	    out[2] = ptr[(x+5*state->xsize)/2];
-	    out += 4;
+	    out += 3;
 	}
 
 	state->shuffle((UINT8*) im->image[state->y],
 		       state->buffer, state->xsize);
 

Vulnerable code: 	    out += 4;
	    out += 4;
Fixed code: from helper import unittest, PillowTestCase, hopper
from PIL import Image

class TestFilePcd(PillowTestCase):

    def test_load_raw(self):
        im = Image.open('Tests/images/hopper.pcd')
        im.load() # should not segfault.

        # Note that this image was created with a resized hopper
        # image, which was then converted to pcd with imagemagick
        # and the colors are wonky in Pillow.  It's unclear if this
        # is a pillow or a convert issue, as other images not generated
        # from convert look find on pillow and not imagemagick.
        
        #target = hopper().resize((768,512))
        #self.assert_image_similar(im, target, 10)

	    out += 3;
	    out += 3;