aboutsummaryrefslogtreecommitdiffstats
path: root/main/py3-pillow/CVE-2020-35655.patch
blob: 2a5048af3c90767a2aae423593ffed559f097f04 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
upstream: https://github.com/python-pillow/Pillow/commit/120eea2e4547a7d1826afdf01563035844f0b7d5

diff --git a/src/libImaging/SgiRleDecode.c b/src/libImaging/SgiRleDecode.c
index a03ecd4..9a8814b 100644
--- a/src/libImaging/SgiRleDecode.c
+++ b/src/libImaging/SgiRleDecode.c
@@ -112,14 +112,33 @@ 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) {
+        state->errcode = IMAGING_CODEC_MEMORY;
+        return -1;
+    }
+
     /* 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) {
+        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);
@@ -134,18 +153,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 ||
@@ -176,7 +188,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 */
@@ -188,7 +200,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;
             }
@@ -209,7 +221,8 @@ sgi_finish_decode: ;
     free(c->lengthtab);
     free(ptr);
     if (err != 0){
-        return err;
+        state->errcode=err;
+        return -1;
     }
     return state->count - c->bufsize;
 }