diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-01-14 16:19:57 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-01-17 21:59:47 +0300 |
commit | d30cc1ea0b9ba64d8a1e22105528b6cb8077692c (patch) | |
tree | 8064a8a4e305a042a8e5d6efbf26b917ca189a3e /source/blender/avi/intern/avi_mjpeg.c | |
parent | a6700362c71c3978acd53762e1f2e11e7f7a38b5 (diff) |
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
Diffstat (limited to 'source/blender/avi/intern/avi_mjpeg.c')
-rw-r--r-- | source/blender/avi/intern/avi_mjpeg.c | 92 |
1 files changed, 51 insertions, 41 deletions
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, movie->header->Height, *size); MEM_freeN(buffer); if (deint) { - buffer = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_from_mjpeg 2"); - interlace(buffer, buf, movie->header->Width, movie->header->Height); + buffer = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_from_mjpeg 2"); + if (buffer) { + interlace(buffer, buf, movie->header->Width, movie->header->Height); + } MEM_freeN(buf); buf = buffer; @@ -314,43 +317,50 @@ void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffe return buf; } -void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, int *size) +void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size) { unsigned char *buf; - int bufsize = *size; + size_t bufsize = *size; numbytes = 0; *size = 0; - buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 1"); + buf = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_to_mjpeg 1"); + if (!buf) { + return NULL; + } + if (!movie->interlace) { Compress_JPEG(movie->streams[stream].sh.Quality / 100, buf, buffer, movie->header->Width, movie->header->Height, bufsize); + *size += numbytes; } else { deinterlace(movie->odd_fields, buf, buffer, movie->header->Width, movie->header->Height); MEM_freeN(buffer); buffer = buf; - buf = MEM_mallocN(movie->header->Height * movie->header->Width * 3, "avi.avi_converter_to_mjpeg 2"); - - Compress_JPEG(movie->streams[stream].sh.Quality / 100, - buf, buffer, - movie->header->Width, - movie->header->Height / 2, - bufsize / 2); - *size += numbytes; - numbytes = 0; - Compress_JPEG(movie->streams[stream].sh.Quality / 100, - buf + *size, buffer + (movie->header->Height / 2) * movie->header->Width * 3, - movie->header->Width, - movie->header->Height / 2, - bufsize / 2); + buf = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_to_mjpeg 1"); + + if (buf) { + Compress_JPEG(movie->streams[stream].sh.Quality / 100, + buf, buffer, + movie->header->Width, + movie->header->Height / 2, + bufsize / 2); + *size += numbytes; + numbytes = 0; + Compress_JPEG(movie->streams[stream].sh.Quality / 100, + buf + *size, buffer + (size_t)(movie->header->Height / 2) * (size_t)movie->header->Width * 3, + movie->header->Width, + movie->header->Height / 2, + bufsize / 2); + *size += numbytes; + } } - *size += numbytes; MEM_freeN(buffer); return buf; @@ -377,7 +387,7 @@ static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo) MEM_freeN(cinfo->dest); } -static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, int bufsize) +static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize) { cinfo->dest = MEM_mallocN(sizeof(*(cinfo->dest)), "avi.jpegmemdestmgr_build"); @@ -430,7 +440,7 @@ static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo) MEM_freeN(dinfo->src); } -static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, int bufsize) +static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, size_t bufsize) { dinfo->src = MEM_mallocN(sizeof(*(dinfo->src)), "avi.jpegmemsrcmgr_build"); |