On Thu, May 12, 2005 at 05:12:46PM +0200, Matej Vela wrote:
> OpenMotif includes an outdated copy of the Xpm library with a number of
> vulnerabilities: CAN-2004-0687, CAN-2004-0688, CAN-2004-0914, and
> CAN-2005-0605.

I investigated this a bit and it seems that upstream only has made
fixes available for the first two CANs yet. For reference I attached
the output of a cvs diff between 2.2.3 and 2.2.4 of the affected files
(AFAICT)

Gruesse,
-- 
Frank Lichtenheld <[EMAIL PROTECTED]>
www: http://www.djpig.de/
Index: XpmAttrib.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/XpmAttrib.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- XpmAttrib.c 10 Jan 2002 20:57:06 -0000      1.2
+++ XpmAttrib.c 16 Nov 2004 10:35:09 -0000      1.3
@@ -41,7 +41,7 @@
 #include "XpmI.h"
 
 /* 3.2 backward compatibility code */
-LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors,
+LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors,
                                 XpmColor ***oldct));
 
 LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors));
@@ -52,12 +52,15 @@
 static int
 CreateOldColorTable(ct, ncolors, oldct)
     XpmColor *ct;
-    int ncolors;
+    unsigned int ncolors;
     XpmColor ***oldct;
 {
     XpmColor **colorTable, **color;
     int a;
 
+    if (ncolors >= SIZE_MAX / sizeof(XpmColor *)) 
+       return XpmNoMemory;
+
     colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
     if (!colorTable) {
        *oldct = NULL;
Index: XpmCrDatFrI.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/XpmCrDatFrI.c,v
retrieving revision 1.2.10.1
retrieving revision 1.4
diff -u -r1.2.10.1 -r1.4
--- XpmCrDatFrI.c       15 Aug 2003 09:20:39 -0000      1.2.10.1
+++ XpmCrDatFrI.c       16 Nov 2004 10:35:09 -0000      1.4
@@ -134,6 +134,8 @@
      */
     header_nlines = 1 + image->ncolors;
     header_size = sizeof(char *) * header_nlines;
+    if (header_size >= SIZE_MAX / sizeof(char *))
+       return (XpmNoMemory);
     header = (char **) XpmCalloc(header_size, sizeof(char *));
     if (!header)
        return (XpmNoMemory);
Index: Xpmcreate.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/Xpmcreate.c,v
retrieving revision 1.3.10.1
retrieving revision 1.6
diff -u -r1.3.10.1 -r1.6
--- Xpmcreate.c 15 Aug 2003 09:23:55 -0000      1.3.10.1
+++ Xpmcreate.c 16 Nov 2004 10:35:09 -0000      1.6
@@ -804,6 +804,9 @@
 
     ErrorStatus = XpmSuccess;
 
+    if (image->ncolors >= SIZE_MAX / sizeof(Pixel)) 
+       return (XpmNoMemory);
+
     /* malloc pixels index tables */
     image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
     if (!image_pixels)
@@ -947,6 +950,8 @@
        return (XpmNoMemory);
 
 #ifndef FOR_MSW
+    if (height != 0 && (*image_return)->bytes_per_line >= SIZE_MAX / height)
+        return (XpmNoMemory);
     /* now that bytes_per_line must have been set properly alloc data */
     (*image_return)->data =
        (char *) XpmMalloc((*image_return)->bytes_per_line * height);
@@ -1992,6 +1997,9 @@
        xpmGetCmt(data, &colors_cmt);
 
     /* malloc pixels index tables */
+    if (ncolors >= SIZE_MAX / sizeof(Pixel)) 
+       return XpmNoMemory;
+
     image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
     if (!image_pixels)
        RETURN(XpmNoMemory);
@@ -2207,6 +2215,9 @@
        {
            unsigned short colidx[256];
 
+           if (ncolors > 256)
+               return (XpmFileInvalid);
+
            bzero((char *)colidx, 256 * sizeof(short));
            for (a = 0; a < ncolors; a++)
                colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
@@ -2305,6 +2316,9 @@
            char *s;
            char buf[BUFSIZ];
 
+           if (cpp >= sizeof(buf))
+               return (XpmFileInvalid);
+
            buf[cpp] = '\0';
            if (USE_HASHTABLE) {
                xpmHashAtom *slot;
Index: Xpmdata.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/Xpmdata.c,v
retrieving revision 1.2.10.1
retrieving revision 1.4
diff -u -r1.2.10.1 -r1.4
--- Xpmdata.c   15 Aug 2003 09:28:35 -0000      1.2.10.1
+++ Xpmdata.c   16 Nov 2004 10:35:09 -0000      1.4
@@ -376,7 +376,7 @@
 {
     if (!mdata->type)
        *cmt = NULL;
-    else if (mdata->CommentLength) {
+    else if (mdata->CommentLength != 0 && mdata->CommentLength < SIZE_MAX - 1) 
{
        *cmt = (char *) XpmMalloc(mdata->CommentLength + 1);
        strncpy(*cmt, mdata->Comment, mdata->CommentLength);
        (*cmt)[mdata->CommentLength] = '\0';
Index: Xpmhashtab.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/Xpmhashtab.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Xpmhashtab.c        10 Jan 2002 20:57:09 -0000      1.2
+++ Xpmhashtab.c        16 Nov 2004 10:35:09 -0000      1.3
@@ -141,7 +141,7 @@
     xpmHashTable *table;
 {
     xpmHashAtom *atomTable = table->atomTable;
-    int size = table->size;
+    unsigned int size = table->size;
     xpmHashAtom *t, *p;
     int i;
     int oldSize = size;
@@ -150,6 +150,8 @@
     HASH_TABLE_GROWS
        table->size = size;
     table->limit = size / 3;
+    if (size >= SIZE_MAX / sizeof(*atomTable)) 
+       return (XpmNoMemory);
     atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable));
     if (!atomTable)
        return (XpmNoMemory);
@@ -210,6 +212,8 @@
     table->size = INITIAL_HASH_SIZE;
     table->limit = table->size / 3;
     table->used = 0;
+    if (table->size >= SIZE_MAX / sizeof(*atomTable))
+       return (XpmNoMemory);
     atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable));
     if (!atomTable)
        return (XpmNoMemory);
Index: XpmI.h
===================================================================
RCS file: /cvs/openmotif/lib/Xm/XpmI.h,v
retrieving revision 1.2
retrieving revision 1.4
diff -u -r1.2 -r1.4
--- XpmI.h      5 Jan 2002 15:21:26 -0000       1.2
+++ XpmI.h      18 Nov 2004 14:03:08 -0000      1.4
@@ -110,6 +110,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <X11/Xmd.h>
 /* stdio.h doesn't declare popen on a Sequent DYNIX OS */
 #ifdef sequent
 extern FILE *popen();
@@ -179,6 +180,18 @@
                boundCheckingCalloc((long)(nelem),(long) (elsize))
 #endif
 
+#if defined(SCO) || defined(__USLC__)
+#include <stdint.h>    /* For SIZE_MAX */
+#endif
+#include <limits.h>
+#ifndef SIZE_MAX
+# ifdef ULONG_MAX
+#  define SIZE_MAX ULONG_MAX
+# else 
+#  define SIZE_MAX UINT_MAX
+# endif
+#endif
+
 #define XPMMAXCMTLEN BUFSIZ
 typedef struct {
     unsigned int type;
@@ -276,9 +289,9 @@
 }      *xpmHashAtom;
 
 typedef struct {
-    int size;
-    int limit;
-    int used;
+    unsigned int size;
+    unsigned int limit;
+    unsigned int used;
     xpmHashAtom *atomTable;
 }      xpmHashTable;
 
Index: Xpmparse.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/Xpmparse.c,v
retrieving revision 1.2.10.1
retrieving revision 1.4
diff -u -r1.2.10.1 -r1.4
--- Xpmparse.c  15 Aug 2003 09:13:43 -0000      1.2.10.1
+++ Xpmparse.c  16 Nov 2004 10:35:09 -0000      1.4
@@ -46,6 +46,25 @@
 
 #include "XpmI.h"
 #include <ctype.h>
+#include <string.h>
+ 
+#ifdef HAS_STRLCAT
+# define STRLCAT(dst, src, dstsize) { \
+       if (strlcat(dst, src, dstsize) >= (dstsize)) \
+           return (XpmFileInvalid); }
+# define STRLCPY(dst, src, dstsize) { \
+       if (strlcpy(dst, src, dstsize) >= (dstsize)) \
+           return (XpmFileInvalid); }
+#else
+# define STRLCAT(dst, src, dstsize) { \
+       if ((strlen(dst) + strlen(src)) < (dstsize)) \
+           strcat(dst, src); \
+       else return (XpmFileInvalid); }
+# define STRLCPY(dst, src, dstsize) { \
+       if (strlen(src) < (dstsize)) \
+           strcpy(dst, src); \
+       else return (XpmFileInvalid); }
+#endif
 
 LFUNC(ParsePixels, int, (xpmData *data, unsigned int width,
                         unsigned int height, unsigned int ncolors,
@@ -215,7 +234,7 @@
     unsigned int *extensions;
 {
     unsigned int l;
-    char buf[BUFSIZ];
+    char buf[BUFSIZ + 1];
 
     if (!data->format) {               /* XPM 2 or 3 */
 
@@ -324,10 +343,10 @@
     XpmColor **colorTablePtr;
     xpmHashTable *hashtable;
 {
-    unsigned int key, l, a, b;
+    unsigned int key, l, a, b, len;
     unsigned int curkey;               /* current color key */
     unsigned int lastwaskey;           /* key read */
-    char buf[BUFSIZ];
+    char buf[BUFSIZ + 1];
     char curbuf[BUFSIZ];               /* current buffer */
     char **sptr, *s;
     XpmColor *color;
@@ -335,6 +354,8 @@
     char **defaults;
     int ErrorStatus;
 
+    if (ncolors >= SIZE_MAX / sizeof(XpmColor))
+        return (XpmNoMemory);
     colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor));
     if (!colorTable)
        return (XpmNoMemory);
@@ -346,6 +367,10 @@
            /*
             * read pixel value
             */
+           if (cpp >= SIZE_MAX - 1) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
            color->string = (char *) XpmMalloc(cpp + 1);
            if (!color->string) {
                xpmFreeColorTable(colorTable, ncolors);
@@ -383,13 +408,14 @@
                }
                if (!lastwaskey && key < NKEYS) {       /* open new key */
                    if (curkey) {       /* flush string */
-                       s = (char *) XpmMalloc(strlen(curbuf) + 1);
+                       len = strlen(curbuf) + 1;
+                       s = (char *) XpmMalloc(len);
                        if (!s) {
                            xpmFreeColorTable(colorTable, ncolors);
                            return (XpmNoMemory);
                        }
                        defaults[curkey] = s;
-                       strcpy(s, curbuf);
+                       memcpy(s, curbuf, len);
                    }
                    curkey = key + 1;   /* set new key  */
                    *curbuf = '\0';     /* reset curbuf */
@@ -400,9 +426,9 @@
                        return (XpmFileInvalid);
                    }
                    if (!lastwaskey)
-                       strcat(curbuf, " ");    /* append space */
+                       STRLCAT(curbuf, " ", sizeof(curbuf)); /* append space */
                    buf[l] = '\0';
-                   strcat(curbuf, buf);/* append buf */
+                   STRLCAT(curbuf, buf, sizeof(curbuf));/* append buf */
                    lastwaskey = 0;
                }
            }
@@ -410,12 +436,13 @@
                xpmFreeColorTable(colorTable, ncolors);
                return (XpmFileInvalid);
            }
-           s = defaults[curkey] = (char *) XpmMalloc(strlen(curbuf) + 1);
+           len = strlen(curbuf) + 1;
+           s = defaults[curkey] = (char *) XpmMalloc(len);
            if (!s) {
                xpmFreeColorTable(colorTable, ncolors);
                return (XpmNoMemory);
            }
-           strcpy(s, curbuf);
+           memcpy(s, curbuf, len);
        }
     } else {                           /* XPM 1 */
        /* get to the beginning of the first string */
@@ -428,6 +455,10 @@
            /*
             * read pixel value
             */
+           if (cpp >= SIZE_MAX - 1) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
            color->string = (char *) XpmMalloc(cpp + 1);
            if (!color->string) {
                xpmFreeColorTable(colorTable, ncolors);
@@ -456,16 +487,17 @@
            *curbuf = '\0';             /* init curbuf */
            while ((l = xpmNextWord(data, buf, BUFSIZ))) {
                if (*curbuf != '\0')
-                   strcat(curbuf, " ");/* append space */
+                   STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */
                buf[l] = '\0';
-               strcat(curbuf, buf);    /* append buf */
+               STRLCAT(curbuf, buf, sizeof(curbuf));   /* append buf */
            }
-           s = (char *) XpmMalloc(strlen(curbuf) + 1);
+           len = strlen(curbuf) + 1;
+           s = (char *) XpmMalloc(len);
            if (!s) {
                xpmFreeColorTable(colorTable, ncolors);
                return (XpmNoMemory);
            }
-           strcpy(s, curbuf);
+           memcpy(s, curbuf, len);
            color->c_color = s;
            *curbuf = '\0';             /* reset curbuf */
            if (a < ncolors - 1)
@@ -490,6 +522,9 @@
     unsigned int *iptr, *iptr2;
     unsigned int a, x, y;
 
+    if ((height > 0 && width >= SIZE_MAX / height) ||
+       width * height >= SIZE_MAX / sizeof(unsigned int)) 
+        return XpmNoMemory;
 #ifndef FOR_MSW
     iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height);
 #else
@@ -513,6 +548,9 @@
        {
            unsigned short colidx[256];
 
+           if (ncolors > 256)
+               return (XpmFileInvalid);
+
            bzero((char *)colidx, 256 * sizeof(short));
            for (a = 0; a < ncolors; a++)
                colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
@@ -590,6 +628,9 @@
            char *s;
            char buf[BUFSIZ];
 
+           if (cpp >= sizeof(buf))
+               return (XpmFileInvalid);
+
            buf[cpp] = '\0';
            if (USE_HASHTABLE) {
                xpmHashAtom *slot;
Index: Xpmscan.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/Xpmscan.c,v
retrieving revision 1.2.10.1
retrieving revision 1.4
diff -u -r1.2.10.1 -r1.4
--- Xpmscan.c   15 Aug 2003 09:25:23 -0000      1.2.10.1
+++ Xpmscan.c   16 Nov 2004 10:35:09 -0000      1.4
@@ -98,7 +98,8 @@
 LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
                                  XpmAttributes *attributes));
 
-LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, int ncolors,
+LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, 
+                            unsigned int ncolors, 
                             Pixel *pixels, unsigned int mask,
                             unsigned int cpp, XpmAttributes *attributes));
 
@@ -225,11 +226,17 @@
     else
        cpp = 0;
 
+    if ((height > 0 && width >= SIZE_MAX / height) ||
+       width * height >= SIZE_MAX / sizeof(unsigned int))
+       RETURN(XpmNoMemory);
     pmap.pixelindex =
        (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
     if (!pmap.pixelindex)
        RETURN(XpmNoMemory);
 
+    if (pmap.size >= SIZE_MAX / sizeof(Pixel)) 
+       RETURN(XpmNoMemory);
+
     pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
     if (!pmap.pixels)
        RETURN(XpmNoMemory);
@@ -284,7 +291,8 @@
      * get rgb values and a string of char, and possibly a name for each
      * color
      */
-
+    if (pmap.ncolors >= SIZE_MAX / sizeof(XpmColor))
+       RETURN(XpmNoMemory);
     colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
     if (!colorTable)
        RETURN(XpmNoMemory);
@@ -332,6 +340,8 @@
 
     /* first get a character string */
     a = 0;
+    if (cpp >= SIZE_MAX - 1)
+       return (XpmNoMemory);
     if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
        return (XpmNoMemory);
     *s++ = printable[c = a % MAXPRINTABLE];
@@ -379,7 +389,7 @@
 ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes)
     Display *display;
     XpmColor *colors;
-    int ncolors;
+    unsigned int ncolors;
     Pixel *pixels;
     unsigned int mask;
     unsigned int cpp;
@@ -423,6 +433,8 @@
     }
 
     /* first get character strings and rgb values */
+    if (ncolors >= SIZE_MAX / sizeof(XColor) || cpp >= SIZE_MAX - 1)
+       return (XpmNoMemory);
     xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
     if (!xcolors)
        return (XpmNoMemory);
Index: XpmWrFFrI.c
===================================================================
RCS file: /cvs/openmotif/lib/Xm/XpmWrFFrI.c,v
retrieving revision 1.2.10.1
retrieving revision 1.4
diff -u -r1.2.10.1 -r1.4
--- XpmWrFFrI.c 15 Aug 2003 09:10:18 -0000      1.2.10.1
+++ XpmWrFFrI.c 16 Nov 2004 10:35:09 -0000      1.4
@@ -244,6 +244,8 @@
     unsigned int x, y, h;
 
     h = height - 1;
+    if (cpp != 0 && width >= (SIZE_MAX - 3)/cpp) 
+       return XpmNoMemory;    
     p = buf = (char *) XpmMalloc(width * cpp + 3);
     if (!buf)
        return (XpmNoMemory);

Reply via email to