Sophie

Sophie

distrib > Mageia > 7 > aarch64 > by-pkgid > e495bfb0c3db167421e07edd8769eed1 > files > 15

python-pillow-5.4.1-1.3.mga7.src.rpm

From cf6da6b79080a8c16984102fdc85f7ce28dca613 Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Mon, 9 Mar 2020 22:09:49 +0000
Subject: [PATCH 1/4] Fix for OOB Read in DecodeJpeg2k

---
 src/libImaging/Jpeg2KDecode.c | 60 +++++++++++++++++++++++++----------
 1 file changed, 43 insertions(+), 17 deletions(-)

diff --git a/src/libImaging/Jpeg2KDecode.c b/src/libImaging/Jpeg2KDecode.c
index f2e437dda2..6cf8b8e9c5 100644
--- a/src/libImaging/Jpeg2KDecode.c
+++ b/src/libImaging/Jpeg2KDecode.c
@@ -110,6 +110,7 @@ j2ku_gray_l(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
     if (shift < 0)
         offset += 1 << (-shift - 1);
 
+    /* csiz*h*w + offset = tileinfo.datasize */
     switch (csiz) {
     case 1:
         for (y = 0; y < h; ++y) {
@@ -557,8 +558,10 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
     opj_dparameters_t params;
     OPJ_COLOR_SPACE color_space;
     j2k_unpacker_t unpack = NULL;
-    size_t buffer_size = 0;
-    unsigned n;
+    size_t buffer_size = 0, tile_bytes = 0;
+    unsigned n, tile_height, tile_width;
+    int components;
+
 
     stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE);
 
@@ -703,8 +706,44 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
         tile_info.x1 = (tile_info.x1 + correction) >> context->reduce;
         tile_info.y1 = (tile_info.y1 + correction) >> context->reduce;
 
+        /* Check the tile bounds; if the tile is outside the image area,
+           or if it has a negative width or height (i.e. the coordinates are
+           swapped), bail. */
+        if (tile_info.x0 >= tile_info.x1
+            || tile_info.y0 >= tile_info.y1
+            || tile_info.x0 < image->x0
+            || tile_info.y0 < image->y0
+            || tile_info.x1 - image->x0 > im->xsize
+            || tile_info.y1 - image->y0 > im->ysize) {
+            state->errcode = IMAGING_CODEC_BROKEN;
+            state->state = J2K_STATE_FAILED;
+            goto quick_exit;
+        }
+
+        /* Sometimes the tile_info.datasize we get back from openjpeg
+           is is less than numcomps*w*h, and we overflow in the
+           shuffle stage */
+
+        tile_width = tile_info.x1 - tile_info.x0;
+        tile_height = tile_info.y1 - tile_info.y0;
+        components = tile_info.nb_comps == 3 ? 4 : tile_info.nb_comps;
+        if (( tile_width > UINT_MAX / components ) ||
+            ( tile_height > UINT_MAX / components ) ||
+            ( tile_width > UINT_MAX / (tile_height * components )) ||
+            ( tile_height > UINT_MAX / (tile_width * components ))) {
+            state->errcode = IMAGING_CODEC_BROKEN;
+            state->state = J2K_STATE_FAILED;
+            goto quick_exit;
+        }
+
+        tile_bytes = tile_width * tile_height * components;
+
+        if (tile_bytes > tile_info.data_size) {
+            tile_info.data_size = tile_bytes;
+        }
+
         if (buffer_size < tile_info.data_size) {
-            /* malloc check ok, tile_info.data_size from openjpeg */
+            /* malloc check ok, overflow and tile size sanity check above */
             UINT8 *new = realloc (state->buffer, tile_info.data_size);
             if (!new) {
                 state->errcode = IMAGING_CODEC_MEMORY;
@@ -715,6 +754,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
             buffer_size = tile_info.data_size;
         }
 
+
         if (!opj_decode_tile_data(codec,
                                   tile_info.tile_index,
                                   (OPJ_BYTE *)state->buffer,
@@ -725,20 +765,6 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
             goto quick_exit;
         }
 
-        /* Check the tile bounds; if the tile is outside the image area,
-           or if it has a negative width or height (i.e. the coordinates are
-           swapped), bail. */
-        if (tile_info.x0 >= tile_info.x1
-            || tile_info.y0 >= tile_info.y1
-            || tile_info.x0 < image->x0
-            || tile_info.y0 < image->y0
-            || tile_info.x1 - image->x0 > im->xsize
-            || tile_info.y1 - image->y0 > im->ysize) {
-            state->errcode = IMAGING_CODEC_BROKEN;
-            state->state = J2K_STATE_FAILED;
-            goto quick_exit;
-        }
-
         unpack(image, &tile_info, state->buffer, im);
     }