[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'ubuntu-trusty'



 debian/changelog                                                                             |   38 
 debian/patches/CVE-2014-8xxx/0000-glx-check-return.patch                                     |  184 ++
 debian/patches/CVE-2014-8xxx/0000-regionsize-size_t.patch                                    |   31 
 debian/patches/CVE-2014-8xxx/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch |   40 
 debian/patches/CVE-2014-8xxx/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch |   34 
 debian/patches/CVE-2014-8xxx/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch   |   47 
 debian/patches/CVE-2014-8xxx/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch |  125 +
 debian/patches/CVE-2014-8xxx/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch |   34 
 debian/patches/CVE-2014-8xxx/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch |   35 
 debian/patches/CVE-2014-8xxx/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch |   73 
 debian/patches/CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch |  551 ++++++
 debian/patches/CVE-2014-8xxx/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch |   27 
 debian/patches/CVE-2014-8xxx/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch |  176 +
 debian/patches/CVE-2014-8xxx/0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch |   64 
 debian/patches/CVE-2014-8xxx/0012-present-unvalidated-lengths-in-Present-extension-pro.patch |   68 
 debian/patches/CVE-2014-8xxx/0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch |   51 
 debian/patches/CVE-2014-8xxx/0014-render-check-request-size-before-reading-it-CVE-2014.patch |   36 
 debian/patches/CVE-2014-8xxx/0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch |  140 +
 debian/patches/CVE-2014-8xxx/0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch |   27 
 debian/patches/CVE-2014-8xxx/0017-Add-request-length-checking-test-cases-for-some-Xinp.patch |  195 ++
 debian/patches/CVE-2014-8xxx/0018-Add-request-length-checking-test-cases-for-some-Xinp.patch |   86 
 debian/patches/CVE-2014-8xxx/0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch      |   74 
 debian/patches/CVE-2014-8xxx/0020-glx-Be-more-paranoid-about-variable-length-requests-.patch |   44 
 debian/patches/CVE-2014-8xxx/0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch |  165 +
 debian/patches/CVE-2014-8xxx/0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch |   59 
 debian/patches/CVE-2014-8xxx/0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch |   59 
 debian/patches/CVE-2014-8xxx/0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch       |   79 
 debian/patches/CVE-2014-8xxx/0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch |   72 
 debian/patches/CVE-2014-8xxx/0026-glx-Integer-overflow-protection-for-non-generated-re.patch |  225 ++
 debian/patches/CVE-2014-8xxx/0027-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch |  155 +
 debian/patches/CVE-2014-8xxx/0028-glx-Top-level-length-checking-for-swapped-VendorPriv.patch |   51 
 debian/patches/CVE-2014-8xxx/0029-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch |   74 
 debian/patches/CVE-2014-8xxx/0030-glx-Length-checking-for-non-generated-vendor-private.patch |   45 
 debian/patches/CVE-2014-8xxx/0031-glx-Length-checking-for-non-generated-single-request.patch |  561 ++++++
 debian/patches/CVE-2014-8xxx/0032-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch |  913 ++++++++++
 debian/patches/CVE-2014-8xxx/0033-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch |   34 
 debian/patches/CVE-2014-8xxx/0034-CVE-2014-8097-additional.patch                             |   47 
 debian/patches/CVE-2014-8xxx/0035-CVE-2014-8098-additional.patch                             |   36 
 debian/patches/CVE-2014-8xxx/0036-CVE-2014-8092-additional.patch                             |   28 
 debian/patches/CVE-2014-8xxx/0037-CVE-2014-8092-additional-2.patch                           |   29 
 debian/patches/series                                                                        |   41 
 41 files changed, 4853 insertions(+)

New commits:
commit 72ff20cdc71762bc9da451b6a999ef4a64238a8e
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Wed Dec 10 19:10:24 2014 +0200

    release to trusty-proposed

diff --git a/debian/changelog b/debian/changelog
index 5c0d482..74075e3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+xorg-server (2:1.15.1-0ubuntu2.6) trusty-proposed; urgency=medium
+
+  * Re-apply changes between -0u2.1..-0u2.3.
+
+ -- Timo Aaltonen <tjaalton@debian.org>  Wed, 10 Dec 2014 19:06:02 +0200
+
 xorg-server (2:1.15.1-0ubuntu2.5) trusty-security; urgency=medium
 
   * SECURITY UPDATE: Dec 2014 security issues - additional fixes

commit 9ddbe364768127f584e991592eda9b2d072f62a7
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Wed Dec 10 19:05:10 2014 +0200

    import changes from -0ubuntu2.5

diff --git a/debian/changelog b/debian/changelog
index 1c184d2..5c0d482 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,35 @@
+xorg-server (2:1.15.1-0ubuntu2.5) trusty-security; urgency=medium
+
+  * SECURITY UPDATE: Dec 2014 security issues - additional fixes
+    - debian/patches/CVE-2014-8xxx/003[4567]*.patch: add additional
+      fixes not included in original pre-advisory bundle.
+
+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com>  Tue, 09 Dec 2014 17:12:42 -0500
+
+xorg-server (2:1.15.1-0ubuntu2.4) trusty-security; urgency=medium
+
+  * SECURITY UPDATE: Dec 2014 protocol handling security issues
+    - debian/patches/CVE-2014-8xxx/*.patch: patches from upstream to fix
+      a multitude of security issues, including a couple of pre-requisite
+      fixes from git.
+    - CVE-2014-8091
+    - CVE-2014-8092
+    - CVE-2014-8093
+    - CVE-2014-8094
+    - CVE-2014-8095
+    - CVE-2014-8096
+    - CVE-2014-8097
+    - CVE-2014-8098
+    - CVE-2014-8099
+    - CVE-2014-8100
+    - CVE-2014-8101
+    - CVE-2014-8102
+    - CVE-2014-8103
+  * This package does _not_ contain the changes from 2:1.15.1-0ubuntu2.3
+    in trusty-proposed.
+
+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com>  Mon, 08 Dec 2014 15:42:08 -0500
+
 xorg-server (2:1.15.1-0ubuntu2.3) trusty-proposed; urgency=medium
 
   * Actually fix the cirrus VGA corruption in gnome-terminal.
diff --git a/debian/patches/CVE-2014-8xxx/0000-glx-check-return.patch b/debian/patches/CVE-2014-8xxx/0000-glx-check-return.patch
new file mode 100644
index 0000000..a652174
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0000-glx-check-return.patch
@@ -0,0 +1,184 @@
+From 61a292adf45405641de1c522a04c148e0a152acd Mon Sep 17 00:00:00 2001
+From: Keith Packard <keithp@keithp.com>
+Date: Thu, 9 Oct 2014 15:17:17 +0200
+Subject: glx: check return from __glXGetAnswerBuffer
+
+This function can return NULL; make sure every caller tests for that.
+
+Reviewed-by: Adam Jackson <ajax@redhat.com>
+Signed-off-by: Keith Packard <keithp@keithp.com>
+
+diff --git a/glx/indirect_dispatch.c b/glx/indirect_dispatch.c
+index 329b2e6..f6cabef 100644
+--- a/glx/indirect_dispatch.c
++++ b/glx/indirect_dispatch.c
+@@ -2464,6 +2464,9 @@ __glXDisp_AreTexturesResident(__GLXclientState * cl, GLbyte * pc)
+         GLboolean answerBuffer[200];
+         GLboolean *residences =
+             __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1);
++
++        if (residences == NULL)
++            return BadAlloc;
+         retval =
+             glAreTexturesResident(n, (const GLuint *) (pc + 4), residences);
+         __glXSendReply(cl->client, residences, n, 1, GL_TRUE, retval);
+@@ -2488,6 +2491,9 @@ __glXDisp_AreTexturesResidentEXT(__GLXclientState * cl, GLbyte * pc)
+         GLboolean answerBuffer[200];
+         GLboolean *residences =
+             __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1);
++
++        if (residences == NULL)
++            return BadAlloc;
+         retval =
+             glAreTexturesResident(n, (const GLuint *) (pc + 4), residences);
+         __glXSendReply(cl->client, residences, n, 1, GL_TRUE, retval);
+@@ -2593,6 +2599,9 @@ __glXDisp_GenTextures(__GLXclientState * cl, GLbyte * pc)
+         GLuint *textures =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (textures == NULL)
++            return BadAlloc;
+         glGenTextures(n, textures);
+         __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0);
+         error = Success;
+@@ -2616,6 +2625,9 @@ __glXDisp_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc)
+         GLuint *textures =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (textures == NULL)
++            return BadAlloc;
+         glGenTextures(n, textures);
+         __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0);
+         error = Success;
+@@ -3883,6 +3895,9 @@ __glXDisp_GenQueries(__GLXclientState * cl, GLbyte * pc)
+         GLuint *ids =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (ids == NULL)
++            return BadAlloc;
+         GenQueries(n, ids);
+         __glXSendReply(cl->client, ids, n, 4, GL_TRUE, 0);
+         error = Success;
+@@ -4253,6 +4268,9 @@ __glXDisp_GenProgramsARB(__GLXclientState * cl, GLbyte * pc)
+         GLuint *programs =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (programs == NULL)
++            return BadAlloc;
+         GenProgramsARB(n, programs);
+         __glXSendReply(cl->client, programs, n, 4, GL_TRUE, 0);
+         error = Success;
+@@ -4630,6 +4648,10 @@ __glXDisp_GenFramebuffers(__GLXclientState * cl, GLbyte * pc)
+         GLuint *framebuffers =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (framebuffers == NULL)
++            return BadAlloc;
++
+         GenFramebuffers(n, framebuffers);
+         __glXSendReply(cl->client, framebuffers, n, 4, GL_TRUE, 0);
+         error = Success;
+@@ -4655,6 +4677,9 @@ __glXDisp_GenRenderbuffers(__GLXclientState * cl, GLbyte * pc)
+         GLuint *renderbuffers =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (renderbuffers == NULL)
++            return BadAlloc;
+         GenRenderbuffers(n, renderbuffers);
+         __glXSendReply(cl->client, renderbuffers, n, 4, GL_TRUE, 0);
+         error = Success;
+diff --git a/glx/indirect_dispatch_swap.c b/glx/indirect_dispatch_swap.c
+index 647d0c9..c0bb64d 100644
+--- a/glx/indirect_dispatch_swap.c
++++ b/glx/indirect_dispatch_swap.c
+@@ -2731,6 +2731,9 @@ __glXDispSwap_AreTexturesResident(__GLXclientState * cl, GLbyte * pc)
+         GLboolean answerBuffer[200];
+         GLboolean *residences =
+             __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1);
++
++        if (residences == NULL)
++            return BadAlloc;
+         retval =
+             glAreTexturesResident(n,
+                                   (const GLuint *)
+@@ -2759,6 +2762,9 @@ __glXDispSwap_AreTexturesResidentEXT(__GLXclientState * cl, GLbyte * pc)
+         GLboolean answerBuffer[200];
+         GLboolean *residences =
+             __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1);
++
++        if (residences == NULL)
++            return BadAlloc;
+         retval =
+             glAreTexturesResident(n,
+                                   (const GLuint *)
+@@ -2878,6 +2884,9 @@ __glXDispSwap_GenTextures(__GLXclientState * cl, GLbyte * pc)
+         GLuint *textures =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (textures == NULL)
++            return BadAlloc;
+         glGenTextures(n, textures);
+         (void) bswap_32_array((uint32_t *) textures, n);
+         __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0);
+@@ -2903,6 +2912,9 @@ __glXDispSwap_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc)
+         GLuint *textures =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (textures == NULL)
++            return BadAlloc;
+         glGenTextures(n, textures);
+         (void) bswap_32_array((uint32_t *) textures, n);
+         __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0);
+@@ -4290,6 +4302,9 @@ __glXDispSwap_GenQueries(__GLXclientState * cl, GLbyte * pc)
+         GLuint *ids =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++        if (ids == NULL)
++            return BadAlloc;
++
+         GenQueries(n, ids);
+         (void) bswap_32_array((uint32_t *) ids, n);
+         __glXSendReplySwap(cl->client, ids, n, 4, GL_TRUE, 0);
+@@ -4697,6 +4712,9 @@ __glXDispSwap_GenProgramsARB(__GLXclientState * cl, GLbyte * pc)
+         GLuint *programs =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++        if (programs == NULL)
++            return BadAlloc;
++
+         GenProgramsARB(n, programs);
+         (void) bswap_32_array((uint32_t *) programs, n);
+         __glXSendReplySwap(cl->client, programs, n, 4, GL_TRUE, 0);
+@@ -5122,6 +5140,10 @@ __glXDispSwap_GenFramebuffers(__GLXclientState * cl, GLbyte * pc)
+         GLuint *framebuffers =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (framebuffers == NULL)
++            return BadAlloc;
++
+         GenFramebuffers(n, framebuffers);
+         (void) bswap_32_array((uint32_t *) framebuffers, n);
+         __glXSendReplySwap(cl->client, framebuffers, n, 4, GL_TRUE, 0);
+@@ -5149,6 +5171,10 @@ __glXDispSwap_GenRenderbuffers(__GLXclientState * cl, GLbyte * pc)
+         GLuint *renderbuffers =
+             __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer),
+                                  4);
++
++        if (renderbuffers == NULL)
++            return BadAlloc;
++
+         GenRenderbuffers(n, renderbuffers);
+         (void) bswap_32_array((uint32_t *) renderbuffers, n);
+         __glXSendReplySwap(cl->client, renderbuffers, n, 4, GL_TRUE, 0);
+-- 
+cgit v0.10.2
+
diff --git a/debian/patches/CVE-2014-8xxx/0000-regionsize-size_t.patch b/debian/patches/CVE-2014-8xxx/0000-regionsize-size_t.patch
new file mode 100644
index 0000000..12025f6
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0000-regionsize-size_t.patch
@@ -0,0 +1,31 @@
+From 995ecfb51d4ab8197e4591d5c0957e08a0bd6a59 Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Thu, 30 Oct 2014 09:00:21 +1000
+Subject: include: change RegionSize() to take a size_t
+
+/usr/include/xorg/regionstr.h:130:36: warning: implicit conversion changes
+signedness: 'int' to 'unsigned long' [-Wsign-conversion]
+    return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
+                                   ^  ~
+
+Really only just pushes the problem to the caller, but maybe that motivates
+someone to fix it.
+
+Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+diff --git a/include/regionstr.h b/include/regionstr.h
+index 4a0725d..515e93f 100644
+--- a/include/regionstr.h
++++ b/include/regionstr.h
+@@ -125,7 +125,7 @@ RegionEnd(RegionPtr reg)
+ }
+ 
+ static inline size_t
+-RegionSizeof(int n)
++RegionSizeof(size_t n)
+ {
+     return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
+ }
+-- 
+cgit v0.10.2
+
diff --git a/debian/patches/CVE-2014-8xxx/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch b/debian/patches/CVE-2014-8xxx/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch
new file mode 100644
index 0000000..b5fbb7d
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch
@@ -0,0 +1,40 @@
+From d2f5bd2c3e3cbe4778749d457550355d344ca62a Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Fri, 17 Jan 2014 18:54:03 -0800
+Subject: [PATCH 01/33] unchecked malloc may allow unauthed client to crash
+ Xserver [CVE-2014-8091]
+
+authdes_ezdecode() calls malloc() using a length provided by the
+connection handshake sent by a newly connected client in order
+to authenticate to the server, so should be treated as untrusted.
+
+It didn't check if malloc() failed before writing to the newly
+allocated buffer, so could lead to a server crash if the server
+fails to allocate memory (up to UINT16_MAX bytes, since the len
+field is a CARD16 in the X protocol).
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ os/rpcauth.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/os/rpcauth.c b/os/rpcauth.c
+index d60ea35..413cc61 100644
+--- a/os/rpcauth.c
++++ b/os/rpcauth.c
+@@ -66,6 +66,10 @@ authdes_ezdecode(const char *inmsg, int len)
+     SVCXPRT xprt;
+ 
+     temp_inmsg = malloc(len);
++    if (temp_inmsg == NULL) {
++        why = AUTH_FAILED; /* generic error, since there is no AUTH_BADALLOC */
++        return NULL;
++    }
+     memmove(temp_inmsg, inmsg, len);
+ 
+     memset((char *) &msg, 0, sizeof(msg));
+-- 
+1.7.9.2
+
diff --git a/debian/patches/CVE-2014-8xxx/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch b/debian/patches/CVE-2014-8xxx/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch
new file mode 100644
index 0000000..085109a
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch
@@ -0,0 +1,34 @@
+From 7e17b41d2907afd82d668f25694e1da12e34895e Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Wed, 22 Jan 2014 21:11:16 -0800
+Subject: [PATCH 02/33] dix: integer overflow in ProcPutImage() [CVE-2014-8092
+ 1/4]
+
+ProcPutImage() calculates a length field from a width, left pad and depth
+specified by the client (if the specified format is XYPixmap).
+
+The calculations for the total amount of memory the server needs for the
+pixmap can overflow a 32-bit number, causing out-of-bounds memory writes
+on 32-bit systems (since the length is stored in a long int variable).
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ dix/dispatch.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: xorg-server-1.15.1/dix/dispatch.c
+===================================================================
+--- xorg-server-1.15.1.orig/dix/dispatch.c	2014-12-04 11:52:11.007847226 -0500
++++ xorg-server-1.15.1/dix/dispatch.c	2014-12-04 11:52:10.975847036 -0500
+@@ -1957,6 +1957,9 @@
+     tmpImage = (char *) &stuff[1];
+     lengthProto = length;
+ 
++    if (lengthProto >= (INT32_MAX / stuff->height))
++        return BadLength;
++
+     if ((bytes_to_int32(lengthProto * stuff->height) +
+          bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
+         return BadLength;
diff --git a/debian/patches/CVE-2014-8xxx/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch b/debian/patches/CVE-2014-8xxx/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch
new file mode 100644
index 0000000..d5f2d75
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch
@@ -0,0 +1,47 @@
+From 2f605f86acec5ce853f764c41f8c737154a274f5 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Mon, 6 Jan 2014 23:30:14 -0800
+Subject: [PATCH 03/33] dix: integer overflow in GetHosts() [CVE-2014-8092
+ 2/4]
+
+GetHosts() iterates over all the hosts it has in memory, and copies
+them to a buffer. The buffer length is calculated by iterating over
+all the hosts and adding up all of their combined length. There is a
+potential integer overflow, if there are lots and lots of hosts (with
+a combined length of > ~4 gig). This should be possible by repeatedly
+calling ProcChangeHosts() on 64bit machines with enough memory.
+
+This patch caps the list at 1mb, because multi-megabyte hostname
+lists for X access control are insane.
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ os/access.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+Index: xorg-server-1.16.0/os/access.c
+===================================================================
+--- xorg-server-1.16.0.orig/os/access.c	2014-12-04 11:11:43.752542885 -0500
++++ xorg-server-1.16.0/os/access.c	2014-12-04 11:11:43.748542843 -0500
+@@ -1323,6 +1323,10 @@
+     for (host = validhosts; host; host = host->next) {
+         nHosts++;
+         n += pad_to_int32(host->len) + sizeof(xHostEntry);
++        /* Could check for INT_MAX, but in reality having more than 1mb of
++           hostnames in the access list is ridiculous */
++        if (n >= 1048576)
++            break;
+     }
+     if (n) {
+         *data = ptr = malloc(n);
+@@ -1331,6 +1335,8 @@
+         }
+         for (host = validhosts; host; host = host->next) {
+             len = host->len;
++            if ((ptr + sizeof(xHostEntry) + len) > (data + n))
++                break;
+             ((xHostEntry *) ptr)->family = host->family;
+             ((xHostEntry *) ptr)->length = len;
+             ptr += sizeof(xHostEntry);
diff --git a/debian/patches/CVE-2014-8xxx/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch b/debian/patches/CVE-2014-8xxx/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch
new file mode 100644
index 0000000..552bd8b
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch
@@ -0,0 +1,125 @@
+From d7b2f5c06259c7e6ba037909adec4c2a5a8b15ec Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Wed, 22 Jan 2014 22:37:15 -0800
+Subject: [PATCH 04/33] dix: integer overflow in RegionSizeof() [CVE-2014-8092
+ 3/4]
+
+RegionSizeof contains several integer overflows if a large length
+value is passed in.  Once we fix it to return 0 on overflow, we
+also have to fix the callers to handle this error condition
+
+v2: Fixed limit calculation in RegionSizeof as pointed out by jcristau.
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+Reviewed-by: Julien Cristau <jcristau@debian.org>
+---
+ dix/region.c        |   20 +++++++++++++-------
+ include/regionstr.h |   10 +++++++---
+ 2 files changed, 20 insertions(+), 10 deletions(-)
+
+Index: xorg-server-1.15.1/dix/region.c
+===================================================================
+--- xorg-server-1.15.1.orig/dix/region.c	2014-12-05 08:24:42.034665485 -0500
++++ xorg-server-1.15.1/dix/region.c	2014-12-05 08:24:42.030665458 -0500
+@@ -169,7 +169,6 @@
+         ((r1)->y1 <= (r2)->y1) && \
+         ((r1)->y2 >= (r2)->y2) )
+ 
+-#define xallocData(n) malloc(RegionSizeof(n))
+ #define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
+ 
+ #define RECTALLOC_BAIL(pReg,n,bail) \
+@@ -205,8 +204,9 @@
+ #define DOWNSIZE(reg,numRects)						 \
+ if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
+ {									 \
+-    RegDataPtr NewData;							 \
+-    NewData = (RegDataPtr)realloc((reg)->data, RegionSizeof(numRects));	 \
++    size_t NewSize = RegionSizeof(numRects);				 \
++    RegDataPtr NewData =						 \
++        (NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ;		 \
+     if (NewData)							 \
+     {									 \
+ 	NewData->size = (numRects);					 \
+@@ -345,17 +345,20 @@
+ RegionRectAlloc(RegionPtr pRgn, int n)
+ {
+     RegDataPtr data;
++    size_t rgnSize;
+ 
+     if (!pRgn->data) {
+         n++;
+-        pRgn->data = xallocData(n);
++        rgnSize = RegionSizeof(n);
++        pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
+         if (!pRgn->data)
+             return RegionBreak(pRgn);
+         pRgn->data->numRects = 1;
+         *RegionBoxptr(pRgn) = pRgn->extents;
+     }
+     else if (!pRgn->data->size) {
+-        pRgn->data = xallocData(n);
++        rgnSize = RegionSizeof(n);
++        pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
+         if (!pRgn->data)
+             return RegionBreak(pRgn);
+         pRgn->data->numRects = 0;
+@@ -367,7 +370,8 @@
+                 n = 250;
+         }
+         n += pRgn->data->numRects;
+-        data = (RegDataPtr) realloc(pRgn->data, RegionSizeof(n));
++        rgnSize = RegionSizeof(n);
++        data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL;
+         if (!data)
+             return RegionBreak(pRgn);
+         pRgn->data = data;
+@@ -1312,6 +1316,7 @@
+ {
+ 
+     RegionPtr pRgn;
++    size_t rgnSize;
+     RegDataPtr pData;
+     BoxPtr pBox;
+     int i;
+@@ -1338,7 +1343,8 @@
+         }
+         return pRgn;
+     }
+-    pData = xallocData(nrects);
++    rgnSize = RegionSizeof(nrects);
++    pData = (rgnSize > 0) ? malloc(rgnSize) : NULL;
+     if (!pData) {
+         RegionBreak(pRgn);
+         return pRgn;
+Index: xorg-server-1.15.1/include/regionstr.h
+===================================================================
+--- xorg-server-1.15.1.orig/include/regionstr.h	2014-12-05 08:24:42.034665485 -0500
++++ xorg-server-1.15.1/include/regionstr.h	2014-12-05 08:24:42.030665458 -0500
+@@ -127,7 +127,10 @@
+ static inline size_t
+ RegionSizeof(size_t n)
+ {
+-    return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
++    if (n < ((INT_MAX - sizeof(RegDataRec)) / sizeof(BoxRec)))
++        return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
++    else
++        return 0;
+ }
+ 
+ static inline void
+@@ -138,9 +141,10 @@
+         (_pReg)->data = (RegDataPtr) NULL;
+     }
+     else {
++        size_t rgnSize;
+         (_pReg)->extents = RegionEmptyBox;
+-        if (((_size) > 1) && ((_pReg)->data =
+-                              (RegDataPtr) malloc(RegionSizeof(_size)))) {
++        if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) &&
++            (((_pReg)->data = malloc(rgnSize)) != NULL)) {
+             (_pReg)->data->size = (_size);
+             (_pReg)->data->numRects = 0;
+         }
diff --git a/debian/patches/CVE-2014-8xxx/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch b/debian/patches/CVE-2014-8xxx/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch
new file mode 100644
index 0000000..1009488
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch
@@ -0,0 +1,34 @@
+From 7d4f361a216718fc7333ab805dafdb9e5c85c180 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Wed, 22 Jan 2014 23:44:46 -0800
+Subject: [PATCH 05/33] dix: integer overflow in REQUEST_FIXED_SIZE()
+ [CVE-2014-8092 4/4]
+
+Force use of 64-bit integers when evaluating data provided by clients
+in 32-bit fields which can overflow when added or multiplied during
+checks.
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ include/dix.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/dix.h b/include/dix.h
+index 991a3ce..e0c6ed8 100644
+--- a/include/dix.h
++++ b/include/dix.h
+@@ -76,7 +76,8 @@ SOFTWARE.
+ 
+ #define REQUEST_FIXED_SIZE(req, n)\
+     if (((sizeof(req) >> 2) > client->req_len) || \
+-        (((sizeof(req) + (n) + 3) >> 2) != client->req_len)) \
++        ((n >> 2) >= client->req_len) || \
++        ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len))  \
+          return(BadLength)
+ 
+ #define LEGAL_NEW_RESOURCE(id,client)\
+-- 
+1.7.9.2
+
diff --git a/debian/patches/CVE-2014-8xxx/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch b/debian/patches/CVE-2014-8xxx/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch
new file mode 100644
index 0000000..430e956
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch
@@ -0,0 +1,35 @@
+From f07eb544bbcfd9d4c64f036b654f4567f1fd2b9c Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Wed, 22 Jan 2014 23:40:18 -0800
+Subject: [PATCH 06/33] dri2: integer overflow in ProcDRI2GetBuffers()
+ [CVE-2014-8094]
+
+ProcDRI2GetBuffers() tries to validate a length field (count).
+There is an integer overflow in the validation. This can cause
+out of bound reads and memory corruption later on.
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+Reviewed-by: Julien Cristau <jcristau@debian.org>
+---
+ hw/xfree86/dri2/dri2ext.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
+index ffd66fa..221ec53 100644
+--- a/hw/xfree86/dri2/dri2ext.c
++++ b/hw/xfree86/dri2/dri2ext.c
+@@ -270,6 +270,9 @@ ProcDRI2GetBuffers(ClientPtr client)
+     unsigned int *attachments;
+ 
+     REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
++    if (stuff->count > (INT_MAX / 4))
++        return BadLength;
++
+     if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
+                        &pDrawable, &status))
+         return status;
+-- 
+1.7.9.2
+
diff --git a/debian/patches/CVE-2014-8xxx/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch b/debian/patches/CVE-2014-8xxx/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch
new file mode 100644
index 0000000..0167ec0
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch
@@ -0,0 +1,73 @@
+From 0d50f11aa10fe64c74ab7b3c572cc2f3ff583020 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Wed, 22 Jan 2014 23:12:04 -0800
+Subject: [PATCH 07/33] dbe: unvalidated lengths in DbeSwapBuffers calls
+ [CVE-2014-8097]
+
+ProcDbeSwapBuffers() has a 32bit (n) length value that it uses to read
+from a buffer. The length is never validated, which can lead to out of
+bound reads, and possibly returning the data read from out of bounds to
+the misbehaving client via an X Error packet.
+
+SProcDbeSwapBuffers() swaps data (for correct endianness) before
+handing it off to the real proc.  While doing the swapping, the
+length field is not validated, which can cause memory corruption.
+
+v2: reorder checks to avoid compilers optimizing out checks for overflow
+that happen after we'd already have done the overflowing multiplications.
+
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ dbe/dbe.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/dbe/dbe.c b/dbe/dbe.c
+index 527588c..df2ad5c 100644
+--- a/dbe/dbe.c
++++ b/dbe/dbe.c
+@@ -450,18 +450,20 @@ ProcDbeSwapBuffers(ClientPtr client)
+     DbeSwapInfoPtr swapInfo;
+     xDbeSwapInfo *dbeSwapInfo;
+     int error;
+-    register int i, j;
+-    int nStuff;
++    unsigned int i, j;
++    unsigned int nStuff;
+ 
+     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
+     nStuff = stuff->n;          /* use local variable for performance. */
+ 
+     if (nStuff == 0) {
++        REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
+         return Success;
+     }
+ 
+     if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
+         return BadAlloc;
++    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
+ 
+     /* Get to the swap info appended to the end of the request. */
+     dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
+@@ -914,13 +916,16 @@ static int
+ SProcDbeSwapBuffers(ClientPtr client)
+ {
+     REQUEST(xDbeSwapBuffersReq);
+-    register int i;
++    unsigned int i;
+     xDbeSwapInfo *pSwapInfo;
+ 
+     swaps(&stuff->length);
+     REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
+ 
+     swapl(&stuff->n);
++    if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
++        return BadAlloc;
++    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
+ 
+     if (stuff->n != 0) {
+         pSwapInfo = (xDbeSwapInfo *) stuff + 1;
+-- 
+1.7.9.2
+
diff --git a/debian/patches/CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch b/debian/patches/CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch
new file mode 100644
index 0000000..421f070
--- /dev/null
+++ b/debian/patches/CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch
@@ -0,0 +1,551 @@
+From 54fa1f815507cd27280f661be7a64f2f2e6c579e Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Sun, 26 Jan 2014 10:54:41 -0800
+Subject: [PATCH 08/33] Xi: unvalidated lengths in Xinput extension
+ [CVE-2014-8095]
+
+Multiple functions in the Xinput extension handling of requests from
+clients failed to check that the length of the request sent by the
+client was large enough to perform all the required operations and
+thus could read or write to memory outside the bounds of the request
+buffer.
+
+This commit includes the creation of a new REQUEST_AT_LEAST_EXTRA_SIZE
+macro in include/dix.h for the common case of needing to ensure a
+request is large enough to include both the request itself and a
+minimum amount of extra data following the request header.
+
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ Xi/chgdctl.c            |    8 ++++++--
+ Xi/chgfctl.c            |    2 ++
+ Xi/sendexev.c           |    3 +++
+ Xi/xiallowev.c          |    2 ++
+ Xi/xichangecursor.c     |    2 +-
+ Xi/xichangehierarchy.c  |   35 ++++++++++++++++++++++++++++++++---
+ Xi/xigetclientpointer.c |    1 +
+ Xi/xigrabdev.c          |    9 ++++++++-
+ Xi/xipassivegrab.c      |   12 ++++++++++--
+ Xi/xiproperty.c         |   14 ++++++--------
+ Xi/xiquerydevice.c      |    1 +
+ Xi/xiquerypointer.c     |    2 ++
+ Xi/xiselectev.c         |    8 ++++++++
+ Xi/xisetclientpointer.c |    3 ++-
+ Xi/xisetdevfocus.c      |    4 ++++
+ Xi/xiwarppointer.c      |    2 ++
+ include/dix.h           |    4 ++++
+ 17 files changed, 94 insertions(+), 18 deletions(-)
+
+diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c
+index d078aa2..b3ee867 100644
+--- a/Xi/chgdctl.c
++++ b/Xi/chgdctl.c
+@@ -78,7 +78,7 @@ SProcXChangeDeviceControl(ClientPtr client)
+ 
+     REQUEST(xChangeDeviceControlReq);
+     swaps(&stuff->length);
+-    REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
++    REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
+     swaps(&stuff->control);
+     ctl = (xDeviceCtl *) &stuff[1];
+     swaps(&ctl->control);
+@@ -115,7 +115,7 @@ ProcXChangeDeviceControl(ClientPtr client)
+     xDeviceEnableCtl *e;
+ 
+     REQUEST(xChangeDeviceControlReq);
+-    REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
++    REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
+ 
+     len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq));
+     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
+@@ -192,6 +192,10 @@ ProcXChangeDeviceControl(ClientPtr client)
+         break;
+     case DEVICE_ENABLE:
+         e = (xDeviceEnableCtl *) &stuff[1];
++        if ((len != bytes_to_int32(sizeof(xDeviceEnableCtl)))) {
++            ret = BadLength;
++            goto out;
++        }
+ 
+         if (IsXTestDevice(dev, NULL))
+             status = !Success;
+diff --git a/Xi/chgfctl.c b/Xi/chgfctl.c
+index 6dcf60c..224c2ba 100644
+--- a/Xi/chgfctl.c
++++ b/Xi/chgfctl.c
+@@ -467,6 +467,8 @@ ProcXChangeFeedbackControl(ClientPtr client)
+         xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
+ 
+         if (client->swapped) {
++            if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
++                return BadLength;
+             swaps(&f->num_keysyms);
+         }
+         if (len !=
+diff --git a/Xi/sendexev.c b/Xi/sendexev.c
+index 3c21386..183f88d 100644
+--- a/Xi/sendexev.c
++++ b/Xi/sendexev.c
+@@ -135,6 +135,9 @@ ProcXSendExtensionEvent(ClientPtr client)
+     if (ret != Success)
+         return ret;
+ 
++    if (stuff->num_events == 0)
++        return ret;
++
+     /* The client's event type must be one defined by an extension. */
+ 
+     first = ((xEvent *) &stuff[1]);
+diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
+index ebef233..ca263ef 100644
+--- a/Xi/xiallowev.c
++++ b/Xi/xiallowev.c
+@@ -48,6 +48,7 @@ int
+ SProcXIAllowEvents(ClientPtr client)
+ {
+     REQUEST(xXIAllowEventsReq);
++    REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq);
+ 
+     swaps(&stuff->length);
+     swaps(&stuff->deviceid);
+@@ -55,6 +56,7 @@ SProcXIAllowEvents(ClientPtr client)
+     if (stuff->length > 3) {
+         xXI2_2AllowEventsReq *req_xi22 = (xXI2_2AllowEventsReq *) stuff;
+ 
++        REQUEST_AT_LEAST_SIZE(xXI2_2AllowEventsReq);
+         swapl(&req_xi22->touchid);
+         swapl(&req_xi22->grab_window);
+     }
+diff --git a/Xi/xichangecursor.c b/Xi/xichangecursor.c
+index 7a1bb7a..8e6255b 100644
+--- a/Xi/xichangecursor.c
++++ b/Xi/xichangecursor.c
+@@ -57,11 +57,11 @@ int
+ SProcXIChangeCursor(ClientPtr client)
+ {
+     REQUEST(xXIChangeCursorReq);
++    REQUEST_SIZE_MATCH(xXIChangeCursorReq);
+     swaps(&stuff->length);
+     swapl(&stuff->win);
+     swapl(&stuff->cursor);
+     swaps(&stuff->deviceid);
+-    REQUEST_SIZE_MATCH(xXIChangeCursorReq);
+     return (ProcXIChangeCursor(client));
+ }
+ 
+diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
+index 9e36354..2732445 100644
+--- a/Xi/xichangehierarchy.c
++++ b/Xi/xichangehierarchy.c
+@@ -411,7 +411,7 @@ int
+ ProcXIChangeHierarchy(ClientPtr client)
+ {
+     xXIAnyHierarchyChangeInfo *any;
+-    int required_len = sizeof(xXIChangeHierarchyReq);
++    size_t len;			/* length of data remaining in request */
+     int rc = Success;
+     int flags[MAXDEVICES] = { 0 };
+ 
+@@ -421,21 +421,46 @@ ProcXIChangeHierarchy(ClientPtr client)
+     if (!stuff->num_changes)
+         return rc;
+ 
++    if (stuff->length > (INT_MAX >> 2))
++        return BadAlloc;
++    len = (stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo);
++
+     any = (xXIAnyHierarchyChangeInfo *) &stuff[1];
+     while (stuff->num_changes--) {
++        if (len < sizeof(xXIAnyHierarchyChangeInfo)) {
++            rc = BadLength;
++            goto unwind;
++        }
++
+         SWAPIF(swaps(&any->type));
+         SWAPIF(swaps(&any->length));
+ 
+-        required_len += any->length;
+-        if ((stuff->length * 4) < required_len)
++        if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2)))
+             return BadLength;
+ 
++#define CHANGE_SIZE_MATCH(type) \
++    do { \
++        if ((len < sizeof(type)) || (any->length != (sizeof(type) >> 2))) { \
++            rc = BadLength; \
++            goto unwind; \
++        } \
++    } while(0)
++
+         switch (any->type) {
+         case XIAddMaster:
+         {
+             xXIAddMasterInfo *c = (xXIAddMasterInfo *) any;
+ 
++            /* Variable length, due to appended name string */
++            if (len < sizeof(xXIAddMasterInfo)) {
++                rc = BadLength;
++                goto unwind;
++            }
+             SWAPIF(swaps(&c->name_len));
++            if (c->name_len > (len - sizeof(xXIAddMasterInfo))) {
++                rc = BadLength;
++                goto unwind;
++            }
+ 
+             rc = add_master(client, c, flags);
+             if (rc != Success)
+@@ -446,6 +471,7 @@ ProcXIChangeHierarchy(ClientPtr client)
+         {
+             xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
+ 
++            CHANGE_SIZE_MATCH(xXIRemoveMasterInfo);
+             rc = remove_master(client, r, flags);
+             if (rc != Success)
+                 goto unwind;
+@@ -455,6 +481,7 @@ ProcXIChangeHierarchy(ClientPtr client)
+         {
+             xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
+ 
++            CHANGE_SIZE_MATCH(xXIDetachSlaveInfo);
+             rc = detach_slave(client, c, flags);
+             if (rc != Success)
+                 goto unwind;
+@@ -464,6 +491,7 @@ ProcXIChangeHierarchy(ClientPtr client)
+         {
+             xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
+ 
++            CHANGE_SIZE_MATCH(xXIAttachSlaveInfo);
+             rc = attach_slave(client, c, flags);
+             if (rc != Success)
+                 goto unwind;
+@@ -471,6 +499,7 @@ ProcXIChangeHierarchy(ClientPtr client)
+             break;
+         }
+ 


Reply to: