--- tetex-src-3.0/libs/xpdf/goo/gmem.c.CVE-2005-3193 2004-01-22 02:26:44.000000000 +0100 +++ tetex-src-3.0/libs/xpdf/goo/gmem.c 2006-01-16 15:41:04.000000000 +0100 @@ -135,6 +135,28 @@ void *grealloc(void *p, int size) { #endif } +void *gmallocn(int nObjs, int objSize) { + int n; + + n = nObjs * objSize; + if (objSize == 0 || n / objSize != nObjs) { + fprintf(stderr, "Bogus memory allocation size\n"); + exit(1); + } + return gmalloc(n); +} + +void *greallocn(void *p, int nObjs, int objSize) { + int n; + + n = nObjs * objSize; + if (objSize == 0 || n / objSize != nObjs) { + fprintf(stderr, "Bogus memory allocation size\n"); + exit(1); + } + return grealloc(p, n); +} + void gfree(void *p) { #ifdef DEBUG_MEM int size; --- tetex-src-3.0/libs/xpdf/goo/gmem.h.CVE-2005-3193 2004-01-22 02:26:44.000000000 +0100 +++ tetex-src-3.0/libs/xpdf/goo/gmem.h 2006-01-16 15:41:04.000000000 +0100 @@ -28,6 +28,15 @@ extern void *gmalloc(int size); extern void *grealloc(void *p, int size); /* + * These are similar to gmalloc and grealloc, but take an object count + * and size. The result is similar to allocating nObjs * objSize + * bytes, but there is an additional error check that the total size + * doesn't overflow an int. + */ +extern void *gmallocn(int nObjs, int objSize); +extern void *greallocn(void *p, int nObjs, int objSize); + +/* * Same as free, but checks for and ignores NULL pointers. */ extern void gfree(void *p); --- tetex-src-3.0/libs/xpdf/xpdf/JPXStream.cc.CVE-2005-3193 2004-01-22 02:26:45.000000000 +0100 +++ tetex-src-3.0/libs/xpdf/xpdf/JPXStream.cc 2006-01-16 15:41:04.000000000 +0100 @@ -666,7 +666,7 @@ GBool JPXStream::readCodestream(Guint le int segType; GBool haveSIZ, haveCOD, haveQCD, haveSOT; Guint precinctSize, style; - Guint segLen, capabilities, comp, i, j, r; + Guint segLen, capabilities, nTiles, comp, i, j, r; //----- main header haveSIZ = haveCOD = haveQCD = haveSOT = gFalse; @@ -701,8 +701,13 @@ GBool JPXStream::readCodestream(Guint le / img.xTileSize; img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1) / img.yTileSize; - img.tiles = (JPXTile *)gmalloc(img.nXTiles * img.nYTiles * - sizeof(JPXTile)); + nTiles = img.nXTiles * img.nYTiles; + // check for overflow before allocating memory + if (nTiles == 0 || nTiles / img.nXTiles != img.nYTiles) { + error(getPos(), "Bad tile count in JPX SIZ marker segment"); + return gFalse; + } + img.tiles = (JPXTile *)gmallocn(nTiles, sizeof(JPXTile)); for (i = 0; i < img.nXTiles * img.nYTiles; ++i) { img.tiles[i].tileComps = (JPXTileComp *)gmalloc(img.nComps * sizeof(JPXTileComp)); --- tetex-src-3.0/libs/xpdf/xpdf/Stream.h.CVE-2005-3193 2004-01-22 02:26:45.000000000 +0100 +++ tetex-src-3.0/libs/xpdf/xpdf/Stream.h 2006-01-16 15:41:04.000000000 +0100 @@ -233,6 +233,8 @@ public: ~StreamPredictor(); + GBool isOk() { return ok; } + int lookChar(); int getChar(); @@ -250,6 +252,7 @@ private: int rowBytes; // bytes per line Guchar *predLine; // line buffer int predIdx; // current index in predLine + GBool ok; }; //------------------------------------------------------------------------ --- tetex-src-3.0/libs/xpdf/xpdf/Stream.cc.CVE-2005-3193 2004-01-22 02:26:45.000000000 +0100 +++ tetex-src-3.0/libs/xpdf/xpdf/Stream.cc 2006-01-16 15:41:04.000000000 +0100 @@ -407,18 +407,33 @@ void ImageStream::skipLine() { StreamPredictor::StreamPredictor(Stream *strA, int predictorA, int widthA, int nCompsA, int nBitsA) { + int totalBits; + str = strA; predictor = predictorA; width = widthA; nComps = nCompsA; nBits = nBitsA; + predLine = NULL; + ok = gFalse; nVals = width * nComps; + totalBits = nVals * nBits; + if (totalBits == 0 || + (totalBits / nBits) / nComps != width || + totalBits + 7 < 0) { + return; + } pixBytes = (nComps * nBits + 7) >> 3; - rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes; + rowBytes = ((totalBits + 7) >> 3) + pixBytes; + if (rowBytes < 0) { + return; + } predLine = (Guchar *)gmalloc(rowBytes); memset(predLine, 0, rowBytes); predIdx = rowBytes; + + ok = gTrue; } StreamPredictor::~StreamPredictor() { @@ -1012,6 +1027,10 @@ LZWStream::LZWStream(Stream *strA, int p FilterStream(strA) { if (predictor != 1) { pred = new StreamPredictor(this, predictor, columns, colors, bits); + if (!pred->isOk()) { + delete pred; + pred = NULL; + } } else { pred = NULL; } @@ -2897,6 +2916,14 @@ GBool DCTStream::readBaselineSOF() { height = read16(); width = read16(); numComps = str->getChar(); + if (numComps <= 0 || numComps > 4) { + error(getPos(), "Bad number of components in DCT stream", prec); + return gFalse; + } + if (numComps <= 0 || numComps > 4) { + error(getPos(), "Bad number of components in DCT stream", prec); + return gFalse; + } if (prec != 8) { error(getPos(), "Bad DCT precision %d", prec); return gFalse; @@ -3255,6 +3282,10 @@ FlateStream::FlateStream(Stream *strA, i FilterStream(strA) { if (predictor != 1) { pred = new StreamPredictor(this, predictor, columns, colors, bits); + if (!pred->isOk()) { + delete pred; + pred = NULL; + } } else { pred = NULL; }