76 lines
3.0 KiB
Diff
76 lines
3.0 KiB
Diff
From 3bf5eddb89afdf690eceaa52bc4d3546ba9a5f87 Mon Sep 17 00:00:00 2001
|
|
From: Eric Soroos <eric-github@soroos.net>
|
|
Date: Sun, 7 Mar 2021 12:32:12 +0100
|
|
Subject: [PATCH] Fix OOB Read in Jpeg2KDecode CVE-2021-25287,CVE-2021-25288
|
|
|
|
Conflict:NA
|
|
Reference:https://github.com/python-pillow/Pillow/commit/3bf5eddb89afdf690eceaa52bc4d3546ba9a5f87
|
|
---
|
|
src/libImaging/Jpeg2KDecode.c | 33 +++++++++++++++++++++++++--------
|
|
1 file changed, 25 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/src/libImaging/Jpeg2KDecode.c b/src/libImaging/Jpeg2KDecode.c
|
|
index 8cce545..60d4d77 100644
|
|
--- a/src/libImaging/Jpeg2KDecode.c
|
|
+++ b/src/libImaging/Jpeg2KDecode.c
|
|
@@ -589,7 +589,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
|
j2k_unpacker_t unpack = NULL;
|
|
size_t buffer_size = 0, tile_bytes = 0;
|
|
unsigned n, tile_height, tile_width;
|
|
- int components;
|
|
+ int total_component_width = 0;
|
|
|
|
|
|
stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE);
|
|
@@ -753,23 +753,40 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
|
goto quick_exit;
|
|
}
|
|
|
|
+ if (tile_info.nb_comps != image->numcomps) {
|
|
+ state->errcode = IMAGING_CODEC_BROKEN;
|
|
+ state->state = J2K_STATE_FAILED;
|
|
+ goto quick_exit;
|
|
+ }
|
|
+
|
|
/* Sometimes the tile_info.datasize we get back from openjpeg
|
|
- is less than numcomps*w*h, and we overflow in the
|
|
+ is less than sum(comp_bytes)*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 ))) {
|
|
+
|
|
+ /* Total component width = sum (component_width) e.g, it's
|
|
+ legal for an la file to have a 1 byte width for l, and 4 for
|
|
+ a. and then a malicious file could have a smaller tile_bytes
|
|
+ */
|
|
+
|
|
+ for (n=0; n < tile_info.nb_comps; n++) {
|
|
+ // see csize /acsize calcs
|
|
+ int csize = (image->comps[n].prec + 7) >> 3;
|
|
+ csize = (csize == 3) ? 4 : csize;
|
|
+ total_component_width += csize;
|
|
+ }
|
|
+ if ((tile_width > UINT_MAX / total_component_width) ||
|
|
+ (tile_height > UINT_MAX / total_component_width) ||
|
|
+ (tile_width > UINT_MAX / (tile_height * total_component_width)) ||
|
|
+ (tile_height > UINT_MAX / (tile_width * total_component_width))) {
|
|
state->errcode = IMAGING_CODEC_BROKEN;
|
|
state->state = J2K_STATE_FAILED;
|
|
goto quick_exit;
|
|
}
|
|
|
|
- tile_bytes = tile_width * tile_height * components;
|
|
+ tile_bytes = tile_width * tile_height * total_component_width;
|
|
|
|
if (tile_bytes > tile_info.data_size) {
|
|
tile_info.data_size = tile_bytes;
|
|
--
|
|
2.23.0
|
|
|