From 92c46f59644120b84299be331bf789cda0bad7bf Mon Sep 17 00:00:00 2001 From: Jon Ciesla Date: Mar 23 2009 15:45:50 +0000 Subject: Patch for ICC library CVE-2009-{0583, 0584} by Tim Waugh. --- diff --git a/argyllcms-CVE-2009-0583,0584.patch b/argyllcms-CVE-2009-0583,0584.patch new file mode 100644 index 0000000..4cd0127 --- /dev/null +++ b/argyllcms-CVE-2009-0583,0584.patch @@ -0,0 +1,1063 @@ +--- icc/icc.c.CVE-2009-0583,0584 2008-09-03 01:10:23.000000000 +0100 ++++ icc/icc.c 2009-03-20 17:36:41.000000000 +0000 +@@ -53,6 +53,8 @@ + + #define _ICC_C_ /* Turn on implimentation code */ + ++#include ++#include + #include + #include + #include +@@ -122,8 +124,11 @@ size_t count + icmFileMem *p = (icmFileMem *)pp; + size_t len; + ++ if (count > 0 && size > SIZE_MAX / count) ++ return 0; ++ + len = size * count; +- if ((p->cur + len) >= p->end) { /* Too much */ ++ if (len > (p->end - p->cur)) { /* Too much */ + if (size > 0) + count = (p->end - p->cur)/size; + else +@@ -146,8 +151,11 @@ size_t count + icmFileMem *p = (icmFileMem *)pp; + size_t len; + ++ if (count > 0 && size > SIZE_MAX / count) ++ return 0; ++ + len = size * count; +- if ((p->cur + len) >= p->end) { /* Too much */ ++ if (len > (p->end - p->cur)) { /* Too much */ + if (size > 0) + count = (p->end - p->cur)/size; + else +@@ -1725,6 +1733,8 @@ static int icmUnknown_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmUnknown_write malloc() failed"); + return icp->errc = 2; +@@ -1833,7 +1843,7 @@ static int icmUnknown_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (unsigned char *) icp->al->malloc(icp->al, p->size * sizeof(unsigned char))) == NULL) { ++ if ((p->data = (unsigned char *) icp->al->calloc(icp->al, p->size, sizeof(unsigned char))) == NULL) { + sprintf(icp->err,"icmUnknown_alloc: malloc() of icmUnknown data failed"); + return icp->errc = 2; + } +@@ -1957,6 +1967,8 @@ static int icmUInt8Array_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmUInt8Array_write malloc() failed"); + return icp->errc = 2; +@@ -2021,7 +2033,7 @@ static int icmUInt8Array_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (unsigned int *) icp->al->malloc(icp->al, p->size * sizeof(unsigned int))) == NULL) { ++ if ((p->data = (unsigned int *) icp->al->calloc(icp->al, p->size, sizeof(unsigned int))) == NULL) { + sprintf(icp->err,"icmUInt8Array_alloc: malloc() of icmUInt8Array data failed"); + return icp->errc = 2; + } +@@ -2072,6 +2084,10 @@ static unsigned int icmUInt16Array_get_s + icmUInt16Array *p = (icmUInt16Array *)pp; + unsigned int len = 0; + len += 8; /* 8 bytes for tag and padding */ ++ if (p->size > (UINT_MAX - len) / 2) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += p->size * 2; /* 2 bytes for each UInt16 */ + return len; + } +@@ -2144,6 +2160,8 @@ static int icmUInt16Array_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmUInt16Array_write malloc() failed"); + return icp->errc = 2; +@@ -2208,7 +2226,7 @@ static int icmUInt16Array_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (unsigned int *) icp->al->malloc(icp->al, p->size * sizeof(unsigned int))) == NULL) { ++ if ((p->data = (unsigned int *) icp->al->calloc(icp->al, p->size, sizeof(unsigned int))) == NULL) { + sprintf(icp->err,"icmUInt16Array_alloc: malloc() of icmUInt16Array data failed"); + return icp->errc = 2; + } +@@ -2259,6 +2277,10 @@ static unsigned int icmUInt32Array_get_s + icmUInt32Array *p = (icmUInt32Array *)pp; + unsigned int len = 0; + len += 8; /* 8 bytes for tag and padding */ ++ if (p->size > (UINT_MAX - len) / 4) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += p->size * 4; /* 4 bytes for each UInt32 */ + return len; + } +@@ -2331,6 +2353,8 @@ static int icmUInt32Array_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmUInt32Array_write malloc() failed"); + return icp->errc = 2; +@@ -2395,7 +2419,7 @@ static int icmUInt32Array_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (unsigned int *) icp->al->malloc(icp->al, p->size * sizeof(unsigned int))) == NULL) { ++ if ((p->data = (unsigned int *) icp->al->calloc(icp->al, p->size, sizeof(unsigned int))) == NULL) { + sprintf(icp->err,"icmUInt32Array_alloc: malloc() of icmUInt32Array data failed"); + return icp->errc = 2; + } +@@ -2446,6 +2470,10 @@ static unsigned int icmUInt64Array_get_s + icmUInt64Array *p = (icmUInt64Array *)pp; + unsigned int len = 0; + len += 8; /* 8 bytes for tag and padding */ ++ if (p->size > (UINT_MAX - len) / 8) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += p->size * 8; /* 8 bytes for each UInt64 */ + return len; + } +@@ -2518,6 +2546,8 @@ static int icmUInt64Array_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmUInt64Array_write malloc() failed"); + return icp->errc = 2; +@@ -2582,7 +2612,7 @@ static int icmUInt64Array_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (icmUint64 *) icp->al->malloc(icp->al, p->size * sizeof(icmUint64))) == NULL) { ++ if ((p->data = (icmUint64 *) icp->al->calloc(icp->al, p->size, sizeof(icmUint64))) == NULL) { + sprintf(icp->err,"icmUInt64Array_alloc: malloc() of icmUInt64Array data failed"); + return icp->errc = 2; + } +@@ -2633,6 +2663,10 @@ static unsigned int icmU16Fixed16Array_g + icmU16Fixed16Array *p = (icmU16Fixed16Array *)pp; + unsigned int len = 0; + len += 8; /* 8 bytes for tag and padding */ ++ if (p->size > (UINT_MAX - len) / 4) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += p->size * 4; /* 4 byte for each U16Fixed16 */ + return len; + } +@@ -2705,6 +2739,8 @@ static int icmU16Fixed16Array_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmU16Fixed16Array_write malloc() failed"); + return icp->errc = 2; +@@ -2769,7 +2805,7 @@ static int icmU16Fixed16Array_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (double *) icp->al->malloc(icp->al, p->size * sizeof(double))) == NULL) { ++ if ((p->data = (double *) icp->al->calloc(icp->al, p->size, sizeof(double))) == NULL) { + sprintf(icp->err,"icmU16Fixed16Array_alloc: malloc() of icmU16Fixed16Array data failed"); + return icp->errc = 2; + } +@@ -2820,6 +2856,10 @@ static unsigned int icmS15Fixed16Array_g + icmS15Fixed16Array *p = (icmS15Fixed16Array *)pp; + unsigned int len = 0; + len += 8; /* 8 bytes for tag and padding */ ++ if (p->size > (UINT_MAX - len) / 4) { ++ p->icp->errc = 1; ++ return (unsigned int) - 1; ++ } + len += p->size * 4; /* 4 byte for each S15Fixed16 */ + return len; + } +@@ -2892,6 +2932,8 @@ static int icmS15Fixed16Array_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmS15Fixed16Array_write malloc() failed"); + return icp->errc = 2; +@@ -2956,7 +2998,7 @@ static int icmS15Fixed16Array_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (double *) icp->al->malloc(icp->al, p->size * sizeof(double))) == NULL) { ++ if ((p->data = (double *) icp->al->calloc(icp->al, p->size, sizeof(double))) == NULL) { + sprintf(icp->err,"icmS15Fixed16Array_alloc: malloc() of icmS15Fixed16Array data failed"); + return icp->errc = 2; + } +@@ -3049,6 +3091,10 @@ static unsigned int icmXYZArray_get_size + icmXYZArray *p = (icmXYZArray *)pp; + unsigned int len = 0; + len += 8; /* 8 bytes for tag and padding */ ++ if (p->size > (UINT_MAX - len) / 12) { ++ p->icp->errc = 1; ++ return (unsigned int) - 1; ++ } + len += p->size * 12; /* 12 bytes for each XYZ */ + return len; + } +@@ -3121,6 +3167,8 @@ static int icmXYZArray_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmXYZArray_write malloc() failed"); + return icp->errc = 2; +@@ -3188,7 +3236,7 @@ static int icmXYZArray_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (icmXYZNumber *) icp->al->malloc(icp->al, p->size * sizeof(icmXYZNumber))) == NULL) { ++ if ((p->data = (icmXYZNumber *) icp->al->calloc(icp->al, p->size, sizeof(icmXYZNumber))) == NULL) { + sprintf(icp->err,"icmXYZArray_alloc: malloc() of icmXYZArray data failed"); + return icp->errc = 2; + } +@@ -3468,6 +3516,10 @@ static unsigned int icmCurve_get_size( + icmCurve *p = (icmCurve *)pp; + unsigned int len = 0; + len += 12; /* 12 bytes for tag, padding and count */ ++ if (p->size > (UINT_MAX - len) / 2) { ++ p->icp->errc = 1; ++ return (unsigned int) - 1; ++ } + len += p->size * 2; /* 2 bytes for each UInt16 */ + return len; + } +@@ -3565,6 +3617,8 @@ static int icmCurve_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmCurve_write malloc() failed"); + return icp->errc = 2; +@@ -3674,7 +3728,7 @@ static int icmCurve_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (double *) icp->al->malloc(icp->al, p->size * sizeof(double))) == NULL) { ++ if ((p->data = (double *) icp->al->calloc(icp->al, p->size, sizeof(double))) == NULL) { + sprintf(icp->err,"icmCurve_alloc: malloc() of icmCurve data failed"); + return icp->errc = 2; + } +@@ -3824,6 +3878,8 @@ static int icmData_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmData_write malloc() failed"); + return icp->errc = 2; +@@ -3971,7 +4027,7 @@ static int icmData_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (unsigned char *) icp->al->malloc(icp->al, p->size * sizeof(unsigned char))) == NULL) { ++ if ((p->data = (unsigned char *) icp->al->calloc(icp->al, p->size, sizeof(unsigned char))) == NULL) { + sprintf(icp->err,"icmData_alloc: malloc() of icmData data failed"); + return icp->errc = 2; + } +@@ -4096,6 +4152,8 @@ static int icmText_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmText_write malloc() failed"); + return icp->errc = 2; +@@ -4185,7 +4243,7 @@ static int icmText_allocate( + if (p->size != p->_size) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (char *) icp->al->malloc(icp->al, p->size * sizeof(char))) == NULL) { ++ if ((p->data = (char *) icp->al->calloc(icp->al, p->size, sizeof(char))) == NULL) { + sprintf(icp->err,"icmText_alloc: malloc() of icmText data failed"); + return icp->errc = 2; + } +@@ -4433,6 +4491,8 @@ static int icmDateTimeNumber_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmDateTimeNumber_write malloc() failed"); + return icp->errc = 2; +@@ -4523,11 +4583,15 @@ static icmBase *new_icmDateTimeNumber( + /* icmLut object */ + + /* Utility function - raise one integer to an integer power */ +-static unsigned int uipow(unsigned int a, unsigned int b) { ++static int uipow(unsigned int a, unsigned int b, unsigned int *ret) { + unsigned int rv = 1; +- for (; b > 0; b--) ++ for (; b > 0; b--) { ++ if (a > 0 && rv > UINT_MAX / a) ++ return 1; + rv *= a; +- return rv; ++ } ++ *ret = rv; ++ return 0; + } + + /* - - - - - - - - - - - - - - - - */ +@@ -4667,7 +4731,7 @@ double *in /* Input array[outputChan] * + if (p->inputChan <= 8) { + gw = GW; /* Use stack allocation */ + } else { +- if ((gw = (double *) icp->al->malloc(icp->al, (1 << p->inputChan) * sizeof(double))) == NULL) { ++ if ((gw = (double *) icp->al->calloc(icp->al, (1 << p->inputChan), sizeof(double))) == NULL) { + sprintf(icp->err,"icmLut_lookup_clut: malloc() failed"); + return icp->errc = 2; + } +@@ -5653,19 +5717,50 @@ static unsigned int icmLut_get_size( + ) { + icmLut *p = (icmLut *)pp; + unsigned int len = 0; ++ unsigned int pw; + + if (p->ttype == icSigLut8Type) { + len += 48; /* tag and header */ ++ if (p->inputChan > 0 && ++ p->inputEnt > (UINT_MAX - len) / p->inputChan / 1) ++ goto overflow; ++ + len += 1 * (p->inputChan * p->inputEnt); +- len += 1 * (p->outputChan * uipow(p->clutPoints,p->inputChan)); ++ if (uipow(p->clutPoints,p->inputChan, &pw) || ++ (p->outputChan > 0 && ++ pw > (UINT_MAX - len) / p->outputChan / 1)) ++ goto overflow; ++ ++ len += 1 * (p->outputChan * pw); ++ if (p->outputChan > 0 && ++ p->outputEnt > (UINT_MAX - len) / p->outputChan / 1) ++ goto overflow; ++ + len += 1 * (p->outputChan * p->outputEnt); + } else { + len += 52; /* tag and header */ ++ if (p->inputChan > 0 && ++ p->inputEnt > (UINT_MAX - len) / p->inputChan / 2) ++ goto overflow; ++ + len += 2 * (p->inputChan * p->inputEnt); +- len += 2 * (p->outputChan * uipow(p->clutPoints,p->inputChan)); ++ if (uipow(p->clutPoints,p->inputChan, &pw) || ++ (p->outputChan > 0 && ++ pw > (UINT_MAX - len) / p->outputChan / 2)) ++ goto overflow; ++ ++ len += 2 * (p->outputChan * pw); ++ if (p->outputChan > 0 && ++ p->outputEnt > (UINT_MAX - len) / p->outputChan / 2) ++ goto overflow; ++ + len += 2 * (p->outputChan * p->outputEnt); + } + return len; ++ ++ overflow: ++ p->icp->errc = 1; ++ return (unsigned int) -1; + } + + /* read the object, return 0 on success, error code on fail */ +@@ -5678,6 +5773,7 @@ static int icmLut_read( + icc *icp = p->icp; + int rv = 0; + unsigned long i, j, g, size; ++ unsigned int pw; + char *bp, *buf; + + if (len < 4) { +@@ -5738,6 +5834,11 @@ static int icmLut_read( + return icp->errc = 1; + } + ++ if (p->clutPoints > 100) { ++ sprintf(icp->err,"icmLut_read: too many clutPoints"); ++ return icp->errc = 1; ++ } ++ + /* Read 3x3 transform matrix */ + for (j = 0; j < 3; j++) { /* Rows */ + for (i = 0; i < 3; i++) { /* Columns */ +@@ -5755,13 +5856,18 @@ static int icmLut_read( + bp = buf+52; + } + +- if (len < icmLut_get_size((icmBase *)p)) { ++ if (len < icmLut_get_size((icmBase *)p) || icp->errc) { + sprintf(icp->err,"icmLut_read: Tag too small for contents"); + icp->al->free(icp->al, buf); + return icp->errc = 1; + } + + /* Read the input tables */ ++ if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) { ++ sprintf(icp->err,"icmLut_read: overflow"); ++ icp->al->free(icp->al, buf); ++ return icp->errc = 1; ++ } + size = (p->inputChan * p->inputEnt); + if ((rv = p->allocate((icmBase *)p)) != 0) { + icp->al->free(icp->al, buf); +@@ -5776,7 +5882,14 @@ static int icmLut_read( + } + + /* Read the clut table */ +- size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); ++ if (uipow(p->clutPoints,p->inputChan,&pw) || ++ (p->outputChan > 0 && ++ pw > UINT_MAX / p->outputChan)) { ++ sprintf(icp->err,"icmLut_read: overflow"); ++ icp->al->free(icp->al, buf); ++ return icp->errc = 1; ++ } ++ size = (p->outputChan * pw); + if ((rv = p->allocate((icmBase *)p)) != 0) { + icp->al->free(icp->al, buf); + return rv; +@@ -5790,6 +5903,11 @@ static int icmLut_read( + } + + /* Read the output tables */ ++ if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) { ++ sprintf(icp->err,"icmLut_read: overflow"); ++ icp->al->free(icp->al, buf); ++ return icp->errc = 1; ++ } + size = (p->outputChan * p->outputEnt); + if ((rv = p->allocate((icmBase *)p)) != 0) { + icp->al->free(icp->al, buf); +@@ -5829,12 +5947,14 @@ static int icmLut_write( + icmLut *p = (icmLut *)pp; + icc *icp = p->icp; + unsigned long i,j; +- unsigned int len, size; ++ unsigned int len, size, pw; + char *bp, *buf; /* Buffer to write from */ + int rv = 0; + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmLut_write malloc() failed"); + return icp->errc = 2; +@@ -5907,6 +6027,11 @@ static int icmLut_write( + } + + /* Write the input tables */ ++ if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) { ++ sprintf(icp->err,"icmLut_write: overflow"); ++ icp->al->free(icp->al, buf); ++ return icp->errc = 1; ++ } + size = (p->inputChan * p->inputEnt); + if (p->ttype == icSigLut8Type) { + for (i = 0; i < size; i++, bp += 1) { +@@ -5927,7 +6052,14 @@ static int icmLut_write( + } + + /* Write the clut table */ +- size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); ++ if (uipow(p->clutPoints,p->inputChan,&pw) || ++ (p->outputChan > 0 && ++ pw > UINT_MAX / p->outputChan)) { ++ sprintf(icp->err,"icmLut_write: overflow"); ++ icp->al->free(icp->al, buf); ++ return icp->errc = 1; ++ } ++ size = (p->outputChan * pw); + if (p->ttype == icSigLut8Type) { + for (i = 0; i < size; i++, bp += 1) { + if ((rv = write_DCS8Number(p->clutTable[i], bp)) != 0) { +@@ -5947,6 +6079,11 @@ static int icmLut_write( + } + + /* Write the output tables */ ++ if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) { ++ sprintf(icp->err,"icmLut_write: overflow"); ++ icp->al->free(icp->al, buf); ++ return icp->errc = 1; ++ } + size = (p->outputChan * p->outputEnt); + if (p->ttype == icSigLut8Type) { + for (i = 0; i < size; i++, bp += 1) { +@@ -6017,7 +6154,14 @@ static void icmLut_dump( + if (p->inputChan > MAX_CHAN) { + op->gprintf(op," !!Can't dump > %d input channel CLUT table!!\n",MAX_CHAN); + } else { +- size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); ++ unsigned int pw; ++ if (uipow(p->clutPoints,p->inputChan,&pw) || ++ (p->outputChan > 0 && ++ pw > UINT_MAX / p->outputChan)) { ++ fprintf(op,"Would overflow.\n"); ++ return; ++ } ++ size = (p->outputChan * pw); + for (j = 0; j < p->inputChan; j++) + ii[j] = 0; + for (i = 0; i < size;) { +@@ -6056,7 +6200,7 @@ static void icmLut_dump( + static int icmLut_allocate( + icmBase *pp + ) { +- unsigned int i, j, g, size; ++ unsigned int i, j, g, size, pw; + icmLut *p = (icmLut *)pp; + icc *icp = p->icp; + +@@ -6071,6 +6215,10 @@ static int icmLut_allocate( + return icp->errc = 1; + } + ++ if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) { ++ sprintf(icp->err,"icmLut_alloc: too many entries"); ++ return icp->errc = 1; ++ } + size = (p->inputChan * p->inputEnt); + if (size != p->inputTable_size) { + if (p->inputTable != NULL) +@@ -6081,7 +6229,13 @@ static int icmLut_allocate( + } + p->inputTable_size = size; + } +- size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); ++ if (uipow(p->clutPoints,p->inputChan,&pw) || ++ (p->outputChan > 0 && ++ pw > UINT_MAX / p->outputChan)) { ++ sprintf(icp->err,"icmLut_alloc: overflow"); ++ return icp->errc = 1; ++ } ++ size = (p->outputChan * pw); + if (size != p->clutTable_size) { + if (p->clutTable != NULL) + icp->al->free(icp->al, p->clutTable); +@@ -6091,6 +6245,10 @@ static int icmLut_allocate( + } + p->clutTable_size = size; + } ++ if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) { ++ sprintf(icp->err,"icmLut_alloc: overflow"); ++ return icp->errc = 1; ++ } + size = (p->outputChan * p->outputEnt); + if (size != p->outputTable_size) { + if (p->outputTable != NULL) +@@ -6286,6 +6444,8 @@ static int icmMeasurement_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmMeasurement_write malloc() failed"); + return icp->errc = 2; +@@ -6553,13 +6713,20 @@ static unsigned int icmNamedColor_get_si + len += p->nDeviceCoords * 1; /* bytes for each named color */ + } + } else { /* Named Color 2 */ ++ unsigned int col; + len += 8; /* 8 bytes for tag and padding */ + len += 4; /* 4 for vendor specific flags */ + len += 4; /* 4 for count of named colors */ + len += 4; /* 4 for number of device coords */ + len += 32; /* 32 for prefix of color names */ + len += 32; /* 32 for suffix of color names */ +- len += p->count * (32 + 6 + p->nDeviceCoords * 2); /* bytes for each named color */ ++ col = 32 + 6 + p->nDeviceCoords * 2; ++ if (p->nDeviceCoords > (UINT_MAX - (32 + 6)) / 2 || ++ (p->count > 0 && col > (UINT_MAX - len) / p->count)) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } ++ len += p->count * col; /* bytes for each named color */ + } + return len; + } +@@ -6723,6 +6890,8 @@ static int icmNamedColor_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmNamedColor_write malloc() failed"); + return icp->errc = 2; +@@ -7116,6 +7285,8 @@ static int icmColorantTable_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmColorantTable_write malloc() failed"); + return icp->errc = 2; +@@ -7270,9 +7441,22 @@ static unsigned int icmTextDescription_g + ) { + icmTextDescription *p = (icmTextDescription *)pp; + unsigned int len = 0; ++ if (p->size > UINT_MAX - (8 + 4 + 8)) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += 8; /* 8 bytes for tag and padding */ + len += 4 + p->size; /* Ascii string length + ascii string */ +- len += 8 + 2 * p->ucSize; /* Unicode language code + length + string */ ++ len += 8; /* Unicode language code + length */ ++ if (p->ucSize > (UINT_MAX - len) / 2) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } ++ len += 2 * p->ucSize; /* Unicode string */ ++ if (len > (UINT_MAX - (3 + 67))) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += 3 + 67; /* ScriptCode code, length string */ + return len; + } +@@ -7460,6 +7644,8 @@ static int icmTextDescription_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmTextDescription_write malloc() failed"); + return icp->errc = 2; +@@ -7710,7 +7896,7 @@ static int icmTextDescription_allocate( + if (p->ucSize != p->uc_size) { + if (p->ucDesc != NULL) + icp->al->free(icp->al, p->ucDesc); +- if ((p->ucDesc = (ORD16 *) icp->al->malloc(icp->al, p->ucSize * sizeof(ORD16))) == NULL) { ++ if ((p->ucDesc = (ORD16 *) icp->al->calloc(icp->al, p->ucSize, sizeof(ORD16))) == NULL) { + sprintf(icp->err,"icmTextDescription_alloc: malloc() of Unicode description failed"); + return icp->errc = 2; + } +@@ -7986,6 +8172,12 @@ static int icmProfileSequenceDesc_read( + bp += 8; /* Skip padding */ + + p->count = read_UInt32Number(bp); /* Number of sequence descriptions */ ++ if (p->count > 1000) { ++ sprintf(icp->err,"icmProfileSequenceDesc_read: too many sequence descriptions"); ++ icp->al->free(icp->al, buf); ++ return icp->errc = 1; ++ } ++ + bp += 4; + + /* Read all the sequence descriptions */ +@@ -8018,6 +8210,8 @@ static int icmProfileSequenceDesc_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmProfileSequenceDesc_write malloc() failed"); + return icp->errc = 2; +@@ -8088,7 +8282,7 @@ static int icmProfileSequenceDesc_alloca + if (p->count != p->_count) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (icmDescStruct *) icp->al->malloc(icp->al, p->count * sizeof(icmDescStruct))) == NULL) { ++ if ((p->data = (icmDescStruct *) icp->al->calloc(icp->al, p->count, sizeof(icmDescStruct))) == NULL) { + sprintf(icp->err,"icmProfileSequenceDesc_allocate Allocation of DescStruct array failed"); + return icp->errc = 2; + } +@@ -8207,6 +8401,8 @@ static int icmSignature_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmSignature_write malloc() failed"); + return icp->errc = 2; +@@ -8322,6 +8518,10 @@ static unsigned int icmScreening_get_siz + icmScreening *p = (icmScreening *)pp; + unsigned int len = 0; + len += 16; /* 16 bytes for tag, padding, flag & channeles */ ++ if (p->channels > (UINT_MAX - len) / 12) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += p->channels * 12; /* 12 bytes for each channel */ + return len; + } +@@ -8401,6 +8601,8 @@ static int icmScreening_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmScreening_write malloc() failed"); + return icp->errc = 2; +@@ -8481,7 +8683,7 @@ static int icmScreening_allocate( + if (p->channels != p->_channels) { + if (p->data != NULL) + icp->al->free(icp->al, p->data); +- if ((p->data = (icmScreeningData *) icp->al->malloc(icp->al, p->channels * sizeof(icmScreeningData))) == NULL) { ++ if ((p->data = (icmScreeningData *) icp->al->calloc(icp->al, p->channels, sizeof(icmScreeningData))) == NULL) { + sprintf(icp->err,"icmScreening_alloc: malloc() of icmScreening data failed"); + return icp->errc = 2; + } +@@ -8532,10 +8734,20 @@ static unsigned int icmUcrBg_get_size( + icmUcrBg *p = (icmUcrBg *)pp; + unsigned int len = 0; + len += 8; /* 8 bytes for tag and padding */ ++ if (p->UCRcount > (UINT_MAX - len - 4) / 2) ++ goto overflow; ++ + len += 4 + p->UCRcount * 2; /* Undercolor Removal */ ++ if (p->BGcount > (UINT_MAX - len - 4 - p->size) / 2) ++ goto overflow; ++ + len += 4 + p->BGcount * 2; /* Black Generation */ + len += p->size; /* Description string */ + return len; ++ ++ overflow: ++ p->icp->errc = 1; ++ return (unsigned int) -1; + } + + /* read the object, return 0 on success, error code on fail */ +@@ -8664,6 +8876,8 @@ static int icmUcrBg_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmUcrBg_write malloc() failed"); + return icp->errc = 2; +@@ -8829,7 +9043,7 @@ static int icmUcrBg_allocate( + if (p->UCRcount != p->UCR_count) { + if (p->UCRcurve != NULL) + icp->al->free(icp->al, p->UCRcurve); +- if ((p->UCRcurve = (double *) icp->al->malloc(icp->al, p->UCRcount * sizeof(double))) == NULL) { ++ if ((p->UCRcurve = (double *) icp->al->calloc(icp->al, p->UCRcount, sizeof(double))) == NULL) { + sprintf(icp->err,"icmUcrBg_allocate: malloc() of UCR curve data failed"); + return icp->errc = 2; + } +@@ -8838,7 +9052,7 @@ static int icmUcrBg_allocate( + if (p->BGcount != p->BG_count) { + if (p->BGcurve != NULL) + icp->al->free(icp->al, p->BGcurve); +- if ((p->BGcurve = (double *) icp->al->malloc(icp->al, p->BGcount * sizeof(double))) == NULL) { ++ if ((p->BGcurve = (double *) icp->al->calloc(icp->al, p->BGcount, sizeof(double))) == NULL) { + sprintf(icp->err,"icmUcrBg_allocate: malloc() of BG curve data failed"); + return icp->errc = 2; + } +@@ -8910,6 +9124,15 @@ static unsigned int icmVideoCardGamma_ge + len += 2; /* 2 bytes for channels */ + len += 2; /* 2 for entry count */ + len += 2; /* 2 for entry size */ ++ if (p->u.table.entryCount > 0 && ++ p->u.table.entrySize > 0 && ++ p->u.table.channels > ++ (UINT_MAX - len) / ++ p->u.table.entryCount / ++ p->u.table.entrySize) { ++ p->icp->errc = 1; ++ return (unsigned int) -1; ++ } + len += ( p->u.table.channels * /* compute table size */ + p->u.table.entryCount * + p->u.table.entrySize ); +@@ -8929,10 +9152,11 @@ static int icmVideoCardGamma_read( + ) { + icmVideoCardGamma *p = (icmVideoCardGamma *)pp; + icc *icp = p->icp; +- int rv, c; ++ int rv; + char *bp, *buf; + ORD8 *pchar; + ORD16 *pshort; ++ unsigned long c; + + if (len < 18) { + sprintf(icp->err,"icmVideoCardGamma_read: Tag too small to be legal"); +@@ -8969,6 +9193,16 @@ static int icmVideoCardGamma_read( + p->u.table.channels = read_UInt16Number(bp+12); + p->u.table.entryCount = read_UInt16Number(bp+14); + p->u.table.entrySize = read_UInt16Number(bp+16); ++ if (p->u.table.entrySize > 65530 || p->u.table.entrySize == 0) { ++ sprintf(icp->err,"icmVideoCardGamma_read: Too many entries (or none)"); ++ return icp->errc = 1; ++ } ++ if (p->u.table.entryCount > 0 && p->u.table.entrySize > 0 && ++ p->u.table.channels > ++ UINT_MAX / p->u.table.entryCount / p->u.table.entrySize) { ++ sprintf(icp->err,"icmVideoCardGamma_read: Overflow reading tag"); ++ return icp->errc = 1; ++ } + if ((len-18) < (unsigned int)(p->u.table.channels + * p->u.table.entryCount + * p->u.table.entrySize)) { +@@ -9039,6 +9273,8 @@ static int icmVideoCardGamma_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmViewingConditions_write malloc() failed"); + return icp->errc = 2; +@@ -9211,7 +9447,7 @@ static int icmVideoCardGamma_allocate( + ) { + icmVideoCardGamma *p = (icmVideoCardGamma *)pp; + icc *icp = p->icp; +- int size; ++ unsigned int size; + + /* note: allocation is only relevant for table type + * and in that case the channels, entryCount, and entrySize +@@ -9221,6 +9457,11 @@ static int icmVideoCardGamma_allocate( + if (p->tagType == icmVideoCardGammaTableType) { + if (p->u.table.data != NULL) + icp->al->free(icp->al, p->u.table.data); ++ if (p->u.table.entryCount > 0 && ++ p->u.table.channels > UINT_MAX / p->u.table.entryCount) { ++ sprintf(icp->err,"icmVideoCardGamma_alloc: table too large"); ++ return icp->errc = 1; ++ } + size = (p->u.table.channels * + p->u.table.entryCount); + switch (p->u.table.entrySize) { +@@ -9228,6 +9469,10 @@ static int icmVideoCardGamma_allocate( + size *= sizeof(ORD8); + break; + case 2: ++ if (size > UINT_MAX / sizeof(unsigned short)) { ++ sprintf(icp->err,"icmVideoCardGamma_alloc: table too large"); ++ return icp->errc = 1; ++ } + size *= sizeof(unsigned short); + break; + default: +@@ -9428,6 +9673,8 @@ static int icmViewingConditions_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmViewingConditions_write malloc() failed"); + return icp->errc = 2; +@@ -9660,6 +9907,8 @@ static int icmCrdInfo_write( + + /* Allocate a file write buffer */ + len = p->get_size((icmBase *)p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { + sprintf(icp->err,"icmCrdInfo_write malloc() failed"); + return icp->errc = 2; +@@ -9977,6 +10226,8 @@ static int icmHeader_write( + int rv = 0; + + len = p->get_size(p); ++ if (icp->errc) ++ return icp->errc; + if ((buf = (char *) icp->al->calloc(icp->al,1,len)) == NULL) { /* Zero it - some CMS are fussy */ + sprintf(icp->err,"icmHeader_write calloc() failed"); + return icp->errc = 2; +@@ -10563,13 +10814,23 @@ static int icc_read_x( + } + + p->count = read_UInt32Number(tcbuf); /* Tag count */ ++ if (p->count > 100) { ++ sprintf(p->err,"icc_read: too many table tags"); ++ return p->errc = 1; ++ } + if (p->count > 0) { + char *bp, *buf; +- if ((p->data = (icmTag *) p->al->malloc(p->al, p->count * sizeof(icmTag))) == NULL) { ++ if ((p->data = (icmTag *) p->al->calloc(p->al, p->count, sizeof(icmTag))) == NULL) { + sprintf(p->err,"icc_read: Tag table malloc() failed"); + return p->errc = 2; + } + ++ if (p->count > (UINT_MAX - 4) / 12) { ++ sprintf(p->err,"icc_read: overflow"); ++ p->al->free(p->al, p->data); ++ p->data = NULL; ++ return p->errc = 1; ++ } + len = 4 + p->count * 12; + if ((buf = (char *) p->al->malloc(p->al, len)) == NULL) { + sprintf(p->err,"icc_read: Tag table read buffer malloc() failed"); +@@ -10592,6 +10853,14 @@ static int icc_read_x( + p->data[i].sig = (icTagSignature)read_SInt32Number(bp + 0); + p->data[i].offset = read_UInt32Number(bp + 4); + p->data[i].size = read_UInt32Number(bp + 8); ++ if (p->data[i].offset + p->data[i].size > ++ p->header->size) { ++ sprintf(p->err,"icc_read: tag out of bounds"); ++ p->al->free(p->al, p->data); ++ p->data = NULL; ++ p->al->free(p->al, buf); ++ return p->errc = 1; ++ } + if ( p->fp->seek(p->fp, of + p->data[i].offset) != 0 + || p->fp->read(p->fp, tcbuf, 1, 4) != 4) { + sprintf(p->err,"icc_read: fseek() or fread() failed on tag headers"); +@@ -10728,9 +10997,19 @@ static unsigned int icc_get_size( + } + + size += p->header->get_size(p->header); ++ if (p->errc) ++ return (unsigned int) -1; + /* Assume header is aligned */ ++ if (p->count > (UINT_MAX - 4 - size) / 12) { ++ p->errc = 1; ++ return (unsigned int) -1; ++ } + size += 4 + p->count * 12; /* Tag table length */ + size = DO_ALIGN(size); ++ if (size == 0) { ++ p->errc = 1; ++ return (unsigned int) -1; ++ } + + /* Reset touched flag for each tag type */ + for (i = 0; i < p->count; i++) { +@@ -10744,8 +11023,13 @@ static unsigned int icc_get_size( + /* Get size for each tag type, skipping links */ + for (i = 0; i < p->count; i++) { + if (p->data[i].objp->touched == 0) { /* Not alllowed for previously */ +- size += p->data[i].objp->get_size(p->data[i].objp); ++ unsigned int obj_size; + size = DO_ALIGN(size); ++ obj_size = p->data[i].objp->get_size(p->data[i].objp); ++ if (size == 0 || p->errc || ++ obj_size > UINT_MAX - size) ++ return (unsigned int) -1; ++ size += obj_size; + p->data[i].objp->touched = 1; /* Don't account for this again */ + } + } +@@ -10787,11 +11071,27 @@ static int icc_write_x( + } + + size += p->header->get_size(p->header); ++ if (p->errc) ++ return p->errc; ++ + /* Assume header is aligned */ + ++ if (p->count > (UINT_MAX - 4 - len) / 12) { ++ sprintf(p->err,"icc_write: too many tags"); ++ return p->errc = 1; ++ } + len = 4 + p->count * 12; /* Tag table length */ +- len = DO_ALIGN(size + len) - size; /* Aligned size */ +- size = DO_ALIGN(size + len); ++ if (size > (UINT_MAX - len)) { ++ sprintf(p->err,"icc_write: overflow writing tag table"); ++ return p->errc = 1; ++ } ++ len = DO_ALIGN(size + len); ++ if (len == 0) { ++ sprintf(p->err,"icc_write: overflow writing tag table"); ++ return p->errc = 1; ++ } ++ len -= size; /* Aligned size */ ++ size = DO_ALIGN(size + len); /* now known not to overflow */ + + /* Allocate memory buffer for tag table */ + if ((buf = (char *) p->al->calloc(p->al, 1, len)) == NULL) { +@@ -10821,9 +11121,19 @@ static int icc_write_x( + if (p->data[i].objp->touched == 0) { /* Allocate space for tag type */ + p->data[i].offset = size; /* Profile relative target */ + p->data[i].size = p->data[i].objp->get_size(p->data[i].objp); ++ if (p->errc || p->data[i].size > UINT_MAX - size) { ++ sprintf(p->err,"icc_write: internal error - overflow?"); ++ p->al->free(p->al, buf); ++ return p->errc = 1; ++ } + size += p->data[i].size; + p->data[i].pad = DO_ALIGN(size) - size; + size = DO_ALIGN(size); ++ if (size == 0) { ++ sprintf(p->err,"icc_write: overflow"); ++ p->al->free(p->al, buf); ++ return p->errc = 1; ++ } + p->data[i].objp->touched = 1; /* Allocated space for it */ + } else { /* must be linked - copy allocation */ + unsigned int k; +@@ -11058,6 +11368,16 @@ static icmBase *icc_add_tag( + } + + /* Make space in tag table for new tag item */ ++ if (p->count > (UINT_MAX / sizeof(icmTag)) - 1) { ++ sprintf(p->err,"icc_add_tag: overflow"); ++ p->errc = 1; ++ return NULL; ++ } ++ if (p->count > (UINT_MAX / sizeof(icmTag)) - 1) { ++ sprintf(p->err,"icc_link_tag: overflow"); ++ p->errc = 1; ++ return NULL; ++ } + if (p->data == NULL) + tp = (icmBase *)p->al->malloc(p->al, (p->count+1) * sizeof(icmTag)); + else +@@ -16161,7 +16481,9 @@ double *chmax /* device return chann + + lut = ll->lut; + gp = lut->clutTable; /* Base of grid array */ +- size = uipow(lut->clutPoints,lut->inputChan); ++ if (uipow(lut->clutPoints,lut->inputChan,&size) || size < 0) { ++ return -1.0; ++ } + for (i = 0; i < size; i++) { + double tot, vv[MAX_CHAN]; + diff --git a/argyllcms.spec b/argyllcms.spec index fdae9d2..441b5b3 100644 --- a/argyllcms.spec +++ b/argyllcms.spec @@ -5,7 +5,7 @@ Name: argyllcms Version: 1.0.3 -Release: 2%{?alphatag}%{?dist} +Release: 3%{?alphatag}%{?dist} Summary: ICC compatible color management system Group: User Interface/X @@ -18,6 +18,7 @@ Patch1: http://www.blackfiveservices.co.uk/Argyll_V1.0.1_autotools.patch.gz Patch2: %{name}-1.0.3-remove-libusb-fork-check.patch # Patch applied for legal reasons Patch4: %{name}-1.0.2-legal.patch +Patch5: argyllcms-CVE-2009-0583,0584.patch BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRequires: libtiff-devel, libusb-devel @@ -64,6 +65,7 @@ This package contains the Argyll color management system documentation. %patch2 -p1 -b .sysusb # Legal patch required %patch4 -p1 -b .legal +%patch5 -p0 # Salvage policy files mv libusb/19-color.fdi . @@ -115,6 +117,9 @@ rm -rf %{buildroot} %changelog +* Mon Mar 23 2009 Jon Ciesla - 1.0.3-3 +- Patch for ICC library CVE-2009-{0583, 0584} by Tim Waugh. + * Mon Feb 23 2009 Fedora Release Engineering - 1.0.3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild