Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Cloud:OpenStack:Pike
python-Pillow
011-Fix-OOB-reads-in-FLI-decoding.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 011-Fix-OOB-reads-in-FLI-decoding.patch of Package python-Pillow
From c66d8aa75436f334f686fe32bca8e414bcdd18e6 Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Mon, 2 Mar 2020 22:57:23 +0000 Subject: [PATCH 01/11] Fli issue 1 --- libImaging/FliDecode.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index 6f48c07d41..484f1ce686 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -165,14 +165,26 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt break; case 15: /* FLI BRUN chunk */ + /* data = ptr + 6 */ for (y = 0; y < state->ysize; y++) { UINT8* out = (UINT8*) im->image[y]; data += 1; /* ignore packetcount byte */ for (x = 0; x < state->xsize; x += i) { + if (data + 2 > ptr + bytes ) { + /* Out of Bounds Read issue, guaranteed to try to read 2 from data */ + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } if (data[0] & 0x80) { i = 256 - data[0]; - if (x + i > state->xsize) + if (x + i > state->xsize) { break; /* safety first */ + } + if (data + i + 1 > ptr + bytes ) { + /* Out of Bounds Read issue */ + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } memcpy(out + x, data + 1, i); data += i + 1; } else { From f6926a041b4b544fd2ced3752542afb6c8c19405 Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Thu, 5 Mar 2020 09:11:13 +0000 Subject: [PATCH 02/11] Refactor to macro --- libImaging/FliDecode.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index 484f1ce686..d53b4a7fd1 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -24,7 +24,12 @@ #define I32(ptr)\ ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) - +#define ERR_IF_DATA_OOB(offset) \ + if ((data + (offset)) > ptr + bytes) {\ + state->errcode = IMAGING_CODEC_OVERRUN; \ + return -1; \ + } + int ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) { @@ -170,21 +175,15 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt UINT8* out = (UINT8*) im->image[y]; data += 1; /* ignore packetcount byte */ for (x = 0; x < state->xsize; x += i) { - if (data + 2 > ptr + bytes ) { - /* Out of Bounds Read issue, guaranteed to try to read 2 from data */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } + /* Out of Bounds Read issue, guaranteed to try to read 2 from data */ + ERR_IF_DATA_OOB(2) if (data[0] & 0x80) { i = 256 - data[0]; if (x + i > state->xsize) { break; /* safety first */ } - if (data + i + 1 > ptr + bytes ) { - /* Out of Bounds Read issue */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } + /* Out of Bounds read issue */ + ERR_IF_DATA_OOB(i+1) memcpy(out + x, data + 1, i); data += i + 1; } else { From b4e439d6d7fd986cd6b4c7f9ca18830d79dacd44 Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Thu, 5 Mar 2020 09:11:50 +0000 Subject: [PATCH 03/11] Fix OOB Reads in SS2 Chunk --- libImaging/FliDecode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index d53b4a7fd1..c404361557 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -83,10 +83,12 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt break; /* ignored; handled by Python code */ case 7: /* FLI SS2 chunk (word delta) */ + /* OOB ok, we've got 10 bytes min on entry */ lines = I16(data); data += 2; for (l = y = 0; l < lines && y < state->ysize; l++, y++) { UINT8* buf = (UINT8*) im->image[y]; int p, packets; + ERR_IF_DATA_OOB(2) packets = I16(data); data += 2; while (packets & 0x8000) { /* flag word */ @@ -101,11 +103,14 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt /* store last byte (used if line width is odd) */ buf[state->xsize-1] = (UINT8) packets; } + ERR_IF_DATA_OOB(2) packets = I16(data); data += 2; } for (p = x = 0; p < packets; p++) { + ERR_IF_DATA_OOB(2) x += data[0]; /* pixel skip */ if (data[1] >= 128) { + ERR_IF_DATA_OOB(4) i = 256-data[1]; /* run */ if (x + i + i > state->xsize) break; @@ -118,6 +123,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt i = 2 * (int) data[1]; /* chunk */ if (x + i > state->xsize) break; + ERR_IF_DATA_OOB(2+i) memcpy(buf + x, data + 2, i); data += 2 + i; x += i; From c88b0204d7c930e3bd72626ae6ea078571cc0ea7 Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Thu, 5 Mar 2020 09:21:35 +0000 Subject: [PATCH 04/11] Fix OOB in LC packet --- libImaging/FliDecode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index c404361557..2316fa814d 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -140,22 +140,26 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt break; case 12: /* FLI LC chunk (byte delta) */ + /* OOB Check ok, we have 10 bytes here */ y = I16(data); ymax = y + I16(data+2); data += 4; for (; y < ymax && y < state->ysize; y++) { UINT8* out = (UINT8*) im->image[y]; int p, packets = *data++; for (p = x = 0; p < packets; p++, x += i) { + ERR_IF_DATA_OOB(2) x += data[0]; /* skip pixels */ if (data[1] & 0x80) { i = 256-data[1]; /* run */ if (x + i > state->xsize) break; + ERR_IF_DATA_OOB(3) memset(out + x, data[2], i); data += 3; } else { i = data[1]; /* chunk */ if (x + i > state->xsize) break; + ERR_IF_DATA_OOB(2+i) memcpy(out + x, data + 2, i); data += i + 2; } From c5edc361fd6450f805a6a444723b0f68190b1d0c Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Thu, 5 Mar 2020 09:51:32 +0000 Subject: [PATCH 05/11] Fix OOB Advance Values --- libImaging/FliDecode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index 2316fa814d..ca9e00327f 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -83,7 +83,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt break; /* ignored; handled by Python code */ case 7: /* FLI SS2 chunk (word delta) */ - /* OOB ok, we've got 10 bytes min on entry */ + /* OOB ok, we've got 4 bytes min on entry */ lines = I16(data); data += 2; for (l = y = 0; l < lines && y < state->ysize; l++, y++) { UINT8* buf = (UINT8*) im->image[y]; @@ -229,6 +229,10 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt return -1; } advance = I32(ptr); + if (advance < 0 || advance > bytes) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } ptr += advance; bytes -= advance; } From 8d4f3c0c5f2fecf175aeb895e9c2d6d06d85bdc9 Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Thu, 5 Mar 2020 10:01:28 +0000 Subject: [PATCH 06/11] Fix OOB Read in FLI Copy Chunk --- libImaging/FliDecode.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index ca9e00327f..98bc037681 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -86,7 +86,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt /* OOB ok, we've got 4 bytes min on entry */ lines = I16(data); data += 2; for (l = y = 0; l < lines && y < state->ysize; l++, y++) { - UINT8* buf = (UINT8*) im->image[y]; + UINT8* local_buf = (UINT8*) im->image[y]; int p, packets; ERR_IF_DATA_OOB(2) packets = I16(data); data += 2; @@ -98,10 +98,10 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt state->errcode = IMAGING_CODEC_OVERRUN; return -1; } - buf = (UINT8*) im->image[y]; + local_buf = (UINT8*) im->image[y]; } else { /* store last byte (used if line width is odd) */ - buf[state->xsize-1] = (UINT8) packets; + local_buf[state->xsize-1] = (UINT8) packets; } ERR_IF_DATA_OOB(2) packets = I16(data); data += 2; @@ -115,8 +115,8 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt if (x + i + i > state->xsize) break; for (j = 0; j < i; j++) { - buf[x++] = data[2]; - buf[x++] = data[3]; + local_buf[x++] = data[2]; + local_buf[x++] = data[3]; } data += 2 + 2; } else { @@ -124,7 +124,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt if (x + i > state->xsize) break; ERR_IF_DATA_OOB(2+i) - memcpy(buf + x, data + 2, i); + memcpy(local_buf + x, data + 2, i); data += 2 + i; x += i; } @@ -213,9 +213,13 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt break; case 16: /* COPY chunk */ + if (state->xsize > bytes/state->ysize) { + /* not enough data for frame */ + return ptr - buf; /* bytes consumed */ + } for (y = 0; y < state->ysize; y++) { - UINT8* buf = (UINT8*) im->image[y]; - memcpy(buf, data, state->xsize); + UINT8* local_buf = (UINT8*) im->image[y]; + memcpy(local_buf, data, state->xsize); data += state->xsize; } break; From 19ff42bd683486a8a308743c76972ef6a6482e9b Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Thu, 5 Mar 2020 10:13:10 +0000 Subject: [PATCH 07/11] tests for Fli OOB reads --- Tests/check_fli_oob.py | 61 ++++++++++++++++++++++ 48 files changed, 71 insertions(+) create mode 100644 Tests/check_fli_oob.py diff --git a/Tests/check_fli_oob.py b/Tests/check_fli_oob.py new file mode 100644 index 0000000000..ca06c2cb82 --- /dev/null +++ b/Tests/check_fli_oob.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +from PIL import Image + +repro_ss2 = ('images/fli_oob/06r/06r00.fli', + 'images/fli_oob/06r/others/06r01.fli', + 'images/fli_oob/06r/others/06r02.fli', + 'images/fli_oob/06r/others/06r03.fli', + 'images/fli_oob/06r/others/06r04.fli' +) + +repro_lc = ('images/fli_oob/05r/05r00.fli', + 'images/fli_oob/05r/others/05r03.fli', + 'images/fli_oob/05r/others/05r06.fli', + 'images/fli_oob/05r/others/05r05.fli', + 'images/fli_oob/05r/others/05r01.fli', + 'images/fli_oob/05r/others/05r04.fli', + 'images/fli_oob/05r/others/05r02.fli', + 'images/fli_oob/05r/others/05r07.fli', +) + + +repro_advance = ('images/fli_oob/03r/03r00.fli', + 'images/fli_oob/03r/others/03r01.fli', + 'images/fli_oob/03r/others/03r09.fli', + 'images/fli_oob/03r/others/03r11.fli', + 'images/fli_oob/03r/others/03r05.fli', + 'images/fli_oob/03r/others/03r10.fli', + 'images/fli_oob/03r/others/03r06.fli', + 'images/fli_oob/03r/others/03r08.fli', + 'images/fli_oob/03r/others/03r03.fli', + 'images/fli_oob/03r/others/03r07.fli', + 'images/fli_oob/03r/others/03r02.fli', + 'images/fli_oob/03r/others/03r04.fli', +) + +repro_brun = ('images/fli_oob/04r/initial.fli', + 'images/fli_oob/04r/others/04r02.fli', + 'images/fli_oob/04r/others/04r05.fli', + 'images/fli_oob/04r/others/04r04.fli', + 'images/fli_oob/04r/others/04r03.fli', + 'images/fli_oob/04r/others/04r01.fli', + 'images/fli_oob/04r/04r00.fli', +) + +repro_copy = ('images/fli_oob/02r/others/02r02.fli', + 'images/fli_oob/02r/others/02r04.fli', + 'images/fli_oob/02r/others/02r03.fli', + 'images/fli_oob/02r/others/02r01.fli', + 'images/fli_oob/02r/02r00.fli', +) + + +for path in repro_ss2 + repro_lc + repro_advance + repro_brun + repro_copy: + im = Image.open(path) + try: + im.load() + except Exception as msg: + print(msg) + + From 088ce4df981b70fbec140ee54417bcb49a7dffca Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Thu, 5 Mar 2020 10:46:27 +0000 Subject: [PATCH 08/11] comments --- libImaging/FliDecode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index 98bc037681..16ddf3a49f 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -140,7 +140,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt break; case 12: /* FLI LC chunk (byte delta) */ - /* OOB Check ok, we have 10 bytes here */ + /* OOB Check ok, we have 4 bytes min here */ y = I16(data); ymax = y + I16(data+2); data += 4; for (; y < ymax && y < state->ysize; y++) { UINT8* out = (UINT8*) im->image[y]; @@ -180,19 +180,17 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt break; case 15: /* FLI BRUN chunk */ - /* data = ptr + 6 */ + /* OOB, ok, we've got 4 bytes min on entry */ for (y = 0; y < state->ysize; y++) { UINT8* out = (UINT8*) im->image[y]; data += 1; /* ignore packetcount byte */ for (x = 0; x < state->xsize; x += i) { - /* Out of Bounds Read issue, guaranteed to try to read 2 from data */ ERR_IF_DATA_OOB(2) if (data[0] & 0x80) { i = 256 - data[0]; if (x + i > state->xsize) { break; /* safety first */ } - /* Out of Bounds read issue */ ERR_IF_DATA_OOB(i+1) memcpy(out + x, data + 1, i); data += i + 1; From 5b490fc413dfab2d52de46a58905c25d9badb650 Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Tue, 10 Mar 2020 20:17:33 +0000 Subject: [PATCH 09/11] additional FLI check --- libImaging/FliDecode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libImaging/FliDecode.c b/libImaging/FliDecode.c index 16ddf3a49f..108e1edf93 100644 --- a/libImaging/FliDecode.c +++ b/libImaging/FliDecode.c @@ -144,6 +144,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int byt y = I16(data); ymax = y + I16(data+2); data += 4; for (; y < ymax && y < state->ysize; y++) { UINT8* out = (UINT8*) im->image[y]; + ERR_IF_DATA_OOB(1) int p, packets = *data++; for (p = x = 0; p < packets; p++, x += i) { ERR_IF_DATA_OOB(2) From 00c6dd72d9ed0124cec81040b4bab0979a200fe2 Mon Sep 17 00:00:00 2001 From: Eric Soroos <eric-github@soroos.net> Date: Tue, 10 Mar 2020 20:29:35 +0000 Subject: [PATCH 10/11] Tests for additional hits --- Tests/check_fli_oob.py | 4 ++++ 5 files changed, 4 insertions(+) diff --git a/Tests/check_fli_oob.py b/Tests/check_fli_oob.py index ca06c2cb82..8d83605aa4 100644 --- a/Tests/check_fli_oob.py +++ b/Tests/check_fli_oob.py @@ -17,6 +17,10 @@ 'images/fli_oob/05r/others/05r04.fli', 'images/fli_oob/05r/others/05r02.fli', 'images/fli_oob/05r/others/05r07.fli', + 'images/fli_oob/patch0/000000', + 'images/fli_oob/patch0/000001', + 'images/fli_oob/patch0/000002', + 'images/fli_oob/patch0/000003', ) From 11ef7ca53a7d0af4bc52666c29199deffa5fc1bd Mon Sep 17 00:00:00 2001 From: Hugo <hugovk@users.noreply.github.com> Date: Thu, 26 Mar 2020 21:39:58 +0200 Subject: [PATCH 11/11] Format with Black --- Tests/check_fli_oob.py | 89 ++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/Tests/check_fli_oob.py b/Tests/check_fli_oob.py index 8d83605aa4..739ad224e7 100644 --- a/Tests/check_fli_oob.py +++ b/Tests/check_fli_oob.py @@ -2,56 +2,61 @@ from PIL import Image -repro_ss2 = ('images/fli_oob/06r/06r00.fli', - 'images/fli_oob/06r/others/06r01.fli', - 'images/fli_oob/06r/others/06r02.fli', - 'images/fli_oob/06r/others/06r03.fli', - 'images/fli_oob/06r/others/06r04.fli' +repro_ss2 = ( + "images/fli_oob/06r/06r00.fli", + "images/fli_oob/06r/others/06r01.fli", + "images/fli_oob/06r/others/06r02.fli", + "images/fli_oob/06r/others/06r03.fli", + "images/fli_oob/06r/others/06r04.fli", ) -repro_lc = ('images/fli_oob/05r/05r00.fli', - 'images/fli_oob/05r/others/05r03.fli', - 'images/fli_oob/05r/others/05r06.fli', - 'images/fli_oob/05r/others/05r05.fli', - 'images/fli_oob/05r/others/05r01.fli', - 'images/fli_oob/05r/others/05r04.fli', - 'images/fli_oob/05r/others/05r02.fli', - 'images/fli_oob/05r/others/05r07.fli', - 'images/fli_oob/patch0/000000', - 'images/fli_oob/patch0/000001', - 'images/fli_oob/patch0/000002', - 'images/fli_oob/patch0/000003', +repro_lc = ( + "images/fli_oob/05r/05r00.fli", + "images/fli_oob/05r/others/05r03.fli", + "images/fli_oob/05r/others/05r06.fli", + "images/fli_oob/05r/others/05r05.fli", + "images/fli_oob/05r/others/05r01.fli", + "images/fli_oob/05r/others/05r04.fli", + "images/fli_oob/05r/others/05r02.fli", + "images/fli_oob/05r/others/05r07.fli", + "images/fli_oob/patch0/000000", + "images/fli_oob/patch0/000001", + "images/fli_oob/patch0/000002", + "images/fli_oob/patch0/000003", ) -repro_advance = ('images/fli_oob/03r/03r00.fli', - 'images/fli_oob/03r/others/03r01.fli', - 'images/fli_oob/03r/others/03r09.fli', - 'images/fli_oob/03r/others/03r11.fli', - 'images/fli_oob/03r/others/03r05.fli', - 'images/fli_oob/03r/others/03r10.fli', - 'images/fli_oob/03r/others/03r06.fli', - 'images/fli_oob/03r/others/03r08.fli', - 'images/fli_oob/03r/others/03r03.fli', - 'images/fli_oob/03r/others/03r07.fli', - 'images/fli_oob/03r/others/03r02.fli', - 'images/fli_oob/03r/others/03r04.fli', +repro_advance = ( + "images/fli_oob/03r/03r00.fli", + "images/fli_oob/03r/others/03r01.fli", + "images/fli_oob/03r/others/03r09.fli", + "images/fli_oob/03r/others/03r11.fli", + "images/fli_oob/03r/others/03r05.fli", + "images/fli_oob/03r/others/03r10.fli", + "images/fli_oob/03r/others/03r06.fli", + "images/fli_oob/03r/others/03r08.fli", + "images/fli_oob/03r/others/03r03.fli", + "images/fli_oob/03r/others/03r07.fli", + "images/fli_oob/03r/others/03r02.fli", + "images/fli_oob/03r/others/03r04.fli", ) -repro_brun = ('images/fli_oob/04r/initial.fli', - 'images/fli_oob/04r/others/04r02.fli', - 'images/fli_oob/04r/others/04r05.fli', - 'images/fli_oob/04r/others/04r04.fli', - 'images/fli_oob/04r/others/04r03.fli', - 'images/fli_oob/04r/others/04r01.fli', - 'images/fli_oob/04r/04r00.fli', +repro_brun = ( + "images/fli_oob/04r/initial.fli", + "images/fli_oob/04r/others/04r02.fli", + "images/fli_oob/04r/others/04r05.fli", + "images/fli_oob/04r/others/04r04.fli", + "images/fli_oob/04r/others/04r03.fli", + "images/fli_oob/04r/others/04r01.fli", + "images/fli_oob/04r/04r00.fli", ) -repro_copy = ('images/fli_oob/02r/others/02r02.fli', - 'images/fli_oob/02r/others/02r04.fli', - 'images/fli_oob/02r/others/02r03.fli', - 'images/fli_oob/02r/others/02r01.fli', - 'images/fli_oob/02r/02r00.fli', +repro_copy = ( + "images/fli_oob/02r/others/02r02.fli", + "images/fli_oob/02r/others/02r04.fli", + "images/fli_oob/02r/others/02r03.fli", + "images/fli_oob/02r/others/02r01.fli", + "images/fli_oob/02r/02r00.fli", ) @@ -61,5 +66,3 @@ im.load() except Exception as msg: print(msg) - -
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor