mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-11 15:54:45 +03:00
CVE-2021-25287,CVE-2021-25288: Fix OOB Read in Jpeg2KDecode
This commit is contained in:
parent
414de92fe3
commit
4b207548e0
|
@ -2,6 +2,14 @@
|
||||||
Changelog (Pillow)
|
Changelog (Pillow)
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
6.2.2.2 (date TBD)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- This is the second Pillow release to support Python 2.7 from ActiveState
|
||||||
|
|
||||||
|
- Fix OOB Read in Jpeg2KDecode. CVE 2021-25287, CVE 2021-25288
|
||||||
|
[emilieyyu]
|
||||||
|
|
||||||
6.2.2.1 (2021-10-08)
|
6.2.2.1 (2021-10-08)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
BIN
Tests/images/crash-4fb027452e6988530aa5dabee76eecacb3b79f8a.j2k
Normal file
BIN
Tests/images/crash-4fb027452e6988530aa5dabee76eecacb3b79f8a.j2k
Normal file
Binary file not shown.
BIN
Tests/images/crash-7d4c83eb92150fb8f1653a697703ae06ae7c4998.j2k
Normal file
BIN
Tests/images/crash-7d4c83eb92150fb8f1653a697703ae06ae7c4998.j2k
Normal file
Binary file not shown.
BIN
Tests/images/crash-ccca68ff40171fdae983d924e127a721cab2bd50.j2k
Normal file
BIN
Tests/images/crash-ccca68ff40171fdae983d924e127a721cab2bd50.j2k
Normal file
Binary file not shown.
BIN
Tests/images/crash-d2c93af851d3ab9a19e34503626368b2ecde9c03.j2k
Normal file
BIN
Tests/images/crash-d2c93af851d3ab9a19e34503626368b2ecde9c03.j2k
Normal file
Binary file not shown.
|
@ -4,6 +4,8 @@ from PIL import Image, Jpeg2KImagePlugin
|
||||||
|
|
||||||
from .helper import PillowTestCase
|
from .helper import PillowTestCase
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
codecs = dir(Image.core)
|
codecs = dir(Image.core)
|
||||||
|
|
||||||
test_card = Image.open("Tests/images/test-card.png")
|
test_card = Image.open("Tests/images/test-card.png")
|
||||||
|
@ -210,3 +212,19 @@ class TestFileJpeg2k(PillowTestCase):
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
self.assertEqual(p.image.size, (640, 480))
|
self.assertEqual(p.image.size, (640, 480))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"test_file",
|
||||||
|
[
|
||||||
|
"Tests/images/crash-4fb027452e6988530aa5dabee76eecacb3b79f8a.j2k",
|
||||||
|
"Tests/images/crash-7d4c83eb92150fb8f1653a697703ae06ae7c4998.j2k",
|
||||||
|
"Tests/images/crash-ccca68ff40171fdae983d924e127a721cab2bd50.j2k",
|
||||||
|
"Tests/images/crash-d2c93af851d3ab9a19e34503626368b2ecde9c03.j2k",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_crashes(test_file):
|
||||||
|
with open(test_file, "rb") as f:
|
||||||
|
with Image.open(f) as im:
|
||||||
|
# Valgrind should not complain here
|
||||||
|
im.load()
|
||||||
|
|
10
docs/releasenotes/6.2.2.2.rst
Normal file
10
docs/releasenotes/6.2.2.2.rst
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
6.2.2.2
|
||||||
|
-------
|
||||||
|
|
||||||
|
Security
|
||||||
|
========
|
||||||
|
|
||||||
|
This release addresses several critical CVEs.
|
||||||
|
|
||||||
|
CVE 2021-25287, CVE 2021-25288 has out-of-bounds read in J2kDecode, in
|
||||||
|
j2ku_graya_la.
|
|
@ -6,6 +6,7 @@ Release Notes
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
6.2.2.2
|
||||||
6.2.2.1
|
6.2.2.1
|
||||||
6.2.2
|
6.2.2
|
||||||
6.2.1
|
6.2.1
|
||||||
|
|
|
@ -557,8 +557,9 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
opj_dparameters_t params;
|
opj_dparameters_t params;
|
||||||
OPJ_COLOR_SPACE color_space;
|
OPJ_COLOR_SPACE color_space;
|
||||||
j2k_unpacker_t unpack = NULL;
|
j2k_unpacker_t unpack = NULL;
|
||||||
size_t buffer_size = 0;
|
size_t buffer_size = 0, tile_bytes = 0;
|
||||||
unsigned n;
|
unsigned n, tile_height, tile_width;
|
||||||
|
int total_component_width = 0;
|
||||||
|
|
||||||
stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE);
|
stream = opj_stream_create(BUFFER_SIZE, OPJ_TRUE);
|
||||||
|
|
||||||
|
@ -703,6 +704,59 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
|
||||||
tile_info.x1 = (tile_info.x1 + correction) >> context->reduce;
|
tile_info.x1 = (tile_info.x1 + correction) >> context->reduce;
|
||||||
tile_info.y1 = (tile_info.y1 + 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 < 0 || tile_info.y0 < 0 ||
|
||||||
|
(OPJ_UINT32)tile_info.x0 < image->x0 ||
|
||||||
|
(OPJ_UINT32)tile_info.y0 < image->y0 ||
|
||||||
|
(OPJ_INT32)(tile_info.x1 - image->x0) > im->xsize ||
|
||||||
|
(OPJ_INT32)(tile_info.y1 - image->y0) > im->ysize) {
|
||||||
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
|
state->state = J2K_STATE_FAILED;
|
||||||
|
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 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;
|
||||||
|
|
||||||
|
/* 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 * total_component_width;
|
||||||
|
|
||||||
|
if (tile_bytes > tile_info.data_size) {
|
||||||
|
tile_info.data_size = tile_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer_size < tile_info.data_size) {
|
if (buffer_size < tile_info.data_size) {
|
||||||
/* malloc check ok, tile_info.data_size from openjpeg */
|
/* malloc check ok, tile_info.data_size from openjpeg */
|
||||||
UINT8 *new = realloc (state->buffer, tile_info.data_size);
|
UINT8 *new = realloc (state->buffer, tile_info.data_size);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user