open-src/lib/libXext/CVE-2013-1982.patch
author Alan Coopersmith <Alan.Coopersmith@Oracle.COM>
Wed, 15 May 2013 13:44:02 -0700
changeset 1345 d5dacbb8de2b
permissions -rw-r--r--
16673783 problem in X11/LIBRARIES 16674478 problem in X11/LIBRARIES

From ca84a813716f9de691dc3f60390d83af4b5ae534 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <[email protected]>
Date: Sat, 13 Apr 2013 09:32:12 -0700
Subject: [PATCH:libXext 1/7] Use _XEatDataWords to avoid overflow of
 rep.length bit shifting

rep.length is a CARD32, so rep.length << 2 could overflow in 32-bit builds

Signed-off-by: Alan Coopersmith <[email protected]>
---
 COPYING         |    3 ++-
 configure.ac    |    6 ++++++
 src/Makefile.am |    1 +
 src/XEVI.c      |    4 +++-
 src/XMultibuf.c |    3 ++-
 src/XSecurity.c |    3 ++-
 src/XShape.c    |    3 ++-
 src/XSync.c     |    3 ++-
 src/Xcup.c      |    7 ++++---
 src/eat.h       |   40 ++++++++++++++++++++++++++++++++++++++++
 10 files changed, 64 insertions(+), 9 deletions(-)
 create mode 100644 src/eat.h

diff --git a/COPYING b/COPYING
index 80622a0..e3a63ef 100644
--- a/COPYING
+++ b/COPYING
@@ -160,7 +160,8 @@ makes no representations about the suitability for any purpose
 of the information in this document.  This documentation is
 provided ``as is'' without express or implied warranty.
 
-Copyright (c) 1999, 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 2005, 2006, 2013, Oracle and/or its affiliates.
+All rights reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/configure.ac b/configure.ac
index 63775de..fb9888d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,6 +38,12 @@ AC_SUBST(XEXT_SOREV)
 # Obtain compiler/linker options for depedencies
 PKG_CHECK_MODULES(XEXT, [xproto >= 7.0.13] [x11 >= 1.1.99.1] [xextproto >= 7.1.99])
 
+# Check for _XEatDataWords function that may be patched into older Xlib releases
+SAVE_LIBS="$LIBS"
+LIBS="$XEXT_LIBS"
+AC_CHECK_FUNCS([_XEatDataWords])
+LIBS="$SAVE_LIBS"
+
 # Allow checking code with lint, sparse, etc.
 XORG_WITH_LINT
 XORG_LINT_LIBRARY([Xext])
diff --git a/src/Makefile.am b/src/Makefile.am
index e236c33..b828547 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,7 @@ libXext_la_LDFLAGS = -version-number $(XEXT_SOREV) -no-undefined
 libXext_la_LIBADD = $(XEXT_LIBS)
 
 libXext_la_SOURCES = \
+	eat.h \
 	DPMS.c \
 	MITMisc.c \
 	XAppgroup.c \
diff --git a/src/XEVI.c b/src/XEVI.c
index eb09daa..0125c51 100644
--- a/src/XEVI.c
+++ b/src/XEVI.c
@@ -30,6 +30,8 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
 #include <X11/Xutil.h>
+#include "eat.h"
+
 static XExtensionInfo *xevi_info;/* needs to move to globals.c */
 static const char *xevi_extension_name = EVINAME;
 #define XeviCheckExtension(dpy,i,val) \
@@ -171,7 +173,7 @@ Status XeviGetVisualInfo(
     xInfoPtr = temp_xInfo = (xExtendedVisualInfo *)Xmalloc(sz_xInfo);
     xConflictPtr = temp_conflict = (VisualID32 *)Xmalloc(sz_xConflict);
     if (!*evi_return || !temp_xInfo || !temp_conflict) {
-        _XEatData(dpy, (sz_xInfo + sz_xConflict + 3) & ~3);
+	_XEatDataWords(dpy, rep.length);
 	UnlockDisplay(dpy);
 	SyncHandle();
 	if (evi_return)
diff --git a/src/XMultibuf.c b/src/XMultibuf.c
index 7a746ba..43d56d3 100644
--- a/src/XMultibuf.c
+++ b/src/XMultibuf.c
@@ -34,6 +34,7 @@ in this Software without prior written authorization from The Open Group.
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/multibufproto.h>
 #include <X11/extensions/multibuf.h>
+#include "eat.h"
 
 static XExtensionInfo _multibuf_info_data;
 static XExtensionInfo *multibuf_info = &_multibuf_info_data;
@@ -408,7 +409,7 @@ Status XmbufGetWindowAttributes (
 	attr->buffers = (Multibuffer *) Xmalloc((unsigned) nbytes);
 	nbytes = rep.length << 2;
 	if (! attr->buffers) {
-	    _XEatData(dpy, (unsigned long) nbytes);
+	    _XEatDataWords(dpy, rep.length);
 	    UnlockDisplay(dpy);
 	    SyncHandle();
 	    return (0);
diff --git a/src/XSecurity.c b/src/XSecurity.c
index f8c7da1..ab17755 100644
--- a/src/XSecurity.c
+++ b/src/XSecurity.c
@@ -33,6 +33,7 @@ in this Software without prior written authorization from The Open Group.
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/securproto.h>
 #include <X11/extensions/security.h>
+#include "eat.h"
 
 static XExtensionInfo _Security_info_data;
 static XExtensionInfo *Security_info = &_Security_info_data;
@@ -282,7 +283,7 @@ XSecurityGenerateAuthorization(
     }
     else
     {
-	_XEatData(dpy, (unsigned long) (rep.dataLength + 3) & ~3);
+	_XEatDataWords(dpy, rep.length);
     }
 
     UnlockDisplay (dpy);
diff --git a/src/XShape.c b/src/XShape.c
index 6e8fbae..3987876 100644
--- a/src/XShape.c
+++ b/src/XShape.c
@@ -35,6 +35,7 @@ in this Software without prior written authorization from The Open Group.
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/shape.h>
 #include <X11/extensions/shapeproto.h>
+#include "eat.h"
 
 static XExtensionInfo _shape_info_data;
 static XExtensionInfo *shape_info = &_shape_info_data;
@@ -468,7 +469,7 @@ XRectangle *XShapeGetRectangles (
 		Xfree (xrects);
 	    if (rects)
 		Xfree (rects);
-	    _XEatData (dpy, *count * sizeof (xRectangle));
+	    _XEatDataWords (dpy, rep.length);
 	    rects = NULL;
 	    *count = 0;
 	} else {
diff --git a/src/XSync.c b/src/XSync.c
index 5775293..3ca1308 100644
--- a/src/XSync.c
+++ b/src/XSync.c
@@ -59,6 +59,7 @@ PERFORMANCE OF THIS SOFTWARE.
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/sync.h>
 #include <X11/extensions/syncproto.h>
+#include "eat.h"
 
 static XExtensionInfo _sync_info_data;
 static XExtensionInfo *sync_info = &_sync_info_data;
@@ -364,7 +365,7 @@ XSyncListSystemCounters(Display *dpy, int *n_counters_return)
 	{
 	    if (list) Xfree((char *) list);
 	    if (pWireSysCounter)   Xfree((char *) pWireSysCounter);
-	    _XEatData(dpy, (unsigned long) replylen);
+	    _XEatDataWords(dpy, rep.length);
 	    list = NULL;
 	    goto bail;
 	}
diff --git a/src/Xcup.c b/src/Xcup.c
index bb9e90f..1f1d625 100644
--- a/src/Xcup.c
+++ b/src/Xcup.c
@@ -36,6 +36,7 @@ in this Software without prior written authorization from The Open Group.
 #include <X11/extensions/cupproto.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
+#include "eat.h"
 
 static XExtensionInfo _xcup_info_data;
 static XExtensionInfo *xcup_info = &_xcup_info_data;
@@ -144,7 +145,7 @@ XcupGetReservedColormapEntries(
 	    rbufp = rbuf;
 
 	if (rbufp == NULL) {
-	    _XEatData (dpy, (unsigned long) nbytes);
+	    _XEatDataWords(dpy, rep.length);
 	    UnlockDisplay (dpy);
 	    SyncHandle ();
 	    return False;
@@ -221,7 +222,7 @@ XcupStoreColors(
 	nbytes = nentries * SIZEOF (xColorItem);
 
 	if (nentries != ncolors) {
-	    _XEatData (dpy, (unsigned long) nbytes);
+	    _XEatDataWords(dpy, rep.length);
 	    UnlockDisplay (dpy);
 	    SyncHandle ();
 	    return False;
@@ -233,7 +234,7 @@ XcupStoreColors(
 	    rbufp = rbuf;
 
 	if (rbufp == NULL) {
-	    _XEatData (dpy, (unsigned long) nbytes);
+	    _XEatDataWords(dpy, rep.length);
 	    UnlockDisplay (dpy);
 	    SyncHandle ();
 	    return False;
diff --git a/src/eat.h b/src/eat.h
new file mode 100644
index 0000000..239532b
--- /dev/null
+++ b/src/eat.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef HAVE__XEATDATAWORDS
+#include <X11/Xmd.h>  /* for LONG64 on 64-bit platforms */
+#include <limits.h>
+
+static inline void _XEatDataWords(Display *dpy, unsigned long n)
+{
+# ifndef LONG64
+    if (n >= (ULONG_MAX >> 2))
+        _XIOError(dpy);
+# endif
+    _XEatData (dpy, n << 2);
+}
+#endif
-- 
1.7.9.2

From d05f27a6f74cb419ad5a437f2e4690b17e7faee5 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <[email protected]>
Date: Sat, 9 Mar 2013 14:40:33 -0800
Subject: [PATCH:libXext 2/7] integer overflow in
 XcupGetReservedColormapEntries() [CVE-2013-1982
 1/6]

If the computed number of entries is large enough that it overflows when
multiplied by the size of a xColorItem struct, or is treated as negative
when compared to the size of the stack allocated buffer, then memory
corruption can occur when more bytes are read from the X server than the
size of the buffer we allocated to hold them.

Reported-by: Ilja Van Sprundel <[email protected]>
Signed-off-by: Alan Coopersmith <[email protected]>
---
 src/Xcup.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/Xcup.c b/src/Xcup.c
index 1f1d625..670f356 100644
--- a/src/Xcup.c
+++ b/src/Xcup.c
@@ -36,6 +36,7 @@ in this Software without prior written authorization from The Open Group.
 #include <X11/extensions/cupproto.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
+#include <limits.h>
 #include "eat.h"
 
 static XExtensionInfo _xcup_info_data;
@@ -134,15 +135,19 @@ XcupGetReservedColormapEntries(
     req->xcupReqType = X_XcupGetReservedColormapEntries;
     req->screen = screen;
     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-	long nbytes;
+	unsigned long nbytes;
 	xColorItem* rbufp;
-	int nentries = rep.length / 3;
+	unsigned int nentries = rep.length / 3;
 
-	nbytes = nentries * SIZEOF (xColorItem);
-	if (nentries > TYP_RESERVED_ENTRIES)
-	    rbufp = (xColorItem*) Xmalloc (nbytes);
-	else
-	    rbufp = rbuf;
+	if (nentries < (INT_MAX / SIZEOF (xColorItem))) {
+	    nbytes = nentries * SIZEOF (xColorItem);
+
+	    if (nentries > TYP_RESERVED_ENTRIES)
+		rbufp = Xmalloc (nbytes);
+	    else
+		rbufp = rbuf;
+	} else
+	    rbufp = NULL;
 
 	if (rbufp == NULL) {
 	    _XEatDataWords(dpy, rep.length);
-- 
1.7.9.2

From 082d70b19848059ba78c9d1c315114fb07e8c0ef Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <[email protected]>
Date: Sat, 9 Mar 2013 14:40:33 -0800
Subject: [PATCH:libXext 3/7] integer overflow in XcupStoreColors()
 [CVE-2013-1982 2/6]

If the computed number of entries is large enough that it overflows when
multiplied by the size of a xColorItem struct, or is treated as negative
when compared to the size of the stack allocated buffer, then memory
corruption can occur when more bytes are read from the X server than the
size of the buffer we allocated to hold them.

The requirement to match the number of colors specified by the caller makes
this much harder to hit than the one in XcupGetReservedColormapEntries()

Reported-by: Ilja Van Sprundel <[email protected]>
Signed-off-by: Alan Coopersmith <[email protected]>
---
 src/Xcup.c |   25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/src/Xcup.c b/src/Xcup.c
index 670f356..cdc64c2 100644
--- a/src/Xcup.c
+++ b/src/Xcup.c
@@ -219,24 +219,21 @@ XcupStoreColors(
     }
 
     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-	long nbytes;
+	unsigned long nbytes;
 	xColorItem* rbufp;
 	xColorItem* cs;
-	int nentries = rep.length / 3;
-
-	nbytes = nentries * SIZEOF (xColorItem);
+	unsigned int nentries = rep.length / 3;
 
-	if (nentries != ncolors) {
-	    _XEatDataWords(dpy, rep.length);
-	    UnlockDisplay (dpy);
-	    SyncHandle ();
-	    return False;
-	}
+	if ((nentries == ncolors) &&
+	    (nentries < (INT_MAX / SIZEOF (xColorItem)))) {
+	    nbytes = nentries * SIZEOF (xColorItem);
 
-	if (ncolors > 256)
-	    rbufp = (xColorItem*) Xmalloc (nbytes);
-	else
-	    rbufp = rbuf;
+	    if (ncolors > 256)
+		rbufp = Xmalloc (nbytes);
+	    else
+		rbufp = rbuf;
+	} else
+	    rbufp = NULL;
 
 	if (rbufp == NULL) {
 	    _XEatDataWords(dpy, rep.length);
-- 
1.7.9.2

From 96d1da55a08c4cd52b763cb07bdce5cdcbec4da8 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <[email protected]>
Date: Sat, 9 Mar 2013 14:40:33 -0800
Subject: [PATCH:libXext 4/7] several integer overflows in XdbeGetVisualInfo()
 [CVE-2013-1982 3/6]

If the number of screens or visuals reported by the server is large enough
that it overflows when multiplied by the size of the appropriate struct,
then memory corruption can occur when more bytes are read from the X server
than the size of the buffer we allocated to hold them.

Reported-by: Ilja Van Sprundel <[email protected]>
Signed-off-by: Alan Coopersmith <[email protected]>
---
 src/Xdbe.c |   27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/Xdbe.c b/src/Xdbe.c
index 4b5fa18..016886c 100644
--- a/src/Xdbe.c
+++ b/src/Xdbe.c
@@ -39,6 +39,8 @@
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/Xdbe.h>
 #include <X11/extensions/dbeproto.h>
+#include <limits.h>
+#include "eat.h"
 
 static XExtensionInfo _dbe_info_data;
 static XExtensionInfo *dbe_info = &_dbe_info_data;
@@ -352,9 +354,12 @@ XdbeScreenVisualInfo *XdbeGetVisualInfo (
        *num_screens = rep.m;
 
     /* allocate list of visual information to be returned */
-    if (!(scrVisInfo =
-        (XdbeScreenVisualInfo *)Xmalloc(
-        (unsigned)(*num_screens * sizeof(XdbeScreenVisualInfo))))) {
+    if ((*num_screens > 0) && (*num_screens < 65536))
+        scrVisInfo = Xmalloc(*num_screens * sizeof(XdbeScreenVisualInfo));
+    else
+        scrVisInfo = NULL;
+    if (scrVisInfo == NULL) {
+        _XEatDataWords(dpy, rep.length);
         UnlockDisplay (dpy);
         SyncHandle ();
         return NULL;
@@ -362,25 +367,27 @@ XdbeScreenVisualInfo *XdbeGetVisualInfo (
 
     for (i = 0; i < *num_screens; i++)
     {
-        int nbytes;
         int j;
-        long c;
+        unsigned long c;
 
-        _XRead32 (dpy, &c, sizeof(CARD32));
-        scrVisInfo[i].count = c;
+        _XRead32 (dpy, (long *) &c, sizeof(CARD32));
 
-        nbytes = scrVisInfo[i].count * sizeof(XdbeVisualInfo);
+        if (c < 65536) {
+            scrVisInfo[i].count = c;
+            scrVisInfo[i].visinfo = Xmalloc(c * sizeof(XdbeVisualInfo));
+        } else
+            scrVisInfo[i].visinfo = NULL;
 
         /* if we can not allocate the list of visual/depth info
          * then free the lists that we already allocate as well
          * as the visual info list itself
          */
-        if (!(scrVisInfo[i].visinfo = (XdbeVisualInfo *)Xmalloc(
-            (unsigned)nbytes))) {
+        if (scrVisInfo[i].visinfo == NULL) {
             for (j = 0; j < i; j++) {
                 Xfree ((char *)scrVisInfo[j].visinfo);
             }
             Xfree ((char *)scrVisInfo);
+            _XEatDataWords(dpy, rep.length);
             UnlockDisplay (dpy);
             SyncHandle ();
             return NULL;
-- 
1.7.9.2

From 67ecdcf7e29de9fa78b421122620525ed2c7db88 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <[email protected]>
Date: Sat, 9 Mar 2013 14:40:33 -0800
Subject: [PATCH:libXext 5/7] integer overflow in XeviGetVisualInfo()
 [CVE-2013-1982 4/6]

If the number of visuals or conflicts reported by the server is large
enough that it overflows when multiplied by the size of the appropriate
struct, then memory corruption can occur when more bytes are read from
the X server than the size of the buffer we allocated to hold them.

Reported-by: Ilja Van Sprundel <[email protected]>
Signed-off-by: Alan Coopersmith <[email protected]>
---
 src/XEVI.c |   25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/src/XEVI.c b/src/XEVI.c
index 0125c51..5a95583 100644
--- a/src/XEVI.c
+++ b/src/XEVI.c
@@ -30,6 +30,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
 #include <X11/Xutil.h>
+#include <limits.h>
 #include "eat.h"
 
 static XExtensionInfo *xevi_info;/* needs to move to globals.c */
@@ -165,13 +166,20 @@ Status XeviGetVisualInfo(
 	return BadAccess;
     }
     Xfree(temp_visual);
-    sz_info = rep.n_info * sizeof(ExtendedVisualInfo);
-    sz_xInfo = rep.n_info * sz_xExtendedVisualInfo;
-    sz_conflict = rep.n_conflicts * sizeof(VisualID);
-    sz_xConflict = rep.n_conflicts * sz_VisualID32;
-    infoPtr = *evi_return = (ExtendedVisualInfo *)Xmalloc(sz_info + sz_conflict);
-    xInfoPtr = temp_xInfo = (xExtendedVisualInfo *)Xmalloc(sz_xInfo);
-    xConflictPtr = temp_conflict = (VisualID32 *)Xmalloc(sz_xConflict);
+    if ((rep.n_info < 65536) && (rep.n_conflicts < 65536)) {
+	sz_info = rep.n_info * sizeof(ExtendedVisualInfo);
+	sz_xInfo = rep.n_info * sz_xExtendedVisualInfo;
+	sz_conflict = rep.n_conflicts * sizeof(VisualID);
+	sz_xConflict = rep.n_conflicts * sz_VisualID32;
+	*evi_return = Xmalloc(sz_info + sz_conflict);
+	temp_xInfo = Xmalloc(sz_xInfo);
+	temp_conflict = Xmalloc(sz_xConflict);
+    } else {
+	sz_xInfo = sz_xConflict = 0;
+	*evi_return = NULL;
+	temp_xInfo = NULL;
+	temp_conflict = NULL;
+    }
     if (!*evi_return || !temp_xInfo || !temp_conflict) {
 	_XEatDataWords(dpy, rep.length);
 	UnlockDisplay(dpy);
@@ -188,6 +196,9 @@ Status XeviGetVisualInfo(
     _XRead(dpy, (char *)temp_conflict, sz_xConflict);
     UnlockDisplay(dpy);
     SyncHandle();
+    infoPtr = *evi_return;
+    xInfoPtr = temp_xInfo;
+    xConflictPtr = temp_conflict;
     n_data = rep.n_info;
     conflict = (VisualID *)(infoPtr + n_data);
     while (n_data-- > 0) {
-- 
1.7.9.2

From 6ecd96e8be3c33e2ffad6631cea4aa0a030d93c2 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <[email protected]>
Date: Sat, 9 Mar 2013 14:40:33 -0800
Subject: [PATCH:libXext 6/7] integer overflow in XShapeGetRectangles()
 [CVE-2013-1982 5/6]

If the number of rectangles reported by the server is large enough that
it overflows when multiplied by the size of the appropriate struct, then
memory corruption can occur when more bytes are read from the X server
than the size of the buffer we allocated to hold them.

Reported-by: Ilja Van Sprundel <[email protected]>
Signed-off-by: Alan Coopersmith <[email protected]>
---
 src/XShape.c |   24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/src/XShape.c b/src/XShape.c
index 3987876..d025020 100644
--- a/src/XShape.c
+++ b/src/XShape.c
@@ -35,6 +35,7 @@ in this Software without prior written authorization from The Open Group.
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/shape.h>
 #include <X11/extensions/shapeproto.h>
+#include <limits.h>
 #include "eat.h"
 
 static XExtensionInfo _shape_info_data;
@@ -443,7 +444,7 @@ XRectangle *XShapeGetRectangles (
     xShapeGetRectanglesReply	    rep;
     XRectangle			    *rects;
     xRectangle			    *xrects;
-    int				    i;
+    unsigned int		    i;
 
     ShapeCheckExtension (dpy, info, (XRectangle *)NULL);
 
@@ -461,20 +462,23 @@ XRectangle *XShapeGetRectangles (
     *count = rep.nrects;
     *ordering = rep.ordering;
     rects = NULL;
-    if (*count) {
-	xrects = (xRectangle *) Xmalloc (*count * sizeof (xRectangle));
-	rects = (XRectangle *) Xmalloc (*count * sizeof (XRectangle));
+    if (rep.nrects) {
+	if (rep.nrects < (INT_MAX / sizeof (XRectangle))) {
+	    xrects = Xmalloc (rep.nrects * sizeof (xRectangle));
+	    rects = Xmalloc (rep.nrects * sizeof (XRectangle));
+	} else {
+	    xrects = NULL;
+	    rects = NULL;
+	}
 	if (!xrects || !rects) {
-	    if (xrects)
-		Xfree (xrects);
-	    if (rects)
-		Xfree (rects);
+	    Xfree (xrects);
+	    Xfree (rects);
 	    _XEatDataWords (dpy, rep.length);
 	    rects = NULL;
 	    *count = 0;
 	} else {
-	    _XRead (dpy, (char *) xrects, *count * sizeof (xRectangle));
-	    for (i = 0; i < *count; i++) {
+	    _XRead (dpy, (char *) xrects, rep.nrects * sizeof (xRectangle));
+	    for (i = 0; i < rep.nrects; i++) {
 	    	rects[i].x = (short) cvtINT16toInt (xrects[i].x);
 	    	rects[i].y = (short) cvtINT16toInt (xrects[i].y);
 	    	rects[i].width = xrects[i].width;
-- 
1.7.9.2

From dfe6e1f3b8ede3d0bab7a5fa57f73513a09ec649 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <[email protected]>
Date: Sat, 9 Mar 2013 14:40:33 -0800
Subject: [PATCH:libXext 7/7] integer overflow in XSyncListSystemCounters()
 [CVE-2013-1982 6/6]

If the number of counters or amount of data reported by the server is
large enough that it overflows when multiplied by the size of the
appropriate struct, then memory corruption can occur when more bytes
are read from the X server than the size of the buffers we allocated
to hold them.

V2: Make sure we don't walk past the end of the reply when converting
data from wire format to the structures returned to the caller.

Reported-by: Ilja Van Sprundel <[email protected]>
Signed-off-by: Alan Coopersmith <[email protected]>
---
 src/XSync.c |   32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/XSync.c b/src/XSync.c
index 3ca1308..ce4ab44 100644
--- a/src/XSync.c
+++ b/src/XSync.c
@@ -59,6 +59,7 @@ PERFORMANCE OF THIS SOFTWARE.
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/sync.h>
 #include <X11/extensions/syncproto.h>
+#include <limits.h>
 #include "eat.h"
 
 static XExtensionInfo _sync_info_data;
@@ -352,19 +353,28 @@ XSyncListSystemCounters(Display *dpy, int *n_counters_return)
     if (rep.nCounters > 0)
     {
 	xSyncSystemCounter *pWireSysCounter, *pNextWireSysCounter;
+	xSyncSystemCounter *pLastWireSysCounter;
 	XSyncCounter counter;
-	int replylen;
+	unsigned int replylen;
 	int i;
 
-	list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter));
-	replylen = rep.length << 2;
-	pWireSysCounter = Xmalloc ((unsigned) replylen + sizeof(XSyncCounter));
-        /* +1 to leave room for last counter read-ahead */
+	if (rep.nCounters < (INT_MAX / sizeof(XSyncSystemCounter)))
+	    list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter));
+	if (rep.length < (INT_MAX >> 2)) {
+	    replylen = rep.length << 2;
+	    pWireSysCounter = Xmalloc (replylen + sizeof(XSyncCounter));
+	    /* +1 to leave room for last counter read-ahead */
+	    pLastWireSysCounter = (xSyncSystemCounter *)
+		((char *)pWireSysCounter) + replylen;
+	} else {
+	    replylen = 0;
+	    pWireSysCounter = NULL;
+	}
 
 	if ((!list) || (!pWireSysCounter))
 	{
-	    if (list) Xfree((char *) list);
-	    if (pWireSysCounter)   Xfree((char *) pWireSysCounter);
+	    Xfree(list);
+	    Xfree(pWireSysCounter);
 	    _XEatDataWords(dpy, rep.length);
 	    list = NULL;
 	    goto bail;
@@ -388,6 +398,14 @@ XSyncListSystemCounters(Display *dpy, int *n_counters_return)
 	    pNextWireSysCounter = (xSyncSystemCounter *)
 		(((char *)pWireSysCounter) + ((SIZEOF(xSyncSystemCounter) +
 				     pWireSysCounter->name_length + 3) & ~3));
+	    /* Make sure we haven't gone too far */
+	    if (pNextWireSysCounter > pLastWireSysCounter) {
+		Xfree(list);
+		Xfree(pWireSysCounter);
+		list = NULL;
+		goto bail;
+	    }
+
 	    counter = pNextWireSysCounter->counter;
 
 	    list[i].name = ((char *)pWireSysCounter) +
-- 
1.7.9.2