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 | dbc11719399ce7e191c806ad6b5c9104666e2a77 (patch) | |
tree | ae13d49a7610df7371b0181486dc7ccaf2b759ee | |
parent | 77edd88e104cbd3fb5dc95473adac1db2c2302a3 (diff) | |
download | nx-libs-dbc11719399ce7e191c806ad6b5c9104666e2a77.tar.gz nx-libs-dbc11719399ce7e191c806ad6b5c9104666e2a77.tar.bz2 nx-libs-dbc11719399ce7e191c806ad6b5c9104666e2a77.zip |
Avoid overflows in XListExtensions() [CVE-2013-1997 15/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>
-rw-r--r-- | nx-X11/lib/X11/ListExt.c | 36 |
1 files changed, 22 insertions, 14 deletions
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); |