Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-01-14 16:19:57 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-01-17 21:59:47 +0300
commitd30cc1ea0b9ba64d8a1e22105528b6cb8077692c (patch)
tree8064a8a4e305a042a8e5d6efbf26b917ca189a3e /source/blender/imbuf/intern/cineon
parenta6700362c71c3978acd53762e1f2e11e7f7a38b5 (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/imbuf/intern/cineon')
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c3
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c101
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.h2
3 files changed, 50 insertions, 56 deletions
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 1e4f299def7..b6e8b43b009 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -193,7 +193,8 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
dpx->srcFormat = format_DPX;
dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB);
- if (dpx->numElements == 0) {
+ size_t max_elements = sizeof(header.imageHeader.element)/sizeof(header.imageHeader.element[0]);
+ if (dpx->numElements == 0 || dpx->numElements >= max_elements) {
if (verbose) printf("DPX: Wrong number of elements: %d\n", dpx->numElements);
logImageClose(dpx);
return NULL;
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index 7b5dec4da41..376d40a5f6b 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -38,6 +38,8 @@
#include "BLI_fileops.h"
#include "BLI_utildefines.h"
+#include "IMB_imbuf.h"
+
#include "MEM_guardedalloc.h"
/*
@@ -162,7 +164,7 @@ void logImageGetSize(LogImageFile *logImage, int *width, int *height, int *depth
* Helper
*/
-unsigned int getRowLength(int width, LogImageElement logElement)
+size_t getRowLength(size_t width, LogImageElement logElement)
{
/* return the row length in bytes according to width and packing method */
switch (logElement.bitsPerSample) {
@@ -201,7 +203,7 @@ int logImageSetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB
float *elementData;
int returnValue;
- elementData = (float *)MEM_mallocN(logImage->width * logImage->height * logImage->depth * sizeof(float), __func__);
+ elementData = (float *)imb_alloc_pixels(logImage->width, logImage->height, logImage->depth, sizeof(float), __func__);
if (elementData == NULL)
return 1;
@@ -238,9 +240,8 @@ int logImageSetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB
static int logImageSetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int rowLength = getRowLength(logImage->width, logElement);
+ size_t rowLength = getRowLength(logImage->width, logElement);
unsigned char *row;
- int x, y;
row = (unsigned char *)MEM_mallocN(rowLength, __func__);
if (row == NULL) {
@@ -249,8 +250,8 @@ static int logImageSetData8(LogImageFile *logImage, LogImageElement logElement,
}
memset(row, 0, rowLength);
- for (y = 0; y < logImage->height; y++) {
- for (x = 0; x < logImage->width * logImage->depth; x++)
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++)
row[x] = (unsigned char)float_uint(data[y * logImage->width * logImage->depth + x], 255);
if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
@@ -265,10 +266,9 @@ static int logImageSetData8(LogImageFile *logImage, LogImageElement logElement,
static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int rowLength = getRowLength(logImage->width, logElement);
+ size_t rowLength = getRowLength(logImage->width, logElement);
unsigned int pixel, index;
unsigned int *row;
- int x, y, offset;
row = (unsigned int *)MEM_mallocN(rowLength, __func__);
if (row == NULL) {
@@ -276,12 +276,12 @@ static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement,
return 1;
}
- for (y = 0; y < logImage->height; y++) {
- offset = 22;
+ for (size_t y = 0; y < logImage->height; y++) {
+ int offset = 22;
index = 0;
pixel = 0;
- for (x = 0; x < logImage->width * logImage->depth; x++) {
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++) {
pixel |= (unsigned int)float_uint(data[y * logImage->width * logImage->depth + x], 1023) << offset;
offset -= 10;
if (offset < 0) {
@@ -308,9 +308,8 @@ static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement,
static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int rowLength = getRowLength(logImage->width, logElement);
+ size_t rowLength = getRowLength(logImage->width, logElement);
unsigned short *row;
- int x, y;
row = (unsigned short *)MEM_mallocN(rowLength, __func__);
if (row == NULL) {
@@ -318,8 +317,8 @@ static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement,
return 1;
}
- for (y = 0; y < logImage->height; y++) {
- for (x = 0; x < logImage->width * logImage->depth; x++)
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++)
row[x] = swap_ushort(((unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 4095)) << 4, logImage->isMSB);
if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
@@ -334,9 +333,8 @@ static int logImageSetData12(LogImageFile *logImage, LogImageElement logElement,
static int logImageSetData16(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int rowLength = getRowLength(logImage->width, logElement);
+ size_t rowLength = getRowLength(logImage->width, logElement);
unsigned short *row;
- int x, y;
row = (unsigned short *)MEM_mallocN(rowLength, __func__);
if (row == NULL) {
@@ -344,8 +342,8 @@ static int logImageSetData16(LogImageFile *logImage, LogImageElement logElement,
return 1;
}
- for (y = 0; y < logImage->height; y++) {
- for (x = 0; x < logImage->width * logImage->depth; x++)
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logImage->depth; x++)
row[x] = swap_ushort((unsigned short)float_uint(data[y * logImage->width * logImage->depth + x], 65535), logImage->isMSB);
if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
@@ -382,7 +380,7 @@ int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB
/* descriptor_Depth and descriptor_Composite are not supported */
if (logImage->element[i].descriptor != descriptor_Depth && logImage->element[i].descriptor != descriptor_Composite) {
/* Allocate memory */
- elementData[i] = (float *)MEM_mallocN(logImage->width * logImage->height * logImage->element[i].depth * sizeof(float), __func__);
+ elementData[i] = imb_alloc_pixels(logImage->width, logImage->height, logImage->element[i].depth, sizeof(float), __func__);
if (elementData[i] == NULL) {
if (verbose) printf("DPX/Cineon: Cannot allocate memory for elementData[%d]\n.", i);
for (j = 0; j < i; j++)
@@ -530,7 +528,7 @@ int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB
}
}
- mergedData = (float *)MEM_mallocN(logImage->width * logImage->height * mergedElement.depth * sizeof(float), __func__);
+ mergedData = (float *)imb_alloc_pixels(logImage->width, logImage->height, mergedElement.depth, sizeof(float), __func__);
if (mergedData == NULL) {
if (verbose) printf("DPX/Cineon: Cannot allocate mergedData.\n");
for (i = 0; i < logImage->numElements; i++)
@@ -590,7 +588,6 @@ static int logImageElementGetData(LogImageFile *logImage, LogImageElement logEle
static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logElement, float *data)
{
unsigned int pixel;
- int x, y, offset;
/* seek at the right place */
if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
@@ -599,14 +596,14 @@ static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logEl
}
/* read 1 bit data padded to 32 bits */
- for (y = 0; y < logImage->height; y++) {
- for (x = 0; x < logImage->width * logElement.depth; x += 32) {
+ for (size_t y = 0; y < logImage->height; y++) {
+ for (size_t x = 0; x < logImage->width * logElement.depth; x += 32) {
if (logimage_read_uint(&pixel, logImage) != 0) {
if (verbose) printf("DPX/Cineon: EOF reached\n");
return 1;
}
pixel = swap_uint(pixel, logImage->isMSB);
- for (offset = 0; offset < 32 && x + offset < logImage->width; offset++)
+ for (int offset = 0; offset < 32 && x + offset < logImage->width; offset++)
data[y * logImage->width * logElement.depth + x + offset] = (float)((pixel >> offset) & 0x01);
}
}
@@ -615,19 +612,18 @@ static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logEl
static int logImageElementGetData8(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int rowLength = getRowLength(logImage->width, logElement);
+ size_t rowLength = getRowLength(logImage->width, logElement);
unsigned char pixel;
- int x, y;
/* extract required pixels */
- for (y = 0; y < logImage->height; y++) {
+ for (size_t y = 0; y < logImage->height; y++) {
/* 8 bits are 32-bits padded so we need to seek at each row */
if (logimage_fseek(logImage, logElement.dataOffset + y * rowLength, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %d\n", logElement.dataOffset + y * (int)rowLength);
+ if (verbose) printf("DPX/Cineon: Couldn't seek at %d\n", (int)(logElement.dataOffset + y * rowLength));
return 1;
}
- for (x = 0; x < logImage->width * logElement.depth; x++) {
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
if (logimage_read_uchar(&pixel, logImage) != 0) {
if (verbose) printf("DPX/Cineon: EOF reached\n");
return 1;
@@ -641,7 +637,6 @@ static int logImageElementGetData8(LogImageFile *logImage, LogImageElement logEl
static int logImageElementGetData10(LogImageFile *logImage, LogImageElement logElement, float *data)
{
unsigned int pixel;
- int x, y, offset;
/* seek to data */
if (logimage_fseek(logImage, logElement.dataOffset, SEEK_SET) != 0) {
@@ -650,9 +645,9 @@ static int logImageElementGetData10(LogImageFile *logImage, LogImageElement logE
}
if (logImage->depth == 1 && logImage->srcFormat == format_DPX) {
- for (y = 0; y < logImage->height; y++) {
- offset = 32;
- for (x = 0; x < logImage->width * logElement.depth; x++) {
+ for (size_t y = 0; y < logImage->height; y++) {
+ int offset = 32;
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
/* we need to read the next long */
if (offset >= 30) {
if (logElement.packing == 1)
@@ -672,9 +667,9 @@ static int logImageElementGetData10(LogImageFile *logImage, LogImageElement logE
}
}
else {
- for (y = 0; y < logImage->height; y++) {
- offset = -1;
- for (x = 0; x < logImage->width * logElement.depth; x++) {
+ for (size_t y = 0; y < logImage->height; y++) {
+ int offset = -1;
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
/* we need to read the next long */
if (offset < 0) {
if (logElement.packing == 1)
@@ -699,23 +694,22 @@ static int logImageElementGetData10(LogImageFile *logImage, LogImageElement logE
static int logImageElementGetData10Packed(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int rowLength = getRowLength(logImage->width, logElement);
+ size_t rowLength = getRowLength(logImage->width, logElement);
unsigned int pixel, oldPixel;
- int offset, offset2, x, y;
/* converting bytes to pixels */
- for (y = 0; y < logImage->height; y++) {
+ for (size_t y = 0; y < logImage->height; y++) {
/* seek to data */
if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %u\n", y * rowLength + logElement.dataOffset);
+ if (verbose) printf("DPX/Cineon: Couldn't seek at %u\n", (int)(y * rowLength + logElement.dataOffset));
return 1;
}
oldPixel = 0;
- offset = 0;
- offset2 = 0;
+ int offset = 0;
+ int offset2 = 0;
- for (x = 0; x < logImage->width * logElement.depth; x++) {
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
if (offset2 != 0) {
offset = 10 - offset2;
offset2 = 0;
@@ -778,23 +772,22 @@ static int logImageElementGetData12(LogImageFile *logImage, LogImageElement logE
static int logImageElementGetData12Packed(LogImageFile *logImage, LogImageElement logElement, float *data)
{
- unsigned int rowLength = getRowLength(logImage->width, logElement);
+ size_t rowLength = getRowLength(logImage->width, logElement);
unsigned int pixel, oldPixel;
- int offset, offset2, x, y;
/* converting bytes to pixels */
- for (y = 0; y < logImage->height; y++) {
+ for (size_t y = 0; y < logImage->height; y++) {
/* seek to data */
if (logimage_fseek(logImage, y * rowLength + logElement.dataOffset, SEEK_SET) != 0) {
- if (verbose) printf("DPX/Cineon: Couldn't seek at %u\n", y * rowLength + logElement.dataOffset);
+ if (verbose) printf("DPX/Cineon: Couldn't seek at %u\n", (int)(y * rowLength + logElement.dataOffset));
return 1;
}
oldPixel = 0;
- offset = 0;
- offset2 = 0;
+ int offset = 0;
+ int offset2 = 0;
- for (x = 0; x < logImage->width * logElement.depth; x++) {
+ for (size_t x = 0; x < logImage->width * logElement.depth; x++) {
if (offset2 != 0) {
offset = 12 - offset2;
offset2 = 0;
@@ -1119,7 +1112,7 @@ static int convertRGBA_RGBA(float *src, float *dst, LogImageFile *logImage,
case transfer_UserDefined:
case transfer_Linear:
case transfer_Logarithmic: {
- memcpy(dst, src, 4 * logImage->width * logImage->height * sizeof(float));
+ memcpy(dst, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
return 0;
}
@@ -1434,11 +1427,11 @@ static int convertRGBAToLogElement(float *src, float *dst, LogImageFile *logImag
if (srcIsLinearRGB != 0) {
/* we need to convert src to sRGB */
- srgbSrc = (float *)MEM_mallocN(4 * logImage->width * logImage->height * sizeof(float), __func__);
+ srgbSrc = (float *)imb_alloc_pixels(logImage->width, logImage->height, 4, sizeof(float), __func__);
if (srgbSrc == NULL)
return 1;
- memcpy(srgbSrc, src, 4 * logImage->width * logImage->height * sizeof(float));
+ memcpy(srgbSrc, src, 4 * (size_t)logImage->width * (size_t)logImage->height * sizeof(float));
srgbSrc_ptr = srgbSrc;
/* convert data from Linear RGB to sRGB via lut */
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h
index e39df1ea096..b6f4fff73f6 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.h
+++ b/source/blender/imbuf/intern/cineon/logImageCore.h
@@ -196,7 +196,7 @@ LogImageFile *logImageCreate(const char *filename, int cineon, int width, int he
void logImageClose(LogImageFile *logImage);
/* Data handling */
-unsigned int getRowLength(int width, LogImageElement logElement);
+size_t getRowLength(size_t width, LogImageElement logElement);
int logImageSetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB);
int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB);