137 lines
4.4 KiB
Diff
137 lines
4.4 KiB
Diff
From f276de1139ec16395dc8b382860fb58e331fbd53 Mon Sep 17 00:00:00 2001
|
|
From: Eric Soroos <eric-github@soroos.net>
|
|
Date: Thu, 29 Oct 2020 23:07:15 +0000
|
|
Subject: [PATCH 1/2] Fix for SGI Decode buffer overrun CVE-2020-35655
|
|
|
|
* Independently found by a contributor and sent to Tidelift, and by Google's OSS Fuzz.
|
|
---
|
|
src/libImaging/SgiRleDecode.c | 23 ++++++++++++++++-------
|
|
1 file changed, 16 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c
|
|
index eb8fc84..c256169 100644
|
|
--- a/src/libImaging/SgiRleDecode.c
|
|
+++ b/src/libImaging/SgiRleDecode.c
|
|
@@ -107,11 +107,27 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
|
int err = 0;
|
|
int status;
|
|
|
|
+ /* size check */
|
|
+ if (im->xsize > INT_MAX / im->bands ||
|
|
+ im->ysize > INT_MAX / im->bands) {
|
|
+ return IMAGING_CODEC_MEMORY;
|
|
+ }
|
|
+
|
|
/* Get all data from File descriptor */
|
|
c = (SGISTATE*)state->context;
|
|
_imaging_seek_pyFd(state->fd, 0L, SEEK_END);
|
|
c->bufsize = _imaging_tell_pyFd(state->fd);
|
|
c->bufsize -= SGI_HEADER_SIZE;
|
|
+
|
|
+ c->tablen = im->bands * im->ysize;
|
|
+ /* below, we populate the starttab and lentab into the bufsize,
|
|
+ each with 4 bytes per element of tablen
|
|
+ Check here before we allocate any memory
|
|
+ */
|
|
+ if (c->bufsize < 8*c->tablen) {
|
|
+ return IMAGING_CODEC_MEMORY;
|
|
+ }
|
|
+
|
|
ptr = malloc(sizeof(UINT8) * c->bufsize);
|
|
if (!ptr) {
|
|
return IMAGING_CODEC_MEMORY;
|
|
@@ -129,18 +145,11 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
|
state->ystep = 1;
|
|
}
|
|
|
|
- if (im->xsize > INT_MAX / im->bands ||
|
|
- im->ysize > INT_MAX / im->bands) {
|
|
- err = IMAGING_CODEC_MEMORY;
|
|
- goto sgi_finish_decode;
|
|
- }
|
|
-
|
|
/* Allocate memory for RLE tables and rows */
|
|
free(state->buffer);
|
|
state->buffer = NULL;
|
|
/* malloc overflow check above */
|
|
state->buffer = calloc(im->xsize * im->bands, sizeof(UINT8) * 2);
|
|
- c->tablen = im->bands * im->ysize;
|
|
c->starttab = calloc(c->tablen, sizeof(UINT32));
|
|
c->lengthtab = calloc(c->tablen, sizeof(UINT32));
|
|
if (!state->buffer ||
|
|
--
|
|
2.29.2
|
|
|
|
From 18aa14484fa63dabcafea63cf0b7bfb4066e979c Mon Sep 17 00:00:00 2001
|
|
From: Eric Soroos <eric-github@soroos.net>
|
|
Date: Fri, 30 Oct 2020 09:57:23 +0000
|
|
Subject: [PATCH 2/2] Make the SGI code return -1 as an error flag, error in
|
|
state
|
|
|
|
---
|
|
src/libImaging/SgiRleDecode.c | 16 ++++++++++------
|
|
1 file changed, 10 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c
|
|
index c256169..2259159 100644
|
|
--- a/src/libImaging/SgiRleDecode.c
|
|
+++ b/src/libImaging/SgiRleDecode.c
|
|
@@ -110,7 +110,8 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
|
/* size check */
|
|
if (im->xsize > INT_MAX / im->bands ||
|
|
im->ysize > INT_MAX / im->bands) {
|
|
- return IMAGING_CODEC_MEMORY;
|
|
+ state->errcode = IMAGING_CODEC_MEMORY;
|
|
+ return -1;
|
|
}
|
|
|
|
/* Get all data from File descriptor */
|
|
@@ -125,12 +126,14 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
|
Check here before we allocate any memory
|
|
*/
|
|
if (c->bufsize < 8*c->tablen) {
|
|
- return IMAGING_CODEC_MEMORY;
|
|
+ state->errcode = IMAGING_CODEC_OVERRUN;
|
|
+ return -1;
|
|
}
|
|
|
|
ptr = malloc(sizeof(UINT8) * c->bufsize);
|
|
if (!ptr) {
|
|
- return IMAGING_CODEC_MEMORY;
|
|
+ state->errcode = IMAGING_CODEC_MEMORY;
|
|
+ return -1;
|
|
}
|
|
_imaging_seek_pyFd(state->fd, SGI_HEADER_SIZE, SEEK_SET);
|
|
_imaging_read_pyFd(state->fd, (char*)ptr, c->bufsize);
|
|
@@ -178,7 +181,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
|
|
|
if (c->rleoffset + c->rlelength > c->bufsize) {
|
|
state->errcode = IMAGING_CODEC_OVERRUN;
|
|
- return -1;
|
|
+ goto sgi_finish_decode;
|
|
}
|
|
|
|
/* row decompression */
|
|
@@ -190,7 +193,7 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
|
|
}
|
|
if (status == -1) {
|
|
state->errcode = IMAGING_CODEC_OVERRUN;
|
|
- return -1;
|
|
+ goto sgi_finish_decode;
|
|
} else if (status == 1) {
|
|
goto sgi_finish_decode;
|
|
}
|
|
@@ -211,7 +214,8 @@ sgi_finish_decode: ;
|
|
free(c->lengthtab);
|
|
free(ptr);
|
|
if (err != 0){
|
|
- return err;
|
|
+ state->errcode=err;
|
|
+ return -1;
|
|
}
|
|
return state->count - c->bufsize;
|
|
}
|
|
--
|
|
2.29.2
|
|
|