Module Name:    xsrc
Committed By:   bouyer
Date:           Wed Oct  5 09:50:10 UTC 2016

Modified Files:
        xsrc/xfree/xc/lib/X11 [netbsd-7]: FontNames.c GetImage.c ListExt.c
            ModMap.c Xlibint.h
        xsrc/xfree/xc/lib/Xi [netbsd-7]: XGMotion.c XGetBMap.c XGetDCtl.c
            XGetFCtl.c XGetKMap.c XGetMMap.c XOpenDev.c XQueryDv.c
        xsrc/xfree/xc/lib/Xrender [netbsd-7]: Filter.c Xrender.c
        xsrc/xfree/xc/lib/Xtst [netbsd-7]: XRecord.c
        xsrc/xfree/xc/lib/Xv [netbsd-7]: Xv.c
        xsrc/xfree/xc/programs/Xserver/include [netbsd-7]: dix.h

Log Message:
Apply patch, requested my mrg in ticket 1263:
        xsrc/xfree/xc/lib/X11/FontNames.c               patch
        xsrc/xfree/xc/lib/X11/GetImage.c                patch
        xsrc/xfree/xc/lib/X11/ListExt.c                 patch
        xsrc/xfree/xc/lib/X11/ModMap.c                  patch
        xsrc/xfree/xc/lib/X11/Xlibint.h                 patch
        xsrc/xfree/xc/lib/Xi/XGMotion.c                 patch
        xsrc/xfree/xc/lib/Xi/XGetBMap.c                 patch
        xsrc/xfree/xc/lib/Xi/XGetDCtl.c                 patch
        xsrc/xfree/xc/lib/Xi/XGetFCtl.c                 patch
        xsrc/xfree/xc/lib/Xi/XGetKMap.c                 patch
        xsrc/xfree/xc/lib/Xi/XGetMMap.c                 patch
        xsrc/xfree/xc/lib/Xi/XOpenDev.c                 patch
        xsrc/xfree/xc/lib/Xi/XQueryDv.c                 patch
        xsrc/xfree/xc/lib/Xrender/Filter.c              patch
        xsrc/xfree/xc/lib/Xrender/Xrender.c             patch
        xsrc/xfree/xc/lib/Xtst/XRecord.c                patch
        xsrc/xfree/xc/lib/Xv/Xv.c                       patch
        xsrc/xfree/xc/programs/Xserver/include/dix.h    patch

Fix (backported from upstream) the following issues in X client
libraries:
libX11 - insufficient validation of data from the X server
         can cause out of boundary memory read (XGetImage())
         or write (XListFonts()).
         Affected versions libX11 <= 1.6.3

libXfixes - insufficient validation of data from the X server
        can cause an integer overflow on 32 bit architectures.
        Affected versions : libXfixes <= 5.0.2

libXi - insufficient validation of data from the X server
        can cause out of boundary memory access or
        endless loops (Denial of Service).
        Affected versions libXi <= 1.7.6

libXrandr - insufficient validation of data from the X server
        can cause out of boundary memory writes.
        Affected versions: libXrandr <= 1.5.0

libXrender - insufficient validation of data from the X server
        can cause out of boundary memory writes.
        Affected version: libXrender <= 0.9.9

XRecord - insufficient validation of data from the X server
        can cause out of boundary memory access or
        endless loops (Denial of Service).
         Affected version libXtst <= 1.2.2

libXv - insufficient validation of data from the X server
        can cause out of boundary memory and memory corruption.
        CVE-2016-5407
        affected versions libXv <= 1.0.10

libXvMC - insufficient validation of data from the X server
        can cause a one byte buffer read underrun.
        Affected versions: libXvMC <= 1.0.9


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.5 -r1.1.1.5.36.1 xsrc/xfree/xc/lib/X11/FontNames.c \
    xsrc/xfree/xc/lib/X11/GetImage.c xsrc/xfree/xc/lib/X11/ModMap.c
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.38.1 xsrc/xfree/xc/lib/X11/ListExt.c
cvs rdiff -u -r1.1.1.7.24.1 -r1.1.1.7.24.2 xsrc/xfree/xc/lib/X11/Xlibint.h
cvs rdiff -u -r1.1.1.5 -r1.1.1.5.38.1 xsrc/xfree/xc/lib/Xi/XGMotion.c \
    xsrc/xfree/xc/lib/Xi/XGetBMap.c xsrc/xfree/xc/lib/Xi/XGetDCtl.c \
    xsrc/xfree/xc/lib/Xi/XGetFCtl.c xsrc/xfree/xc/lib/Xi/XGetMMap.c \
    xsrc/xfree/xc/lib/Xi/XOpenDev.c xsrc/xfree/xc/lib/Xi/XQueryDv.c
cvs rdiff -u -r1.1.1.6 -r1.1.1.6.36.1 xsrc/xfree/xc/lib/Xi/XGetKMap.c
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.38.1 xsrc/xfree/xc/lib/Xrender/Filter.c
cvs rdiff -u -r1.1.1.5 -r1.1.1.5.38.1 xsrc/xfree/xc/lib/Xrender/Xrender.c
cvs rdiff -u -r1.1.1.6 -r1.1.1.6.24.1 xsrc/xfree/xc/lib/Xtst/XRecord.c
cvs rdiff -u -r1.1.1.6 -r1.1.1.6.24.1 xsrc/xfree/xc/lib/Xv/Xv.c
cvs rdiff -u -r1.1.1.6.36.1 -r1.1.1.6.36.2 \
    xsrc/xfree/xc/programs/Xserver/include/dix.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/xfree/xc/lib/X11/FontNames.c
diff -u xsrc/xfree/xc/lib/X11/FontNames.c:1.1.1.5 xsrc/xfree/xc/lib/X11/FontNames.c:1.1.1.5.36.1
--- xsrc/xfree/xc/lib/X11/FontNames.c:1.1.1.5	Fri Mar  5 14:24:07 2004
+++ xsrc/xfree/xc/lib/X11/FontNames.c	Wed Oct  5 09:50:09 2016
@@ -29,6 +29,7 @@ in this Software without prior written a
 
 #define NEED_REPLIES
 #include "Xlibint.h"
+#include <limits.h>
 
 char **
 XListFonts(
@@ -41,7 +42,9 @@ int *actualCount)	/* RETURN */
     register unsigned i;
     register int length;
     char **flist;
-    char *ch;
+    char *ch = NULL;
+    char *chend;
+    int count = 0;
     xListFontsReply rep;
     register xListFontsReq *req;
     register long rlen;
@@ -63,9 +66,11 @@ int *actualCount)	/* RETURN */
 
     if (rep.nFonts) {
 	flist = (char **)Xmalloc ((unsigned)rep.nFonts * sizeof(char *));
-	rlen = rep.length << 2;
-	ch = (char *) Xmalloc((unsigned) (rlen + 1));
-	    /* +1 to leave room for last null-terminator */
+	if (rep.length > 0 && rep.length < (INT_MAX >> 2)) {
+	    rlen = rep.length << 2;
+	    ch = (char *) Xmalloc((unsigned) (rlen + 1));
+	        /* +1 to leave room for last null-terminator */
+	}
 
 	if ((! flist) || (! ch)) {
 	    if (flist) Xfree((char *) flist);
@@ -81,17 +86,33 @@ 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 ... */
+		if (ch <= chend) {
+		    length = *(unsigned char *)ch;
+		    *ch = '\0';  /* and replace with null-termination */
+		    count++;
+	        } else {
+		    Xfree(flist);
+		    flist = NULL;
+		    count = 0;
+		    break;
+		}
+	    } else {
+	       Xfree(flist);
+	       flist = NULL;
+	       count = 0;
+	       break;
+	    }
 	}
     }
     else flist = (char **) NULL;
-    *actualCount = rep.nFonts;
+    *actualCount = count;
     UnlockDisplay(dpy);
     SyncHandle();
     return (flist);
Index: xsrc/xfree/xc/lib/X11/GetImage.c
diff -u xsrc/xfree/xc/lib/X11/GetImage.c:1.1.1.5 xsrc/xfree/xc/lib/X11/GetImage.c:1.1.1.5.36.1
--- xsrc/xfree/xc/lib/X11/GetImage.c:1.1.1.5	Fri Mar  5 14:24:07 2004
+++ xsrc/xfree/xc/lib/X11/GetImage.c	Wed Oct  5 09:50:09 2016
@@ -30,6 +30,7 @@ in this Software without prior written a
 #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,6 +57,7 @@ XImage *XGetImage (dpy, d, x, y, width, 
 	char *data;
 	long nbytes;
 	XImage *image;
+	int planes;
 	LockDisplay(dpy);
 	GetReq (GetImage, req);
 	/*
@@ -85,18 +87,28 @@ XImage *XGetImage (dpy, d, x, y, width, 
 	    return (XImage *) NULL;
 	}
         _XReadPad (dpy, data, nbytes);
-        if (format == XYPixmap)
-	   image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual),
-		  Ones (plane_mask &
-			(((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))),
-		  format, 0, data, width, height, dpy->bitmap_pad, 0);
-	else /* format == ZPixmap */
-           image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual),
-		 rep.depth, ZPixmap, 0, data, width, height,
-		  _XGetScanlinePad(dpy, (int) rep.depth), 0);
+        if (format == XYPixmap) {
+	    image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual),
+		Ones (plane_mask &
+		    (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))),
+		format, 0, data, width, height, dpy->bitmap_pad, 0);
+	    planes = image->depth;
+	} else { /* format == ZPixmap */
+            image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual),
+		rep.depth, ZPixmap, 0, data, width, height,
+		    _XGetScanlinePad(dpy, (int) rep.depth), 0);
+	    planes = 1;
+	}
 
 	if (!image)
 	    Xfree(data);
+	if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 ||
+	    INT_MAX / image->height <= image->bytes_per_line ||
+	    INT_MAX / planes <= image->height * image->bytes_per_line ||
+	    nbytes < planes * image->height * image->bytes_per_line) {
+	    XDestroyImage(image);
+	    image = NULL;
+	}
 	UnlockDisplay(dpy);
 	SyncHandle();
 	return (image);
Index: xsrc/xfree/xc/lib/X11/ModMap.c
diff -u xsrc/xfree/xc/lib/X11/ModMap.c:1.1.1.5 xsrc/xfree/xc/lib/X11/ModMap.c:1.1.1.5.36.1
--- xsrc/xfree/xc/lib/X11/ModMap.c:1.1.1.5	Fri Mar  5 14:24:08 2004
+++ xsrc/xfree/xc/lib/X11/ModMap.c	Wed Oct  5 09:50:09 2016
@@ -28,6 +28,7 @@ in this Software without prior written a
 
 #define NEED_REPLIES
 #include "Xlibint.h"
+#include <limits.h>
 
 XModifierKeymap *
 XGetModifierMapping(dpy)
@@ -42,8 +43,13 @@ XGetModifierMapping(dpy)
     GetEmptyReq(GetModifierMapping, req);
     (void) _XReply (dpy, (xReply *)&rep, 0, xFalse);
 
-    nbytes = (unsigned long)rep.length << 2;
-    res = (XModifierKeymap *) Xmalloc(sizeof (XModifierKeymap));
+    if (rep.length < (INT_MAX >> 2) &&
+	(rep.length >> 1) == rep.numKeyPerModifier) {
+        nbytes = (unsigned long)rep.length << 2;
+        res = (XModifierKeymap *) Xmalloc(sizeof (XModifierKeymap));
+    } else
+	res = NULL;
+
     if (res) res->modifiermap = (KeyCode *) Xmalloc ((unsigned) nbytes);
     if ((! res) || (! res->modifiermap)) {
 	if (res) Xfree((char *) res);

Index: xsrc/xfree/xc/lib/X11/ListExt.c
diff -u xsrc/xfree/xc/lib/X11/ListExt.c:1.1.1.4 xsrc/xfree/xc/lib/X11/ListExt.c:1.1.1.4.38.1
--- xsrc/xfree/xc/lib/X11/ListExt.c:1.1.1.4	Sat Jan 19 14:55:27 2002
+++ xsrc/xfree/xc/lib/X11/ListExt.c	Wed Oct  5 09:50:09 2016
@@ -28,6 +28,7 @@ in this Software without prior written a
 
 #define NEED_REPLIES
 #include "Xlibint.h"
+#include <limits.h>
 
 char **XListExtensions(dpy, nextensions)
 register Display *dpy;
@@ -35,7 +36,9 @@ int *nextensions;	/* RETURN */
 {
 	xListExtensionsReply rep;
 	char **list;
-	char *ch;
+	char *ch = NULL;
+	char *chend;
+	int count = 0;
 	register unsigned i;
 	register int length;
 	register xReq *req;
@@ -53,9 +56,11 @@ int *nextensions;	/* RETURN */
 	if (rep.nExtensions) {
 	    list = (char **) Xmalloc (
                 (unsigned)(rep.nExtensions * sizeof (char *)));
-	    rlen = rep.length << 2;
-	    ch = (char *) Xmalloc ((unsigned) rlen + 1);
-                /* +1 to leave room for last null-terminator */
+	    if (rep.length > 0 && rep.length < (INT_MAX >> 2)) {
+	        rlen = rep.length << 2;
+	        ch = (char *) Xmalloc ((unsigned) rlen + 1);
+                    /* +1 to leave room for last null-terminator */
+	    }
 
 	    if ((!list) || (!ch)) {
 		if (list) Xfree((char *) list);
@@ -70,17 +75,26 @@ int *nextensions;	/* RETURN */
 	    /*
 	     * 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 ... */
+		    if (ch <= chend) {
+			length = *ch;
+			*ch = '\0'; /* and replace with null-termination */
+			count++;
+		    } else {
+			list[i] = NULL;
+		    }
+		} else
+		    list[i] = NULL;
 	    }
 	}
 	else list = (char **) NULL;
 
-	*nextensions = rep.nExtensions;
+	*nextensions = count;
 	UnlockDisplay(dpy);
 	SyncHandle();
 	return (list);

Index: xsrc/xfree/xc/lib/X11/Xlibint.h
diff -u xsrc/xfree/xc/lib/X11/Xlibint.h:1.1.1.7.24.1 xsrc/xfree/xc/lib/X11/Xlibint.h:1.1.1.7.24.2
--- xsrc/xfree/xc/lib/X11/Xlibint.h:1.1.1.7.24.1	Sun Apr 19 04:57:34 2015
+++ xsrc/xfree/xc/lib/X11/Xlibint.h	Wed Oct  5 09:50:09 2016
@@ -542,7 +542,7 @@ extern LockInfoPtr _Xglobal_lock;
     unsigned long _BRlen = req->length - 1; \
     req->length = 0; \
     memcpy(_BRdat, ((char *)req) + (_BRlen << 2), 4); \
-    memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
+    memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \
     memcpy(((char *)req) + 4, _BRdat, 4); \
     Data32(dpy, (long *)&_BRdat, 4); \
     }

Index: xsrc/xfree/xc/lib/Xi/XGMotion.c
diff -u xsrc/xfree/xc/lib/Xi/XGMotion.c:1.1.1.5 xsrc/xfree/xc/lib/Xi/XGMotion.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xi/XGMotion.c:1.1.1.5	Fri Feb 28 13:18:51 2003
+++ xsrc/xfree/xc/lib/Xi/XGMotion.c	Wed Oct  5 09:50:09 2016
@@ -59,6 +59,7 @@ SOFTWARE.
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
+#include <limits.h>
 
 XDeviceTimeCoord
 *XGetDeviceMotionEvents (dpy, dev, start, stop, nEvents, mode, axis_count)
@@ -74,7 +75,7 @@ XDeviceTimeCoord
     xGetDeviceMotionEventsReply 	rep;
     XDeviceTimeCoord *tc;
     int *data, *bufp, *readp, *savp;
-    long size, size2;
+    long size;
     int	 i, j;
     XExtDisplayInfo *info = XInput_find_display (dpy);
 
@@ -105,11 +106,23 @@ XDeviceTimeCoord
         SyncHandle();
 	return (NULL);
 	}
-    size = rep.length << 2;
-    size2 = rep.nEvents * 
-	(sizeof (XDeviceTimeCoord) + (rep.axes * sizeof (int)));
-    savp = readp = (int *) Xmalloc (size);
-    bufp = (int *) Xmalloc (size2);
+    if (rep.length < (INT_MAX >> 2)) {
+	size = rep.length << 2;
+	savp = readp = Xmalloc(size);
+    } else {
+	size = 0;
+	savp = readp = NULL;
+    }
+    /* rep.axes is a CARD8, so assume max number of axes for bounds check */
+    if (rep.nEvents <
+        (INT_MAX / (sizeof(XDeviceTimeCoord) + (UCHAR_MAX * sizeof(int)))) &&
+        rep.nEvents * (rep.axes + 1) <= rep.length) {
+        size_t bsize = rep.nEvents *
+            (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int)));
+        bufp = Xmalloc(bsize);
+    } else
+        bufp = NULL;
+
     if (!bufp || !savp)
 	{
 	*nEvents = 0;
Index: xsrc/xfree/xc/lib/Xi/XGetBMap.c
diff -u xsrc/xfree/xc/lib/Xi/XGetBMap.c:1.1.1.5 xsrc/xfree/xc/lib/Xi/XGetBMap.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xi/XGetBMap.c:1.1.1.5	Fri Feb 28 13:18:51 2003
+++ xsrc/xfree/xc/lib/Xi/XGetBMap.c	Wed Oct  5 09:50:09 2016
@@ -90,16 +90,20 @@ XGetDeviceButtonMapping (dpy, device, ma
     req->deviceid = device->device_id;
 
     status = _XReply (dpy, (xReply *)&rep, 0, xFalse);
-    if (status == 1)
-	{
-	nbytes = (long)rep.length << 2;
-	_XRead (dpy, (char *)mapping, nbytes);
+    if (status == 1) {
+	if (rep.length <= (sizeof(mapping) >> 2) &&
+	    rep.nElts <= (rep.length << 2)) {
+	    nbytes = (long)rep.length << 2;
+	    _XRead (dpy, (char *)mapping, nbytes);
 
-	/* don't return more data than the user asked for. */
-	if (rep.nElts) 
-	    memcpy ((char *) map, (char *) mapping, MIN((int)rep.nElts, nmap));
-	status = rep.nElts;
+	    /* don't return more data than the user asked for. */
+	    if (rep.nElts) 
+	        memcpy ((char *) map, (char *) mapping, MIN((int)rep.nElts, nmap));
+	    status = rep.nElts;
+	} else {
+	    status = 0;
 	}
+    }
     else
 	status = 0;
     UnlockDisplay(dpy);
Index: xsrc/xfree/xc/lib/Xi/XGetDCtl.c
diff -u xsrc/xfree/xc/lib/Xi/XGetDCtl.c:1.1.1.5 xsrc/xfree/xc/lib/Xi/XGetDCtl.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xi/XGetDCtl.c:1.1.1.5	Fri Feb 28 13:18:51 2003
+++ xsrc/xfree/xc/lib/Xi/XGetDCtl.c	Wed Oct  5 09:50:09 2016
@@ -60,6 +60,7 @@ SOFTWARE.
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
+#include <limits.h>
 
 XDeviceControl
 *XGetDeviceControl (dpy, dev, control)
@@ -95,8 +96,11 @@ XDeviceControl
 	}
     if (rep.length > 0) 
 	{
-	nbytes = (long)rep.length << 2;
-	d = (xDeviceState *) Xmalloc((unsigned) nbytes);
+	if (rep.length < (INT_MAX >> 2) &&
+	    (rep.length << 2) >= sizeof(xDeviceState)) {
+	    nbytes = (long)rep.length << 2;
+	    d = (xDeviceState *) Xmalloc((unsigned) nbytes);
+	}
         if (!d)
 	    {
 	    _XEatData (dpy, (unsigned long) nbytes);
@@ -112,10 +116,16 @@ XDeviceControl
 	    case DEVICE_RESOLUTION:
 		{
 		xDeviceResolutionState *r;
+		size_t val_size;
 
 		r = (xDeviceResolutionState *) d;
-		size += sizeof (XDeviceResolutionState) + 
-			(3 * sizeof(int) * r->num_valuators);
+	        if (sizeof(xDeviceResolutionState) > nbytes ||
+		    r->num_valuators >= (INT_MAX / (3 * sizeof(int))))
+ 		    goto out;
+		val_size = 3 * sizeof(int) * r->num_valuators;
+		if ((sizeof(xDeviceResolutionState) + val_size) > nbytes)
+		    goto out;
+		size = sizeof(XDeviceResolutionState) + val_size;
 		break;
 		}
 	    default:
@@ -158,6 +168,7 @@ XDeviceControl
 	    default:
 		break;
 	    }
+out:
 	XFree (sav);
 	}
 
Index: xsrc/xfree/xc/lib/Xi/XGetFCtl.c
diff -u xsrc/xfree/xc/lib/Xi/XGetFCtl.c:1.1.1.5 xsrc/xfree/xc/lib/Xi/XGetFCtl.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xi/XGetFCtl.c:1.1.1.5	Fri Feb 28 13:18:51 2003
+++ xsrc/xfree/xc/lib/Xi/XGetFCtl.c	Wed Oct  5 09:50:09 2016
@@ -60,6 +60,7 @@ SOFTWARE.
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
+#include <limits.h>
 
 XFeedbackState
 *XGetFeedbackControl (dpy, dev, num_feedbacks)
@@ -73,6 +74,7 @@ XFeedbackState
     XFeedbackState *Sav = NULL;
     xFeedbackState *f = NULL;
     xFeedbackState *sav = NULL;
+    char *end = NULL;
     xGetFeedbackControlReq *req;
     xGetFeedbackControlReply rep;
     XExtDisplayInfo *info = XInput_find_display (dpy);
@@ -95,8 +97,11 @@ XFeedbackState
     if (rep.length > 0) 
 	{
 	*num_feedbacks = rep.num_feedbacks;
-	nbytes = (long)rep.length << 2;
-	f = (xFeedbackState *) Xmalloc((unsigned) nbytes);
+
+	if (rep.length < (INT_MAX >> 2)) {
+	    nbytes = (long)rep.length << 2;
+	    f = (xFeedbackState *) Xmalloc((unsigned) nbytes);
+	}
         if (!f)
 	    {
 	    _XEatData (dpy, (unsigned long) nbytes);
@@ -105,10 +110,14 @@ XFeedbackState
 	    return (XFeedbackState *) NULL;
 	    }
 	sav = f;
+	end = (char *)f + nbytes;
 	_XRead (dpy, (char *) f, nbytes);
 
 	for (i=0; i<*num_feedbacks; i++)
 	    {
+	    if ((char *)f + sizeof(*f) > end ||
+	        f->length == 0 || f->length > nbytes)
+ 		goto out;
 	    switch (f->class)
 		{
 		case KbdFeedbackClass:
@@ -258,6 +267,7 @@ XFeedbackState
 	    f = (xFeedbackState *) ((char *) f + f->length);
 	    Feedback = (XFeedbackState *) ((char *) Feedback+Feedback->length);
 	    }
+out:
 	XFree ((char *)sav);
 	}
 
Index: xsrc/xfree/xc/lib/Xi/XGetMMap.c
diff -u xsrc/xfree/xc/lib/Xi/XGetMMap.c:1.1.1.5 xsrc/xfree/xc/lib/Xi/XGetMMap.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xi/XGetMMap.c:1.1.1.5	Fri Feb 28 13:18:51 2003
+++ xsrc/xfree/xc/lib/Xi/XGetMMap.c	Wed Oct  5 09:50:09 2016
@@ -53,6 +53,7 @@ SOFTWARE.
  *
  */
 
+#include <limits.h>
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
 #include <X11/Xlibint.h>
@@ -86,8 +87,14 @@ XModifierKeymap 
 	SyncHandle();
 	return (XModifierKeymap *) NULL;
 	}
-    nbytes = (unsigned long)rep.length << 2;
-    res = (XModifierKeymap *) Xmalloc(sizeof (XModifierKeymap));
+    if (rep.length < (INT_MAX >> 2) &&
+	rep.numKeyPerModifier == rep.length >> 1) {
+        nbytes = (unsigned long)rep.length << 2;
+        res = (XModifierKeymap *) Xmalloc(sizeof (XModifierKeymap));
+    } else {
+	nbytes = 0;
+	res = NULL;
+    }
     if (res)
 	{
         res->modifiermap = (KeyCode *) Xmalloc (nbytes);
Index: xsrc/xfree/xc/lib/Xi/XOpenDev.c
diff -u xsrc/xfree/xc/lib/Xi/XOpenDev.c:1.1.1.5 xsrc/xfree/xc/lib/Xi/XOpenDev.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xi/XOpenDev.c:1.1.1.5	Fri Feb 28 13:18:51 2003
+++ xsrc/xfree/xc/lib/Xi/XOpenDev.c	Wed Oct  5 09:50:09 2016
@@ -53,6 +53,7 @@ SOFTWARE.
  *
  */
 
+#include <limits.h>
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
 #include <X11/Xlibint.h>
@@ -87,9 +88,15 @@ XDevice
 	return (XDevice *) NULL;
 	}
 
-    rlen = rep.length << 2;
-    dev = (XDevice *) Xmalloc (sizeof(XDevice) + rep.num_classes * 
-	sizeof (XInputClassInfo));
+    if (rep.length < INT_MAX >> 2 &&
+	(rep.length << 2) >= rep.num_classes * sizeof(xInputClassInfo)) {
+        rlen = rep.length << 2;
+        dev = (XDevice *) Xmalloc (sizeof(XDevice) + rep.num_classes * 
+	    sizeof (XInputClassInfo));
+    } else {
+	rlen = 0;
+	dev = NULL;
+    }
     if (dev)
 	{
 	int dlen; /* data length */
Index: xsrc/xfree/xc/lib/Xi/XQueryDv.c
diff -u xsrc/xfree/xc/lib/Xi/XQueryDv.c:1.1.1.5 xsrc/xfree/xc/lib/Xi/XQueryDv.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xi/XQueryDv.c:1.1.1.5	Fri Feb 28 13:18:51 2003
+++ xsrc/xfree/xc/lib/Xi/XQueryDv.c	Wed Oct  5 09:50:09 2016
@@ -59,6 +59,7 @@ SOFTWARE.
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
+#include <limits.h>
 
 XDeviceState
 *XQueryDeviceState (dpy, dev)
@@ -66,13 +67,13 @@ XDeviceState
     XDevice *dev;
     {       
     int				i,j;
-    int				rlen;
+    int				rlen = 0;
     int				size = 0;
     xQueryDeviceStateReq 	*req;
     xQueryDeviceStateReply 	rep;
     XDeviceState		*state = NULL;
     XInputClass			*any, *Any;
-    char			*data;
+    char			*data = NULL, *end = NULL;
     XExtDisplayInfo *info = XInput_find_display (dpy);
 
     LockDisplay (dpy);
@@ -91,10 +92,12 @@ XDeviceState
 	return (XDeviceState *) NULL;
 	}
 
-    rlen = rep.length << 2;
-    if (rlen > 0)
-	{
-	data = Xmalloc (rlen);
+    if (rep.length > 0) {
+	if (rep.length < (INT_MAX >> 2)) {
+	    rlen = (unsigned long) rep.length << 2;
+	    data = Xmalloc(rlen);
+	    end = data + rlen;
+	}
 	if (!data)
 	    {
 	    _XEatData (dpy, (unsigned long) rlen);
@@ -102,10 +105,14 @@ XDeviceState
     	    SyncHandle();
     	    return ((XDeviceState *) NULL);
 	    }
+        end = data + rlen;
 	_XRead (dpy, data, rlen);
 
 	for (i=0, any=(XInputClass *) data; i<(int)rep.num_classes; i++)
 	    {
+	    if ((char *)any + sizeof(XInputClass) > end ||
+		any->length == 0 || any->length > rlen)
+ 		goto out;
 	    switch (any->class)
 		{
 		case KeyClass:
@@ -117,6 +124,8 @@ XDeviceState
 		case ValuatorClass:
 		    {
 		    xValuatorState *v = (xValuatorState *) any;
+		    if ((char *)any + sizeof(xValuatorState) > end)
+		        goto out;
 		    size += (sizeof (XValuatorState) + 
 			(v->num_valuators * sizeof(int)));
 		    }
@@ -186,6 +195,7 @@ XDeviceState
 	Xfree(data);
 	}
 
+out:
     UnlockDisplay(dpy);
     SyncHandle();
     return (state);

Index: xsrc/xfree/xc/lib/Xi/XGetKMap.c
diff -u xsrc/xfree/xc/lib/Xi/XGetKMap.c:1.1.1.6 xsrc/xfree/xc/lib/Xi/XGetKMap.c:1.1.1.6.36.1
--- xsrc/xfree/xc/lib/Xi/XGetKMap.c:1.1.1.6	Fri Mar  5 14:24:25 2004
+++ xsrc/xfree/xc/lib/Xi/XGetKMap.c	Wed Oct  5 09:50:09 2016
@@ -53,6 +53,7 @@ SOFTWARE.
  *
  */
 
+#include <limits.h>
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
 #include <X11/Xlibint.h>
@@ -96,9 +97,16 @@ XGetDeviceKeyMapping (
 	return (KeySym *) NULL;
 	}
     if (rep.length > 0) {
-        *syms_per_code = rep.keySymsPerKeyCode;
-	nbytes = (long)rep.length << 2;
-	mapping = (KeySym *) Xmalloc((unsigned) nbytes);
+	if (rep.length < INT_MAX >> 2 &&
+	    rep.length == rep.keySymsPerKeyCode * keycount) {
+            *syms_per_code = rep.keySymsPerKeyCode;
+	    nbytes = (long)rep.length << 2;
+	    mapping = (KeySym *) Xmalloc((unsigned) nbytes);
+	} else {
+	    *syms_per_code = 0;
+	    nbytes = 0;
+	    mapping = NULL;
+	}
 	if (mapping)
 	    _XRead (dpy, (char *)mapping, nbytes);
 	else

Index: xsrc/xfree/xc/lib/Xrender/Filter.c
diff -u xsrc/xfree/xc/lib/Xrender/Filter.c:1.1.1.1 xsrc/xfree/xc/lib/Xrender/Filter.c:1.1.1.1.38.1
--- xsrc/xfree/xc/lib/Xrender/Filter.c:1.1.1.1	Fri Feb 28 13:18:52 2003
+++ xsrc/xfree/xc/lib/Xrender/Filter.c	Wed Oct  5 09:50:09 2016
@@ -35,7 +35,7 @@ XRenderQueryFilters (Display *dpy, Drawa
     char			*name;
     char			len;
     int				i;
-    long			nbytes, nbytesAlias, nbytesName;
+    long			nbytes, nbytesAlias, nbytesName, reply_left;
     
     if (!XextHasExtension (info))
 	return 0;
@@ -101,6 +101,7 @@ XRenderQueryFilters (Display *dpy, Drawa
      * Read the filter aliases
      */
     _XRead16Pad (dpy, filters->alias, 2 * rep.numAliases);
+    reply_left = 8 + rep.length - 2 * rep.numAliases;;
 
     /*
      * Read the filter names
@@ -109,9 +110,18 @@ XRenderQueryFilters (Display *dpy, Drawa
     {
 	int	l;
 	_XRead (dpy, &len, 1);
+	reply_left--;
 	l = len & 0xff;
+	if ((unsigned long)l + 1 > nbytesName) {
+	    Xfree(filters);
+	    UnlockDisplay (dpy);
+	    SyncHandle ();
+	    return NULL;
+	}
+	nbytesName -= l + 1;
 	filters->filter[i] = name;
 	_XRead (dpy, name, l);
+        reply_left -= l;
 	name[l] = '\0';
 	name += l + 1;
     }

Index: xsrc/xfree/xc/lib/Xrender/Xrender.c
diff -u xsrc/xfree/xc/lib/Xrender/Xrender.c:1.1.1.5 xsrc/xfree/xc/lib/Xrender/Xrender.c:1.1.1.5.38.1
--- xsrc/xfree/xc/lib/Xrender/Xrender.c:1.1.1.5	Fri Feb 28 13:18:52 2003
+++ xsrc/xfree/xc/lib/Xrender/Xrender.c	Wed Oct  5 09:50:09 2016
@@ -289,12 +289,28 @@ XRenderQueryFormats (Display *dpy)
 	screen->fallback = _XRenderFindFormat (xri, xScreen->fallback);
 	screen->subpixel = SubPixelUnknown;
 	xDepth = (xPictDepth *) (xScreen + 1);
+	if (screen->ndepths > rep.numDepths) {
+	    Xfree (xri);
+	    Xfree (xData);
+	    UnlockDisplay (dpy);
+	    SyncHandle ();
+	    return 0;
+	}
+	rep.numDepths -= screen->ndepths;
 	for (nd = 0; nd < screen->ndepths; nd++)
 	{
 	    depth->depth = xDepth->depth;
 	    depth->nvisuals = xDepth->nPictVisuals;
 	    depth->visuals = visual;
 	    xVisual = (xPictVisual *) (xDepth + 1);
+	    if (depth->nvisuals > rep.numVisuals) {
+		Xfree (xri);
+		Xfree (xData);
+		UnlockDisplay (dpy);
+		SyncHandle ();
+		return 0;
+	    }
+	    rep.numVisuals -= depth->nvisuals;
 	    for (nv = 0; nv < depth->nvisuals; nv++)
 	    {
 		visual->visual = _XRenderFindVisual (dpy, xVisual->visual);

Index: xsrc/xfree/xc/lib/Xtst/XRecord.c
diff -u xsrc/xfree/xc/lib/Xtst/XRecord.c:1.1.1.6 xsrc/xfree/xc/lib/Xtst/XRecord.c:1.1.1.6.24.1
--- xsrc/xfree/xc/lib/Xtst/XRecord.c:1.1.1.6	Fri Mar 18 13:04:54 2005
+++ xsrc/xfree/xc/lib/Xtst/XRecord.c	Wed Oct  5 09:50:09 2016
@@ -51,6 +51,7 @@ from The Open Group.
 /* $XFree86: xc/lib/Xtst/XRecord.c,v 1.8 2005/01/27 02:28:59 dawes Exp $ */
 
 #include <stdio.h>
+#include <limits.h>
 #include <assert.h>
 #define NEED_EVENTS
 #define NEED_REPLIES
@@ -728,15 +729,23 @@ parse_reply_call_callback(Display *dpy, 
 	switch (rep->category) {
 	case XRecordFromServer:
 	    if (rep->elementHeader&XRecordFromServerTime) {
+		if (current_index + 4 > rep->length << 2)
+		    return Error;
 		EXTRACT_CARD32(rep->clientSwapped,
 			       reply->buf+current_index,
 			       data->server_time);
 		current_index += 4;
 	    }
+	    if (current_index + 1 > rep->length << 2)
+		return Error;
 	    switch (reply->buf[current_index]) {
 	    case X_Reply: /* reply */
+		if (current_index + 8 > rep->length << 2)
+		    return Error;
 		EXTRACT_CARD32(rep->clientSwapped,
 			       reply->buf+current_index+4, datum_bytes);
+		if (datum_bytes < 0 || datum_bytes > ((INT_MAX >> 2) - 8))
+		    return Error;
 		datum_bytes = (datum_bytes+8) << 2;
 		break;
 	    default: /* error or event */
@@ -745,52 +754,73 @@ parse_reply_call_callback(Display *dpy, 
 	    break;
 	case XRecordFromClient:
 	    if (rep->elementHeader&XRecordFromClientTime) {
+		if (current_index + 4 > rep->length << 2)
+		    return Error;
 		EXTRACT_CARD32(rep->clientSwapped,
 			       reply->buf+current_index,
 			       data->server_time);
 		current_index += 4;
 	    }
 	    if (rep->elementHeader&XRecordFromClientSequence) {
+		if (current_index + 4 > rep->length << 2)
+		    return Error;
 		EXTRACT_CARD32(rep->clientSwapped,
 			       reply->buf+current_index,
 			       data->client_seq);
 		current_index += 4;
 	    }
+	    if (current_index + 4 > rep->length<<2)
+		return Error;
 	    if (reply->buf[current_index+2] == 0
 		&& reply->buf[current_index+3] == 0) /* needn't swap 0 */
 	    {	/* BIG-REQUESTS */
+		if (current_index + 8 > rep->length << 2)
+		    return Error;
 		EXTRACT_CARD32(rep->clientSwapped,
 			       reply->buf+current_index+4, datum_bytes);
 	    } else {
 		EXTRACT_CARD16(rep->clientSwapped,
 			       reply->buf+current_index+2, datum_bytes);
 	    }
+	    if (datum_bytes < 0 || datum_bytes > INT_MAX >> 2)
+		return Error;
 	    datum_bytes <<= 2;
 	    break;
 	case XRecordClientStarted:
+	    if (current_index + 8 > rep->length << 2)
+		return Error;
 	    EXTRACT_CARD16(rep->clientSwapped,
 			   reply->buf+current_index+6, datum_bytes);
 	    datum_bytes = (datum_bytes+2) << 2;
 	    break;
 	case XRecordClientDied:
 	    if (rep->elementHeader&XRecordFromClientSequence) {
+		if (current_index + 4 > rep->length << 2)
+		    return Error;
 		EXTRACT_CARD32(rep->clientSwapped,
 			       reply->buf+current_index,
 			       data->client_seq);
 		current_index += 4;
-	    }
-	    /* fall through */
+	    } else if (current_index < rep->length << 2)
+		return Error;
+	    datum_bytes = 0;
+	    break;
 	case XRecordStartOfData:
 	case XRecordEndOfData:
+	    if (current_index < rep->length << 2)
+		return Error;
 	    datum_bytes = 0;
+	    break;
 	}
 	
 	if (datum_bytes > 0) {
-	    if (current_index + datum_bytes > rep->length << 2)
+	    if (INT_MAX - datum_bytes < (rep->length << 2) - current_index) {
 		fprintf(stderr,
 			"XRecord: %lu-byte reply claims %d-byte element (seq %lu)\n",
-			(long)rep->length << 2, current_index + datum_bytes,
+			(unsigned long)rep->length << 2, current_index + datum_bytes,
 			dpy->last_request_read);
+		return Error;
+	    }
 	    /*
 	     * This assignment (and indeed the whole buffer sharing
 	     * scheme) assumes arbitrary 4-byte boundaries are
@@ -842,6 +872,12 @@ XRecordEnableContext(Display *dpy, XReco
 	    return 0;
 	}
 
+	if (rep.length > INT_MAX >> 2) {
+	    UnlockDisplay(dpy);
+	    SyncHandle();
+	    return 0;
+	}
+
 	if (rep.length > 0) {
 	    reply = alloc_reply_buffer(info, rep.length<<2);
 	    if (!reply) {

Index: xsrc/xfree/xc/lib/Xv/Xv.c
diff -u xsrc/xfree/xc/lib/Xv/Xv.c:1.1.1.6 xsrc/xfree/xc/lib/Xv/Xv.c:1.1.1.6.24.1
--- xsrc/xfree/xc/lib/Xv/Xv.c:1.1.1.6	Fri Mar 18 13:04:54 2005
+++ xsrc/xfree/xc/lib/Xv/Xv.c	Wed Oct  5 09:50:09 2016
@@ -150,9 +150,11 @@ XvQueryAdaptors(
   xvQueryAdaptorsReply rep;
   int size,ii,jj;
   char *name;
+  char *end;
   XvAdaptorInfo *pas, *pa;
   XvFormat *pfs, *pf;
   char *buffer;
+  int status;
   union 
     {
       char *buffer;
@@ -177,14 +179,17 @@ XvQueryAdaptors(
   }
 
   size = rep.length << 2;
-  if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
+  if (size > 0) {
+    if ((buffer = Xmalloc(size)) == NULL) {
       UnlockDisplay(dpy);
       SyncHandle();
       return(XvBadAlloc);
+    }
+    _XRead(dpy, buffer, (long) size);
   }
-  _XRead (dpy, buffer, size);
 
   u.buffer = buffer;
+  end = buffer + size;
 
   /* GET INPUT ADAPTORS */
 
@@ -212,6 +217,10 @@ XvQueryAdaptors(
 
   pa = pas;
   for (ii=0; ii<rep.num_adaptors; ii++) {
+      if (u.buffer + sz_xvAdaptorInfo > end) {
+        status = XvBadReply;
+        goto out;
+      }
       pa->type = u.pa->type;
       pa->base_id = u.pa->base_id;
       pa->num_ports = u.pa->num_ports;
@@ -223,6 +232,11 @@ XvQueryAdaptors(
       size = u.pa->name_size;
       u.buffer += (sz_xvAdaptorInfo + 3) & ~3;
 
+      if (u.buffer + size > end) {
+        status = XvBadReply;
+        goto out;
+      }
+
       if ( (name = (char *)Xmalloc(size+1)) == NULL)
 	{
 	  XvFreeAdaptorInfo(pas);
@@ -250,6 +264,11 @@ XvQueryAdaptors(
 
       pf = pfs;
       for (jj=0; jj<pa->num_formats; jj++) {
+          if (u.buffer + sz_xvFormat > end) {
+            Xfree(pfs);
+            status = XvBadReply;
+            goto out;
+          }
 	  pf->depth = u.pf->depth;
 	  pf->visual_id = u.pf->visual;
 	  pf++;
@@ -266,11 +285,14 @@ XvQueryAdaptors(
   *p_nAdaptors = rep.num_adaptors;
   *p_pAdaptors = pas;
 
+  status = Success;
+
+out:
   Xfree(buffer);
   UnlockDisplay(dpy);
   SyncHandle();
 
-  return (Success);
+  return (status);
 }
 
 
@@ -312,6 +334,8 @@ XvQueryEncodings(
   xvQueryEncodingsReply rep;
   int size, jj;
   char *name;
+  char *end;
+  int status;
   XvEncodingInfo *pes, *pe;
   char *buffer;
   union 
@@ -337,14 +361,17 @@ XvQueryEncodings(
   }
 
   size = rep.length << 2;
-  if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
+  if (size > 0) {
+    if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
       UnlockDisplay(dpy);
       SyncHandle();
       return(XvBadAlloc);
+    }
+    _XRead (dpy, buffer, size);
   }
-  _XRead (dpy, buffer, size);
 
   u.buffer = buffer;
+  end = buffer + size;
 
   /* GET ENCODINGS */
 
@@ -367,6 +394,10 @@ XvQueryEncodings(
 
   pe = pes;
   for (jj=0; jj<rep.num_encodings; jj++) {
+      if (u.buffer + sz_xvEncodingInfo > end) {
+        status = XvBadReply;
+        goto out;
+      }
       pe->encoding_id = u.pe->encoding;
       pe->width = u.pe->width;
       pe->height = u.pe->height;
@@ -377,6 +408,10 @@ XvQueryEncodings(
       size = u.pe->name_size;
       u.buffer += (sz_xvEncodingInfo + 3) & ~3;
 
+      if (u.buffer + size > end) {
+        status = XvBadReply;
+        goto out;
+      }
       if ( (name = (char *)Xmalloc(size+1)) == NULL) {
 	  Xfree(buffer);
           UnlockDisplay(dpy);
@@ -394,11 +429,14 @@ XvQueryEncodings(
   *p_nEncodings = rep.num_encodings;
   *p_pEncodings = pes;
 
+  status = Success;
+
+out:
   Xfree(buffer);
   UnlockDisplay(dpy);
   SyncHandle();
 
-  return (Success);
+  return (status);
 }
 
 void

Index: xsrc/xfree/xc/programs/Xserver/include/dix.h
diff -u xsrc/xfree/xc/programs/Xserver/include/dix.h:1.1.1.6.36.1 xsrc/xfree/xc/programs/Xserver/include/dix.h:1.1.1.6.36.2
--- xsrc/xfree/xc/programs/Xserver/include/dix.h:1.1.1.6.36.1	Thu Dec 11 13:33:15 2014
+++ xsrc/xfree/xc/programs/Xserver/include/dix.h	Wed Oct  5 09:50:10 2016
@@ -53,6 +53,7 @@ SOFTWARE.
 #include "gc.h"
 #include "window.h"
 #include "input.h"
+#include <stdint.h>
 
 #define EARLIER -1
 #define SAMETIME 0

Reply via email to