Merge pull request #2 from ActiveState/jeremyp/cve-2020-11538

CVE-2020-11538: fix SGI-RLE buffer overflow
This commit is contained in:
Jeremy Paige 2021-10-12 13:21:49 -07:00 committed by GitHub
commit d22b3879a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 3 deletions

View File

@ -2,6 +2,14 @@
Changelog (Pillow) Changelog (Pillow)
================== ==================
6.2.2.1 (2021-10-08)
------------------
- This is the first Pillow release to support Python 2.7 from ActiveState
- Catch SGI out-of-bounds reads. CVE 2020-11538
[ucodery]
6.2.2 (2020-01-02) 6.2.2 (2020-01-02)
------------------ ------------------

BIN
Tests/images/sgi_crash.bin Normal file

Binary file not shown.

Binary file not shown.

17
Tests/test_sgi_crash.py Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
import pytest
from PIL import Image
def test_crashes():
with open("Tests/images/sgi_crash.bin", "rb") as f:
im = Image.open(f)
with pytest.raises(IOError):
im.load()
def test_overrun_crashes():
with open("Tests/images/sgi_overrun_expandrowF04.bin", "rb") as f:
im = Image.open(f)
with pytest.raises(IOError):
im.load()

View File

@ -0,0 +1,10 @@
6.2.2.1
-------
Security
========
This release addresses CVE-2020-11538.
CVE-2019-11538 is regarding SGI images. An out-of-bounds read can occur in the
parsing of SGI image files.

View File

@ -6,6 +6,7 @@ Release Notes
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
6.2.2.1
6.2.2 6.2.2
6.2.1 6.2.1
6.2.0 6.2.0

View File

@ -1,2 +1,2 @@
# Master version for Pillow # Master version for Pillow
__version__ = "6.2.2" __version__ = "6.2.2.1"

View File

@ -28,6 +28,7 @@ static void read4B(UINT32* dest, UINT8* buf)
static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize) static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
{ {
UINT8 pixel, count; UINT8 pixel, count;
int x = 0;
for (;n > 0; n--) for (;n > 0; n--)
{ {
@ -37,9 +38,10 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
count = pixel & RLE_MAX_RUN; count = pixel & RLE_MAX_RUN;
if (!count) if (!count)
return count; return count;
if (count > xsize) { if (x + count > xsize) {
return -1; return -1;
} }
x += count;
if (pixel & RLE_COPY_FLAG) { if (pixel & RLE_COPY_FLAG) {
while(count--) { while(count--) {
*dest = *src++; *dest = *src++;
@ -62,6 +64,7 @@ static int expandrow(UINT8* dest, UINT8* src, int n, int z, int xsize)
static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize) static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
{ {
UINT8 pixel, count; UINT8 pixel, count;
int x = 0;
for (;n > 0; n--) for (;n > 0; n--)
@ -73,9 +76,10 @@ static int expandrow2(UINT8* dest, const UINT8* src, int n, int z, int xsize)
count = pixel & RLE_MAX_RUN; count = pixel & RLE_MAX_RUN;
if (!count) if (!count)
return count; return count;
if (count > xsize) { if (x + count > xsize) {
return -1; return -1;
} }
x += count;
if (pixel & RLE_COPY_FLAG) { if (pixel & RLE_COPY_FLAG) {
while(count--) { while(count--) {
memcpy(dest, src, 2); memcpy(dest, src, 2);