File xpdf-3.02pl4-CVE-2009-1187,1188,3608.patch of Package xpdf
diff -upr xpdf-3.02/splash/SplashBitmap.cc xpdf-3.02.new/splash/SplashBitmap.cc
--- xpdf-3.02/splash/SplashBitmap.cc 2009-10-15 10:18:51.000000000 +0200
+++ xpdf-3.02.new/splash/SplashBitmap.cc 2009-10-15 10:23:08.000000000 +0200
@@ -27,23 +27,41 @@ SplashBitmap::SplashBitmap(int widthA, i
mode = modeA;
switch (mode) {
case splashModeMono1:
- rowSize = (width + 7) >> 3;
+ if (width > 0) {
+ rowSize = ((SafeInt(width) + 7) >> 3).Int();
+ } else {
+ rowSize = -1;
+ }
break;
case splashModeMono8:
- rowSize = width;
+ if (width > 0) {
+ rowSize = width;
+ } else {
+ rowSize = -1;
+ }
break;
case splashModeRGB8:
case splashModeBGR8:
- rowSize = width * 3;
+ if (width > 0) {
+ rowSize = (SafeInt(width) * 3).Int();
+ } else {
+ rowSize = -1;
+ }
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- rowSize = width * 4;
+ if (width > 0) {
+ rowSize = (SafeInt(width) * 4).Int();
+ } else {
+ rowSize = -1;
+ }
break;
#endif
}
- rowSize += rowPad - 1;
- rowSize -= rowSize % rowPad;
+ if (rowSize > 0) {
+ rowSize += (SafeInt(rowPad) - 1).Int();
+ rowSize -= (SafeInt(rowSize) % rowPad).Int();
+ }
data = (SplashColorPtr)gmallocn(rowSize, height);
if (!topDown) {
data += (height - 1) * rowSize;
diff -upr xpdf-3.02/splash/Splash.cc xpdf-3.02.new/splash/Splash.cc
--- xpdf-3.02/splash/Splash.cc 2009-10-15 10:18:51.000000000 +0200
+++ xpdf-3.02.new/splash/Splash.cc 2009-10-15 10:23:08.000000000 +0200
@@ -1912,6 +1912,9 @@ SplashError Splash::fillImageMask(Splash
xq = w % scaledWidth;
// allocate pixel buffer
+ if (yp < 0) {
+ return splashErrBadArg;
+ }
pixBuf = (SplashColorPtr)gmalloc(((SafeInt(yp) + SafeInt(1)) * SafeInt(w)).Int());
// initialize the pixel pipe
@@ -2208,6 +2211,9 @@ SplashError Splash::drawImage(SplashImag
xq = w % scaledWidth;
// allocate pixel buffers
+ if (yp < 0) {
+ return splashErrBadArg;
+ }
colorBuf = (SplashColorPtr)gmalloc(((SafeInt(yp) + SafeInt(1)) * SafeInt(w) * SafeInt(nComps)).Int());
if (srcAlpha) {
alphaBuf = (Guchar *)gmalloc(((SafeInt(yp) + SafeInt(1)) * SafeInt(w)).Int());
diff -upr xpdf-3.02/splash/SplashErrorCodes.h xpdf-3.02.new/splash/SplashErrorCodes.h
--- xpdf-3.02/splash/SplashErrorCodes.h 2007-02-27 23:05:52.000000000 +0100
+++ xpdf-3.02.new/splash/SplashErrorCodes.h 2009-10-15 10:23:08.000000000 +0200
@@ -29,4 +29,6 @@
#define splashErrSingularMatrix 8 // matrix is singular
+#define splashErrBadArg 9 // bad argument
+
#endif
diff -upr xpdf-3.02/xpdf/Stream.cc xpdf-3.02.new/xpdf/Stream.cc
--- xpdf-3.02/xpdf/Stream.cc 2009-10-15 10:18:52.000000000 +0200
+++ xpdf-3.02.new/xpdf/Stream.cc 2009-10-15 10:23:08.000000000 +0200
@@ -323,6 +323,10 @@ ImageStream::ImageStream(Stream *strA, i
} else {
imgLineSize = nVals;
}
+ if (width > INT_MAX / nComps) {
+ // force a call to gmallocn(-1,...), which will throw an exception
+ imgLineSize = -1;
+ }
imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
imgIdx = nVals;
}
diff -upr xpdf-3.02/xpdf/XRef.cc xpdf-3.02.new/xpdf/XRef.cc
--- xpdf-3.02/xpdf/XRef.cc 2009-10-15 10:18:52.000000000 +0200
+++ xpdf-3.02.new/xpdf/XRef.cc 2009-10-15 14:26:57.000000000 +0200
@@ -52,6 +52,8 @@ public:
// generation 0.
ObjectStream(XRef *xref, int objStrNumA);
+ GBool isOk() { return ok; }
+
~ObjectStream();
// Return the object number of this object stream.
@@ -67,6 +69,7 @@ private:
int nObjects; // number of objects in the stream
Object *objs; // the objects (length = nObjects)
int *objNums; // the object numbers (length = nObjects)
+ GBool ok;
};
ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
@@ -80,6 +83,7 @@ ObjectStream::ObjectStream(XRef *xref, i
nObjects = 0;
objs = NULL;
objNums = NULL;
+ ok = gFalse;
if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
goto err1;
@@ -105,6 +109,13 @@ ObjectStream::ObjectStream(XRef *xref, i
goto err1;
}
+ // this is an arbitrary limit to avoid integer overflow problems
+ // in the 'new Object[nObjects]' call (Acrobat apparently limits
+ // object streams to 100-200 objects)
+ if (nObjects > 1000000) {
+ error(-1, "Too many objects in an object stream");
+ goto err1;
+ }
objs = new Object[nObjects];
objNums = (int *)gmallocn(nObjects, sizeof(int));
offsets = (int *)gmallocn(nObjects, sizeof(int));
@@ -161,10 +172,10 @@ ObjectStream::ObjectStream(XRef *xref, i
}
gfree(offsets);
+ ok = gTrue;
err1:
objStr.free();
- return;
}
ObjectStream::~ObjectStream() {
@@ -839,6 +850,11 @@ Object *XRef::fetch(int num, int gen, Ob
delete objStr;
}
objStr = new ObjectStream(this, e->offset);
+ if (!objStr->isOk()) {
+ delete objStr;
+ objStr = NULL;
+ goto err;
+ }
}
objStr->getObject(e->gen, num, obj);
break;