Your message dated Fri, 03 Apr 2009 21:47:08 +0000
with message-id <e1lprec-0004mm...@ries.debian.org>
and subject line Bug#522448: fixed in argyll 1.0.3-2
has caused the Debian Bug report #522448,
regarding CVE-2009-0584/CVE-2009-0583: Security issues in ICC library
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
522448: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=522448
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: argyll
Severity: grave
Tags: security

Let's welcome argyll in the archive with an RC security bug :-)

argyll embeds a copy of icclib, which has recently been fixed in
a DSA for ghostscript. I'm attaching the patch from the DSA, please
pass it to argyll upstream and the maintainer of debian-multimedia.org

Cheers,
        Moritz

-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 2.6.29-1-686 (SMP w/1 CPU core)
Locale: LANG=C, lc_ctype=de_de.iso-8859...@euro (charmap=ISO-8859-15)
Shell: /bin/sh linked to /bin/bash
#! /bin/sh /usr/share/dpatch/dpatch-run

@DPATCH@
--- ../old/ghostscript-8.62.dfsg.1/icclib/icc.c	2006-05-24 18:23:16.000000000 +0000
+++ ghostscript-8.62.dfsg.1/icclib/icc.c	2009-03-14 12:55:13.000000000 +0000
@@ -152,6 +152,8 @@
  *      Various bug fixes and enhancements.
  */
 
+#include <limits.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -313,8 +315,11 @@
 	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
@@ -1634,6 +1639,8 @@
 
 	/* 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;
@@ -1698,7 +1705,7 @@
 	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;
 		}
@@ -1749,6 +1756,10 @@
 	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;
 }
@@ -1821,6 +1832,8 @@
 
 	/* 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;
@@ -1885,7 +1898,7 @@
 	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;
 		}
@@ -1936,6 +1949,10 @@
 	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;
 }
@@ -2008,6 +2025,8 @@
 
 	/* 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;
@@ -2072,7 +2091,7 @@
 	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;
 		}
@@ -2123,6 +2142,10 @@
 	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;
 }
@@ -2195,6 +2218,8 @@
 
 	/* 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;
@@ -2259,7 +2284,7 @@
 	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;
 		}
@@ -2310,6 +2335,10 @@
 	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;
 }
@@ -2382,6 +2411,8 @@
 
 	/* 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;
@@ -2446,7 +2477,7 @@
 	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;
 		}
@@ -2497,6 +2528,10 @@
 	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;
 }
@@ -2569,6 +2604,8 @@
 
 	/* 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;
@@ -2633,7 +2670,7 @@
 	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;
 		}
@@ -2726,6 +2763,10 @@
 	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;
 }
@@ -2798,6 +2839,8 @@
 
 	/* 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;
@@ -2865,7 +2908,7 @@
 	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;
 		}
@@ -3001,7 +3044,7 @@
 			int nf;			/* Next free slot */
 			if (rt->rlists[j] == NULL) {	/* No allocation */
 				as = 5;						/* Start with space for 5 */
-				if ((rt->rlists[j] = (int *) icp->al->malloc(icp->al, sizeof(int) * as)) == NULL) {
+				if ((rt->rlists[j] = (int *) icp->al->calloc(icp->al, sizeof(int), as)) == NULL) {
 					return 2;
 				}
 				rt->rlists[j][0] = as;
@@ -3141,6 +3184,10 @@
 	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;
 }
@@ -3238,6 +3285,8 @@
 
 	/* 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;
@@ -3347,7 +3396,7 @@
 	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;
 		}
@@ -3493,6 +3542,8 @@
 
 	/* 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;
@@ -3745,6 +3796,8 @@
 
 	/* 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;
@@ -4038,6 +4091,8 @@
 
 	/* 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;
@@ -4128,11 +4183,15 @@
 /* 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;
 }
 
 /* - - - - - - - - - - - - - - - - */
@@ -4268,7 +4327,7 @@
 	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;
 		}
@@ -4819,19 +4878,50 @@
 ) {
 	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 */
@@ -4844,6 +4934,7 @@
 	icc *icp = p->icp;
 	int rv = 0;
 	unsigned long i, j, g, size;
+	unsigned int pw;
 	char *bp, *buf;
 
 	if (len < 4) {
@@ -4904,6 +4995,11 @@
 		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 */
@@ -4921,13 +5017,18 @@
 		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);
@@ -4942,7 +5043,14 @@
 	}
 
 	/* 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;
@@ -4956,6 +5064,11 @@
 	}
 
 	/* 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);
@@ -4995,12 +5108,14 @@
 	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;
@@ -5066,6 +5181,11 @@
 	}
 
 	/* 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) {
@@ -5086,7 +5206,14 @@
 	}
 
 	/* 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) {
@@ -5106,6 +5233,11 @@
 	}
 
 	/* 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) {
@@ -5177,7 +5309,14 @@
 		if (p->inputChan > MAX_CHAN) {
 			fprintf(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;) {
@@ -5216,7 +5355,7 @@
 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;
 
@@ -5231,6 +5370,10 @@
 		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)
@@ -5241,7 +5384,13 @@
 		}
 		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);
@@ -5251,6 +5400,10 @@
 		}
 		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)
@@ -5441,6 +5594,8 @@
 
 	/* 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;
@@ -5712,13 +5867,20 @@
 			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;
 }
@@ -5882,6 +6044,8 @@
 
 	/* 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;
@@ -6109,9 +6273,22 @@
 ) {
 	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;
 }
@@ -6294,6 +6471,8 @@
 
 	/* 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;
@@ -6544,7 +6723,7 @@
 	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;
 		}
@@ -6820,6 +6999,12 @@
 	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 */
@@ -6852,6 +7037,8 @@
 
 	/* 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;
@@ -6922,7 +7109,7 @@
 	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;
 		}
@@ -7041,6 +7228,8 @@
 
 	/* 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;
@@ -7156,6 +7345,10 @@
 	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;
 }
@@ -7235,6 +7428,8 @@
 
 	/* 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;
@@ -7315,7 +7510,7 @@
 	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;
 		}
@@ -7366,10 +7561,20 @@
 	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 */
@@ -7498,6 +7703,8 @@
 
 	/* 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;
@@ -7663,7 +7870,7 @@
 	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;
 		}
@@ -7672,7 +7879,7 @@
 	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;
 		}
@@ -7743,6 +7950,15 @@
 		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 );
@@ -7762,10 +7978,11 @@
 ) {
 	icmVideoCardGamma *p = (icmVideoCardGamma *)pp;
 	icc *icp = p->icp;
-	int rv, c;
+	int rv;
 	char *bp, *buf;
 	unsigned char *pchar;
 	unsigned short *pshort;
+	unsigned long c;
 
 	if (len < 18) {
 		sprintf(icp->err,"icmVideoCardGamma_read: Tag too small to be legal");
@@ -7803,6 +8020,16 @@
 		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 < p->u.table.channels*p->u.table.entryCount*p->u.table.entrySize) {
 			sprintf(icp->err,"icmVideoCardGamma_read: Tag too small to be legal");
 			return icp->errc = 1;
@@ -7871,6 +8098,8 @@
 
 	/* 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;
@@ -8049,7 +8278,7 @@
 ) {
 	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
@@ -8059,6 +8288,11 @@
 	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) {
@@ -8066,6 +8300,10 @@
 			size *= sizeof(unsigned char);
 			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:
@@ -8201,6 +8439,8 @@
 
 	/* 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;
@@ -8433,6 +8673,8 @@
 
 	/* 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;
@@ -8736,6 +8978,8 @@
 	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;
@@ -9245,13 +9489,23 @@
 	}
 
 	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");
@@ -9274,6 +9528,14 @@
 	    	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");
@@ -9314,8 +9576,14 @@
 	}
 
 	size += p->header->get_size(p->header);
+	if (p->errc)
+		return (unsigned int) -1;
 
 	size = DO_ALIGN(size);
+	if (size == 0 || p->count > (UINT_MAX - 4 - size) / 12) {
+		p->errc = 1;
+		return (unsigned int) -1;
+	}
 	size += 4 + p->count * 12;	/* Tag table length */
 	
 	/* Reset touched flag for each tag type */
@@ -9330,8 +9598,13 @@
 	/* 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 */
+			unsigned int obj_size;
 			size = DO_ALIGN(size);
-			size += p->data[i].objp->get_size(p->data[i].objp);
+			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 */
 		}
 	}
@@ -9366,9 +9639,19 @@
 	}
 
 	size += p->header->get_size(p->header);
+	if (p->errc)
+		return p->errc;
 
+	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 */
 	size = DO_ALIGN(size);
+	if (size == 0 || size > UINT_MAX - len) {
+		sprintf(p->err,"icc_write: overflow writing tag table");
+		return p->errc = 1;
+	}
 	size += len;
 	
 	/* Allocate memory buffer for tag table */
@@ -9399,6 +9682,12 @@
 			size = DO_ALIGN(size);
 			p->data[i].offset = size;			/* Profile relative target */
 			p->data[i].size = p->data[i].objp->get_size(p->data[i].objp);
+			if (size == 0 ||
+			    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;
+			}
 			size += p->data[i].size;
 			p->data[i].objp->touched = 1;	/* Allocated space for it */
 		} else { /* must be linked - copy allocation */
@@ -9522,6 +9811,11 @@
 	}
 
 	/* 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->data == NULL)
 		tp = p->al->malloc(p->al, (p->count+1) * sizeof(icmTag));
 	else
@@ -9605,6 +9899,11 @@
 	}
 
 	/* Make space in tag table for new tag item */
+	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 = p->al->malloc(p->al, (p->count+1) * sizeof(icmTag));
 	else

--- End Message ---
--- Begin Message ---
Source: argyll
Source-Version: 1.0.3-2

We believe that the bug you reported is fixed in the latest version of
argyll, which is due to be installed in the Debian FTP archive:

argyll_1.0.3-2.diff.gz
  to pool/main/a/argyll/argyll_1.0.3-2.diff.gz
argyll_1.0.3-2.dsc
  to pool/main/a/argyll/argyll_1.0.3-2.dsc
argyll_1.0.3-2_i386.deb
  to pool/main/a/argyll/argyll_1.0.3-2_i386.deb



A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 522...@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Roland Mas <lola...@debian.org> (supplier of updated argyll package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmas...@debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Format: 1.8
Date: Fri, 03 Apr 2009 22:43:14 +0200
Source: argyll
Binary: argyll
Architecture: source i386
Version: 1.0.3-2
Distribution: unstable
Urgency: low
Maintainer: Roland Mas <lola...@debian.org>
Changed-By: Roland Mas <lola...@debian.org>
Description: 
 argyll     - Color Management System, calibrator and profiler
Closes: 522448
Changes: 
 argyll (1.0.3-2) unstable; urgency=low
 .
   * Patched embedded copy of icclib to fix integer overflow and denial of
     service vulnerabilities as described in CVE-2009-0583 and
     CVE-2009-0584.  Patch provided by Moritz Muehlenhoff and the Debian
     security team (closes: #522448).
Checksums-Sha1: 
 8a5304d70518cee6c37c02aca9bc80a34d7f7565 1205 argyll_1.0.3-2.dsc
 9ddfb321ea35fe4c51064bd35d1e2a08cc429b0e 21234 argyll_1.0.3-2.diff.gz
 f264658ca0e7e9801a6eab211370c0dc8aa3fe24 9754298 argyll_1.0.3-2_i386.deb
Checksums-Sha256: 
 ce5ad1ee153cc457fc223aaa8dbd342210023d13cc964654a407ea5227eb53fd 1205 
argyll_1.0.3-2.dsc
 1fa82ca0c07d82a04baf8fcb306896d3d03e24c46202735fda67e2d3103acafe 21234 
argyll_1.0.3-2.diff.gz
 824a1e411f81f04f50e7cdef7eab7c5a0429f0074fa6dbbef69f416939cba489 9754298 
argyll_1.0.3-2_i386.deb
Files: 
 8c26f8fc2a85f114b208d1cc56fdcbd5 1205 graphics optional argyll_1.0.3-2.dsc
 505d3ad51621ba8fff80e4a376d35b57 21234 graphics optional argyll_1.0.3-2.diff.gz
 9290f1be87c3e011ee11ee255bedc95b 9754298 graphics optional 
argyll_1.0.3-2_i386.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iD8DBQFJ1n/HDqdWtRRIQ/URAnpXAKChYBfD1HGyCfjmuKr9rU7fo3MUCwCfdrj5
7a34CMhXFQHSecMRJwgtcCU=
=yhzV
-----END PGP SIGNATURE-----



--- End Message ---

Reply via email to