[Bf-blender-cvs] [d30cc1ea0b9] master: Fix buffer overflows in TIFF, PNG, IRIS, DPX, HDR and AVI loading.

Brecht Van Lommel noreply at git.blender.org
Wed Jan 17 20:30:04 CET 2018


Commit: d30cc1ea0b9ba64d8a1e22105528b6cb8077692c
Author: Brecht Van Lommel
Date:   Sun Jan 14 14:19:57 2018 +0100
Branches: master
https://developer.blender.org/rBd30cc1ea0b9ba64d8a1e22105528b6cb8077692c

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. @@



More information about the Bf-blender-cvs mailing list