diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2013-03-02 15:08:21 -0800 |
---|---|---|
committer | Ulrich Sibiller <uli42@gmx.de> | 2016-10-12 09:34:39 +0200 |
commit | f6c5069ac78d2fe9883cc7ddaf1f32cc17d27107 (patch) | |
tree | e341ef2942069eba48f4ef8c6b3d36864f58c610 /nx-X11/lib | |
parent | 0284afb80cefe1ae3c2567dd46427b5d425791b1 (diff) | |
download | nx-libs-f6c5069ac78d2fe9883cc7ddaf1f32cc17d27107.tar.gz nx-libs-f6c5069ac78d2fe9883cc7ddaf1f32cc17d27107.tar.bz2 nx-libs-f6c5069ac78d2fe9883cc7ddaf1f32cc17d27107.zip |
Avoid overflows in XListFonts() [CVE-2013-1997 13/15]
Ensure that when breaking the returned list into individual strings,
we don't walk past the end of allocated memory to write the '\0' bytes
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Matthieu Herrb <matthieu.herrb@laas.fr>
Signed-off-by: Julien Cristau <jcristau@debian.org>
Backported-to-NX-by: Ulrich Sibiller <uli42@gmx.de>
Diffstat (limited to 'nx-X11/lib')
-rw-r--r-- | nx-X11/lib/X11/FontNames.c | 35 |
1 files changed, 22 insertions, 13 deletions
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); |