Commit: 0dfcf7b0d2fe4ad164f94aae052c25005601f131 Author: Brecht Van Lommel Date: Sun Jan 14 14:19:57 2018 +0100 Branches: blender-v2.79-release https://developer.blender.org/rB0dfcf7b0d2fe4ad164f94aae052c25005601f131
Fix buffer overflows in TIFF, PNG, IRIS, DPX, HDR and AVI loading. Solves these security issues from T52924: CVE-2017-2899 CVE-2017-2900 CVE-2017-2901 CVE-2017-2902 CVE-2017-2903 CVE-2017-2904 CVE-2017-2905 CVE-2017-2906 CVE-2017-2907 CVE-2017-2918 Differential Revision: https://developer.blender.org/D2999 =================================================================== M source/blender/avi/CMakeLists.txt M source/blender/avi/intern/avi.c M source/blender/avi/intern/avi_codecs.c M source/blender/avi/intern/avi_intern.h M source/blender/avi/intern/avi_mjpeg.c M source/blender/avi/intern/avi_mjpeg.h M source/blender/avi/intern/avi_rgb.c M source/blender/avi/intern/avi_rgb.h M source/blender/avi/intern/avi_rgb32.c M source/blender/avi/intern/avi_rgb32.h M source/blender/imbuf/IMB_imbuf.h M source/blender/imbuf/intern/allocimbuf.c M source/blender/imbuf/intern/bmp.c M source/blender/imbuf/intern/cineon/dpxlib.c M source/blender/imbuf/intern/cineon/logImageCore.c M source/blender/imbuf/intern/cineon/logImageCore.h M source/blender/imbuf/intern/iris.c M source/blender/imbuf/intern/png.c M source/blender/imbuf/intern/radiance_hdr.c M source/blender/imbuf/intern/tiff.c =================================================================== diff --git a/source/blender/avi/CMakeLists.txt b/source/blender/avi/CMakeLists.txt index 292206d8cb9..5009bd2a30b 100644 --- a/source/blender/avi/CMakeLists.txt +++ b/source/blender/avi/CMakeLists.txt @@ -26,6 +26,7 @@ set(INC . ../blenlib + ../imbuf ../../../intern/guardedalloc ) diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 9601d6e5002..6695998fd35 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -285,13 +285,15 @@ bool AVI_is_avi(const char *name) fseek(movie.fp, movie.header->size - 14 * 4, SEEK_CUR); - if (movie.header->Streams < 1) { - DEBUG_PRINT("streams less than 1\n"); + /* Limit number of streams to some reasonable amount to prevent + * buffer oveflow vulnerabilities. */ + if (movie.header->Streams < 1 || movie.header->Streams > 65536) { + DEBUG_PRINT("Number of streams should be in range 1-65536\n"); fclose(movie.fp); return 0; } - movie.streams = (AviStreamRec *) MEM_callocN(sizeof(AviStreamRec) * movie.header->Streams, "moviestreams"); + movie.streams = (AviStreamRec *) MEM_calloc_arrayN(movie.header->Streams, sizeof(AviStreamRec), "moviestreams"); for (temp = 0; temp < movie.header->Streams; temp++) { @@ -486,12 +488,14 @@ AviError AVI_open_movie(const char *name, AviMovie *movie) fseek(movie->fp, movie->header->size - 14 * 4, SEEK_CUR); - if (movie->header->Streams < 1) { - DEBUG_PRINT("streams less than 1\n"); + /* Limit number of streams to some reasonable amount to prevent + * buffer oveflow vulnerabilities. */ + if (movie->header->Streams < 1 || movie->header->Streams > 65536) { + DEBUG_PRINT("Number of streams should be in range 1-65536\n"); return AVI_ERROR_FORMAT; } - movie->streams = (AviStreamRec *) MEM_callocN(sizeof(AviStreamRec) * movie->header->Streams, "moviestreams"); + movie->streams = (AviStreamRec *) MEM_calloc_arrayN(movie->header->Streams, sizeof(AviStreamRec), "moviestreams"); for (temp = 0; temp < movie->header->Streams; temp++) { @@ -689,7 +693,7 @@ AviError AVI_open_movie(const char *name, AviMovie *movie) void *AVI_read_frame(AviMovie *movie, AviFormat format, int frame, int stream) { - int cur_frame = -1, temp, i = 0, rewind = 1; + int cur_frame = -1, i = 0, rewind = 1; void *buffer; /* Retrieve the record number of the desired frame in the index @@ -720,16 +724,16 @@ void *AVI_read_frame(AviMovie *movie, AviFormat format, int frame, int stream) fseek(movie->fp, movie->read_offset + movie->entries[i - 1].Offset, SEEK_SET); - temp = GET_FCC(movie->fp); - buffer = MEM_mallocN(temp, "readbuffer"); + size_t size = GET_FCC(movie->fp); + buffer = MEM_mallocN(size, "readbuffer"); - if (fread(buffer, 1, temp, movie->fp) != temp) { + if (fread(buffer, 1, size, movie->fp) != size) { MEM_freeN(buffer); return NULL; } - buffer = avi_format_convert(movie, stream, buffer, movie->streams[stream].format, format, &temp); + buffer = avi_format_convert(movie, stream, buffer, movie->streams[stream].format, format, &size); return buffer; } @@ -801,6 +805,13 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...) movie->header->Reserved[2] = 0; movie->header->Reserved[3] = 0; + /* Limit number of streams to some reasonable amount to prevent + * buffer oveflow vulnerabilities. */ + if (movie->header->Streams < 0 || movie->header->Streams > 65536) { + DEBUG_PRINT("Number of streams should be in range 0-65536\n"); + return AVI_ERROR_FORMAT; + } + movie->streams = (AviStreamRec *) MEM_mallocN(sizeof(AviStreamRec) * movie->header->Streams, "moviestreams"); va_start(ap, streams); @@ -968,7 +979,6 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...) int64_t rec_off; AviFormat format; void *buffer; - int size; if (frame_num < 0) return AVI_ERROR_OPTION; @@ -1002,7 +1012,7 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...) format = va_arg(ap, AviFormat); buffer = va_arg(ap, void *); - size = va_arg(ap, int); + size_t size = va_arg(ap, int); /* Convert the buffer into the output format */ buffer = avi_format_convert(movie, stream, buffer, format, movie->streams[stream].format, &size); diff --git a/source/blender/avi/intern/avi_codecs.c b/source/blender/avi/intern/avi_codecs.c index c14d088c8ea..f52ec44faab 100644 --- a/source/blender/avi/intern/avi_codecs.c +++ b/source/blender/avi/intern/avi_codecs.c @@ -39,7 +39,7 @@ #include "avi_mjpeg.h" #include "avi_rgb32.h" -void *avi_format_convert(AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size) +void *avi_format_convert(AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, size_t *size) { if (from == to) return buffer; diff --git a/source/blender/avi/intern/avi_intern.h b/source/blender/avi/intern/avi_intern.h index 0b494047612..b2fec1edfc1 100644 --- a/source/blender/avi/intern/avi_intern.h +++ b/source/blender/avi/intern/avi_intern.h @@ -59,7 +59,7 @@ unsigned int GET_TCC(FILE *fp); putc(ch2[1], fp); \ } (void)0 -void *avi_format_convert(AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size); +void *avi_format_convert(AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, size_t *size); int avi_get_data_id(AviFormat format, int stream); int avi_get_format_type(AviFormat format); diff --git a/source/blender/avi/intern/avi_mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c index 1fa9da6b3a2..258426809fb 100644 --- a/source/blender/avi/intern/avi_mjpeg.c +++ b/source/blender/avi/intern/avi_mjpeg.c @@ -39,15 +39,17 @@ #include "MEM_guardedalloc.h" +#include "IMB_imbuf.h" + #include "jpeglib.h" #include "jerror.h" #include "avi_mjpeg.h" -static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, int bufsize); -static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, int bufsize); +static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize); +static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, size_t bufsize); -static int numbytes; +static size_t numbytes; static void add_huff_table(j_decompress_ptr dinfo, JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) { @@ -151,10 +153,8 @@ static void std_huff_tables(j_decompress_ptr dinfo) bits_ac_chrominance, val_ac_chrominance); } -static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsigned int width, unsigned int height, int bufsize) +static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsigned int width, unsigned int height, size_t bufsize) { - int rowstride; - unsigned int y; struct jpeg_decompress_struct dinfo; struct jpeg_error_mgr jerr; @@ -174,8 +174,8 @@ static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsign jpeg_start_decompress(&dinfo); - rowstride = dinfo.output_width * dinfo.output_components; - for (y = 0; y < dinfo.output_height; y++) { + size_t rowstride = dinfo.output_width * dinfo.output_components; + for (size_t y = 0; y < dinfo.output_height; y++) { jpeg_read_scanlines(&dinfo, (JSAMPARRAY) &outBuffer, 1); outBuffer += rowstride; } @@ -194,7 +194,7 @@ static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsign jpeg_start_decompress(&dinfo); rowstride = dinfo.output_width * dinfo.output_components; - for (y = 0; y < dinfo.output_height; y++) { + for (size_t y = 0; y < dinfo.output_height; y++) { jpeg_read_scanlines(&dinfo, (JSAMPARRAY) &outBuffer, 1); outBuffer += rowstride; } @@ -204,10 +204,8 @@ static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsign return 1; } -static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned char *inBuffer, int width, int height, int bufsize) +static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned char *inBuffer, int width, int height, size_t bufsize) { - int i, rowstride; - unsigned int y; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; unsigned char marker[60]; @@ -240,7 +238,7 @@ static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned jpeg_start_compress(&cinfo, false); - i = 0; + int i = 0; marker[i++] = 'A'; marker[i++] = 'V'; marker[i++] = 'I'; @@ -257,8 +255,8 @@ static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned jpeg_write_marker(&cinfo, JPEG_COM, marker, 60); - rowstride = cinfo.image_width * cinfo.input_components; - for (y = 0; y < cinfo.image_height; y++) { + size_t rowstride = cinfo.image_width * cinfo.input_components; + for (size_t y = 0; y < cinfo.image_height; y++) { jpeg_write_scanlines(&cinfo, (JSAMPARRAY) &inBuffer, 1); inBuffer += rowstride; } @@ -268,7 +266,7 @@ static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned static void interlace(unsigned char *to, unsigned char *from, int width, int height) { - int i, rowstride = width * 3; + size_t i, rowstride = width * 3; for (i = 0; i < height; i++) { if (i & 1) @@ -280,7 +278,7 @@ static void interlace(unsigned char *to, unsigned char *from, int width, int hei static void deinterlace(int odd, unsigned char *to, unsigned char *from, int width, int height) { - int i, rowstride = width * 3; + size_t i, rowstride = width * 3; for (i = 0; i < height; i++) { if ((i & 1) == odd) @@ -290,22 +288,27 @@ static void deinterlace(int odd, unsigned char *to, unsigned char *from, int wid } } -void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, int *size) +void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size) { int deint; unsigned char *buf; (void)stream; /* unused */ - buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_from_mjpeg 1"); + buf = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_from_mjpeg 1"); + if (!buf) { + return NULL; + } deint = Decode_JPEG(buffer, buf, movie->header->Width, movi @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs