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 <tjaal...@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 <tjaal...@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 <tjaal...@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.deslauri...@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.deslauri...@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 <kei...@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 <a...@redhat.com> +Signed-off-by: Keith Packard <kei...@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.hutte...@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.hutte...@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.coopersm...@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 <ivansprun...@ioactive.com> +Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@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.coopersm...@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 <ivansprun...@ioactive.com> +Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@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.coopersm...@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 <ivansprun...@ioactive.com> +Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@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.coopersm...@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 <ivansprun...@ioactive.com> +Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net> +Reviewed-by: Julien Cristau <jcris...@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.coopersm...@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 <ivansprun...@ioactive.com> +Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@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.coopersm...@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 <ivansprun...@ioactive.com> +Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net> +Reviewed-by: Julien Cristau <jcris...@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.coopersm...@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 <ivansprun...@ioactive.com> +Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@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.coopersm...@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.coopersm...@oracle.com> +Reviewed-by: Peter Hutterer <peter.hutte...@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; + } + -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/e1xyknh-00065r...@moszumanska.debian.org