http://openwall.com/lists/oss-security/2017/08/28/3 https://github.com/uclouvain/openjpeg/commit/2cd30c2b06ce332dede81cccad8b334cde997281.patch From 2cd30c2b06ce332dede81cccad8b334cde997281 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 17 Aug 2017 11:47:40 +0200 Subject: [PATCH] tgatoimage(): avoid excessive memory allocation attempt, and fixes unaligned load (#995) --- src/bin/jp2/convert.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/bin/jp2/convert.c b/src/bin/jp2/convert.c index a4eb81f6a..73dfc8d5f 100644 --- a/src/bin/jp2/convert.c +++ b/src/bin/jp2/convert.c @@ -580,13 +580,10 @@ struct tga_header { }; #endif /* INFORMATION_ONLY */ -static unsigned short get_ushort(const unsigned char *data) +/* Returns a ushort from a little-endian serialized value */ +static unsigned short get_tga_ushort(const unsigned char *data) { - unsigned short val = *(const unsigned short *)data; -#ifdef OPJ_BIG_ENDIAN - val = ((val & 0xffU) << 8) | (val >> 8); -#endif - return val; + return data[0] | (data[1] << 8); } #define TGA_HEADER_SIZE 18 @@ -613,17 +610,17 @@ static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel, id_len = tga[0]; /*cmap_type = tga[1];*/ image_type = tga[2]; - /*cmap_index = get_ushort(&tga[3]);*/ - cmap_len = get_ushort(&tga[5]); + /*cmap_index = get_tga_ushort(&tga[3]);*/ + cmap_len = get_tga_ushort(&tga[5]); cmap_entry_size = tga[7]; #if 0 - x_origin = get_ushort(&tga[8]); - y_origin = get_ushort(&tga[10]); + x_origin = get_tga_ushort(&tga[8]); + y_origin = get_tga_ushort(&tga[10]); #endif - image_w = get_ushort(&tga[12]); - image_h = get_ushort(&tga[14]); + image_w = get_tga_ushort(&tga[12]); + image_h = get_tga_ushort(&tga[14]); pixel_depth = tga[16]; image_desc = tga[17]; @@ -817,6 +814,24 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) color_space = OPJ_CLRSPC_SRGB; } + /* If the declared file size is > 10 MB, check that the file is big */ + /* enough to avoid excessive memory allocations */ + if (image_height != 0 && image_width > 10000000 / image_height / numcomps) { + char ch; + OPJ_UINT64 expected_file_size = + (OPJ_UINT64)image_width * image_height * numcomps; + long curpos = ftell(f); + if (expected_file_size > (OPJ_UINT64)INT_MAX) { + expected_file_size = (OPJ_UINT64)INT_MAX; + } + fseek(f, (long)expected_file_size - 1, SEEK_SET); + if (fread(&ch, 1, 1, f) != 1) { + fclose(f); + return NULL; + } + fseek(f, curpos, SEEK_SET); + } + subsampling_dx = parameters->subsampling_dx; subsampling_dy = parameters->subsampling_dy;