[arch-commits] Commit in ghostscript/trunk (3 files)

andyrtr at archlinux.org andyrtr at archlinux.org
Sun Apr 12 13:34:02 UTC 2009


    Date: Sunday, April 12, 2009 @ 09:34:02
  Author: andyrtr
Revision: 35333

upgpkg: ghostscript 8.64-4
    apply some security fixes

Added:
  ghostscript/trunk/ghostscript-CVE-2009-0583_and_0584.patch
  ghostscript/trunk/jbig2_symbol_dict.patch
Modified:
  ghostscript/trunk/PKGBUILD

------------------------------------------+
 PKGBUILD                                 |   15 
 ghostscript-CVE-2009-0583_and_0584.patch |  989 +++++++++++++++++++++++++++++
 jbig2_symbol_dict.patch                  |   45 +
 3 files changed, 1046 insertions(+), 3 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2009-04-12 12:46:16 UTC (rev 35332)
+++ PKGBUILD	2009-04-12 13:34:02 UTC (rev 35333)
@@ -3,7 +3,7 @@
 
 pkgname=ghostscript
 pkgver=8.64
-pkgrel=3
+pkgrel=4
 pkgdesc="An interpreter for the PostScript language"
 arch=(i686 x86_64)
 license=('GPL' 'custom')
@@ -15,17 +15,26 @@
 url="http://www.cs.wisc.edu/~ghost/"
 source=(http://ghostscript.com/releases/ghostscript-${pkgver}.tar.bz2
 	ghostscript-fPIC.patch
-	gdevbit.c.patch)
+	gdevbit.c.patch
+	ghostscript-CVE-2009-0583_and_0584.patch
+	jbig2_symbol_dict.patch)
 options=('!libtool' '!makeflags')
 md5sums=('b13289cb2115f38f40c5e064f87e228a'
          '1a8fcacf0005214db823225c870f093d'
-         '47cda3310c19cd19bd822012a12f1e07')
+         '47cda3310c19cd19bd822012a12f1e07'
+         '777ee8cb08cb4fee9aeb3b8b6494b957'
+         '7fa28af9e59749a168d1881f5b35c466')
 
 build() {
   cd ${srcdir}/ghostscript-${pkgver}
   #fix http://bugs.ghostscript.com/show_bug.cgi?id=690287 / http://bugs.archlinux.org/task/13259
   patch -Np0 -i ${srcdir}/gdevbit.c.patch || return 1
 
+  # security fixes from Fedora
+  patch -Np1 -i ${srcdir}/ghostscript-CVE-2009-0583_and_0584.patch || return 1
+  # https://bugzilla.redhat.com/show_bug.cgi?id=493379
+  patch -Np0 -i ${srcdir}/jbig2_symbol_dict.patch || return 1
+  
   if [ "$CARCH" = "x86_64" ]; then
     patch -Np1 -i ${srcdir}/ghostscript-fPIC.patch || return 1
   fi

Added: ghostscript-CVE-2009-0583_and_0584.patch
===================================================================
--- ghostscript-CVE-2009-0583_and_0584.patch	                        (rev 0)
+++ ghostscript-CVE-2009-0583_and_0584.patch	2009-04-12 13:34:02 UTC (rev 35333)
@@ -0,0 +1,989 @@
+diff -up ghostscript-8.64/icclib/icc.c.CVE-2009-0583,0584 ghostscript-8.64/icclib/icc.c
+--- ghostscript-8.64/icclib/icc.c.CVE-2009-0583,0584	2008-05-09 05:12:01.000000000 +0100
++++ ghostscript-8.64/icclib/icc.c	2009-03-06 15:24:33.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 @@ 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
+@@ -1634,6 +1639,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;
+@@ -1698,7 +1705,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;
+ 		}
+@@ -1749,6 +1756,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;
+ }
+@@ -1821,6 +1832,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;
+@@ -1885,7 +1898,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;
+ 		}
+@@ -1936,6 +1949,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;
+ }
+@@ -2008,6 +2025,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;
+@@ -2072,7 +2091,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;
+ 		}
+@@ -2123,6 +2142,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;
+ }
+@@ -2195,6 +2218,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;
+@@ -2259,7 +2284,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;
+ 		}
+@@ -2310,6 +2335,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;
+ }
+@@ -2382,6 +2411,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;
+@@ -2446,7 +2477,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;
+ 		}
+@@ -2497,6 +2528,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;
+ }
+@@ -2569,6 +2604,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;
+@@ -2633,7 +2670,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;
+ 		}
+@@ -2726,6 +2763,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;
+ }
+@@ -2798,6 +2839,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;
+@@ -2865,7 +2908,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;
+ 		}
+@@ -3001,7 +3044,7 @@ static int icmTable_setup_bwd(
+ 			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 @@ 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;
+ }
+@@ -3238,6 +3285,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;
+@@ -3347,7 +3396,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;
+ 		}
+@@ -3493,6 +3542,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;
+@@ -3745,6 +3796,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;
+@@ -4038,6 +4091,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;
+@@ -4128,11 +4183,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;
+ }
+ 
+ /* - - - - - - - - - - - - - - - - */
+@@ -4268,7 +4327,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;
+ 		}
+@@ -4819,19 +4878,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 */
+@@ -4844,6 +4934,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) {
+@@ -4904,6 +4995,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 */
+@@ -4921,13 +5017,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);
+@@ -4942,7 +5043,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;
+@@ -4956,6 +5064,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);
+@@ -4995,12 +5108,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;
+@@ -5066,6 +5181,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) {
+@@ -5086,7 +5206,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) {
+@@ -5106,6 +5233,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) {
+@@ -5177,7 +5309,14 @@ static void icmLut_dump(
+ 		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 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;
+ 
+@@ -5231,6 +5370,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)
+@@ -5241,7 +5384,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);
+@@ -5251,6 +5400,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)
+@@ -5441,6 +5594,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;
+@@ -5712,13 +5867,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;
+ }
+@@ -5882,6 +6044,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;
+@@ -6109,9 +6273,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;
+ }
+@@ -6294,6 +6471,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;
+@@ -6544,7 +6723,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;
+ 		}
+@@ -6820,6 +6999,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 */
+@@ -6852,6 +7037,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;
+@@ -6922,7 +7109,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;
+ 		}
+@@ -7041,6 +7228,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;
+@@ -7156,6 +7345,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;
+ }
+@@ -7235,6 +7428,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;
+@@ -7315,7 +7510,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;
+ 		}
+@@ -7366,10 +7561,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 */
+@@ -7498,6 +7703,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;
+@@ -7663,7 +7870,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;
+ 		}
+@@ -7672,7 +7879,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;
+ 		}
+@@ -7743,6 +7950,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 );
+@@ -7762,10 +7978,11 @@ static int icmVideoCardGamma_read(
+ ) {
+ 	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 @@ 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 < 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 @@ 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;
+@@ -8049,7 +8278,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
+@@ -8059,6 +8288,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) {
+@@ -8066,6 +8300,10 @@ static int icmVideoCardGamma_allocate(
+ 			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 @@ 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;
+@@ -8433,6 +8673,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;
+@@ -8736,6 +8978,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;
+@@ -9245,13 +9489,23 @@ static int icc_read(
+ 	}
+ 
+ 	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");
+@@ -9281,6 +9535,14 @@ static int icc_read(
+ 	    	    return p->errc = 1;
+ 	    	}
+ 	    	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");
+@@ -9321,8 +9583,14 @@ static unsigned int icc_get_size(
+ 	}
+ 
+ 	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 */
+@@ -9337,8 +9605,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 */
++			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 */
+ 		}
+ 	}
+@@ -9373,9 +9646,19 @@ static int icc_write(
+ 	}
+ 
+ 	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 */
+@@ -9406,6 +9689,12 @@ static int icc_write(
+ 			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 */
+@@ -9529,6 +9818,11 @@ 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->data == NULL)
+ 		tp = p->al->malloc(p->al, (p->count+1) * sizeof(icmTag));
+ 	else
+@@ -9612,6 +9906,11 @@ static icmBase *icc_link_tag(
+ 	}
+ 
+ 	/* 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

Added: jbig2_symbol_dict.patch
===================================================================
--- jbig2_symbol_dict.patch	                        (rev 0)
+++ jbig2_symbol_dict.patch	2009-04-12 13:34:02 UTC (rev 35333)
@@ -0,0 +1,45 @@
+From 902b821d05aaeb052d591f9fba697624c2faad81 Mon Sep 17 00:00:00 2001
+From: Ralph Giles <giles at ghostscript.com>
+Date: Wed, 1 Apr 2009 15:52:17 -0700
+Subject: [PATCH] Bounds check exported symbol run-lengths. CVE-2009-0196.
+
+The final symbol dictionary is built from a combination of symbols
+from referenced dictionaries and new symbols coded in the current
+segment. Because the symbols can be composed and refined, not all
+coded symbols are necessarily exported.
+
+The list of symbols to export from those constructed by the decoding
+process is coded as a series of on/off run-lengths. Previously we
+accepted the value read as the run-length, even though this could
+result in writing off the end of the exported symbol array. This
+commit checks the read value against the number of elements remaining
+in the export array and throws a fatal error if there is an overflow.
+
+Thanks for Alin Rad Pop of Secunia Research for pointing out the issue.
+---
+ jbig2_symbol_dict.c |    9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/jbig2_symbol_dict.c b/jbig2_symbol_dict.c
+index 10a0211..4524f85 100644
+--- jbid2dec/jbig2_symbol_dict.c
++++ jbig2dec/jbig2_symbol_dict.c
+@@ -696,6 +696,15 @@ jbig2_decode_symbol_dict(Jbig2Ctx *ctx,
+         exrunlength = params->SDNUMEXSYMS;
+       else
+         code = jbig2_arith_int_decode(IAEX, as, &exrunlength);
++      if (exrunlength > params->SDNUMEXSYMS - j) {
++        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
++          "runlength too large in export symbol table (%d > %d - %d)\n",
++          exrunlength, params->SDNUMEXSYMS, j);
++        jbig2_sd_release(ctx, SDEXSYMS);
++        /* skip to the cleanup code and return SDEXSYMS = NULL */
++        SDEXSYMS = NULL;
++        break;
++      }
+       for(k = 0; k < exrunlength; k++)
+         if (exflag) {
+           SDEXSYMS->glyphs[j++] = (i < m) ?
+-- 
+1.6.1.3
+




More information about the arch-commits mailing list