open-src/lib/libX11/CVE-2013-1981.patch
changeset 1345 d5dacbb8de2b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/lib/libX11/CVE-2013-1981.patch	Wed May 15 13:44:02 2013 -0700
@@ -0,0 +1,1442 @@
+From 4ccc31a3b1decfdec554db5204cd138d32566ed3 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sat, 2 Mar 2013 13:03:55 -0800
+Subject: [PATCH:libX11 01/38] Move repeated #ifdef magic to find PATH_MAX
+ into a common header
+
+Lets stop duplicating the mess all over
+
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/GetDflt.c         |   25 +--------------
+ src/Makefile.am       |    1 +
+ src/pathmax.h         |   82 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/xlibi18n/lcFile.c |   24 +--------------
+ 4 files changed, 85 insertions(+), 47 deletions(-)
+ create mode 100644 src/pathmax.h
+
+diff --git a/src/GetDflt.c b/src/GetDflt.c
+index 6f62cd8..4962530 100644
+--- a/src/GetDflt.c
++++ b/src/GetDflt.c
+@@ -52,30 +52,7 @@ SOFTWARE.
+ #include "Xlibint.h"
+ #include <X11/Xos.h>
+ #include <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 <X11/Xthreads.h>
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 71e02e7..27b74b0 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -210,6 +210,7 @@ libX11_la_SOURCES = \
+                   ParseCmd.c \
+                   ParseCol.c \
+                   ParseGeom.c \
++                  pathmax.h \
+                   PeekEvent.c \
+                   PeekIfEv.c \
+                   Pending.c \
+diff --git a/src/pathmax.h b/src/pathmax.h
+new file mode 100644
+index 0000000..a8aaaa5
+--- /dev/null
++++ b/src/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 <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
++
+diff --git a/src/xlibi18n/lcFile.c b/src/xlibi18n/lcFile.c
+index 2c06fa2..61a14e7 100644
+--- a/src/xlibi18n/lcFile.c
++++ b/src/xlibi18n/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
+ 
+-- 
+1.7.9.2
+
+From bee46fae41c84f42cb025811ec767c9c8cfcb32c Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 1 Mar 2013 21:05:27 -0800
+Subject: [PATCH:libX11 03/38] integer overflow in _XQueryFont() on 32-bit
+ platforms [CVE-2013-1981 1/13]
+
+If the CARD32 reply.nCharInfos * sizeof(XCharStruct) overflows an
+unsigned long, then too small of a buffer will be allocated for the
+data copied in from the reply.
+
+v2: Fix reply_left calculations, check calculated sizes fit in reply_left
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+---
+ src/Font.c |   35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/src/Font.c b/src/Font.c
+index 25e1790..9ee127c 100644
+--- a/src/Font.c
++++ b/src/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,16 +242,19 @@ _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
+@@ -256,16 +262,21 @@ _XQueryFont (
+      */
+     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);
+     }
+ 
+-- 
+1.7.9.2
+
+From ed74729326d04eb736dd2cdffa394c9638a28ab2 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 1 Mar 2013 21:05:27 -0800
+Subject: [PATCH:libX11 04/38] integer overflow in _XF86BigfontQueryFont()
+ [CVE-2013-1981 2/13]
+
+Similar to _XQueryFont, but with more ways to go wrong and overflow.
+Only compiled if libX11 is built with XF86BigFont support.
+
+v2: Fix reply_left calculations, check calculated sizes fit in reply_left
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+---
+ src/Font.c |   42 +++++++++++++++++++++++++-----------------
+ 1 file changed, 25 insertions(+), 17 deletions(-)
+
+diff --git a/src/Font.c b/src/Font.c
+index 9ee127c..5dbdb29 100644
+--- a/src/Font.c
++++ b/src/Font.c
+@@ -403,7 +403,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;
+@@ -456,13 +457,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;
+@@ -488,23 +486,32 @@ _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((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)) {
+@@ -518,14 +525,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);
+@@ -580,6 +587,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);
+-- 
+1.7.9.2
+
+From ce805b2d94edf8109ed8b7f53d440b012b350326 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 1 Mar 2013 22:49:01 -0800
+Subject: [PATCH:libX11 05/38] integer overflow in XListFontsWithInfo()
+ [CVE-2013-1981 3/13]
+
+If the reported number of remaining fonts is too large, the calculations
+to allocate memory for them may overflow, leaving us writing beyond the
+bounds of the allocation.
+
+v2: Fix reply_left calculations, check calculated sizes fit in reply_left
+v3: On error cases, also set values to be returned in pointer args to 0/NULL
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+---
+ src/FontInfo.c |  105 ++++++++++++++++++++++++++------------------------------
+ 1 file changed, 49 insertions(+), 56 deletions(-)
+
+diff --git a/src/FontInfo.c b/src/FontInfo.c
+index fb296b8..4b295a5 100644
+--- a/src/FontInfo.c
++++ b/src/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,52 +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)));
++		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;
+-
+-		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);
+-		    }
+-		    Xfree((char *) flist);
+-		    Xfree((char *) finfo);
+-		    goto clearwire;
+-		}
++		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;
+ 		}
+@@ -138,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) {
+@@ -185,19 +182,15 @@ XFontStruct **info)	/* RETURN */
+ 
+   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;
+ }
+ 
+-- 
+1.7.9.2
+
+From 3eaf200b6d60de2284c6d7e0180ddf9cabf25a64 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 1 Mar 2013 22:49:01 -0800
+Subject: [PATCH:libX11 06/38] integer overflow in XGetMotionEvents()
+ [CVE-2013-1981 4/13]
+
+If the reported number of motion events is too large, the calculations
+to allocate memory for them may overflow, leaving us writing beyond the
+bounds of the allocation.
+
+v2: Ensure nEvents is set to 0 when returning NULL events pointer
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+---
+ src/GetMoEv.c |   26 +++++++++++---------------
+ 1 file changed, 11 insertions(+), 15 deletions(-)
+
+diff --git a/src/GetMoEv.c b/src/GetMoEv.c
+index 3db176f..ad9c772 100644
+--- a/src/GetMoEv.c
++++ b/src/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);
+-- 
+1.7.9.2
+
+From b0528a42d6728c119af2fcb28407efa7b0b9fe54 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 1 Mar 2013 22:49:01 -0800
+Subject: [PATCH:libX11 07/38] integer overflow in XListHosts() [CVE-2013-1981
+ 5/13]
+
+If the reported number of host entries is too large, the calculations
+to allocate memory for them may overflow, leaving us writing beyond the
+bounds of the allocation.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/LiHosts.c |   22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/src/LiHosts.c b/src/LiHosts.c
+index 0f5e837..83cf3c7 100644
+--- a/src/LiHosts.c
++++ b/src/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)
+-- 
+1.7.9.2
+
+From fa0ab9b0a1e2dae89895919a9dcdff5f6851ee64 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sat, 2 Mar 2013 11:44:19 -0800
+Subject: [PATCH:libX11 20/38] Integer overflows in stringSectionSize() cause
+ buffer overflow in ReadColornameDB()
+ [CVE-2013-1981 6/13]
+
+LoadColornameDB() calls stringSectionSize() to do a first pass over the
+file (which may be provided by the user via XCMSDB environment variable)
+to determine how much memory needs to be allocated to read in the file,
+then allocates the returned sizes and calls ReadColornameDB() to load the
+data from the file into that newly allocated memory.
+
+If stringSectionSize() overflows the signed ints used to calculate the
+file size (say if you have an xcmsdb with ~4 billion lines in or a
+combined string length of ~4 gig - which while it may have been
+inconceivable when Xlib was written, is quite possible today), then
+LoadColornameDB() may allocate a memory buffer much smaller than the
+amount of data ReadColornameDB() will write to it.
+
+The total size is left limited to an int, because if your xcmsdb file
+is larger than 2gb, you're doing it wrong.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/xcms/cmsColNm.c |   27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/src/xcms/cmsColNm.c b/src/xcms/cmsColNm.c
+index a6749c0..8d0d4a7 100644
+--- a/src/xcms/cmsColNm.c
++++ b/src/xcms/cmsColNm.c
+@@ -40,6 +40,7 @@
+ #include <sys/stat.h>
+ #include <stdio.h>
+ #include <ctype.h>
++#include <limits.h>
+ #define XK_LATIN1
+ #include <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);
+ }
+ 
+-- 
+1.7.9.2
+
+From de8462f73c41b2253d920a713725c96591ab5690 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 1 Mar 2013 18:37:37 -0800
+Subject: [PATCH:libX11 21/38] integer overflow in ReadInFile() in Xrm.c
+ [CVE-2013-1981 7/13]
+
+Called from XrmGetFileDatabase() which gets called from InitDefaults()
+which gets the filename from getenv ("XENVIRONMENT")
+
+If file is exactly 0xffffffff bytes long (or longer and truncates to
+0xffffffff, on implementations where off_t is larger than an int),
+then size may be set to a value which overflows causing less memory
+to be allocated than is written to by the following read() call.
+
+size is left limited to an int, because if your Xresources file is
+larger than 2gb, you're very definitely doing it wrong.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/Xrm.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/Xrm.c b/src/Xrm.c
+index d6899d9..3e29ab0 100644
+--- a/src/Xrm.c
++++ b/src/Xrm.c
+@@ -62,6 +62,7 @@ from The Open Group.
+ #endif
+ #include	<X11/Xos.h>
+ #include	<sys/stat.h>
++#include	<limits.h>
+ #include "Xresinternal.h"
+ #include "Xresource.h"
+ 
+@@ -1594,11 +1595,12 @@ ReadInFile(_Xconst char *filename)
+      */
+     {
+ 	struct stat status_buffer;
+-	if ( (fstat(fd, &status_buffer)) == -1 ) {
++	if ( ((fstat(fd, &status_buffer)) == -1 ) ||
++             (status_buffer.st_size >= INT_MAX) ) {
+ 	    close (fd);
+ 	    return (char *)NULL;
+ 	} else
+-	    size = status_buffer.st_size;
++	    size = (int) status_buffer.st_size;
+     }
+ 
+     if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */
+-- 
+1.7.9.2
+
+From 9a8117101fe3c6c615fbce34eca244f149bb2766 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 1 Mar 2013 18:37:37 -0800
+Subject: [PATCH:libX11 24/38] integer truncation in _XimParseStringFile()
+ [CVE-2013-1981 8/13]
+
+Called from _XimCreateDefaultTree() which uses getenv("XCOMPOSEFILE")
+to specify filename.
+
+If the size of off_t is larger than the size of unsigned long (as in
+32-bit builds with large file flags), a file larger than 4 gigs could
+have its size truncated, leading to data from that file being written
+past the end of the undersized buffer allocated for it.
+
+While configure.ac does not use AC_SYS_LARGEFILE to set large file mode,
+builders may have added the large file compilation flags to CFLAGS on
+their own.
+
+size is left limited to an int, because if your Xim file is
+larger than 2gb, you're doing it wrong.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ modules/im/ximcp/imLcPrs.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/modules/im/ximcp/imLcPrs.c b/modules/im/ximcp/imLcPrs.c
+index 4c7d6f0..bcf4579 100644
+--- a/modules/im/ximcp/imLcPrs.c
++++ b/modules/im/ximcp/imLcPrs.c
+@@ -41,6 +41,7 @@ OR PERFORMANCE OF THIS SOFTWARE.
+ #include "Ximint.h"
+ #include <sys/stat.h>
+ #include <stdio.h>
++#include <limits.h>
+ 
+ #define XLC_BUFSIZE 256
+ 
+@@ -688,6 +689,8 @@ parsestringfile(
+ 
+     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);
+ 
+-- 
+1.7.9.2
+
+From 692e43c2d5fbc56f38371f3f44a1d339595f0056 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sat, 2 Mar 2013 13:18:48 -0800
+Subject: [PATCH:libX11 25/38] integer overflows in TransFileName()
+ [CVE-2013-1981 9/13]
+
+When trying to process file paths the tokens %H, %L, & %S are expanded
+to $HOME, the standard compose file path & the xlocaledir path.
+If enough of these tokens are repeated and values like $HOME are set to
+very large values, the calculation of the total string size required to
+hold the expanded path can overflow, resulting in allocating a smaller
+string than the amount of data we'll write to it.
+
+Simply restrict all of these values, and the total path size to PATH_MAX,
+because really, that's all you should need for a filename path.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ modules/im/ximcp/Makefile.am |    1 +
+ modules/im/ximcp/imLcPrs.c   |   45 +++++++++++++++++++++++++++++++-----------
+ 2 files changed, 35 insertions(+), 11 deletions(-)
+
+diff --git a/modules/im/ximcp/Makefile.am b/modules/im/ximcp/Makefile.am
+index 16a6ca8..8aae839 100644
+--- a/modules/im/ximcp/Makefile.am
++++ b/modules/im/ximcp/Makefile.am
+@@ -6,6 +6,7 @@ AM_CPPFLAGS= \
+ 	-I$(top_srcdir)/src/xcms \
+ 	-I$(top_srcdir)/src/xkb \
+ 	-I$(top_srcdir)/src/xlibi18n \
++	-I$(top_srcdir)/src \
+ 	-D_BSD_SOURCE -DXIM_t -DTRANS_CLIENT
+ 
+ AM_CFLAGS= \
+diff --git a/modules/im/ximcp/imLcPrs.c b/modules/im/ximcp/imLcPrs.c
+index bcf4579..f3627a0 100644
+--- a/modules/im/ximcp/imLcPrs.c
++++ b/modules/im/ximcp/imLcPrs.c
+@@ -42,6 +42,7 @@ OR PERFORMANCE OF THIS SOFTWARE.
+ #include <sys/stat.h>
+ #include <stdio.h>
+ #include <limits.h>
++#include "pathmax.h"
+ 
+ #define XLC_BUFSIZE 256
+ 
+@@ -307,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 == '%') {
+@@ -319,30 +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':
+                  if (lcCompose == NULL)
+                      lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE);
+-                 if (lcCompose)
+-                     l += strlen(lcCompose);
++                 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 == '%') {
+@@ -374,6 +396,7 @@ TransFileName(Xim im, char *name)
+       }
+    }
+    *j = '\0';
++end:
+    Xfree(lcCompose);
+    return ret;
+ }
+-- 
+1.7.9.2
+
+From ea8bc513f6849cadc93dd68de8a562d6e63b19d5 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 8 Mar 2013 22:25:35 -0800
+Subject: [PATCH:libX11 26/38] integer overflow in XGetWindowProperty()
+ [CVE-2013-1981 10/13]
+
+If the reported number of properties is too large, the calculations
+to allocate memory for them may overflow, leaving us returning less
+memory to the caller than implied by the value written to *nitems.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/GetProp.c |   25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/src/GetProp.c b/src/GetProp.c
+index 5d6e0b8..ae14edc 100644
+--- a/src/GetProp.c
++++ b/src/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(
+@@ -66,8 +67,17 @@ XGetWindowProperty(
+ 
+     *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 +86,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 +122,7 @@ XGetWindowProperty(
+ 	    break;
+ 	}
+ 	if (! *prop) {
+-	    _XEatData(dpy, (unsigned long) netbytes);
++	    _XEatDataWords(dpy, reply.length);
+ 	    UnlockDisplay(dpy);
+ 	    SyncHandle();
+ 	    return(BadAlloc);	/* not Success */
+-- 
+1.7.9.2
+
+From 0febed454ee211deb6ae56d4febf71393e0aff2b Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sat, 2 Mar 2013 15:08:21 -0800
+Subject: [PATCH:libX11 27/38] integer overflow in XGetImage() [CVE-2013-1981
+ 11/13]
+
+Ensure that we don't underallocate when the server claims to have sent a
+very large reply.
+
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/GetImage.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/src/GetImage.c b/src/GetImage.c
+index e8f1b03..c461abc 100644
+--- a/src/GetImage.c
++++ b/src/GetImage.c
+@@ -30,6 +30,7 @@ in this Software without prior written authorization from The Open Group.
+ #include "Xlibint.h"
+ #include <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;
+-- 
+1.7.9.2
+
+From 83f1fc4205d2c9c886bdc4bdab2a27cb0e280110 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sat, 2 Mar 2013 15:08:21 -0800
+Subject: [PATCH:libX11 28/38] integer overflow in XGetPointerMapping() &
+ XGetKeyboardMapping() [CVE-2013-1981 12/13]
+
+Ensure that we don't underallocate when the server claims a very large reply
+
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/GetPntMap.c |   31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+diff --git a/src/GetPntMap.c b/src/GetPntMap.c
+index 0fcdb66..29fdf21 100644
+--- a/src/GetPntMap.c
++++ b/src/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;
+-- 
+1.7.9.2
+
+From b2e9b2585a4528e23df9f9067c6c6c91115ae55b Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sat, 2 Mar 2013 15:08:21 -0800
+Subject: [PATCH:libX11 29/38] integer overflow in XGetModifierMapping()
+ [CVE-2013-1981 13/13]
+
+Ensure that we don't underallocate when the server claims a very large reply
+
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/ModMap.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/src/ModMap.c b/src/ModMap.c
+index c99bfdd..122ca80 100644
+--- a/src/ModMap.c
++++ b/src/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;
+-- 
+1.7.9.2
+
+From 3fb82a4726114c1e9916658dad659a4dbfb050c8 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sat, 9 Mar 2013 11:04:37 -0800
+Subject: [PATCH:libX11 33/38] Make XGetWindowProperty() always initialize
+ returned values
+
+Avoids memory corruption and other errors when callers access them
+without checking to see if XGetWindowProperty() returned an error value.
+
+Callers are still required to check for errors, this just reduces the
+damage when they don't.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+---
+ src/GetProp.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/src/GetProp.c b/src/GetProp.c
+index ae14edc..9eb422e 100644
+--- a/src/GetProp.c
++++ b/src/GetProp.c
+@@ -49,6 +49,13 @@ XGetWindowProperty(
+     register xGetPropertyReq *req;
+     xError error = {0};
+ 
++    /* 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;
+@@ -65,7 +72,6 @@ XGetWindowProperty(
+ 	return (1);	/* not Success */
+ 	}
+ 
+-    *prop = (unsigned char *) NULL;
+     if (reply.propertyType != None) {
+ 	unsigned long nbytes, netbytes;
+ 	int format = reply.format;
+-- 
+1.7.9.2
+