[poppler] poppler/Stream.cc poppler/XRef.cc splash/SplashBitmap.cc splash/Splash.cc splash/SplashErrorCodes.h

Albert Astals Cid aacid at kemper.freedesktop.org
Fri Oct 16 14:18:29 PDT 2009


 poppler/Stream.cc         |    4 ++++
 poppler/XRef.cc           |   19 +++++++++++++++----
 splash/Splash.cc          |    7 +++++++
 splash/SplashBitmap.cc    |   37 ++++++++++++++++++++++++++++++-------
 splash/SplashErrorCodes.h |    4 +++-
 5 files changed, 59 insertions(+), 12 deletions(-)

New commits:
commit 1082e1671afd8ab91583dabc876304008acb021c
Author: Albert Astals Cid <aacid at kde.org>
Date:   Fri Oct 16 23:17:22 2009 +0200

    Some "security" fixes based on newly released Xpdf 3.02pl4

diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 7137c5e..6634317 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -405,6 +405,10 @@ ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
   } 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 --git a/poppler/XRef.cc b/poppler/XRef.cc
index 832a038..e5fd92a 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -76,6 +76,8 @@ public:
   // generation 0.
   ObjectStream(XRef *xref, int objStrNumA);
 
+  GBool isOk() { return ok; }
+
   ~ObjectStream();
 
   // Return the object number of this object stream.
@@ -91,6 +93,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) {
@@ -104,6 +107,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
   nObjects = 0;
   objs = NULL;
   objNums = NULL;
+  ok = gFalse;
 
   if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
     goto err1;
@@ -129,11 +133,13 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
     goto err1;
   }
 
-  if (nObjects >= INT_MAX / (int)sizeof(int)) {
-    error(-1, "Invalid 'nObjects'");
+  // 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));
@@ -190,10 +196,10 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
   }
 
   gfree(offsets);
+  ok = gTrue;
 
  err1:
   objStr.free();
-  return;
 }
 
 ObjectStream::~ObjectStream() {
@@ -970,6 +976,11 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
 	delete objStr;
       }
       objStr = new ObjectStream(this, e->offset);
+      if (!objStr->isOk()) {
+	delete objStr;
+	objStr = NULL;
+	goto err;
+      }
     }
     objStr->getObject(e->gen, num, obj);
     break;
diff --git a/splash/Splash.cc b/splash/Splash.cc
index a1deb85..834cb10 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -27,6 +27,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 #include "goo/gmem.h"
 #include "SplashErrorCodes.h"
 #include "SplashMath.h"
@@ -2001,6 +2002,9 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
   xq = w % scaledWidth;
 
   // allocate pixel buffer
+  if (yp < 0 || yp > INT_MAX - 1) {
+    return splashErrBadArg;
+  }
   pixBuf = (SplashColorPtr)gmallocn((yp + 1), w);
 
   // initialize the pixel pipe
@@ -2301,6 +2305,9 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
   xq = w % scaledWidth;
 
   // allocate pixel buffers
+  if (yp < 0 || yp > INT_MAX - 1) {
+    return splashErrBadArg;
+  }
   colorBuf = (SplashColorPtr)gmallocn3((yp + 1), w, nComps);
   if (srcAlpha) {
     alphaBuf = (Guchar *)gmallocn((yp + 1), w);
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index 2337a62..999efd1 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -29,6 +29,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <limits.h>
 #include "goo/gmem.h"
 #include "SplashErrorCodes.h"
 #include "SplashBitmap.h"
@@ -48,26 +49,48 @@ SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
   mode = modeA;
   switch (mode) {
   case splashModeMono1:
-    rowSize = (width + 7) >> 3;
+    if (width > 0) {
+      rowSize = (width + 7) >> 3;
+    } 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 && width <= INT_MAX / 3) {
+      rowSize = width * 3;
+    } else {
+      rowSize = -1;
+    }
     break;
   case splashModeXBGR8:
-    rowSize = width * 4;
+    if (width > 0 && width <= INT_MAX / 4) {
+      rowSize = width * 4;
+    } else {
+      rowSize = -1;
+    }
     break;
 #if SPLASH_CMYK
   case splashModeCMYK8:
-    rowSize = width * 4;
+    if (width > 0 && width <= INT_MAX / 4) {
+      rowSize = width * 4;
+    } else {
+      rowSize = -1;
+    }
     break;
 #endif
   }
-  rowSize += rowPad - 1;
-  rowSize -= rowSize % rowPad;
+  if (rowSize > 0) {
+    rowSize += rowPad - 1;
+    rowSize -= rowSize % rowPad;
+  }
   data = (SplashColorPtr)gmallocn(rowSize, height);
   if (!topDown) {
     data += (height - 1) * rowSize;
diff --git a/splash/SplashErrorCodes.h b/splash/SplashErrorCodes.h
index 9c30982..d1f81f8 100644
--- a/splash/SplashErrorCodes.h
+++ b/splash/SplashErrorCodes.h
@@ -41,7 +41,9 @@
 
 #define splashErrSingularMatrix  8	// matrix is singular
 
-#define splashErrZeroImage       9      // image of 0x0
+#define splashErrBadArg          9      // bad argument
+
+#define splashErrZeroImage     254      // image of 0x0
 
 #define splashErrGeneric       255
 


More information about the poppler mailing list