From c206f36a4b6ecf2555ab2291c349ab7d7d0b02f5 Mon Sep 17 00:00:00 2001
From: Nathan Kidd <nkidd@opentext.com>
Date: Fri, 9 Jan 2015 09:57:23 -0500
Subject: Unvalidated lengths

v2: Add overflow check and remove unnecessary check (Julien Cristau)

This addresses:
CVE-2017-12184 in XINERAMA
CVE-2017-12185 in MIT-SCREEN-SAVER
CVE-2017-12186 in X-Resource
CVE-2017-12187 in RENDER

Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Nathan Kidd <nkidd@opentext.com>
Signed-off-by: Julien Cristau <jcristau@debian.org>
(cherry picked from commit cad5a1050b7184d828aef9c1dd151c3ab649d37e)

diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 209df29..844ea49 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -988,10 +988,11 @@ ProcPanoramiXGetScreenSize(ClientPtr client)
     xPanoramiXGetScreenSizeReply rep;
     int rc;
 
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+
     if (stuff->screen >= PanoramiXNumScreens)
         return BadMatch;
 
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
     if (rc != Success)
         return rc;
diff --git a/Xext/saver.c b/Xext/saver.c
index 750b8b9..45ac4d2 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -1185,6 +1185,8 @@ ProcScreenSaverUnsetAttributes(ClientPtr client)
         PanoramiXRes *draw;
         int rc, i;
 
+        REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
+
         rc = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
         if (rc != Success)
diff --git a/Xext/xres.c b/Xext/xres.c
index ae779df..bc54133 100644
--- a/Xext/xres.c
+++ b/Xext/xres.c
@@ -947,6 +947,8 @@ ProcXResQueryResourceBytes (ClientPtr client)
     ConstructResourceBytesCtx    ctx;
 
     REQUEST_AT_LEAST_SIZE(xXResQueryResourceBytesReq);
+    if (stuff->numSpecs > UINT32_MAX / sizeof(ctx.specs[0]))
+        return BadLength;
     REQUEST_FIXED_SIZE(xXResQueryResourceBytesReq,
                        stuff->numSpecs * sizeof(ctx.specs[0]));
 
@@ -1052,8 +1054,8 @@ SProcXResQueryResourceBytes (ClientPtr client)
     int c;
     xXResResourceIdSpec *specs = (void*) ((char*) stuff + sizeof(*stuff));
 
-    swapl(&stuff->numSpecs);
     REQUEST_AT_LEAST_SIZE(xXResQueryResourceBytesReq);
+    swapl(&stuff->numSpecs);
     REQUEST_FIXED_SIZE(xXResQueryResourceBytesReq,
                        stuff->numSpecs * sizeof(specs[0]));
 
diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c
index 8a35b7b..4d412b8 100644
--- a/Xext/xvdisp.c
+++ b/Xext/xvdisp.c
@@ -1493,12 +1493,14 @@ XineramaXvShmPutImage(ClientPtr client)
 {
     REQUEST(xvShmPutImageReq);
     PanoramiXRes *draw, *gc, *port;
-    Bool send_event = stuff->send_event;
+    Bool send_event;
     Bool isRoot;
     int result, i, x, y;
 
     REQUEST_SIZE_MATCH(xvShmPutImageReq);
 
+    send_event = stuff->send_event;
+
     result = dixLookupResourceByClass((void **) &draw, stuff->drawable,
                                       XRC_DRAWABLE, client, DixWriteAccess);
     if (result != Success)
diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c
index 1f1022e..63caec9 100644
--- a/hw/dmx/dmxpict.c
+++ b/hw/dmx/dmxpict.c
@@ -716,6 +716,8 @@ dmxProcRenderSetPictureFilter(ClientPtr client)
         filter = (char *) (stuff + 1);
         params = (XFixed *) (filter + ((stuff->nbytes + 3) & ~3));
         nparams = ((XFixed *) stuff + client->req_len) - params;
+        if (nparams < 0)
+            return BadLength;
 
         XRenderSetPictureFilter(dmxScreen->beDisplay,
                                 pPictPriv->pict, filter, params, nparams);
diff --git a/pseudoramiX/pseudoramiX.c b/pseudoramiX/pseudoramiX.c
index d8b2593..95f6e10 100644
--- a/pseudoramiX/pseudoramiX.c
+++ b/pseudoramiX/pseudoramiX.c
@@ -297,10 +297,11 @@ ProcPseudoramiXGetScreenSize(ClientPtr client)
 
     TRACE;
 
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+
     if (stuff->screen >= pseudoramiXNumScreens)
       return BadMatch;
 
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
     if (rc != Success)
         return rc;
diff --git a/render/render.c b/render/render.c
index bfacaa0..3a41e33 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1757,6 +1757,9 @@ ProcRenderSetPictureFilter(ClientPtr client)
     name = (char *) (stuff + 1);
     params = (xFixed *) (name + pad_to_int32(stuff->nbytes));
     nparams = ((xFixed *) stuff + client->req_len) - params;
+    if (nparams < 0)
+	return BadLength;
+
     result = SetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
     return result;
 }
-- 
cgit v0.10.2

