diff options
31 files changed, 528 insertions, 303 deletions
diff --git a/nx-X11/lib/X11/AllCells.c b/nx-X11/lib/X11/AllCells.c index bbc977059..6d9548f0d 100644 --- a/nx-X11/lib/X11/AllCells.c +++ b/nx-X11/lib/X11/AllCells.c @@ -54,8 +54,13 @@ Status XAllocColorCells( status = _XReply(dpy, (xReply *)&rep, 0, xFalse); if (status) { - _XRead32 (dpy, (long *) pixels, 4L * (long) (rep.nPixels)); - _XRead32 (dpy, (long *) masks, 4L * (long) (rep.nMasks)); + if ((rep.nPixels > ncolors) || (rep.nMasks > nplanes)) { + _XEatDataWords(dpy, rep.length); + status = 0; /* Failure */ + } else { + _XRead32 (dpy, (long *) pixels, 4L * (long) (rep.nPixels)); + _XRead32 (dpy, (long *) masks, 4L * (long) (rep.nMasks)); + } } UnlockDisplay(dpy); diff --git a/nx-X11/lib/X11/Font.c b/nx-X11/lib/X11/Font.c index f60a8a874..d311cd0f7 100644 --- a/nx-X11/lib/X11/Font.c +++ b/nx-X11/lib/X11/Font.c @@ -31,6 +31,7 @@ authorization from the X Consortium and the XFree86 Project. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> #if defined(XF86BIGFONT) #define USE_XF86BIGFONT @@ -183,7 +184,8 @@ _XQueryFont ( unsigned long seq) { register XFontStruct *fs; - register long nbytes; + unsigned long nbytes; + unsigned long reply_left; /* unused data words left in reply buffer */ xQueryFontReply reply; register xResourceReq *req; register _XExtension *ext; @@ -211,9 +213,10 @@ _XQueryFont ( } if (seq) DeqAsyncHandler(dpy, &async); + reply_left = reply.length - + ((SIZEOF(xQueryFontReply) - SIZEOF(xReply)) >> 2); if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) { - _XEatData(dpy, (unsigned long)(reply.nFontProps * SIZEOF(xFontProp) + - reply.nCharInfos * SIZEOF(xCharInfo))); + _XEatDataWords(dpy, reply_left); return (XFontStruct *)NULL; } fs->ext_data = NULL; @@ -239,32 +242,42 @@ _XQueryFont ( */ fs->properties = NULL; if (fs->n_properties > 0) { - nbytes = reply.nFontProps * sizeof(XFontProp); - fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes); + /* nFontProps is a CARD16 */ nbytes = reply.nFontProps * SIZEOF(xFontProp); + if ((nbytes >> 2) <= reply_left) { + size_t pbytes = reply.nFontProps * sizeof(XFontProp); + fs->properties = Xmalloc (pbytes); + } if (! fs->properties) { Xfree((char *) fs); - _XEatData(dpy, (unsigned long) - (nbytes + reply.nCharInfos * SIZEOF(xCharInfo))); + _XEatDataWords(dpy, reply_left); return (XFontStruct *)NULL; } _XRead32 (dpy, (long *)fs->properties, nbytes); + reply_left -= (nbytes >> 2); } /* * If no characters in font, then it is a bad font, but * shouldn't try to read nothing. */ + /* have to unpack charinfos on some machines (CRAY) */ fs->per_char = NULL; if (reply.nCharInfos > 0){ - nbytes = reply.nCharInfos * sizeof(XCharStruct); - if (! (fs->per_char = (XCharStruct *) Xmalloc ((unsigned) nbytes))) { + /* nCharInfos is a CARD32 */ + if (reply.nCharInfos < (INT_MAX / sizeof(XCharStruct))) { + nbytes = reply.nCharInfos * SIZEOF(xCharInfo); + if ((nbytes >> 2) <= reply_left) { + size_t cibytes = reply.nCharInfos * sizeof(XCharStruct); + fs->per_char = Xmalloc (cibytes); + } + } + if (! fs->per_char) { if (fs->properties) Xfree((char *) fs->properties); Xfree((char *) fs); - _XEatData(dpy, (unsigned long) - (reply.nCharInfos * SIZEOF(xCharInfo))); + _XEatDataWords(dpy, reply_left); return (XFontStruct *)NULL; } - nbytes = reply.nCharInfos * SIZEOF(xCharInfo); + _XRead16 (dpy, (char *)fs->per_char, nbytes); } @@ -391,7 +404,8 @@ _XF86BigfontQueryFont ( unsigned long seq) { register XFontStruct *fs; - register long nbytes; + unsigned long nbytes; + unsigned long reply_left; /* unused data left in reply buffer */ xXF86BigfontQueryFontReply reply; register xXF86BigfontQueryFontReq *req; register _XExtension *ext; @@ -444,13 +458,10 @@ _XF86BigfontQueryFont ( DeqAsyncHandler(dpy, &async2); if (seq) DeqAsyncHandler(dpy, &async1); + reply_left = reply.length - + ((SIZEOF(xXF86BigfontQueryFontReply) - SIZEOF(xReply)) >> 2); if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) { - _XEatData(dpy, - reply.nFontProps * SIZEOF(xFontProp) - + (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1) - ? reply.nUniqCharInfos * SIZEOF(xCharInfo) - + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16) - : 0)); + _XEatDataWords(dpy, reply_left); return (XFontStruct *)NULL; } fs->ext_data = NULL; @@ -476,23 +487,33 @@ _XF86BigfontQueryFont ( */ fs->properties = NULL; if (fs->n_properties > 0) { - nbytes = reply.nFontProps * sizeof(XFontProp); - fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes); + /* nFontProps is a CARD16 */ nbytes = reply.nFontProps * SIZEOF(xFontProp); + if ((nbytes >> 2) <= reply_left) { + size_t pbytes = reply.nFontProps * sizeof(XFontProp); + fs->properties = Xmalloc (pbytes); + } if (! fs->properties) { Xfree((char *) fs); - _XEatData(dpy, - nbytes - + (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1) - ? reply.nUniqCharInfos * SIZEOF(xCharInfo) - + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16) - : 0)); + _XEatDataWords(dpy, reply_left); return (XFontStruct *)NULL; } _XRead32 (dpy, (long *)fs->properties, nbytes); + reply_left -= (nbytes >> 2); } fs->per_char = NULL; +#ifndef LONG64 + /* compares each part to half the maximum, which should be far more than + any real font needs, so the combined total doesn't overflow either */ + if (reply.nUniqCharInfos > ((ULONG_MAX / 2) / SIZEOF(xCharInfo)) || + reply.nCharInfos > ((ULONG_MAX / 2) / sizeof(CARD16))) { + Xfree(fs->properties); + Xfree((char *) fs); + _XEatDataWords(dpy, reply_left); + return (XFontStruct *)NULL; + } +#endif if (reply.nCharInfos > 0) { /* fprintf(stderr, "received font metrics, nCharInfos = %d, nUniqCharInfos = %d, shmid = %d\n", reply.nCharInfos, reply.nUniqCharInfos, reply.shmid); */ if (reply.shmid == (CARD32)(-1)) { @@ -506,14 +527,14 @@ _XF86BigfontQueryFont ( if (!pUniqCI) { if (fs->properties) Xfree((char *) fs->properties); Xfree((char *) fs); - _XEatData(dpy, nbytes); + _XEatDataWords(dpy, reply_left); return (XFontStruct *)NULL; } if (! (fs->per_char = (XCharStruct *) Xmalloc (reply.nCharInfos * sizeof(XCharStruct)))) { Xfree((char *) pUniqCI); if (fs->properties) Xfree((char *) fs->properties); Xfree((char *) fs); - _XEatData(dpy, nbytes); + _XEatDataWords(dpy, reply_left); return (XFontStruct *)NULL; } _XRead16 (dpy, (char *) pUniqCI, nbytes); @@ -568,6 +589,7 @@ _XF86BigfontQueryFont ( if (!(extcodes->serverCapabilities & CAP_VerifiedLocal)) { struct shmid_ds buf; if (!(shmctl(reply.shmid, IPC_STAT, &buf) >= 0 + && reply.nCharInfos < (LONG_MAX / sizeof(XCharStruct)) && buf.shm_segsz >= reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct) + sizeof(CARD32) && *(CARD32 *)(addr + reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct)) == extcodes->serverSignature)) { shmdt(addr); diff --git a/nx-X11/lib/X11/FontInfo.c b/nx-X11/lib/X11/FontInfo.c index 368beebe4..0cb5b1910 100644 --- a/nx-X11/lib/X11/FontInfo.c +++ b/nx-X11/lib/X11/FontInfo.c @@ -28,6 +28,7 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> #if defined(XF86BIGFONT) #define USE_XF86BIGFONT @@ -45,10 +46,11 @@ int maxNames, int *actualCount, /* RETURN */ XFontStruct **info) /* RETURN */ { - register long nbytes; + unsigned long nbytes; + unsigned long reply_left; /* unused data left in reply buffer */ register int i; register XFontStruct *fs; - register int size = 0; + unsigned int size = 0; XFontStruct *finfo = NULL; char **flist = NULL; xListFontsWithInfoReply reply; @@ -67,51 +69,44 @@ XFontStruct **info) /* RETURN */ if (!_XReply (dpy, (xReply *) &reply, ((SIZEOF(xListFontsWithInfoReply) - SIZEOF(xGenericReply)) >> 2), xFalse)) { - for (j=(i-1); (j >= 0); j--) { - Xfree(flist[j]); - if (finfo[j].properties) Xfree((char *) finfo[j].properties); - } - if (flist) Xfree((char *) flist); - if (finfo) Xfree((char *) finfo); - UnlockDisplay(dpy); - SyncHandle(); - return ((char **) NULL); + reply.nameLength = 0; /* avoid trying to read more replies */ + reply_left = 0; + goto badmem; } - if (reply.nameLength == 0) + reply_left = reply.length - + ((SIZEOF(xListFontsWithInfoReply) - SIZEOF(xGenericReply)) >> 2); + if (reply.nameLength == 0) { + _XEatDataWords(dpy, reply_left); break; + } + if (reply.nReplies >= (INT_MAX - i)) /* avoid overflowing size */ + goto badmem; if ((i + reply.nReplies) >= size) { size = i + reply.nReplies + 1; + if (size >= (INT_MAX / sizeof(XFontStruct))) + goto badmem; + if (finfo) { - XFontStruct * tmp_finfo = (XFontStruct *) - Xrealloc ((char *) finfo, - (unsigned) (sizeof(XFontStruct) * size)); - char ** tmp_flist = (char **) - Xrealloc ((char *) flist, - (unsigned) (sizeof(char *) * (size+1))); - - if ((! tmp_finfo) || (! tmp_flist)) { - /* free all the memory that we allocated */ - for (j=(i-1); (j >= 0); j--) { - Xfree(flist[j]); - if (finfo[j].properties) - Xfree((char *) finfo[j].properties); - } - if (tmp_flist) Xfree((char *) tmp_flist); - else Xfree((char *) flist); - if (tmp_finfo) Xfree((char *) tmp_finfo); - else Xfree((char *) finfo); - goto clearwire; - } - finfo = tmp_finfo; - flist = tmp_flist; + XFontStruct * tmp_finfo; + char ** tmp_flist; + + tmp_finfo = Xrealloc (finfo, sizeof(XFontStruct) * size); + if (tmp_finfo) + finfo = tmp_finfo; + else + goto badmem; + + tmp_flist = Xrealloc (flist, sizeof(char *) * (size+1)); + if (tmp_flist) + flist = tmp_flist; + else + goto badmem; } else { - if (! (finfo = (XFontStruct *) - Xmalloc((unsigned) (sizeof(XFontStruct) * size)))) + if (! (finfo = Xmalloc(sizeof(XFontStruct) * size))) goto clearwire; - if (! (flist = (char **) - Xmalloc((unsigned) (sizeof(char *) * (size+1))))) { + if (! (flist = Xmalloc(sizeof(char *) * (size+1)))) { Xfree((char *) finfo); goto clearwire; } @@ -137,24 +132,27 @@ XFontStruct **info) /* RETURN */ fs->max_bounds = * (XCharStruct *) &reply.maxBounds; fs->n_properties = reply.nFontProps; + fs->properties = NULL; if (fs->n_properties > 0) { - nbytes = reply.nFontProps * sizeof(XFontProp); - if (! (fs->properties = (XFontProp *) Xmalloc((unsigned) nbytes))) - goto badmem; + /* nFontProps is a CARD16 */ nbytes = reply.nFontProps * SIZEOF(xFontProp); + if ((nbytes >> 2) <= reply_left) { + size_t pbytes = reply.nFontProps * sizeof(XFontProp); + fs->properties = Xmalloc (pbytes); + } + if (! fs->properties) + goto badmem; _XRead32 (dpy, (long *)fs->properties, nbytes); + reply_left -= (nbytes >> 2); + } - } else - fs->properties = NULL; - - j = reply.nameLength + 1; + /* nameLength is a CARD8 */ + nbytes = reply.nameLength + 1; if (!i) - j++; /* make first string 1 byte longer, to match XListFonts */ - flist[i] = (char *) Xmalloc ((unsigned int) j); + nbytes++; /* make first string 1 byte longer, to match XListFonts */ + flist[i] = Xmalloc (nbytes); if (! flist[i]) { if (finfo[i].properties) Xfree((char *) finfo[i].properties); - nbytes = (reply.nameLength + 3) & ~3; - _XEatData(dpy, (unsigned long) nbytes); goto badmem; } if (!i) { @@ -176,27 +174,25 @@ XFontStruct **info) /* RETURN */ badmem: /* Free all memory allocated by this function. */ for (j=(i-1); (j >= 0); j--) { - Xfree(flist[j]); - if (finfo[j].properties) Xfree((char *) finfo[j].properties); + if (j == 0) + flist[j]--; /* was incremented above */ + Xfree(flist[j]); + if (finfo[j].properties) Xfree((char *) finfo[j].properties); } if (flist) Xfree((char *) flist); if (finfo) Xfree((char *) finfo); clearwire: /* Clear the wire. */ - do { - if (reply.nFontProps) - _XEatData(dpy, (unsigned long) - (reply.nFontProps * SIZEOF(xFontProp))); - nbytes = (reply.nameLength + 3) & ~3; - _XEatData(dpy, (unsigned long) nbytes); - } - while (_XReply(dpy,(xReply *) &reply, ((SIZEOF(xListFontsWithInfoReply) - - SIZEOF(xGenericReply)) >> 2), - xFalse) && (reply.nameLength != 0)); - + _XEatDataWords(dpy, reply_left); + while ((reply.nameLength != 0) && + _XReply(dpy, (xReply *) &reply, + ((SIZEOF(xListFontsWithInfoReply) - SIZEOF(xGenericReply)) + >> 2), xTrue)); UnlockDisplay(dpy); SyncHandle(); + *info = NULL; + *actualCount = 0; return (char **) NULL; } diff --git a/nx-X11/lib/X11/FontNames.c b/nx-X11/lib/X11/FontNames.c index 3018cf2cf..b5bc7b4ba 100644 --- a/nx-X11/lib/X11/FontNames.c +++ b/nx-X11/lib/X11/FontNames.c @@ -29,6 +29,7 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> char ** XListFonts( @@ -40,11 +41,13 @@ int *actualCount) /* RETURN */ register long nbytes; register unsigned i; register int length; - char **flist; - char *ch; + char **flist = NULL; + char *ch = NULL; + char *chend; + int count = 0; xListFontsReply rep; register xListFontsReq *req; - register long rlen; + unsigned long rlen; LockDisplay(dpy); GetReq(ListFonts, req); @@ -62,15 +65,17 @@ int *actualCount) /* RETURN */ } if (rep.nFonts) { - flist = (char **)Xmalloc ((unsigned)rep.nFonts * sizeof(char *)); - rlen = rep.length << 2; - ch = (char *) Xmalloc((unsigned) (rlen + 1)); + flist = Xmalloc (rep.nFonts * sizeof(char *)); + if (rep.length < (LONG_MAX >> 2)) { + rlen = rep.length << 2; + ch = Xmalloc(rlen + 1); /* +1 to leave room for last null-terminator */ + } if ((! flist) || (! ch)) { if (flist) Xfree((char *) flist); if (ch) Xfree(ch); - _XEatData(dpy, (unsigned long) rlen); + _XEatDataWords(dpy, rep.length); *actualCount = 0; UnlockDisplay(dpy); SyncHandle(); @@ -81,17 +86,21 @@ int *actualCount) /* RETURN */ /* * unpack into null terminated strings. */ + chend = ch + (rlen + 1); length = *(unsigned char *)ch; *ch = 1; /* make sure it is non-zero for XFreeFontNames */ for (i = 0; i < rep.nFonts; i++) { - flist[i] = ch + 1; /* skip over length */ - ch += length + 1; /* find next length ... */ - length = *(unsigned char *)ch; - *ch = '\0'; /* and replace with null-termination */ + if (ch + length < chend) { + flist[i] = ch + 1; /* skip over length */ + ch += length + 1; /* find next length ... */ + length = *(unsigned char *)ch; + *ch = '\0'; /* and replace with null-termination */ + count++; + } else + flist[i] = NULL; } } - else flist = (char **) NULL; - *actualCount = rep.nFonts; + *actualCount = count; UnlockDisplay(dpy); SyncHandle(); return (flist); diff --git a/nx-X11/lib/X11/GetAtomNm.c b/nx-X11/lib/X11/GetAtomNm.c index 9823c690c..996f7ebf9 100644 --- a/nx-X11/lib/X11/GetAtomNm.c +++ b/nx-X11/lib/X11/GetAtomNm.c @@ -78,7 +78,7 @@ char *XGetAtomName( name[rep.nameLength] = '\0'; _XUpdateAtomCache(dpy, name, atom, 0, -1, 0); } else { - _XEatData(dpy, (unsigned long) (rep.nameLength + 3) & ~3); + _XEatDataWords(dpy, rep.length); name = (char *) NULL; } UnlockDisplay(dpy); @@ -176,7 +176,7 @@ XGetAtomNames ( _XUpdateAtomCache(dpy, names_return[missed], atoms[missed], 0, -1, 0); } else { - _XEatData(dpy, (unsigned long) (rep.nameLength + 3) & ~3); + _XEatDataWords(dpy, rep.length); async_state.status = 0; } } diff --git a/nx-X11/lib/X11/GetDflt.c b/nx-X11/lib/X11/GetDflt.c index 0c00b3c94..749893c7e 100644 --- a/nx-X11/lib/X11/GetDflt.c +++ b/nx-X11/lib/X11/GetDflt.c @@ -52,30 +52,7 @@ SOFTWARE. #include "Xlibint.h" #include <nx-X11/Xos.h> #include <nx-X11/Xresource.h> - -#ifndef X_NOT_POSIX -#ifdef _POSIX_SOURCE -#include <limits.h> -#else -#define _POSIX_SOURCE -#include <limits.h> -#undef _POSIX_SOURCE -#endif -#endif -#ifndef PATH_MAX -#ifdef WIN32 -#define PATH_MAX 512 -#else -#include <sys/param.h> -#endif -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif -#endif +#include "pathmax.h" #ifdef XTHREADS #include <nx-X11/Xthreads.h> diff --git a/nx-X11/lib/X11/GetFPath.c b/nx-X11/lib/X11/GetFPath.c index 7d497c92e..abd4a5dbd 100644 --- a/nx-X11/lib/X11/GetFPath.c +++ b/nx-X11/lib/X11/GetFPath.c @@ -28,15 +28,18 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> char **XGetFontPath( register Display *dpy, int *npaths) /* RETURN */ { xGetFontPathReply rep; - register long nbytes; - char **flist; - char *ch; + unsigned long nbytes; + char **flist = NULL; + char *ch = NULL; + char *chend; + int count = 0; register unsigned i; register int length; register xReq *req; @@ -46,16 +49,17 @@ char **XGetFontPath( (void) _XReply (dpy, (xReply *) &rep, 0, xFalse); if (rep.nPaths) { - flist = (char **) - Xmalloc((unsigned) rep.nPaths * sizeof (char *)); - nbytes = (long)rep.length << 2; - ch = (char *) Xmalloc ((unsigned) (nbytes + 1)); + flist = Xmalloc(rep.nPaths * sizeof (char *)); + if (rep.length < (LONG_MAX >> 2)) { + nbytes = (unsigned long) rep.length << 2; + ch = Xmalloc (nbytes + 1); /* +1 to leave room for last null-terminator */ + } if ((! flist) || (! ch)) { if (flist) Xfree((char *) flist); if (ch) Xfree(ch); - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (char **) NULL; @@ -65,16 +69,20 @@ char **XGetFontPath( /* * unpack into null terminated strings. */ + chend = ch + (nbytes + 1); length = *ch; for (i = 0; i < rep.nPaths; i++) { - flist[i] = ch+1; /* skip over length */ - ch += length + 1; /* find next length ... */ - length = *ch; - *ch = '\0'; /* and replace with null-termination */ + if (ch + length < chend) { + flist[i] = ch+1; /* skip over length */ + ch += length + 1; /* find next length ... */ + length = *ch; + *ch = '\0'; /* and replace with null-termination */ + count++; + } else + flist[i] = NULL; } } - else flist = NULL; - *npaths = rep.nPaths; + *npaths = count; UnlockDisplay(dpy); SyncHandle(); return (flist); diff --git a/nx-X11/lib/X11/GetImage.c b/nx-X11/lib/X11/GetImage.c index ddd434a81..59fb45eb1 100644 --- a/nx-X11/lib/X11/GetImage.c +++ b/nx-X11/lib/X11/GetImage.c @@ -30,6 +30,7 @@ in this Software without prior written authorization from The Open Group. #include "Xlibint.h" #include <nx-X11/Xutil.h> /* for XDestroyImage */ #include "ImUtil.h" +#include <limits.h> #define ROUNDUP(nbytes, pad) (((((nbytes) - 1) + (pad)) / (pad)) * (pad)) @@ -56,7 +57,7 @@ XImage *XGetImage ( xGetImageReply rep; register xGetImageReq *req; char *data; - long nbytes; + unsigned long nbytes; XImage *image; LockDisplay(dpy); GetReq (GetImage, req); @@ -78,10 +79,13 @@ XImage *XGetImage ( return (XImage *)NULL; } - nbytes = (long)rep.length << 2; - data = (char *) Xmalloc((unsigned) nbytes); + if (rep.length < (INT_MAX >> 2)) { + nbytes = (unsigned long)rep.length << 2; + data = Xmalloc(nbytes); + } else + data = NULL; if (! data) { - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (XImage *) NULL; diff --git a/nx-X11/lib/X11/GetMoEv.c b/nx-X11/lib/X11/GetMoEv.c index 3db176feb..ad9c77277 100644 --- a/nx-X11/lib/X11/GetMoEv.c +++ b/nx-X11/lib/X11/GetMoEv.c @@ -28,6 +28,7 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> XTimeCoord *XGetMotionEvents( register Display *dpy, @@ -39,7 +40,6 @@ XTimeCoord *XGetMotionEvents( xGetMotionEventsReply rep; register xGetMotionEventsReq *req; XTimeCoord *tc = NULL; - long nbytes; LockDisplay(dpy); GetReq(GetMotionEvents, req); req->window = w; @@ -52,26 +52,22 @@ XTimeCoord *XGetMotionEvents( return (NULL); } - if (rep.nEvents) { - if (! (tc = (XTimeCoord *) - Xmalloc( (unsigned) - (nbytes = (long) rep.nEvents * sizeof(XTimeCoord))))) { - _XEatData (dpy, (unsigned long) nbytes); - UnlockDisplay(dpy); - SyncHandle(); - return (NULL); - } + if (rep.nEvents && (rep.nEvents < (INT_MAX / sizeof(XTimeCoord)))) + tc = Xmalloc(rep.nEvents * sizeof(XTimeCoord)); + if (tc == NULL) { + /* server returned either no events or a bad event count */ + *nEvents = 0; + _XEatDataWords (dpy, rep.length); } - - *nEvents = rep.nEvents; - nbytes = SIZEOF (xTimecoord); + else { register XTimeCoord *tcptr; - register int i; + unsigned int i; xTimecoord xtc; + *nEvents = (int) rep.nEvents; for (i = rep.nEvents, tcptr = tc; i > 0; i--, tcptr++) { - _XRead (dpy, (char *) &xtc, nbytes); + _XRead (dpy, (char *) &xtc, SIZEOF (xTimecoord)); tcptr->time = xtc.time; tcptr->x = cvtINT16toShort (xtc.x); tcptr->y = cvtINT16toShort (xtc.y); diff --git a/nx-X11/lib/X11/GetPntMap.c b/nx-X11/lib/X11/GetPntMap.c index 0fcdb6696..29fdf21f0 100644 --- a/nx-X11/lib/X11/GetPntMap.c +++ b/nx-X11/lib/X11/GetPntMap.c @@ -29,6 +29,7 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> #ifdef MIN /* some systems define this in <sys/param.h> */ #undef MIN @@ -42,7 +43,7 @@ int XGetPointerMapping ( { unsigned char mapping[256]; /* known fixed size */ - long nbytes, remainder = 0; + unsigned long nbytes, remainder = 0; xGetPointerMappingReply rep; register xReq *req; @@ -54,9 +55,15 @@ int XGetPointerMapping ( return 0; } - nbytes = (long)rep.length << 2; - /* Don't count on the server returning a valid value */ + if (rep.length >= (INT_MAX >> 2)) { + _XEatDataWords(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + + nbytes = (unsigned long) rep.length << 2; if (nbytes > sizeof mapping) { remainder = nbytes - sizeof mapping; nbytes = sizeof mapping; @@ -69,7 +76,7 @@ int XGetPointerMapping ( } if (remainder) - _XEatData(dpy, (unsigned long)remainder); + _XEatData(dpy, remainder); UnlockDisplay(dpy); SyncHandle(); @@ -86,8 +93,8 @@ XGetKeyboardMapping (Display *dpy, int count, int *keysyms_per_keycode) { - long nbytes; - unsigned long nkeysyms; + unsigned long nbytes; + CARD32 nkeysyms; register KeySym *mapping = NULL; xGetKeyboardMappingReply rep; register xGetKeyboardMappingReq *req; @@ -102,17 +109,19 @@ XGetKeyboardMapping (Display *dpy, return (KeySym *) NULL; } - nkeysyms = (unsigned long) rep.length; + nkeysyms = rep.length; if (nkeysyms > 0) { - nbytes = nkeysyms * sizeof (KeySym); - mapping = (KeySym *) Xmalloc ((unsigned) nbytes); - nbytes = nkeysyms << 2; + if (nkeysyms < (INT_MAX / sizeof (KeySym))) { + nbytes = nkeysyms * sizeof (KeySym); + mapping = Xmalloc (nbytes); + } if (! mapping) { - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (KeySym *) NULL; } + nbytes = nkeysyms << 2; _XRead32 (dpy, (long *) mapping, nbytes); } *keysyms_per_keycode = rep.keySymsPerKeyCode; diff --git a/nx-X11/lib/X11/GetProp.c b/nx-X11/lib/X11/GetProp.c index a80c19c50..4149199f5 100644 --- a/nx-X11/lib/X11/GetProp.c +++ b/nx-X11/lib/X11/GetProp.c @@ -28,6 +28,7 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> int XGetWindowProperty( @@ -48,6 +49,13 @@ XGetWindowProperty( register xGetPropertyReq *req; xError error; + /* Always initialize return values, in case callers fail to initialize + them and fail to check the return code for an error. */ + *actual_type = None; + *actual_format = 0; + *nitems = *bytesafter = 0L; + *prop = (unsigned char *) NULL; + LockDisplay(dpy); GetReq (GetProperty, req); req->window = w; @@ -64,10 +72,18 @@ XGetWindowProperty( return (1); /* not Success */ } - *prop = (unsigned char *) NULL; if (reply.propertyType != None) { - long nbytes, netbytes; - switch (reply.format) { + unsigned long nbytes, netbytes; + int format = reply.format; + + /* + * Protect against both integer overflow and just plain oversized + * memory allocation - no server should ever return this many props. + */ + if (reply.nItems >= (INT_MAX >> 4)) + format = -1; /* fall through to default error case */ + + switch (format) { /* * One extra byte is malloced than is needed to contain the property * data, but this last byte is null terminated and convenient for @@ -76,24 +92,21 @@ XGetWindowProperty( */ case 8: nbytes = netbytes = reply.nItems; - if (nbytes + 1 > 0 && - (*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1))) + if (nbytes + 1 > 0 && (*prop = Xmalloc (nbytes + 1))) _XReadPad (dpy, (char *) *prop, netbytes); break; case 16: nbytes = reply.nItems * sizeof (short); netbytes = reply.nItems << 1; - if (nbytes + 1 > 0 && - (*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1))) + if (nbytes + 1 > 0 && (*prop = Xmalloc (nbytes + 1))) _XRead16Pad (dpy, (short *) *prop, netbytes); break; case 32: nbytes = reply.nItems * sizeof (long); netbytes = reply.nItems << 2; - if (nbytes + 1 > 0 && - (*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1))) + if (nbytes + 1 > 0 && (*prop = Xmalloc (nbytes + 1))) _XRead32 (dpy, (long *) *prop, netbytes); break; @@ -115,7 +128,7 @@ XGetWindowProperty( break; } if (! *prop) { - _XEatData(dpy, (unsigned long) netbytes); + _XEatDataWords(dpy, reply.length); UnlockDisplay(dpy); SyncHandle(); return(BadAlloc); /* not Success */ diff --git a/nx-X11/lib/X11/Imakefile b/nx-X11/lib/X11/Imakefile index d4045b615..5a1fc5ff2 100644 --- a/nx-X11/lib/X11/Imakefile +++ b/nx-X11/lib/X11/Imakefile @@ -1146,7 +1146,7 @@ MakeLintSubdirs($(LINTSUBDIRS),install.ln,install.ln) #endif #endif -includes:: XlibConf.h +includes:: XlibConf.h pathmax.h #include <Threads.tmpl> diff --git a/nx-X11/lib/X11/LiHosts.c b/nx-X11/lib/X11/LiHosts.c index 63ecc508a..6ec956e72 100644 --- a/nx-X11/lib/X11/LiHosts.c +++ b/nx-X11/lib/X11/LiHosts.c @@ -62,6 +62,8 @@ X Window System is a trademark of The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> + /* * can be freed using XFree. */ @@ -73,7 +75,6 @@ XHostAddress *XListHosts ( { register XHostAddress *outbuf = NULL, *op; xListHostsReply reply; - long nbytes; unsigned char *buf, *bp; register unsigned i; register xListHostsReq *req; @@ -90,19 +91,26 @@ XHostAddress *XListHosts ( } if (reply.nHosts) { - nbytes = reply.length << 2; /* compute number of bytes in reply */ + unsigned long nbytes = reply.length << 2; /* number of bytes in reply */ + const unsigned long max_hosts = INT_MAX / + (sizeof(XHostAddress) + sizeof(XServerInterpretedAddress)); + + if (reply.nHosts < max_hosts) { + unsigned long hostbytes = reply.nHosts * + (sizeof(XHostAddress) + sizeof(XServerInterpretedAddress)); - op = outbuf = (XHostAddress *) - Xmalloc((unsigned) (nbytes + - (reply.nHosts * sizeof(XHostAddress)) + - (reply.nHosts * sizeof(XServerInterpretedAddress)))); + if (reply.length < (INT_MAX >> 2) && + (hostbytes >> 2) < ((INT_MAX >> 2) - reply.length)) + outbuf = Xmalloc(nbytes + hostbytes); + } if (! outbuf) { - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, reply.length); UnlockDisplay(dpy); SyncHandle(); return (XHostAddress *) NULL; } + op = outbuf; sip = (XServerInterpretedAddress *) (((unsigned char *) outbuf) + (reply.nHosts * sizeof(XHostAddress))); bp = buf = ((unsigned char *) sip) diff --git a/nx-X11/lib/X11/LiICmaps.c b/nx-X11/lib/X11/LiICmaps.c index e98161916..45a2f2fd3 100644 --- a/nx-X11/lib/X11/LiICmaps.c +++ b/nx-X11/lib/X11/LiICmaps.c @@ -34,7 +34,7 @@ Colormap *XListInstalledColormaps( Window win, int *n) /* RETURN */ { - long nbytes; + unsigned long nbytes; Colormap *cmaps; xListInstalledColormapsReply rep; register xResourceReq *req; @@ -51,14 +51,14 @@ Colormap *XListInstalledColormaps( if (rep.nColormaps) { nbytes = rep.nColormaps * sizeof(Colormap); - cmaps = (Colormap *) Xmalloc((unsigned) nbytes); - nbytes = rep.nColormaps << 2; + cmaps = Xmalloc(nbytes); if (! cmaps) { - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return((Colormap *) NULL); } + nbytes = rep.nColormaps << 2; _XRead32 (dpy, (long *) cmaps, nbytes); } else cmaps = (Colormap *) NULL; diff --git a/nx-X11/lib/X11/LiProps.c b/nx-X11/lib/X11/LiProps.c index 72560aba7..d9c746563 100644 --- a/nx-X11/lib/X11/LiProps.c +++ b/nx-X11/lib/X11/LiProps.c @@ -34,7 +34,7 @@ Atom *XListProperties( Window window, int *n_props) /* RETURN */ { - long nbytes; + unsigned long nbytes; xListPropertiesReply rep; Atom *properties; register xResourceReq *req; @@ -50,14 +50,14 @@ Atom *XListProperties( if (rep.nProperties) { nbytes = rep.nProperties * sizeof(Atom); - properties = (Atom *) Xmalloc ((unsigned) nbytes); - nbytes = rep.nProperties << 2; + properties = Xmalloc (nbytes); if (! properties) { - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (Atom *) NULL; } + nbytes = rep.nProperties << 2; _XRead32 (dpy, (long *) properties, nbytes); } else properties = (Atom *) NULL; diff --git a/nx-X11/lib/X11/ListExt.c b/nx-X11/lib/X11/ListExt.c index 16b522e88..e925c4773 100644 --- a/nx-X11/lib/X11/ListExt.c +++ b/nx-X11/lib/X11/ListExt.c @@ -28,18 +28,21 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> char **XListExtensions( register Display *dpy, int *nextensions) /* RETURN */ { xListExtensionsReply rep; - char **list; - char *ch; + char **list = NULL; + char *ch = NULL; + char *chend; + int count = 0; register unsigned i; register int length; register xReq *req; - register long rlen; + unsigned long rlen; LockDisplay(dpy); GetEmptyReq (ListExtensions, req); @@ -51,16 +54,17 @@ char **XListExtensions( } if (rep.nExtensions) { - list = (char **) Xmalloc ( - (unsigned)(rep.nExtensions * sizeof (char *))); - rlen = rep.length << 2; - ch = (char *) Xmalloc ((unsigned) rlen + 1); + list = Xmalloc (rep.nExtensions * sizeof (char *)); + if (rep.length < (LONG_MAX >> 2)) { + rlen = rep.length << 2; + ch = Xmalloc (rlen + 1); /* +1 to leave room for last null-terminator */ + } if ((!list) || (!ch)) { if (list) Xfree((char *) list); if (ch) Xfree((char *) ch); - _XEatData(dpy, (unsigned long) rlen); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (char **) NULL; @@ -70,17 +74,21 @@ char **XListExtensions( /* * unpack into null terminated strings. */ + chend = ch + (rlen + 1); length = *ch; for (i = 0; i < rep.nExtensions; i++) { - list[i] = ch+1; /* skip over length */ - ch += length + 1; /* find next length ... */ - length = *ch; - *ch = '\0'; /* and replace with null-termination */ + if (ch + length < chend) { + list[i] = ch+1; /* skip over length */ + ch += length + 1; /* find next length ... */ + length = *ch; + *ch = '\0'; /* and replace with null-termination */ + count++; + } else + list[i] = NULL; } } - else list = (char **) NULL; - *nextensions = rep.nExtensions; + *nextensions = count; UnlockDisplay(dpy); SyncHandle(); return (list); diff --git a/nx-X11/lib/X11/ModMap.c b/nx-X11/lib/X11/ModMap.c index c99bfdd5f..122ca80db 100644 --- a/nx-X11/lib/X11/ModMap.c +++ b/nx-X11/lib/X11/ModMap.c @@ -28,6 +28,7 @@ in this Software without prior written authorization from The Open Group. #include <config.h> #endif #include "Xlibint.h" +#include <limits.h> XModifierKeymap * XGetModifierMapping(register Display *dpy) @@ -41,13 +42,17 @@ XGetModifierMapping(register Display *dpy) GetEmptyReq(GetModifierMapping, req); (void) _XReply (dpy, (xReply *)&rep, 0, xFalse); - nbytes = (unsigned long)rep.length << 2; - res = (XModifierKeymap *) Xmalloc(sizeof (XModifierKeymap)); - if (res) res->modifiermap = (KeyCode *) Xmalloc ((unsigned) nbytes); + if (rep.length < (LONG_MAX >> 2)) { + nbytes = (unsigned long)rep.length << 2; + res = Xmalloc(sizeof (XModifierKeymap)); + if (res) + res->modifiermap = Xmalloc (nbytes); + } else + res = NULL; if ((! res) || (! res->modifiermap)) { if (res) Xfree((char *) res); res = (XModifierKeymap *) NULL; - _XEatData(dpy, nbytes); + _XEatDataWords(dpy, rep.length); } else { _XReadPad(dpy, (char *) res->modifiermap, (long) nbytes); res->max_keypermod = rep.numKeyPerModifier; diff --git a/nx-X11/lib/X11/OpenDis.c b/nx-X11/lib/X11/OpenDis.c index a17b8b161..4036572a8 100644 --- a/nx-X11/lib/X11/OpenDis.c +++ b/nx-X11/lib/X11/OpenDis.c @@ -549,9 +549,7 @@ fallback_success: /* * Now iterate down setup information..... */ - dpy->pixmap_format = - (ScreenFormat *)Xmalloc( - (unsigned) (dpy->nformats *sizeof(ScreenFormat))); + dpy->pixmap_format = Xcalloc(dpy->nformats, sizeof(ScreenFormat)); if (dpy->pixmap_format == NULL) { OutOfMemory (dpy, setup); return(NULL); @@ -579,8 +577,7 @@ fallback_success: /* * next the Screen structures. */ - dpy->screens = - (Screen *)Xmalloc((unsigned) dpy->nscreens*sizeof(Screen)); + dpy->screens = Xcalloc(dpy->nscreens, sizeof(Screen)); if (dpy->screens == NULL) { OutOfMemory (dpy, setup); return(NULL); @@ -622,8 +619,7 @@ fallback_success: /* * lets set up the depth structures. */ - sp->depths = (Depth *)Xmalloc( - (unsigned)sp->ndepths*sizeof(Depth)); + sp->depths = Xcalloc(sp->ndepths, sizeof(Depth)); if (sp->depths == NULL) { OutOfMemory (dpy, setup); return(NULL); @@ -645,8 +641,7 @@ fallback_success: dp->nvisuals = u.dp->nVisuals; u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth); if (dp->nvisuals > 0) { - dp->visuals = - (Visual *)Xmalloc((unsigned)dp->nvisuals*sizeof(Visual)); + dp->visuals = Xcalloc(dp->nvisuals, sizeof(Visual)); if (dp->visuals == NULL) { OutOfMemory (dpy, setup); return(NULL); @@ -788,7 +783,7 @@ fallback_success: dpy->xdefaults[reply.nItems] = '\0'; } else if (reply.propertyType != None) - _XEatData(dpy, reply.nItems * (reply.format >> 3)); + _XEatDataWords(dpy, reply.length); } #if !USE_XCB DeqAsyncHandler(dpy, &async); diff --git a/nx-X11/lib/X11/QuColors.c b/nx-X11/lib/X11/QuColors.c index e51375fa0..a8bc8837b 100644 --- a/nx-X11/lib/X11/QuColors.c +++ b/nx-X11/lib/X11/QuColors.c @@ -37,9 +37,7 @@ XQueryColors( int ncolors) { register int i; - xrgb *color; xQueryColorsReply rep; - long nbytes; register xQueryColorsReq *req; LockDisplay(dpy); @@ -53,8 +51,9 @@ XQueryColors( /* XXX this isn't very efficient */ if (_XReply(dpy, (xReply *) &rep, 0, xFalse) != 0) { - if ((color = (xrgb *) - Xmalloc((unsigned) (nbytes = (long) ncolors * SIZEOF(xrgb))))) { + unsigned long nbytes = (long) ncolors * SIZEOF(xrgb); + xrgb *color = Xmalloc(nbytes); + if (color != NULL) { _XRead(dpy, (char *) color, nbytes); @@ -68,7 +67,8 @@ XQueryColors( } Xfree((char *)color); } - else _XEatData(dpy, (unsigned long) nbytes); + else + _XEatDataWords(dpy, rep.length); } UnlockDisplay(dpy); SyncHandle(); diff --git a/nx-X11/lib/X11/QuTree.c b/nx-X11/lib/X11/QuTree.c index 3cea282fa..8da2ae261 100644 --- a/nx-X11/lib/X11/QuTree.c +++ b/nx-X11/lib/X11/QuTree.c @@ -37,7 +37,7 @@ Status XQueryTree ( Window **children, /* RETURN */ unsigned int *nchildren) /* RETURN */ { - long nbytes; + unsigned long nbytes; xQueryTreeReply rep; register xResourceReq *req; @@ -52,14 +52,14 @@ Status XQueryTree ( *children = (Window *) NULL; if (rep.nChildren != 0) { nbytes = rep.nChildren * sizeof(Window); - *children = (Window *) Xmalloc((unsigned) nbytes); - nbytes = rep.nChildren << 2; + *children = Xmalloc(nbytes); if (! *children) { - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (0); } + nbytes = rep.nChildren << 2; _XRead32 (dpy, (long *) *children, nbytes); } *parent = rep.parent; diff --git a/nx-X11/lib/X11/XKBExtDev.c b/nx-X11/lib/X11/XKBExtDev.c index de5570337..47b94a3aa 100644 --- a/nx-X11/lib/X11/XKBExtDev.c +++ b/nx-X11/lib/X11/XKBExtDev.c @@ -181,6 +181,9 @@ int tmp; return tmp; } if (rep->nBtnsWanted>0) { + if (((unsigned short) rep->firstBtnWanted + rep->nBtnsWanted) + >= devi->num_btns) + goto BAILOUT; act= &devi->btn_acts[rep->firstBtnWanted]; bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction))); } @@ -190,6 +193,9 @@ int tmp; goto BAILOUT; if (rep->nBtnsRtrn>0) { int size; + if (((unsigned short) rep->firstBtnRtrn + rep->nBtnsRtrn) + >= devi->num_btns) + goto BAILOUT; act= &devi->btn_acts[rep->firstBtnRtrn]; size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc); if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size)) diff --git a/nx-X11/lib/X11/XKBGeom.c b/nx-X11/lib/X11/XKBGeom.c index 5ab51b682..1f9628bea 100644 --- a/nx-X11/lib/X11/XKBGeom.c +++ b/nx-X11/lib/X11/XKBGeom.c @@ -364,12 +364,16 @@ Status rtrn; } ol->num_points= olWire->nPoints; } - if (shapeWire->primaryNdx!=XkbNoShape) + if ((shapeWire->primaryNdx!=XkbNoShape) && + (shapeWire->primaryNdx < shapeWire->nOutlines)) shape->primary= &shape->outlines[shapeWire->primaryNdx]; - else shape->primary= NULL; - if (shapeWire->approxNdx!=XkbNoShape) + else + shape->primary= NULL; + if ((shapeWire->approxNdx!=XkbNoShape) && + (shapeWire->approxNdx < shapeWire->nOutlines)) shape->approx= &shape->outlines[shapeWire->approxNdx]; - else shape->approx= NULL; + else + shape->approx= NULL; XkbComputeShapeBounds(shape); } return Success; @@ -615,6 +619,9 @@ XkbGeometryPtr geom; if (status==Success) status= _XkbReadGeomKeyAliases(&buf,geom,rep); left= _XkbFreeReadBuffer(&buf); + if ((rep->baseColorNdx > geom->num_colors) || + (rep->labelColorNdx > geom->num_colors)) + status = BadLength; if ((status!=Success) || left || buf.error) { if (status==Success) status= BadLength; diff --git a/nx-X11/lib/X11/XKBGetMap.c b/nx-X11/lib/X11/XKBGetMap.c index a38907671..391d7aa89 100644 --- a/nx-X11/lib/X11/XKBGetMap.c +++ b/nx-X11/lib/X11/XKBGetMap.c @@ -152,9 +152,12 @@ XkbClientMapPtr map; map= xkb->map; if (map->key_sym_map==NULL) { register int offset; + int size = xkb->max_key_code + 1; XkbSymMapPtr oldMap; xkbSymMapWireDesc *newMap; - map->key_sym_map= _XkbTypedCalloc((xkb->max_key_code+1),XkbSymMapRec); + if (((unsigned short)rep->firstKeySym + rep->nKeySyms) > size) + return BadLength; + map->key_sym_map= _XkbTypedCalloc(size,XkbSymMapRec); if (map->key_sym_map==NULL) return BadAlloc; if (map->syms==NULL) { @@ -210,6 +213,8 @@ XkbClientMapPtr map; KeySym * newSyms; int tmp; + if (((unsigned short)rep->firstKeySym + rep->nKeySyms) > map->num_syms) + return BadLength; oldMap = &map->key_sym_map[rep->firstKeySym]; for (i=0;i<(int)rep->nKeySyms;i++,oldMap++) { newMap= (xkbSymMapWireDesc *) @@ -265,6 +270,10 @@ Status ret = Success; symMap = &info->map->key_sym_map[rep->firstKeyAct]; for (i=0;i<(int)rep->nKeyActs;i++,symMap++) { if (numDesc[i]==0) { + if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) { + ret = BadLength; + goto done; + } info->server->key_acts[i+rep->firstKeyAct]= 0; } else { @@ -297,8 +306,10 @@ register int i; xkbBehaviorWireDesc *wire; if ( rep->totalKeyBehaviors>0 ) { + int size = xkb->max_key_code + 1; + if ( ((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size) + return BadLength; if ( xkb->server->behaviors == NULL ) { - int size = xkb->max_key_code+1; xkb->server->behaviors = _XkbTypedCalloc(size,XkbBehavior); if (xkb->server->behaviors==NULL) return BadAlloc; @@ -310,7 +321,7 @@ xkbBehaviorWireDesc *wire; for (i=0;i<rep->totalKeyBehaviors;i++) { wire= (xkbBehaviorWireDesc *)_XkbGetReadBufferPtr(buf, SIZEOF(xkbBehaviorWireDesc)); - if (wire==NULL) + if (wire==NULL || wire->key >= size) return BadLength; xkb->server->behaviors[wire->key].type= wire->type; xkb->server->behaviors[wire->key].data= wire->data; @@ -352,8 +363,10 @@ register int i; unsigned char *wire; if ( rep->totalKeyExplicit>0 ) { + int size = xkb->max_key_code + 1; + if ( ((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size) + return BadLength; if ( xkb->server->explicit == NULL ) { - int size = xkb->max_key_code+1; xkb->server->explicit = _XkbTypedCalloc(size,unsigned char); if (xkb->server->explicit==NULL) return BadAlloc; @@ -367,6 +380,8 @@ unsigned char *wire; if (!wire) return BadLength; for (i=0;i<rep->totalKeyExplicit;i++,wire+=2) { + if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) + return BadLength; xkb->server->explicit[wire[0]]= wire[1]; } } @@ -380,6 +395,9 @@ register int i; unsigned char *wire; if ( rep->totalModMapKeys>0 ) { + if ( ((int)rep->firstModMapKey + rep->nModMapKeys) > + (xkb->max_key_code + 1)) + return BadLength; if ((xkb->map->modmap==NULL)&& (XkbAllocClientMap(xkb,XkbModifierMapMask,0)!=Success)) { return BadAlloc; @@ -392,6 +410,8 @@ unsigned char *wire; if (!wire) return BadLength; for (i=0;i<rep->totalModMapKeys;i++,wire+=2) { + if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) + return BadLength; xkb->map->modmap[wire[0]]= wire[1]; } } @@ -406,6 +426,9 @@ xkbVModMapWireDesc * wire; XkbServerMapPtr srv; if ( rep->totalVModMapKeys>0 ) { + if (((int) rep->firstVModMapKey + rep->nVModMapKeys) + > xkb->max_key_code + 1) + return BadLength; if (((xkb->server==NULL)||(xkb->server->vmodmap==NULL))&& (XkbAllocServerMap(xkb,XkbVirtualModMapMask,0)!=Success)) { return BadAlloc; @@ -462,6 +485,8 @@ unsigned mask; if ( xkb->device_spec == XkbUseCoreKbd ) xkb->device_spec= rep->deviceID; + if ( rep->maxKeyCode < rep->minKeyCode ) + return BadImplementation; xkb->min_key_code = rep->minKeyCode; xkb->max_key_code = rep->maxKeyCode; diff --git a/nx-X11/lib/X11/XKBNames.c b/nx-X11/lib/X11/XKBNames.c index 04cd6f3e3..c82b59e30 100644 --- a/nx-X11/lib/X11/XKBNames.c +++ b/nx-X11/lib/X11/XKBNames.c @@ -180,6 +180,8 @@ _XkbReadGetNamesReply( Display * dpy, nKeys= xkb->max_key_code+1; names->keys= _XkbTypedCalloc(nKeys,XkbKeyNameRec); } + else if ( ((int)rep->firstKey + rep->nKeys) > xkb->max_key_code + 1) + goto BAILOUT; if (names->keys!=NULL) { if (!_XkbCopyFromReadBuffer(&buf, (char *)&names->keys[rep->firstKey], diff --git a/nx-X11/lib/X11/Xrm.c b/nx-X11/lib/X11/Xrm.c index d88442c6e..818e72906 100644 --- a/nx-X11/lib/X11/Xrm.c +++ b/nx-X11/lib/X11/Xrm.c @@ -1087,13 +1087,15 @@ static void GetIncludeFile( XrmDatabase db, _Xconst char *base, _Xconst char *fname, - int fnamelen); + int fnamelen, + int depth); static void GetDatabase( XrmDatabase db, _Xconst register char *str, _Xconst char *filename, - Bool doall) + Bool doall, + int depth) { char *rhs; char *lhs, lhs_s[DEF_BUFF_SIZE]; @@ -1203,7 +1205,8 @@ static void GetDatabase( } while (c != '"' && !is_EOL(bits)); /* must have an ending " */ if (c == '"') - GetIncludeFile(db, filename, fname, str - len - fname); + GetIncludeFile(db, filename, fname, str - len - fname, + depth); } } /* spin to next newline */ @@ -1544,7 +1547,7 @@ XrmPutLineResource( { if (!*pdb) *pdb = NewDatabase(); _XLockMutex(&(*pdb)->linfo); - GetDatabase(*pdb, line, (char *)NULL, False); + GetDatabase(*pdb, line, (char *)NULL, False, 0); _XUnlockMutex(&(*pdb)->linfo); } @@ -1556,7 +1559,7 @@ XrmGetStringDatabase( db = NewDatabase(); _XLockMutex(&db->linfo); - GetDatabase(db, data, (char *)NULL, True); + GetDatabase(db, data, (char *)NULL, True, 0); _XUnlockMutex(&db->linfo); return db; } @@ -1594,6 +1597,12 @@ ReadInFile(_Xconst char *filename) */ GetSizeOfFile(fd, size); + /* There might have been a problem trying to stat a file */ + if (size == -1) { + close (fd); + return (char *)NULL; + } + if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */ close(fd); return (char *)NULL; @@ -1627,7 +1636,8 @@ GetIncludeFile( XrmDatabase db, _Xconst char *base, _Xconst char *fname, - int fnamelen) + int fnamelen, + int depth) { int len; char *str; @@ -1635,6 +1645,8 @@ GetIncludeFile( if (fnamelen <= 0 || fnamelen >= BUFSIZ) return; + if (depth >= MAXDBDEPTH) + return; if (*fname != '/' && base && (str = strrchr(base, '/'))) { len = str - base + 1; if (len + fnamelen >= BUFSIZ) @@ -1648,7 +1660,7 @@ GetIncludeFile( } if (!(str = ReadInFile(realfname))) return; - GetDatabase(db, str, realfname, True); + GetDatabase(db, str, realfname, True, depth + 1); Xfree(str); } @@ -1664,7 +1676,7 @@ XrmGetFileDatabase( db = NewDatabase(); _XLockMutex(&db->linfo); - GetDatabase(db, str, filename, True); + GetDatabase(db, str, filename, True, 0); _XUnlockMutex(&db->linfo); Xfree(str); return db; @@ -1688,7 +1700,7 @@ XrmCombineFileDatabase( } else db = NewDatabase(); _XLockMutex(&db->linfo); - GetDatabase(db, str, filename, True); + GetDatabase(db, str, filename, True, 0); _XUnlockMutex(&db->linfo); Xfree(str); if (!override) diff --git a/nx-X11/lib/X11/XrmI.h b/nx-X11/lib/X11/XrmI.h index a1615f4e5..63ed257ed 100644 --- a/nx-X11/lib/X11/XrmI.h +++ b/nx-X11/lib/X11/XrmI.h @@ -35,11 +35,13 @@ from The Open Group. #include <nx-X11/Xos.h> #include <sys/stat.h> +#include <limits.h> #define GetSizeOfFile(fd,size) \ { \ struct stat status_buffer; \ - if ( (fstat((fd), &status_buffer)) == -1 ) \ + if ( ((fstat((fd), &status_buffer)) == -1 ) || \ + (status_buffer.st_size >= INT_MAX) ) \ size = -1; \ else \ size = status_buffer.st_size; \ diff --git a/nx-X11/lib/X11/cmsColNm.c b/nx-X11/lib/X11/cmsColNm.c index 82ffab5f6..5f9724822 100644 --- a/nx-X11/lib/X11/cmsColNm.c +++ b/nx-X11/lib/X11/cmsColNm.c @@ -40,6 +40,7 @@ #include <sys/stat.h> #include <stdio.h> #include <ctype.h> +#include <limits.h> #define XK_LATIN1 #include <nx-X11/keysymdef.h> #include "Cv.h" @@ -542,7 +543,10 @@ stringSectionSize( char *pBuf; char *f1; char *f2; - int i; + size_t i; + + unsigned int numEntries = 0; + unsigned int sectionSize = 0; *pNumEntries = 0; *pSectionSize = 0; @@ -576,26 +580,37 @@ stringSectionSize( return(XcmsFailure); } - (*pNumEntries)++; + numEntries++; + if (numEntries >= INT_MAX) + return(XcmsFailure); - (*pSectionSize) += (i = strlen(f1)) + 1; + i = strlen(f1); + if (i >= INT_MAX - sectionSize) + return(XcmsFailure); + sectionSize += i + 1; for (; i; i--, f1++) { /* REMOVE SPACES FROM COUNT */ if (isspace(*f1)) { - (*pSectionSize)--; + sectionSize--; } } - (*pSectionSize) += (i = strlen(f2)) + 1; + i = strlen(f2); + if (i >= INT_MAX - sectionSize) + return(XcmsFailure); + sectionSize += i + 1; for (; i; i--, f2++) { /* REMOVE SPACES FROM COUNT */ if (isspace(*f2)) { - (*pSectionSize)--; + sectionSize--; } } } + *pNumEntries = (int) numEntries; + *pSectionSize = (int) sectionSize; + return(XcmsSuccess); } diff --git a/nx-X11/lib/X11/imLcPrs.c b/nx-X11/lib/X11/imLcPrs.c index 4dbcbbed4..ad65da694 100644 --- a/nx-X11/lib/X11/imLcPrs.c +++ b/nx-X11/lib/X11/imLcPrs.c @@ -41,6 +41,8 @@ OR PERFORMANCE OF THIS SOFTWARE. #include "Ximint.h" #include <sys/stat.h> #include <stdio.h> +#include <limits.h> +#include "pathmax.h" #define XLC_BUFSIZE 256 @@ -56,6 +58,8 @@ extern int _Xmbstoutf8( int len ); +static void parsestringfile(FILE *fp, Xim im, int depth); + /* * Parsing File Format: * @@ -304,9 +308,9 @@ static char* TransFileName(Xim im, char *name) { char *home = NULL, *lcCompose = NULL; - char dir[XLC_BUFSIZE]; - char *i = name, *ret, *j; - int l = 0; + char dir[XLC_BUFSIZE] = ""; + char *i = name, *ret = NULL, *j; + size_t l = 0; while (*i) { if (*i == '%') { @@ -316,29 +320,51 @@ TransFileName(Xim im, char *name) l++; break; case 'H': - home = getenv("HOME"); - if (home) - l += strlen(home); + if (home == NULL) + home = getenv("HOME"); + if (home) { + size_t Hsize = strlen(home); + if (Hsize > PATH_MAX) + /* your home directory length is ridiculous */ + goto end; + l += Hsize; + } break; case 'L': - lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE); - if (lcCompose) - l += strlen(lcCompose); + if (lcCompose == NULL) + lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE); + if (lcCompose) { + size_t Lsize = strlen(lcCompose); + if (Lsize > PATH_MAX) + /* your compose pathname length is ridiculous */ + goto end; + l += Lsize; + } break; case 'S': - xlocaledir(dir, XLC_BUFSIZE); - l += strlen(dir); + if (dir[0] == '\0') + xlocaledir(dir, XLC_BUFSIZE); + if (dir[0]) { + size_t Ssize = strlen(dir); + if (Ssize > PATH_MAX) + /* your locale directory path length is ridiculous */ + goto end; + l += Ssize; + } break; } } else { l++; } i++; + if (l > PATH_MAX) + /* your expanded path length is ridiculous */ + goto end; } j = ret = Xmalloc(l+1); if (ret == NULL) - return ret; + goto end; i = name; while (*i) { if (*i == '%') { @@ -357,7 +383,6 @@ TransFileName(Xim im, char *name) if (lcCompose) { strcpy(j, lcCompose); j += strlen(lcCompose); - Xfree(lcCompose); } break; case 'S': @@ -371,6 +396,8 @@ TransFileName(Xim im, char *name) } } *j = '\0'; +end: + Xfree(lcCompose); return ret; } @@ -422,7 +449,8 @@ static int parseline( FILE *fp, Xim im, - char* tokenbuf) + char* tokenbuf, + int depth) { int token; DTModifier modifier_mask; @@ -469,11 +497,13 @@ parseline( goto error; if ((filename = TransFileName(im, tokenbuf)) == NULL) goto error; + if (++depth > 100) + goto error; infp = _XFopenFile(filename, "r"); Xfree(filename); if (infp == NULL) goto error; - _XimParseStringFile(infp, im); + parsestringfile(infp, im, depth); fclose(infp); return (0); } else if ((token == KEY) && (strcmp("None", tokenbuf) == 0)) { @@ -667,17 +697,28 @@ _XimParseStringFile( FILE *fp, Xim im) { + parsestringfile(fp, im, 0); +} + +static void +parsestringfile( + FILE *fp, + Xim im, + int depth) +{ char tb[8192]; char* tbp; struct stat st; if (fstat (fileno (fp), &st) != -1) { unsigned long size = (unsigned long) st.st_size; + if (st.st_size >= INT_MAX) + return; if (size <= sizeof tb) tbp = tb; else tbp = malloc (size); if (tbp != NULL) { - while (parseline(fp, im, tbp) >= 0) {} + while (parseline(fp, im, tbp, depth) >= 0) {} if (tbp != tb) free (tbp); } } diff --git a/nx-X11/lib/X11/imTrX.c b/nx-X11/lib/X11/imTrX.c index eba328057..2b5455f1b 100644 --- a/nx-X11/lib/X11/imTrX.c +++ b/nx-X11/lib/X11/imTrX.c @@ -372,7 +372,7 @@ _XimXGetReadData( XFree(prop_ret); return False; } - if (buf_len >= length) { + if (buf_len >= (int)nitems) { (void)memcpy(buf, prop_ret, (int)nitems); *ret_len = (int)nitems; if (bytes_after_ret > 0) { diff --git a/nx-X11/lib/X11/lcFile.c b/nx-X11/lib/X11/lcFile.c index 50159f64b..8c2e7c062 100644 --- a/nx-X11/lib/X11/lcFile.c +++ b/nx-X11/lib/X11/lcFile.c @@ -54,29 +54,7 @@ #define XLC_BUFSIZE 256 -#ifndef X_NOT_POSIX -#ifdef _POSIX_SOURCE -#include <limits.h> -#else -#define _POSIX_SOURCE -#include <limits.h> -#undef _POSIX_SOURCE -#endif -#endif -#ifndef PATH_MAX -#ifdef WIN32 -#define PATH_MAX 512 -#else -#include <sys/param.h> -#endif -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif -#endif +#include "pathmax.h" #define NUM_LOCALEDIR 64 diff --git a/nx-X11/lib/X11/pathmax.h b/nx-X11/lib/X11/pathmax.h new file mode 100644 index 000000000..ffec295e0 --- /dev/null +++ b/nx-X11/lib/X11/pathmax.h @@ -0,0 +1,82 @@ + +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Provides a single definition of PATH_MAX instead of replicating this mess + * in multiple files + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <nx-X11/Xos.h> + +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#ifndef PATH_MAX +#ifdef WIN32 +#define PATH_MAX 512 +#else +#include <sys/param.h> +#endif +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + |