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);