diff -u xorg-server-1.15.1/debian/changelog xorg-server-1.15.1/debian/changelog --- xorg-server-1.15.1/debian/changelog +++ xorg-server-1.15.1/debian/changelog @@ -1,3 +1,113 @@ +xorg-server (2:1.15.1-0ubuntu2.8) trusty; urgency=medium + + [ Krzysztof Okupski ] + * Fixed bug related to screen freezes when using touchpad. (LP: #1220426) + + -- Krzysztof Okupski Sun, 03 Jan 2016 20:34:52 +0100 + +xorg-server (2:1.15.1-0ubuntu2.7) trusty-security; urgency=medium + + * SECURITY UPDATE: information leak and denial of service in + XkbSetGeometry + - debian/patches/CVE-2015-0255.patch: properly check lengths in + xkb/xkb.c. + - CVE-2015-0255 + * debian/patches/CVE-2014-8xxx/0038-CVE-2014-8092-*: fix regression in + previous security update by allowing zero-height PutImage requests in + dix/dispatch.c. + + -- Marc Deslauriers Thu, 12 Feb 2015 08:42:55 -0500 + +xorg-server (2:1.15.1-0ubuntu2.6) trusty-proposed; urgency=medium + + [ Laércio de Sousa ] + * Backport support for logind-based multiseat back to trusty. (LP: #1209008) + + [ Maarten Lankhorst ] + * Re-enable support for rotation and transforms on gpu-screens with support. + - Allows re-enabling intel SNA rotation after fixing it. (LP: #1386620) + * Fix black screen when using qemu with cirrus vga. + - fb-24-depth.patch (LP: #1318119) + + -- Maarten Lankhorst Mon, 03 Nov 2014 12:36:32 +0100 + +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 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 Mon, 08 Dec 2014 15:42:08 -0500 + +xorg-server (2:1.15.1-0ubuntu2.1) trusty-proposed; urgency=medium + + * Copy utopic package back to trusty. + - Fix ppc64el byte order. (LP: #1333422) + + xi-dont-copy-too-much.patch + - Fix valgrind issue with xi copying too much. + + xi-dont-copy-too-much.patch + - Fix crash related to suspend/shutdown. (LP: #1208473) + + mi-dont-process-disabled.patch + - Fix touch event history overflow. + + xi2-resize-touch.patch + - Fix switching to guest sessions. (LP: #1322212) + + Revive drm_device_keep_trying.patch + + -- Maarten Lankhorst Wed, 02 Jul 2014 12:37:25 +0200 + +xorg-server (2:1.15.1-0ubuntu6) utopic; urgency=medium + + * ppc64el-endian-fix.patch: Fix PPC endian assumptions (LP: #1333422) + + -- Adam Conrad Mon, 23 Jun 2014 23:47:15 -0600 + +xorg-server (2:1.15.1-0ubuntu5) utopic; urgency=low + + * Add upstream patch to fix some valgrind issues. + - xi-dont-copy-too-much.patch + * Fix crash related to suspend/shutdown. (LP: #1208473) + - mi-dont-process-disabled.patch + + -- Maarten Lankhorst Tue, 20 May 2014 11:32:41 +0200 + +xorg-server (2:1.15.1-0ubuntu4) utopic; urgency=low + + * Resize touch event history if the array is filled up. + - xi2-resize-touch.patch + + -- Maarten Lankhorst Wed, 07 May 2014 13:52:59 +0200 + +xorg-server (2:1.15.1-0ubuntu3) utopic; urgency=medium + + * Revive the old drm_device_keep_trying.patch. + - Removing the call to get_drm_info fixes switching to guest sessions. + + -- Maarten Lankhorst Mon, 28 Apr 2014 10:06:21 +0200 + xorg-server (2:1.15.1-0ubuntu2) trusty; urgency=medium * Disable support for rotations and transforms diff -u xorg-server-1.15.1/debian/patches/series xorg-server-1.15.1/debian/patches/series --- xorg-server-1.15.1/debian/patches/series +++ xorg-server-1.15.1/debian/patches/series @@ -53,0 +54,54 @@ +drm_device_keep_trying.patch +xi2-resize-touch.patch +xi-dont-copy-too-much.patch +mi-dont-process-disabled.patch +ppc64el-endian-fix.patch +xfree86_allow_fallback_to_pci_bus_probe_for_non_seat0.patch +xfree86_keep_non_seat0_from_touching_vts.patch +xfree86_add_matchseat_key_to_xorg_conf.patch +xfree86_add_matchseat_key_description_to_xorg_conf_man.patch +rotation-slaved-crtc-bounds.patch +fb-24-depth.patch + +# CVE-2014-8095 to CVE-2014-8103 +CVE-2014-8xxx/0000-glx-check-return.patch +CVE-2014-8xxx/0000-regionsize-size_t.patch +CVE-2014-8xxx/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch +CVE-2014-8xxx/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch +CVE-2014-8xxx/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch +CVE-2014-8xxx/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch +CVE-2014-8xxx/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch +CVE-2014-8xxx/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch +CVE-2014-8xxx/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch +CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch +CVE-2014-8xxx/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch +CVE-2014-8xxx/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch +CVE-2014-8xxx/0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch +CVE-2014-8xxx/0012-present-unvalidated-lengths-in-Present-extension-pro.patch +CVE-2014-8xxx/0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch +CVE-2014-8xxx/0014-render-check-request-size-before-reading-it-CVE-2014.patch +CVE-2014-8xxx/0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch +CVE-2014-8xxx/0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch +CVE-2014-8xxx/0017-Add-request-length-checking-test-cases-for-some-Xinp.patch +CVE-2014-8xxx/0018-Add-request-length-checking-test-cases-for-some-Xinp.patch +CVE-2014-8xxx/0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch +CVE-2014-8xxx/0020-glx-Be-more-paranoid-about-variable-length-requests-.patch +CVE-2014-8xxx/0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch +CVE-2014-8xxx/0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch +CVE-2014-8xxx/0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch +CVE-2014-8xxx/0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch +CVE-2014-8xxx/0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch +CVE-2014-8xxx/0026-glx-Integer-overflow-protection-for-non-generated-re.patch +CVE-2014-8xxx/0027-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch +CVE-2014-8xxx/0028-glx-Top-level-length-checking-for-swapped-VendorPriv.patch +CVE-2014-8xxx/0029-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch +CVE-2014-8xxx/0030-glx-Length-checking-for-non-generated-vendor-private.patch +CVE-2014-8xxx/0031-glx-Length-checking-for-non-generated-single-request.patch +CVE-2014-8xxx/0032-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch +CVE-2014-8xxx/0033-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch +CVE-2014-8xxx/0034-CVE-2014-8097-additional.patch +CVE-2014-8xxx/0035-CVE-2014-8098-additional.patch +CVE-2014-8xxx/0036-CVE-2014-8092-additional.patch +CVE-2014-8xxx/0037-CVE-2014-8092-additional-2.patch +CVE-2014-8xxx/0038-CVE-2014-8092-dix-allow-zero-height-putimage-requests.patch +CVE-2015-0255.patch diff -u xorg-server-1.15.1/debian/patches/disable-rotation-transform-gpuscreens.patch xorg-server-1.15.1/debian/patches/disable-rotation-transform-gpuscreens.patch --- xorg-server-1.15.1/debian/patches/disable-rotation-transform-gpuscreens.patch +++ xorg-server-1.15.1/debian/patches/disable-rotation-transform-gpuscreens.patch @@ -1,22 +1,13 @@ ---- a/hw/xfree86/modes/xf86RandR12.c -+++ b/hw/xfree86/modes/xf86RandR12.c -@@ -932,6 +932,9 @@ - if (xf86RandR12Key == NULL) - return; - -+ if (pScreen->isGPU) -+ rotations = RR_Rotate_0; -+ - randrp = XF86RANDRINFO(pScreen); - #if RANDR_12_INTERFACE - for (c = 0; c < config->num_crtc; c++) { -@@ -954,6 +957,9 @@ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - #endif - -+ if (pScreen->isGPU) -+ transforms = FALSE; -+ - if (xf86RandR12Key == NULL) - return; - +diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c +index a441fd1..9147a26 100644 +--- a/hw/xfree86/modes/xf86Crtc.c ++++ b/hw/xfree86/modes/xf86Crtc.c +@@ -778,7 +778,7 @@ xf86CrtcScreenInit(ScreenPtr screen) + if (!crtc->funcs->shadow_allocate || !crtc->funcs->shadow_create) + break; + } +- if (c == config->num_crtc) { ++ if (c == config->num_crtc && !screen->isGPU) { + xf86RandR12SetRotations(screen, RR_Rotate_0 | RR_Rotate_90 | + RR_Rotate_180 | RR_Rotate_270 | + RR_Reflect_X | RR_Reflect_Y); only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0000-glx-check-return.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Keith Packard + +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 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0000-regionsize-size_t.patch +++ xorg-server-1.15.1/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 +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 + +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 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + 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 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + 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; only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + 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); only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Reviewed-by: Julien Cristau +--- + 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; + } only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + 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 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Reviewed-by: Julien Cristau +--- + 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 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch +++ xorg-server-1.15.1/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 +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 +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + 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 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch +++ xorg-server-1.15.1/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 +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 +Reviewed-by: Peter Hutterer +--- + 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; + } + ++ len -= any->length * 4; + any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4); + } + +diff --git a/Xi/xigetclientpointer.c b/Xi/xigetclientpointer.c +index 3c90d58..306dd39 100644 +--- a/Xi/xigetclientpointer.c ++++ b/Xi/xigetclientpointer.c +@@ -50,6 +50,7 @@ int + SProcXIGetClientPointer(ClientPtr client) + { + REQUEST(xXIGetClientPointerReq); ++ REQUEST_SIZE_MATCH(xXIGetClientPointerReq); + + swaps(&stuff->length); + swapl(&stuff->win); +diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c +index 63d95bc..e2a2ae3 100644 +--- a/Xi/xigrabdev.c ++++ b/Xi/xigrabdev.c +@@ -47,6 +47,11 @@ int + SProcXIGrabDevice(ClientPtr client) + { + REQUEST(xXIGrabDeviceReq); ++ /* ++ * Check here for at least the length of the struct we swap, then ++ * let ProcXIGrabDevice check the full size after we swap mask_len. ++ */ ++ REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -71,7 +76,7 @@ ProcXIGrabDevice(ClientPtr client) + unsigned int pointer_mode; + + REQUEST(xXIGrabDeviceReq); +- REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); ++ REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4); + + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); + if (ret != Success) +@@ -131,6 +136,7 @@ int + SProcXIUngrabDevice(ClientPtr client) + { + REQUEST(xXIUngrabDeviceReq); ++ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -148,6 +154,7 @@ ProcXIUngrabDevice(ClientPtr client) + TimeStamp time; + + REQUEST(xXIUngrabDeviceReq); ++ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq); + + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (ret != Success) +diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c +index 700622d..9241ffd 100644 +--- a/Xi/xipassivegrab.c ++++ b/Xi/xipassivegrab.c +@@ -53,6 +53,7 @@ SProcXIPassiveGrabDevice(ClientPtr client) + uint32_t *mods; + + REQUEST(xXIPassiveGrabDeviceReq); ++ REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -63,6 +64,8 @@ SProcXIPassiveGrabDevice(ClientPtr client) + swaps(&stuff->mask_len); + swaps(&stuff->num_modifiers); + ++ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, ++ ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4); + mods = (uint32_t *) &stuff[1] + stuff->mask_len; + + for (i = 0; i < stuff->num_modifiers; i++, mods++) { +@@ -92,7 +95,8 @@ ProcXIPassiveGrabDevice(ClientPtr client) + int mask_len; + + REQUEST(xXIPassiveGrabDeviceReq); +- REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq); ++ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, ++ ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4); + + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; +@@ -252,6 +256,7 @@ SProcXIPassiveUngrabDevice(ClientPtr client) + uint32_t *modifiers; + + REQUEST(xXIPassiveUngrabDeviceReq); ++ REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); + + swaps(&stuff->length); + swapl(&stuff->grab_window); +@@ -259,6 +264,8 @@ SProcXIPassiveUngrabDevice(ClientPtr client) + swapl(&stuff->detail); + swaps(&stuff->num_modifiers); + ++ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq, ++ ((uint32_t) stuff->num_modifiers) << 2); + modifiers = (uint32_t *) &stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) +@@ -277,7 +284,8 @@ ProcXIPassiveUngrabDevice(ClientPtr client) + int i, rc; + + REQUEST(xXIPassiveUngrabDeviceReq); +- REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); ++ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq, ++ ((uint32_t) stuff->num_modifiers) << 2); + + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; +diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c +index 463607d..8e8e4b0 100644 +--- a/Xi/xiproperty.c ++++ b/Xi/xiproperty.c +@@ -1013,10 +1013,9 @@ int + SProcXListDeviceProperties(ClientPtr client) + { + REQUEST(xListDevicePropertiesReq); ++ REQUEST_SIZE_MATCH(xListDevicePropertiesReq); + + swaps(&stuff->length); +- +- REQUEST_SIZE_MATCH(xListDevicePropertiesReq); + return (ProcXListDeviceProperties(client)); + } + +@@ -1037,10 +1036,10 @@ int + SProcXDeleteDeviceProperty(ClientPtr client) + { + REQUEST(xDeleteDevicePropertyReq); ++ REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq); + + swaps(&stuff->length); + swapl(&stuff->property); +- REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq); + return (ProcXDeleteDeviceProperty(client)); + } + +@@ -1048,13 +1047,13 @@ int + SProcXGetDeviceProperty(ClientPtr client) + { + REQUEST(xGetDevicePropertyReq); ++ REQUEST_SIZE_MATCH(xGetDevicePropertyReq); + + swaps(&stuff->length); + swapl(&stuff->property); + swapl(&stuff->type); + swapl(&stuff->longOffset); + swapl(&stuff->longLength); +- REQUEST_SIZE_MATCH(xGetDevicePropertyReq); + return (ProcXGetDeviceProperty(client)); + } + +@@ -1253,11 +1252,10 @@ int + SProcXIListProperties(ClientPtr client) + { + REQUEST(xXIListPropertiesReq); ++ REQUEST_SIZE_MATCH(xXIListPropertiesReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +- +- REQUEST_SIZE_MATCH(xXIListPropertiesReq); + return (ProcXIListProperties(client)); + } + +@@ -1279,11 +1277,11 @@ int + SProcXIDeleteProperty(ClientPtr client) + { + REQUEST(xXIDeletePropertyReq); ++ REQUEST_SIZE_MATCH(xXIDeletePropertyReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); + swapl(&stuff->property); +- REQUEST_SIZE_MATCH(xXIDeletePropertyReq); + return (ProcXIDeleteProperty(client)); + } + +@@ -1291,6 +1289,7 @@ int + SProcXIGetProperty(ClientPtr client) + { + REQUEST(xXIGetPropertyReq); ++ REQUEST_SIZE_MATCH(xXIGetPropertyReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -1298,7 +1297,6 @@ SProcXIGetProperty(ClientPtr client) + swapl(&stuff->type); + swapl(&stuff->offset); + swapl(&stuff->len); +- REQUEST_SIZE_MATCH(xXIGetPropertyReq); + return (ProcXIGetProperty(client)); + } + +diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c +index 4e544f0..67a9a4f 100644 +--- a/Xi/xiquerydevice.c ++++ b/Xi/xiquerydevice.c +@@ -54,6 +54,7 @@ int + SProcXIQueryDevice(ClientPtr client) + { + REQUEST(xXIQueryDeviceReq); ++ REQUEST_SIZE_MATCH(xXIQueryDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c +index e9bdd42..7ec0c85 100644 +--- a/Xi/xiquerypointer.c ++++ b/Xi/xiquerypointer.c +@@ -63,6 +63,8 @@ int + SProcXIQueryPointer(ClientPtr client) + { + REQUEST(xXIQueryPointerReq); ++ REQUEST_SIZE_MATCH(xXIQueryPointerReq); ++ + swaps(&stuff->length); + swaps(&stuff->deviceid); + swapl(&stuff->win); +diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c +index 45a996e..168579f 100644 +--- a/Xi/xiselectev.c ++++ b/Xi/xiselectev.c +@@ -114,6 +114,7 @@ int + SProcXISelectEvents(ClientPtr client) + { + int i; ++ int len; + xXIEventMask *evmask; + + REQUEST(xXISelectEventsReq); +@@ -122,10 +123,17 @@ SProcXISelectEvents(ClientPtr client) + swapl(&stuff->win); + swaps(&stuff->num_masks); + ++ len = stuff->length - bytes_to_int32(sizeof(xXISelectEventsReq)); + evmask = (xXIEventMask *) &stuff[1]; + for (i = 0; i < stuff->num_masks; i++) { ++ if (len < bytes_to_int32(sizeof(xXIEventMask))) ++ return BadLength; ++ len -= bytes_to_int32(sizeof(xXIEventMask)); + swaps(&evmask->deviceid); + swaps(&evmask->mask_len); ++ if (len < evmask->mask_len) ++ return BadLength; ++ len -= evmask->mask_len; + evmask = + (xXIEventMask *) (((char *) &evmask[1]) + evmask->mask_len * 4); + } +diff --git a/Xi/xisetclientpointer.c b/Xi/xisetclientpointer.c +index 38ff51e..24d4a53 100644 +--- a/Xi/xisetclientpointer.c ++++ b/Xi/xisetclientpointer.c +@@ -51,10 +51,11 @@ int + SProcXISetClientPointer(ClientPtr client) + { + REQUEST(xXISetClientPointerReq); ++ REQUEST_SIZE_MATCH(xXISetClientPointerReq); ++ + swaps(&stuff->length); + swapl(&stuff->win); + swaps(&stuff->deviceid); +- REQUEST_SIZE_MATCH(xXISetClientPointerReq); + return (ProcXISetClientPointer(client)); + } + +diff --git a/Xi/xisetdevfocus.c b/Xi/xisetdevfocus.c +index 372ec24..96a9a16 100644 +--- a/Xi/xisetdevfocus.c ++++ b/Xi/xisetdevfocus.c +@@ -44,6 +44,8 @@ int + SProcXISetFocus(ClientPtr client) + { + REQUEST(xXISetFocusReq); ++ REQUEST_AT_LEAST_SIZE(xXISetFocusReq); ++ + swaps(&stuff->length); + swaps(&stuff->deviceid); + swapl(&stuff->focus); +@@ -56,6 +58,8 @@ int + SProcXIGetFocus(ClientPtr client) + { + REQUEST(xXIGetFocusReq); ++ REQUEST_AT_LEAST_SIZE(xXIGetFocusReq); ++ + swaps(&stuff->length); + swaps(&stuff->deviceid); + +diff --git a/Xi/xiwarppointer.c b/Xi/xiwarppointer.c +index 3f051f7..780758a 100644 +--- a/Xi/xiwarppointer.c ++++ b/Xi/xiwarppointer.c +@@ -56,6 +56,8 @@ int + SProcXIWarpPointer(ClientPtr client) + { + REQUEST(xXIWarpPointerReq); ++ REQUEST_SIZE_MATCH(xXIWarpPointerReq); ++ + swaps(&stuff->length); + swapl(&stuff->src_win); + swapl(&stuff->dst_win); +diff --git a/include/dix.h b/include/dix.h +index e0c6ed8..21176a8 100644 +--- a/include/dix.h ++++ b/include/dix.h +@@ -74,6 +74,10 @@ SOFTWARE. + if ((sizeof(req) >> 2) > client->req_len )\ + return(BadLength) + ++#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \ ++ if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \ ++ return(BadLength) ++ + #define REQUEST_FIXED_SIZE(req, n)\ + if (((sizeof(req) >> 2) > client->req_len) || \ + ((n >> 2) >= client->req_len) || \ +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch @@ -0,0 +1,27 @@ +From 5fdc679e24abb348014164bf53b82a884a5b380d Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 17:18:54 -0800 +Subject: [PATCH 09/33] xcmisc: unvalidated length in SProcXCMiscGetXIDList() + [CVE-2014-8096] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + Xext/xcmisc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Xext/xcmisc.c b/Xext/xcmisc.c +index 034bfb6..1e91010 100644 +--- a/Xext/xcmisc.c ++++ b/Xext/xcmisc.c +@@ -167,6 +167,7 @@ static int + SProcXCMiscGetXIDList(ClientPtr client) + { + REQUEST(xXCMiscGetXIDListReq); ++ REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq); + + swaps(&stuff->length); + swapl(&stuff->count); +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch @@ -0,0 +1,176 @@ +From 362ea7ec75543b694ebc8ab7268a2402e80a10bd Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:23:17 -0800 +Subject: [PATCH 10/33] Xv: unvalidated lengths in XVideo extension swapped + procs [CVE-2014-8099] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + Xext/xvdisp.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +Index: xorg-server-1.16.0/Xext/xvdisp.c +=================================================================== +--- xorg-server-1.16.0.orig/Xext/xvdisp.c 2014-12-04 11:15:10.726714736 -0500 ++++ xorg-server-1.16.0/Xext/xvdisp.c 2014-12-04 11:15:10.722714693 -0500 +@@ -1207,6 +1207,7 @@ + SProcXvQueryExtension(ClientPtr client) + { + REQUEST(xvQueryExtensionReq); ++ REQUEST_SIZE_MATCH(xvQueryExtensionReq); + swaps(&stuff->length); + return XvProcVector[xv_QueryExtension] (client); + } +@@ -1215,6 +1216,7 @@ + SProcXvQueryAdaptors(ClientPtr client) + { + REQUEST(xvQueryAdaptorsReq); ++ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); + swaps(&stuff->length); + swapl(&stuff->window); + return XvProcVector[xv_QueryAdaptors] (client); +@@ -1224,6 +1226,7 @@ + SProcXvQueryEncodings(ClientPtr client) + { + REQUEST(xvQueryEncodingsReq); ++ REQUEST_SIZE_MATCH(xvQueryEncodingsReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_QueryEncodings] (client); +@@ -1233,6 +1236,7 @@ + SProcXvGrabPort(ClientPtr client) + { + REQUEST(xvGrabPortReq); ++ REQUEST_SIZE_MATCH(xvGrabPortReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->time); +@@ -1243,6 +1247,7 @@ + SProcXvUngrabPort(ClientPtr client) + { + REQUEST(xvUngrabPortReq); ++ REQUEST_SIZE_MATCH(xvUngrabPortReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->time); +@@ -1253,6 +1258,7 @@ + SProcXvPutVideo(ClientPtr client) + { + REQUEST(xvPutVideoReq); ++ REQUEST_SIZE_MATCH(xvPutVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1272,6 +1278,7 @@ + SProcXvPutStill(ClientPtr client) + { + REQUEST(xvPutStillReq); ++ REQUEST_SIZE_MATCH(xvPutStillReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1291,6 +1298,7 @@ + SProcXvGetVideo(ClientPtr client) + { + REQUEST(xvGetVideoReq); ++ REQUEST_SIZE_MATCH(xvGetVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1310,6 +1318,7 @@ + SProcXvGetStill(ClientPtr client) + { + REQUEST(xvGetStillReq); ++ REQUEST_SIZE_MATCH(xvGetStillReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1329,6 +1338,7 @@ + SProcXvPutImage(ClientPtr client) + { + REQUEST(xvPutImageReq); ++ REQUEST_AT_LEAST_SIZE(xvPutImageReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1352,6 +1362,7 @@ + SProcXvShmPutImage(ClientPtr client) + { + REQUEST(xvShmPutImageReq); ++ REQUEST_SIZE_MATCH(xvShmPutImageReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1379,6 +1390,7 @@ + SProcXvSelectVideoNotify(ClientPtr client) + { + REQUEST(xvSelectVideoNotifyReq); ++ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); + swaps(&stuff->length); + swapl(&stuff->drawable); + return XvProcVector[xv_SelectVideoNotify] (client); +@@ -1388,6 +1400,7 @@ + SProcXvSelectPortNotify(ClientPtr client) + { + REQUEST(xvSelectPortNotifyReq); ++ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_SelectPortNotify] (client); +@@ -1397,6 +1410,7 @@ + SProcXvStopVideo(ClientPtr client) + { + REQUEST(xvStopVideoReq); ++ REQUEST_SIZE_MATCH(xvStopVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1407,6 +1421,7 @@ + SProcXvSetPortAttribute(ClientPtr client) + { + REQUEST(xvSetPortAttributeReq); ++ REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->attribute); +@@ -1418,6 +1433,7 @@ + SProcXvGetPortAttribute(ClientPtr client) + { + REQUEST(xvGetPortAttributeReq); ++ REQUEST_SIZE_MATCH(xvGetPortAttributeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->attribute); +@@ -1428,6 +1444,7 @@ + SProcXvQueryBestSize(ClientPtr client) + { + REQUEST(xvQueryBestSizeReq); ++ REQUEST_SIZE_MATCH(xvQueryBestSizeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swaps(&stuff->vid_w); +@@ -1441,6 +1458,7 @@ + SProcXvQueryPortAttributes(ClientPtr client) + { + REQUEST(xvQueryPortAttributesReq); ++ REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_QueryPortAttributes] (client); +@@ -1450,6 +1468,7 @@ + SProcXvQueryImageAttributes(ClientPtr client) + { + REQUEST(xvQueryImageAttributesReq); ++ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->id); +@@ -1462,6 +1481,7 @@ + SProcXvListImageFormats(ClientPtr client) + { + REQUEST(xvListImageFormatsReq); ++ REQUEST_SIZE_MATCH(xvListImageFormatsReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_ListImageFormats] (client); only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch @@ -0,0 +1,64 @@ +From 45000a2286023e2307fda53e602ab24afd2193be Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:28:05 -0800 +Subject: [PATCH 11/33] dri3: unvalidated lengths in DRI3 extension swapped + procs [CVE-2014-8103 1/2] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + dri3/dri3_request.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: xorg-server-1.15.1/dri3/dri3_request.c +=================================================================== +--- xorg-server-1.15.1.orig/dri3/dri3_request.c 2014-12-04 11:53:23.380277861 -0500 ++++ xorg-server-1.15.1/dri3/dri3_request.c 2014-12-04 11:53:23.376277836 -0500 +@@ -311,6 +311,7 @@ + sproc_dri3_query_version(ClientPtr client) + { + REQUEST(xDRI3QueryVersionReq); ++ REQUEST_SIZE_MATCH(xDRI3QueryVersionReq); + + swaps(&stuff->length); + swapl(&stuff->majorVersion); +@@ -322,6 +323,7 @@ + sproc_dri3_open(ClientPtr client) + { + REQUEST(xDRI3OpenReq); ++ REQUEST_SIZE_MATCH(xDRI3OpenReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); +@@ -333,6 +335,7 @@ + sproc_dri3_pixmap_from_buffer(ClientPtr client) + { + REQUEST(xDRI3PixmapFromBufferReq); ++ REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq); + + swaps(&stuff->length); + swapl(&stuff->pixmap); +@@ -348,6 +351,7 @@ + sproc_dri3_buffer_from_pixmap(ClientPtr client) + { + REQUEST(xDRI3BufferFromPixmapReq); ++ REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq); + + swaps(&stuff->length); + swapl(&stuff->pixmap); +@@ -358,6 +362,7 @@ + sproc_dri3_fence_from_fd(ClientPtr client) + { + REQUEST(xDRI3FenceFromFDReq); ++ REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); +@@ -369,6 +374,7 @@ + sproc_dri3_fd_from_fence(ClientPtr client) + { + REQUEST(xDRI3FDFromFenceReq); ++ REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0012-present-unvalidated-lengths-in-Present-extension-pro.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0012-present-unvalidated-lengths-in-Present-extension-pro.patch @@ -0,0 +1,68 @@ +From e4bde707b4972a03ffc7737bb8e70eed830670ca Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:33:34 -0800 +Subject: [PATCH 12/33] present: unvalidated lengths in Present extension + procs [CVE-2014-8103 2/2] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Reviewed-by: Julien Cristau +--- + present/present_request.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/present/present_request.c b/present/present_request.c +index 835890d..7c53e72 100644 +--- a/present/present_request.c ++++ b/present/present_request.c +@@ -210,6 +210,7 @@ proc_present_query_capabilities (ClientPtr client) + RRCrtcPtr crtc = NULL; + int r; + ++ REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq); + r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess); + switch (r) { + case Success: +@@ -254,6 +255,7 @@ static int + sproc_present_query_version(ClientPtr client) + { + REQUEST(xPresentQueryVersionReq); ++ REQUEST_SIZE_MATCH(xPresentQueryVersionReq); + + swaps(&stuff->length); + swapl(&stuff->majorVersion); +@@ -265,6 +267,7 @@ static int + sproc_present_pixmap(ClientPtr client) + { + REQUEST(xPresentPixmapReq); ++ REQUEST_AT_LEAST_SIZE(xPresentPixmapReq); + + swaps(&stuff->length); + swapl(&stuff->window); +@@ -284,6 +287,7 @@ static int + sproc_present_notify_msc(ClientPtr client) + { + REQUEST(xPresentNotifyMSCReq); ++ REQUEST_SIZE_MATCH(xPresentNotifyMSCReq); + + swaps(&stuff->length); + swapl(&stuff->window); +@@ -297,6 +301,7 @@ static int + sproc_present_select_input (ClientPtr client) + { + REQUEST(xPresentSelectInputReq); ++ REQUEST_SIZE_MATCH(xPresentSelectInputReq); + + swaps(&stuff->length); + swapl(&stuff->window); +@@ -308,6 +313,7 @@ static int + sproc_present_query_capabilities (ClientPtr client) + { + REQUEST(xPresentQueryCapabilitiesReq); ++ REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq); + swaps(&stuff->length); + swapl(&stuff->target); + return (*proc_present_vector[stuff->presentReqType]) (client); +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch @@ -0,0 +1,51 @@ +From 1322c6ce2a64ca3290ec76144d8443dec50f2183 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:38:09 -0800 +Subject: [PATCH 13/33] randr: unvalidated lengths in RandR extension swapped + procs [CVE-2014-8101] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + randr/rrsdispatch.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c +index 08c3b6a..47558cf 100644 +--- a/randr/rrsdispatch.c ++++ b/randr/rrsdispatch.c +@@ -27,6 +27,7 @@ SProcRRQueryVersion(ClientPtr client) + { + REQUEST(xRRQueryVersionReq); + ++ REQUEST_SIZE_MATCH(xRRQueryVersionReq); + swaps(&stuff->length); + swapl(&stuff->majorVersion); + swapl(&stuff->minorVersion); +@@ -38,6 +39,7 @@ SProcRRGetScreenInfo(ClientPtr client) + { + REQUEST(xRRGetScreenInfoReq); + ++ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + swaps(&stuff->length); + swapl(&stuff->window); + return (*ProcRandrVector[stuff->randrReqType]) (client); +@@ -69,6 +71,7 @@ SProcRRSelectInput(ClientPtr client) + { + REQUEST(xRRSelectInputReq); + ++ REQUEST_SIZE_MATCH(xRRSelectInputReq); + swaps(&stuff->length); + swapl(&stuff->window); + swaps(&stuff->enable); +@@ -152,6 +155,7 @@ SProcRRConfigureOutputProperty(ClientPtr client) + { + REQUEST(xRRConfigureOutputPropertyReq); + ++ REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq); + swaps(&stuff->length); + swapl(&stuff->output); + swapl(&stuff->property); +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0014-render-check-request-size-before-reading-it-CVE-2014.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0014-render-check-request-size-before-reading-it-CVE-2014.patch @@ -0,0 +1,36 @@ +From c12a45abf1ae41f5deca298489f5e76ac54f2121 Mon Sep 17 00:00:00 2001 +From: Julien Cristau +Date: Tue, 28 Oct 2014 10:30:04 +0100 +Subject: [PATCH 14/33] render: check request size before reading it + [CVE-2014-8100 1/2] + +Otherwise we may be reading outside of the client request. + +Signed-off-by: Julien Cristau +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith +--- + render/render.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/render/render.c b/render/render.c +index e3031da..200e0c8 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -276,11 +276,11 @@ ProcRenderQueryVersion(ClientPtr client) + + REQUEST(xRenderQueryVersionReq); + ++ REQUEST_SIZE_MATCH(xRenderQueryVersionReq); ++ + pRenderClient->major_version = stuff->majorVersion; + pRenderClient->minor_version = stuff->minorVersion; + +- REQUEST_SIZE_MATCH(xRenderQueryVersionReq); +- + if ((stuff->majorVersion * 1000 + stuff->minorVersion) < + (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) { + rep.majorVersion = stuff->majorVersion; +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch @@ -0,0 +1,140 @@ +From c21e46f03bd2096aaed666d91a3188a5676f6222 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:51:29 -0800 +Subject: [PATCH 15/33] render: unvalidated lengths in Render extn. swapped + procs [CVE-2014-8100 2/2] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + render/render.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/render/render.c b/render/render.c +index 200e0c8..723f380 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -1995,7 +1995,7 @@ static int + SProcRenderQueryVersion(ClientPtr client) + { + REQUEST(xRenderQueryVersionReq); +- ++ REQUEST_SIZE_MATCH(xRenderQueryVersionReq); + swaps(&stuff->length); + swapl(&stuff->majorVersion); + swapl(&stuff->minorVersion); +@@ -2006,6 +2006,7 @@ static int + SProcRenderQueryPictFormats(ClientPtr client) + { + REQUEST(xRenderQueryPictFormatsReq); ++ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); + swaps(&stuff->length); + return (*ProcRenderVector[stuff->renderReqType]) (client); + } +@@ -2014,6 +2015,7 @@ static int + SProcRenderQueryPictIndexValues(ClientPtr client) + { + REQUEST(xRenderQueryPictIndexValuesReq); ++ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); + swaps(&stuff->length); + swapl(&stuff->format); + return (*ProcRenderVector[stuff->renderReqType]) (client); +@@ -2029,6 +2031,7 @@ static int + SProcRenderCreatePicture(ClientPtr client) + { + REQUEST(xRenderCreatePictureReq); ++ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + swaps(&stuff->length); + swapl(&stuff->pid); + swapl(&stuff->drawable); +@@ -2042,6 +2045,7 @@ static int + SProcRenderChangePicture(ClientPtr client) + { + REQUEST(xRenderChangePictureReq); ++ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); + swaps(&stuff->length); + swapl(&stuff->picture); + swapl(&stuff->mask); +@@ -2053,6 +2057,7 @@ static int + SProcRenderSetPictureClipRectangles(ClientPtr client) + { + REQUEST(xRenderSetPictureClipRectanglesReq); ++ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + swaps(&stuff->length); + swapl(&stuff->picture); + swaps(&stuff->xOrigin); +@@ -2065,6 +2070,7 @@ static int + SProcRenderFreePicture(ClientPtr client) + { + REQUEST(xRenderFreePictureReq); ++ REQUEST_SIZE_MATCH(xRenderFreePictureReq); + swaps(&stuff->length); + swapl(&stuff->picture); + return (*ProcRenderVector[stuff->renderReqType]) (client); +@@ -2074,6 +2080,7 @@ static int + SProcRenderComposite(ClientPtr client) + { + REQUEST(xRenderCompositeReq); ++ REQUEST_SIZE_MATCH(xRenderCompositeReq); + swaps(&stuff->length); + swapl(&stuff->src); + swapl(&stuff->mask); +@@ -2093,6 +2100,7 @@ static int + SProcRenderScale(ClientPtr client) + { + REQUEST(xRenderScaleReq); ++ REQUEST_SIZE_MATCH(xRenderScaleReq); + swaps(&stuff->length); + swapl(&stuff->src); + swapl(&stuff->dst); +@@ -2193,6 +2201,7 @@ static int + SProcRenderCreateGlyphSet(ClientPtr client) + { + REQUEST(xRenderCreateGlyphSetReq); ++ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); + swaps(&stuff->length); + swapl(&stuff->gsid); + swapl(&stuff->format); +@@ -2203,6 +2212,7 @@ static int + SProcRenderReferenceGlyphSet(ClientPtr client) + { + REQUEST(xRenderReferenceGlyphSetReq); ++ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); + swaps(&stuff->length); + swapl(&stuff->gsid); + swapl(&stuff->existing); +@@ -2213,6 +2223,7 @@ static int + SProcRenderFreeGlyphSet(ClientPtr client) + { + REQUEST(xRenderFreeGlyphSetReq); ++ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); + swaps(&stuff->length); + swapl(&stuff->glyphset); + return (*ProcRenderVector[stuff->renderReqType]) (client); +@@ -2227,6 +2238,7 @@ SProcRenderAddGlyphs(ClientPtr client) + xGlyphInfo *gi; + + REQUEST(xRenderAddGlyphsReq); ++ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); + swaps(&stuff->length); + swapl(&stuff->glyphset); + swapl(&stuff->nglyphs); +@@ -2261,6 +2273,7 @@ static int + SProcRenderFreeGlyphs(ClientPtr client) + { + REQUEST(xRenderFreeGlyphsReq); ++ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); + swaps(&stuff->length); + swapl(&stuff->glyphset); + SwapRestL(stuff); +@@ -2278,6 +2291,7 @@ SProcRenderCompositeGlyphs(ClientPtr client) + int size; + + REQUEST(xRenderCompositeGlyphsReq); ++ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch @@ -0,0 +1,27 @@ +From c0308b700e3e0f0b6b1dc350e822b6218d080f1a Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 20:02:20 -0800 +Subject: [PATCH 16/33] xfixes: unvalidated length in + SProcXFixesSelectSelectionInput [CVE-2014-8102] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + xfixes/select.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xfixes/select.c b/xfixes/select.c +index c088ed3..e964d58 100644 +--- a/xfixes/select.c ++++ b/xfixes/select.c +@@ -201,6 +201,7 @@ SProcXFixesSelectSelectionInput(ClientPtr client) + { + REQUEST(xXFixesSelectSelectionInputReq); + ++ REQUEST_SIZE_MATCH(xXFixesSelectSelectionInputReq); + swaps(&stuff->length); + swapl(&stuff->window); + swapl(&stuff->selection); +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0017-Add-request-length-checking-test-cases-for-some-Xinp.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0017-Add-request-length-checking-test-cases-for-some-Xinp.patch @@ -0,0 +1,195 @@ +From 0b199c0b23aecfdce53c28ea653c9342217d6f33 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 21:27:27 -0800 +Subject: [PATCH 17/33] Add request length checking test cases for some Xinput + 1.x requests + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + configure.ac | 1 + + test/Makefile.am | 2 +- + test/xi1/Makefile.am | 34 +++++++++ + test/xi1/protocol-xchangedevicecontrol.c | 122 ++++++++++++++++++++++++++++++ + 4 files changed, 158 insertions(+), 1 deletion(-) + create mode 100644 test/xi1/Makefile.am + create mode 100644 test/xi1/protocol-xchangedevicecontrol.c + +Index: xorg-server-1.15.1/configure.ac +=================================================================== +--- xorg-server-1.15.1.orig/configure.ac 2014-12-04 11:54:14.712587810 -0500 ++++ xorg-server-1.15.1/configure.ac 2014-12-04 11:54:14.708587787 -0500 +@@ -2553,6 +2553,7 @@ + hw/kdrive/linux/Makefile + hw/kdrive/src/Makefile + test/Makefile ++test/xi1/Makefile + test/xi2/Makefile + xserver.ent + xorg-server.pc +Index: xorg-server-1.15.1/test/xi1/Makefile.am +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-1.15.1/test/xi1/Makefile.am 2014-12-04 11:54:14.708587787 -0500 +@@ -0,0 +1,34 @@ ++if ENABLE_UNIT_TESTS ++if HAVE_LD_WRAP ++noinst_PROGRAMS = \ ++ protocol-xchangedevicecontrol ++ ++TESTS=$(noinst_PROGRAMS) ++TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV) ++ ++AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@ ++AM_CPPFLAGS = @XORG_INCS@ -I$(srcdir)/../xi2 ++TEST_LDADD=../libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLX_SYS_LIBS) ++COMMON_SOURCES=$(srcdir)/../xi2/protocol-common.c ++ ++if SPECIAL_DTRACE_OBJECTS ++TEST_LDADD += $(OS_LIB) $(DIX_LIB) ++endif ++ ++protocol_xchangedevicecontrol_LDADD=$(TEST_LDADD) ++ ++protocol_xchangedevicecontrol_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient ++ ++protocol_xchangedevicecontrol_SOURCES=$(COMMON_SOURCES) protocol-xchangedevicecontrol.c ++ ++else ++# Print that xi1-tests were skipped (exit code 77 for automake test harness) ++TESTS = xi1-tests ++CLEANFILES = $(TESTS) ++ ++xi1-tests: ++ @echo 'echo "ld -wrap support required for xi1 unit tests, skipping"' > $@ ++ @echo 'exit 77' >> $@ ++ $(AM_V_GEN)chmod +x $@ ++endif ++endif +Index: xorg-server-1.15.1/test/xi1/protocol-xchangedevicecontrol.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-1.15.1/test/xi1/protocol-xchangedevicecontrol.c 2014-12-04 11:54:14.708587787 -0500 +@@ -0,0 +1,122 @@ ++/** ++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifdef HAVE_DIX_CONFIG_H ++#include ++#endif ++ ++/* ++ * Protocol testing for ChangeDeviceControl request. ++ */ ++#include ++#include ++#include ++#include ++#include "inputstr.h" ++#include "chgdctl.h" ++ ++#include "protocol-common.h" ++ ++static ClientRec client_request; ++ ++static void ++reply_ChangeDeviceControl(ClientPtr client, int len, char *data, void *userdata) ++{ ++ xChangeDeviceControlReply *rep = (xChangeDeviceControlReply *) data; ++ ++ if (client->swapped) { ++ swapl(&rep->length); ++ swaps(&rep->sequenceNumber); ++ } ++ ++ reply_check_defaults(rep, len, ChangeDeviceControl); ++ ++ /* XXX: check status code in reply */ ++} ++ ++static void ++request_ChangeDeviceControl(ClientPtr client, xChangeDeviceControlReq * req, ++ xDeviceCtl *ctl, int error) ++{ ++ int rc; ++ ++ client_request.req_len = req->length; ++ rc = ProcXChangeDeviceControl(&client_request); ++ assert(rc == error); ++ ++ /* XXX: ChangeDeviceControl doesn't seem to fill in errorValue to check */ ++ ++ client_request.swapped = TRUE; ++ swaps(&req->length); ++ swaps(&req->control); ++ swaps(&ctl->length); ++ swaps(&ctl->control); ++ /* XXX: swap other contents of ctl, depending on type */ ++ rc = SProcXChangeDeviceControl(&client_request); ++ assert(rc == error); ++} ++ ++static unsigned char *data[4096]; /* the request buffer */ ++ ++static void ++test_ChangeDeviceControl(void) ++{ ++ xChangeDeviceControlReq *request = (xChangeDeviceControlReq *) data; ++ xDeviceCtl *control = (xDeviceCtl *) (&request[1]); ++ ++ request_init(request, ChangeDeviceControl); ++ ++ reply_handler = reply_ChangeDeviceControl; ++ ++ client_request = init_client(request->length, request); ++ ++ printf("Testing invalid lengths:\n"); ++ printf(" -- no control struct\n"); ++ request_ChangeDeviceControl(&client_request, request, control, BadLength); ++ ++ printf(" -- xDeviceResolutionCtl\n"); ++ request_init(request, ChangeDeviceControl); ++ request->control = DEVICE_RESOLUTION; ++ control->length = (sizeof(xDeviceResolutionCtl) >> 2); ++ request->length += control->length - 2; ++ request_ChangeDeviceControl(&client_request, request, control, BadLength); ++ ++ printf(" -- xDeviceEnableCtl\n"); ++ request_init(request, ChangeDeviceControl); ++ request->control = DEVICE_ENABLE; ++ control->length = (sizeof(xDeviceEnableCtl) >> 2); ++ request->length += control->length - 2; ++ request_ChangeDeviceControl(&client_request, request, control, BadLength); ++ ++ /* XXX: Test functionality! */ ++} ++ ++int ++main(int argc, char **argv) ++{ ++ init_simple(); ++ ++ test_ChangeDeviceControl(); ++ ++ return 0; ++} only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0018-Add-request-length-checking-test-cases-for-some-Xinp.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0018-Add-request-length-checking-test-cases-for-some-Xinp.patch @@ -0,0 +1,86 @@ +From a8d2ec0a4c11fb5804c073a5b74ba342d59843a8 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 21:28:05 -0800 +Subject: [PATCH 18/33] Add request length checking test cases for some Xinput + 2.x requests + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + test/xi2/protocol-xigetclientpointer.c | 5 +++++ + test/xi2/protocol-xipassivegrabdevice.c | 8 ++++++++ + test/xi2/protocol-xiquerypointer.c | 4 ++++ + test/xi2/protocol-xiwarppointer.c | 3 +++ + 4 files changed, 20 insertions(+) + +Index: xorg-server-1.15.1/test/xi2/protocol-xigetclientpointer.c +=================================================================== +--- xorg-server-1.15.1.orig/test/xi2/protocol-xigetclientpointer.c 2014-12-04 11:54:32.024693177 -0500 ++++ xorg-server-1.15.1/test/xi2/protocol-xigetclientpointer.c 2014-12-04 11:54:32.020693152 -0500 +@@ -124,6 +124,11 @@ + request.win = INVALID_WINDOW_ID; + request_XIGetClientPointer(&client_request, &request, BadWindow); + ++ printf("Testing invalid length\n"); ++ client_request.req_len -= 4; ++ request_XIGetClientPointer(&client_request, &request, BadLength); ++ client_request.req_len += 4; ++ + test_data.cp_is_set = FALSE; + + printf("Testing window None, unset ClientPointer.\n"); +Index: xorg-server-1.15.1/test/xi2/protocol-xipassivegrabdevice.c +=================================================================== +--- xorg-server-1.15.1.orig/test/xi2/protocol-xipassivegrabdevice.c 2014-12-04 11:54:32.024693177 -0500 ++++ xorg-server-1.15.1/test/xi2/protocol-xipassivegrabdevice.c 2014-12-04 11:54:32.020693152 -0500 +@@ -139,6 +139,7 @@ + int modifiers; + int mask_len; + ++ client_request.req_len = req->length; + rc = ProcXIPassiveGrabDevice(&client_request); + assert(rc == error); + +@@ -190,6 +191,13 @@ + request_XIPassiveGrabDevice(&client_request, request, BadDevice, + request->deviceid); + ++ printf("Testing invalid length\n"); ++ request->length -= 2; ++ request_XIPassiveGrabDevice(&client_request, request, BadLength, ++ client_request.errorValue); ++ /* re-init request since swapped length test leaves some values swapped */ ++ request_init(request, XIPassiveGrabDevice); ++ request->grab_window = CLIENT_WINDOW_ID; + request->deviceid = XIAllMasterDevices; + + printf("Testing invalid grab types\n"); +Index: xorg-server-1.15.1/test/xi2/protocol-xiquerypointer.c +=================================================================== +--- xorg-server-1.15.1.orig/test/xi2/protocol-xiquerypointer.c 2014-12-04 11:54:32.024693177 -0500 ++++ xorg-server-1.15.1/test/xi2/protocol-xiquerypointer.c 2014-12-04 11:54:32.020693152 -0500 +@@ -201,6 +201,10 @@ + test_data.dev = devices.mouse; + request.deviceid = devices.mouse->id; + request_XIQueryPointer(&client_request, &request, Success); ++ ++ /* test REQUEST_SIZE_MATCH */ ++ client_request.req_len -= 4; ++ request_XIQueryPointer(&client_request, &request, BadLength); + } + + int +Index: xorg-server-1.15.1/test/xi2/protocol-xiwarppointer.c +=================================================================== +--- xorg-server-1.15.1.orig/test/xi2/protocol-xiwarppointer.c 2014-12-04 11:54:32.024693177 -0500 ++++ xorg-server-1.15.1/test/xi2/protocol-xiwarppointer.c 2014-12-04 11:54:32.020693152 -0500 +@@ -198,6 +198,9 @@ + request_XIWarpPointer(&client_request, &request, Success); + + /* FIXME: src_x/y checks */ ++ ++ client_request.req_len -= 2; /* invalid length */ ++ request_XIWarpPointer(&client_request, &request, BadLength); + } + + int only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch @@ -0,0 +1,74 @@ +From d4934a8fb4fab54d39c42ca445687985fe4410cd Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 22:42:47 -0800 +Subject: [PATCH 19/33] Add REQUEST_FIXED_SIZE testcases to test/misc.c + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +--- + test/misc.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/test/misc.c b/test/misc.c +index dd792e6..66330a1 100644 +--- a/test/misc.c ++++ b/test/misc.c +@@ -28,6 +28,8 @@ + #include + #include "misc.h" + #include "scrnintstr.h" ++#include "dix.h" ++#include "dixstruct.h" + + ScreenInfo screenInfo; + +@@ -155,11 +157,46 @@ dix_update_desktop_dimensions(void) + assert_dimensions(-w2, -h2, w2, h2); + } + ++static int ++dix_request_fixed_size_overflow(ClientRec *client) ++{ ++ xReq req = { 0 }; ++ ++ client->req_len = req.length = 1; ++ REQUEST_FIXED_SIZE(req, SIZE_MAX); ++ return Success; ++} ++ ++static int ++dix_request_fixed_size_match(ClientRec *client) ++{ ++ xReq req = { 0 }; ++ ++ client->req_len = req.length = 9; ++ REQUEST_FIXED_SIZE(req, 30); ++ return Success; ++} ++ ++static void ++dix_request_size_checks(void) ++{ ++ ClientRec client = { 0 }; ++ int rc; ++ ++ rc = dix_request_fixed_size_overflow(&client); ++ assert(rc == BadLength); ++ ++ rc = dix_request_fixed_size_match(&client); ++ assert(rc == Success); ++} ++ ++ + int + main(int argc, char **argv) + { + dix_version_compare(); + dix_update_desktop_dimensions(); ++ dix_request_size_checks(); + + return 0; + } +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0020-glx-Be-more-paranoid-about-variable-length-requests-.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0020-glx-Be-more-paranoid-about-variable-length-requests-.patch @@ -0,0 +1,44 @@ +From 096a5af8e52faafc38ae84dd17bede7ac03a3b83 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:36 -0500 +Subject: [PATCH 20/33] glx: Be more paranoid about variable-length requests + [CVE-2014-8093 1/6] + +If the size computation routine returns -1 we should just reject the +request outright. Clamping it to zero could give an attacker the +opportunity to also mangle cmdlen in such a way that the subsequent +length check passes, and the request would get executed, thus passing +data we wanted to reject to the renderer. + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/glxcmds.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: xorg-server-1.15.1/glx/glxcmds.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/glxcmds.c 2014-12-04 11:55:22.293001486 -0500 ++++ xorg-server-1.15.1/glx/glxcmds.c 2014-12-04 11:55:22.289001461 -0500 +@@ -2052,7 +2052,7 @@ + extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, + client->swapped); + if (extra < 0) { +- extra = 0; ++ return BadLength; + } + if (cmdlen != __GLX_PAD(entry.bytes + extra)) { + return BadLength; +@@ -2169,7 +2169,7 @@ + extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE, + client->swapped); + if (extra < 0) { +- extra = 0; ++ return BadLength; + } + /* large command's header is 4 bytes longer, so add 4 */ + if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) { only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch @@ -0,0 +1,165 @@ +From 74e31c4809dbfe437a3e2a53ee38658da1f3c8ed Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:37 -0500 +Subject: [PATCH 21/33] glx: Be more strict about rejecting invalid image + sizes [CVE-2014-8093 2/6] + +Before this we'd just clamp the image size to 0, which was just +hideously stupid; if the parameters were such that they'd overflow an +integer, you'd allocate a small buffer, then pass huge values into (say) +ReadPixels, and now you're scribbling over arbitrary server memory. + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/singlepix.c | 16 ++++++++-------- + glx/singlepixswap.c | 16 ++++++++-------- + 2 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/glx/singlepix.c b/glx/singlepix.c +index 506fdaa..8b6c261 100644 +--- a/glx/singlepix.c ++++ b/glx/singlepix.c +@@ -65,7 +65,7 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc) + lsbFirst = *(GLboolean *) (pc + 25); + compsize = __glReadPixels_size(format, type, width, height); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); +@@ -124,7 +124,7 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc) + compsize = + __glGetTexImage_size(target, level, format, type, width, height, depth); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -218,9 +218,9 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + + if (compsize < 0) +- compsize = 0; ++ return BadLength; + if (compsize2 < 0) +- compsize2 = 0; ++ return BadLength; + compsize = __GLX_PAD(compsize); + compsize2 = __GLX_PAD(compsize2); + +@@ -296,7 +296,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -365,7 +365,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -426,7 +426,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + + compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -491,7 +491,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +diff --git a/glx/singlepixswap.c b/glx/singlepixswap.c +index 8469101..8dc304f 100644 +--- a/glx/singlepixswap.c ++++ b/glx/singlepixswap.c +@@ -75,7 +75,7 @@ __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc) + lsbFirst = *(GLboolean *) (pc + 25); + compsize = __glReadPixels_size(format, type, width, height); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); +@@ -144,7 +144,7 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc) + compsize = + __glGetTexImage_size(target, level, format, type, width, height, depth); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -252,9 +252,9 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + + if (compsize < 0) +- compsize = 0; ++ return BadLength; + if (compsize2 < 0) +- compsize2 = 0; ++ return BadLength; + compsize = __GLX_PAD(compsize); + compsize2 = __GLX_PAD(compsize2); + +@@ -338,7 +338,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -415,7 +415,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -483,7 +483,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + + compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -554,7 +554,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch @@ -0,0 +1,59 @@ +From 902b6a30c660f4b38afd936726071b631ada3fcf Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:38 -0500 +Subject: [PATCH 22/33] glx: Additional paranoia in __glXGetAnswerBuffer / + __GLX_GET_ANSWER_BUFFER (v2) [CVE-2014-8093 3/6] + +If the computed reply size is negative, something went wrong, treat it +as an error. + +v2: Be more careful about size_t being unsigned (Matthieu Herrb) +v3: SIZE_MAX not SIZE_T_MAX (Alan Coopersmith) + +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/indirect_util.c | 7 ++++++- + glx/unpack.h | 3 ++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/glx/indirect_util.c b/glx/indirect_util.c +index 926e57c..de81491 100644 +--- a/glx/indirect_util.c ++++ b/glx/indirect_util.c +@@ -76,9 +76,14 @@ __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size, + const unsigned mask = alignment - 1; + + if (local_size < required_size) { +- const size_t worst_case_size = required_size + alignment; ++ size_t worst_case_size; + intptr_t temp_buf; + ++ if (required_size < SIZE_MAX - alignment) ++ worst_case_size = required_size + alignment; ++ else ++ return NULL; ++ + if (cl->returnBufSize < worst_case_size) { + void *temp = realloc(cl->returnBuf, worst_case_size); + +diff --git a/glx/unpack.h b/glx/unpack.h +index 52fba74..2b1ebcf 100644 +--- a/glx/unpack.h ++++ b/glx/unpack.h +@@ -83,7 +83,8 @@ extern xGLXSingleReply __glXReply; + ** pointer. + */ + #define __GLX_GET_ANSWER_BUFFER(res,cl,size,align) \ +- if ((size) > sizeof(answerBuffer)) { \ ++ if (size < 0) return BadLength; \ ++ else if ((size) > sizeof(answerBuffer)) { \ + int bump; \ + if ((cl)->returnBufSize < (size)+(align)) { \ + (cl)->returnBuf = (GLbyte*)realloc((cl)->returnBuf, \ +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch @@ -0,0 +1,59 @@ +From 53e2f52df33e5d45ce070ab2454c5a3d497cc8f6 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:39 -0500 +Subject: [PATCH 23/33] glx: Fix image size computation for + EXT_texture_integer [CVE-2014-8098 1/8] + +Without this we'd reject the request with BadLength. Note that some old +versions of Mesa had a bug in the same place, and would _send_ zero +bytes of image data; these will now be rejected, correctly. + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/rensize.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/glx/rensize.c b/glx/rensize.c +index ba22d10..9ff73c7 100644 +--- a/glx/rensize.c ++++ b/glx/rensize.c +@@ -224,6 +224,11 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: ++ case GL_RED_INTEGER_EXT: ++ case GL_GREEN_INTEGER_EXT: ++ case GL_BLUE_INTEGER_EXT: ++ case GL_ALPHA_INTEGER_EXT: ++ case GL_LUMINANCE_INTEGER_EXT: + elementsPerGroup = 1; + break; + case GL_422_EXT: +@@ -234,14 +239,19 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + case GL_DEPTH_STENCIL_MESA: + case GL_YCBCR_MESA: + case GL_LUMINANCE_ALPHA: ++ case GL_LUMINANCE_ALPHA_INTEGER_EXT: + elementsPerGroup = 2; + break; + case GL_RGB: + case GL_BGR: ++ case GL_RGB_INTEGER_EXT: ++ case GL_BGR_INTEGER_EXT: + elementsPerGroup = 3; + break; + case GL_RGBA: + case GL_BGRA: ++ case GL_RGBA_INTEGER_EXT: ++ case GL_BGRA_INTEGER_EXT: + case GL_ABGR_EXT: + elementsPerGroup = 4; + break; +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch @@ -0,0 +1,79 @@ +From 13f54e513024fc8224065515d9c664135aba1848 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:40 -0500 +Subject: [PATCH 24/33] glx: Add safe_{add,mul,pad} (v3) [CVE-2014-8093 4/6] + +These are paranoid about integer overflow, and will return -1 if their +operation would overflow a (signed) integer or if either argument is +negative. + +Note that RenderLarge requests are sized with a uint32_t so in principle +this could be sketchy there, but dix limits bigreqs to 128M so you +shouldn't ever notice, and honestly if you're sending more than 2G of +rendering commands you're already doing something very wrong. + +v2: Use INT_MAX for consistency with the rest of the server (jcristau) +v3: Reject negative arguments (anholt) + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/glxserver.h | 41 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +Index: xorg-server-1.15.1/glx/glxserver.h +=================================================================== +--- xorg-server-1.15.1.orig/glx/glxserver.h 2014-12-04 11:55:58.221223978 -0500 ++++ xorg-server-1.15.1/glx/glxserver.h 2014-12-04 11:55:58.217223954 -0500 +@@ -230,6 +230,47 @@ + * Routines for computing the size of variably-sized rendering commands. + */ + ++static _X_INLINE int ++safe_add(int a, int b) ++{ ++ if (a < 0 || b < 0) ++ return -1; ++ ++ if (INT_MAX - a < b) ++ return -1; ++ ++ return a + b; ++} ++ ++static _X_INLINE int ++safe_mul(int a, int b) ++{ ++ if (a < 0 || b < 0) ++ return -1; ++ ++ if (a == 0 || b == 0) ++ return 0; ++ ++ if (a > INT_MAX / b) ++ return -1; ++ ++ return a * b; ++} ++ ++static _X_INLINE int ++safe_pad(int a) ++{ ++ int ret; ++ ++ if (a < 0) ++ return -1; ++ ++ if ((ret = safe_add(a, 3)) < 0) ++ return -1; ++ ++ return ret & (GLuint)~3; ++} ++ + extern int __glXTypeSize(GLenum enm); + extern int __glXImageSize(GLenum format, GLenum type, + GLenum target, GLsizei w, GLsizei h, GLsizei d, only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch @@ -0,0 +1,72 @@ +From 02f91446a5446d7287a0fc30aa8b15a1cd29c2cf Mon Sep 17 00:00:00 2001 +From: Julien Cristau +Date: Mon, 10 Nov 2014 12:13:41 -0500 +Subject: [PATCH 25/33] glx: Length checking for GLXRender requests (v2) + [CVE-2014-8098 2/8] + +v2: +Remove can't-happen comparison for cmdlen < 0 (Michal Srb) + +Reviewed-by: Adam Jackson +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Julien Cristau +Signed-off-by: Alan Coopersmith +--- + glx/glxcmds.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +Index: xorg-server-1.15.1/glx/glxcmds.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/glxcmds.c 2014-12-04 11:56:07.897284200 -0500 ++++ xorg-server-1.15.1/glx/glxcmds.c 2014-12-04 11:56:07.893284176 -0500 +@@ -2015,7 +2015,7 @@ + left = (req->length << 2) - sz_xGLXRenderReq; + while (left > 0) { + __GLXrenderSizeData entry; +- int extra; ++ int extra = 0; + __GLXdispatchRenderProcPtr proc; + int err; + +@@ -2034,6 +2034,9 @@ + cmdlen = hdr->length; + opcode = hdr->opcode; + ++ if (left < cmdlen) ++ return BadLength; ++ + /* + ** Check for core opcodes and grab entry data. + */ +@@ -2047,6 +2050,10 @@ + return __glXError(GLXBadRenderRequest); + } + ++ if (cmdlen < entry.bytes) { ++ return BadLength; ++ } ++ + if (entry.varsize) { + /* variable size command */ + extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, +@@ -2054,17 +2061,9 @@ + if (extra < 0) { + return BadLength; + } +- if (cmdlen != __GLX_PAD(entry.bytes + extra)) { +- return BadLength; +- } + } +- else { +- /* constant size command */ +- if (cmdlen != __GLX_PAD(entry.bytes)) { +- return BadLength; +- } +- } +- if (left < cmdlen) { ++ ++ if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) { + return BadLength; + } + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0026-glx-Integer-overflow-protection-for-non-generated-re.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0026-glx-Integer-overflow-protection-for-non-generated-re.patch @@ -0,0 +1,225 @@ +From 84caa119e859d66e1a8368f265c16769e44e3291 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:42 -0500 +Subject: [PATCH 26/33] glx: Integer overflow protection for non-generated + render requests (v3) [CVE-2014-8093 5/6] + +v2: +Fix constants in __glXMap2fReqSize (Michal Srb) +Validate w/h/d for proxy targets too (Keith Packard) + +v3: +Fix Map[12]Size to correctly reject order == 0 (Julien Cristau) + +Reviewed-by: Keith Packard +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/rensize.c | 77 ++++++++++++++++++++++++++++++--------------------------- + 1 file changed, 41 insertions(+), 36 deletions(-) + +diff --git a/glx/rensize.c b/glx/rensize.c +index 9ff73c7..d46334a 100644 +--- a/glx/rensize.c ++++ b/glx/rensize.c +@@ -43,19 +43,11 @@ + (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \ + ((a & 0xff00U)<<8) | ((a & 0xffU)<<24)) + +-static int +-Map1Size(GLint k, GLint order) +-{ +- if (order <= 0 || k < 0) +- return -1; +- return k * order; +-} +- + int + __glXMap1dReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint order, k; ++ GLint order; + + target = *(GLenum *) (pc + 16); + order = *(GLint *) (pc + 20); +@@ -63,15 +55,16 @@ __glXMap1dReqSize(const GLbyte * pc, Bool swap) + target = SWAPL(target); + order = SWAPL(order); + } +- k = __glMap1d_size(target); +- return 8 * Map1Size(k, order); ++ if (order < 1) ++ return -1; ++ return safe_mul(8, safe_mul(__glMap1d_size(target), order)); + } + + int + __glXMap1fReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint order, k; ++ GLint order; + + target = *(GLenum *) (pc + 0); + order = *(GLint *) (pc + 12); +@@ -79,23 +72,24 @@ __glXMap1fReqSize(const GLbyte * pc, Bool swap) + target = SWAPL(target); + order = SWAPL(order); + } +- k = __glMap1f_size(target); +- return 4 * Map1Size(k, order); ++ if (order < 1) ++ return -1; ++ return safe_mul(4, safe_mul(__glMap1f_size(target), order)); + } + + static int + Map2Size(int k, int majorOrder, int minorOrder) + { +- if (majorOrder <= 0 || minorOrder <= 0 || k < 0) ++ if (majorOrder < 1 || minorOrder < 1) + return -1; +- return k * majorOrder * minorOrder; ++ return safe_mul(k, safe_mul(majorOrder, minorOrder)); + } + + int + __glXMap2dReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint uorder, vorder, k; ++ GLint uorder, vorder; + + target = *(GLenum *) (pc + 32); + uorder = *(GLint *) (pc + 36); +@@ -105,15 +99,14 @@ __glXMap2dReqSize(const GLbyte * pc, Bool swap) + uorder = SWAPL(uorder); + vorder = SWAPL(vorder); + } +- k = __glMap2d_size(target); +- return 8 * Map2Size(k, uorder, vorder); ++ return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder)); + } + + int + __glXMap2fReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint uorder, vorder, k; ++ GLint uorder, vorder; + + target = *(GLenum *) (pc + 0); + uorder = *(GLint *) (pc + 12); +@@ -123,8 +116,7 @@ __glXMap2fReqSize(const GLbyte * pc, Bool swap) + uorder = SWAPL(uorder); + vorder = SWAPL(vorder); + } +- k = __glMap2f_size(target); +- return 4 * Map2Size(k, uorder, vorder); ++ return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder)); + } + + /** +@@ -175,14 +167,16 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + GLint bytesPerElement, elementsPerGroup, groupsPerRow; + GLint groupSize, rowSize, padding, imageSize; + ++ if (w == 0 || h == 0 || d == 0) ++ return 0; ++ + if (w < 0 || h < 0 || d < 0 || + (type == GL_BITMAP && + (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) { + return -1; + } +- if (w == 0 || h == 0 || d == 0) +- return 0; + ++ /* proxy targets have no data */ + switch (target) { + case GL_PROXY_TEXTURE_1D: + case GL_PROXY_TEXTURE_2D: +@@ -199,6 +193,12 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + return 0; + } + ++ /* real data has to have real sizes */ ++ if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0) ++ return -1; ++ if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8) ++ return -1; ++ + if (type == GL_BITMAP) { + if (rowLength > 0) { + groupsPerRow = rowLength; +@@ -207,11 +207,14 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + groupsPerRow = w; + } + rowSize = bits_to_bytes(groupsPerRow); ++ if (rowSize < 0) ++ return -1; + padding = (rowSize % alignment); + if (padding) { + rowSize += alignment - padding; + } +- return ((h + skipRows) * rowSize); ++ ++ return safe_mul(safe_add(h, skipRows), rowSize); + } + else { + switch (format) { +@@ -303,6 +306,7 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + default: + return -1; + } ++ /* known safe by the switches above, not checked */ + groupSize = bytesPerElement * elementsPerGroup; + if (rowLength > 0) { + groupsPerRow = rowLength; +@@ -310,18 +314,21 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + else { + groupsPerRow = w; + } +- rowSize = groupsPerRow * groupSize; ++ ++ if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0) ++ return -1; + padding = (rowSize % alignment); + if (padding) { + rowSize += alignment - padding; + } +- if (imageHeight > 0) { +- imageSize = (imageHeight + skipRows) * rowSize; +- } +- else { +- imageSize = (h + skipRows) * rowSize; +- } +- return ((d + skipImages) * imageSize); ++ ++ if (imageHeight > 0) ++ h = imageHeight; ++ h = safe_add(h, skipRows); ++ ++ imageSize = safe_mul(h, rowSize); ++ ++ return safe_mul(safe_add(d, skipImages), imageSize); + } + } + +@@ -445,9 +452,7 @@ __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap) + /* XXX Should rowLength be used for either or both image? */ + image1size = __glXImageSize(format, type, 0, w, 1, 1, + 0, rowLength, 0, 0, alignment); +- image1size = __GLX_PAD(image1size); + image2size = __glXImageSize(format, type, 0, h, 1, 1, + 0, rowLength, 0, 0, alignment); +- return image1size + image2size; +- ++ return safe_add(safe_pad(image1size), image2size); + } +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0027-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0027-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch @@ -0,0 +1,155 @@ +From 6070d07a25b33e9630f8dbbde1d1df6f25164286 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:43 -0500 +Subject: [PATCH 27/33] glx: Length checking for RenderLarge requests (v2) + [CVE-2014-8098 3/8] + +This is a half-measure until we start passing request length into the +varsize function, but it's better than the nothing we had before. + +v2: Verify that there's at least a large render header's worth of +dataBytes (Julien Cristau) + +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/glxcmds.c | 57 ++++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 34 insertions(+), 23 deletions(-) + +Index: xorg-server-1.15.1/glx/glxcmds.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/glxcmds.c 2014-12-04 11:56:22.749376887 -0500 ++++ xorg-server-1.15.1/glx/glxcmds.c 2014-12-04 11:56:22.745376862 -0500 +@@ -2099,6 +2099,8 @@ + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq); ++ + req = (xGLXRenderLargeReq *) pc; + if (client->swapped) { + __GLX_SWAP_SHORT(&req->length); +@@ -2114,12 +2116,14 @@ + __glXResetLargeCommandStatus(cl); + return error; + } ++ if (safe_pad(req->dataBytes) < 0) ++ return BadLength; + dataBytes = req->dataBytes; + + /* + ** Check the request length. + */ +- if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) { ++ if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) { + client->errorValue = req->length; + /* Reset in case this isn't 1st request. */ + __glXResetLargeCommandStatus(cl); +@@ -2129,7 +2133,7 @@ + + if (cl->largeCmdRequestsSoFar == 0) { + __GLXrenderSizeData entry; +- int extra; ++ int extra = 0; + size_t cmdlen; + int err; + +@@ -2142,13 +2146,17 @@ + return __glXError(GLXBadLargeRequest); + } + ++ if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE) ++ return BadLength; ++ + hdr = (__GLXrenderLargeHeader *) pc; + if (client->swapped) { + __GLX_SWAP_INT(&hdr->length); + __GLX_SWAP_INT(&hdr->opcode); + } +- cmdlen = hdr->length; + opcode = hdr->opcode; ++ if ((cmdlen = safe_pad(hdr->length)) < 0) ++ return BadLength; + + /* + ** Check for core opcodes and grab entry data. +@@ -2170,17 +2178,13 @@ + if (extra < 0) { + return BadLength; + } +- /* large command's header is 4 bytes longer, so add 4 */ +- if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) { +- return BadLength; +- } + } +- else { +- /* constant size command */ +- if (cmdlen != __GLX_PAD(entry.bytes + 4)) { +- return BadLength; +- } ++ ++ /* the +4 is safe because we know entry.bytes is small */ ++ if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) { ++ return BadLength; + } ++ + /* + ** Make enough space in the buffer, then copy the entire request. + */ +@@ -2207,6 +2211,7 @@ + ** We are receiving subsequent (i.e. not the first) requests of a + ** multi request command. + */ ++ int bytesSoFar; /* including this packet */ + + /* + ** Check the request number and the total request count. +@@ -2225,11 +2230,18 @@ + /* + ** Check that we didn't get too much data. + */ +- if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) { ++ if ((bytesSoFar = safe_add(cl->largeCmdBytesSoFar, dataBytes)) < 0) { + client->errorValue = dataBytes; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); + } ++ ++ if (bytesSoFar > cl->largeCmdBytesTotal) { ++ client->errorValue = dataBytes; ++ __glXResetLargeCommandStatus(cl); ++ return __glXError(GLXBadLargeRequest); ++ } ++ + memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes); + cl->largeCmdBytesSoFar += dataBytes; + cl->largeCmdRequestsSoFar++; +@@ -2241,17 +2253,16 @@ + ** This is the last request; it must have enough bytes to complete + ** the command. + */ +- /* NOTE: the two pad macros have been added below; they are needed +- ** because the client library pads the total byte count, but not +- ** the per-request byte counts. The Protocol Encoding says the +- ** total byte count should not be padded, so a proposal will be +- ** made to the ARB to relax the padding constraint on the total +- ** byte count, thus preserving backward compatibility. Meanwhile, +- ** the padding done below fixes a bug that did not allow +- ** large commands of odd sizes to be accepted by the server. ++ /* NOTE: the pad macro below is needed because the client library ++ ** pads the total byte count, but not the per-request byte counts. ++ ** The Protocol Encoding says the total byte count should not be ++ ** padded, so a proposal will be made to the ARB to relax the ++ ** padding constraint on the total byte count, thus preserving ++ ** backward compatibility. Meanwhile, the padding done below ++ ** fixes a bug that did not allow large commands of odd sizes to ++ ** be accepted by the server. + */ +- if (__GLX_PAD(cl->largeCmdBytesSoFar) != +- __GLX_PAD(cl->largeCmdBytesTotal)) { ++ if (safe_pad(cl->largeCmdBytesSoFar) != cl->largeCmdBytesTotal) { + client->errorValue = dataBytes; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0028-glx-Top-level-length-checking-for-swapped-VendorPriv.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0028-glx-Top-level-length-checking-for-swapped-VendorPriv.patch @@ -0,0 +1,51 @@ +From efb3efd096edba7551e4e0e40bea522651211303 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:44 -0500 +Subject: [PATCH 28/33] glx: Top-level length checking for swapped + VendorPrivate requests [CVE-2014-8098 4/8] + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/glxcmdsswap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/glx/glxcmdsswap.c b/glx/glxcmdsswap.c +index 5d179f3..9ec1222 100644 +--- a/glx/glxcmdsswap.c ++++ b/glx/glxcmdsswap.c +@@ -958,11 +958,13 @@ __glXDispSwap_RenderLarge(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXVendorPrivateReq *req; + GLint vendorcode; + __GLXdispatchVendorPrivProcPtr proc; + + __GLX_DECLARE_SWAP_VARIABLES; ++ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); + + req = (xGLXVendorPrivateReq *) pc; + __GLX_SWAP_SHORT(&req->length); +@@ -985,11 +987,13 @@ __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXVendorPrivateWithReplyReq *req; + GLint vendorcode; + __GLXdispatchVendorPrivProcPtr proc; + + __GLX_DECLARE_SWAP_VARIABLES; ++ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateWithReplyReq); + + req = (xGLXVendorPrivateWithReplyReq *) pc; + __GLX_SWAP_SHORT(&req->length); +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0029-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0029-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch @@ -0,0 +1,74 @@ +From 554e382ba7aae961ca88c75edb1caffb5d00e9f6 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:45 -0500 +Subject: [PATCH 29/33] glx: Request length checks for SetClientInfoARB + [CVE-2014-8098 5/8] + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/clientinfo.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/glx/clientinfo.c b/glx/clientinfo.c +index 4aaa4c9..c5fef30 100644 +--- a/glx/clientinfo.c ++++ b/glx/clientinfo.c +@@ -33,18 +33,21 @@ static int + set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req, + unsigned bytes_per_version) + { ++ ClientPtr client = cl->client; + char *gl_extensions; + char *glx_extensions; + ++ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); ++ + /* Verify that the size of the packet matches the size inferred from the + * sizes specified for the various fields. + */ +- const unsigned expected_size = sz_xGLXSetClientInfoARBReq +- + (req->numVersions * bytes_per_version) +- + __GLX_PAD(req->numGLExtensionBytes) +- + __GLX_PAD(req->numGLXExtensionBytes); ++ int size = sz_xGLXSetClientInfoARBReq; ++ size = safe_add(size, safe_mul(req->numVersions, bytes_per_version)); ++ size = safe_add(size, safe_pad(req->numGLExtensionBytes)); ++ size = safe_add(size, safe_pad(req->numGLXExtensionBytes)); + +- if (req->length != (expected_size / 4)) ++ if (size < 0 || req->length != (size / 4)) + return BadLength; + + /* Verify that the actual length of the GL extension string matches what's +@@ -80,8 +83,11 @@ __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc; + ++ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); ++ + req->length = bswap_16(req->length); + req->numVersions = bswap_32(req->numVersions); + req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes); +@@ -99,8 +105,11 @@ __glXDisp_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc; + ++ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); ++ + req->length = bswap_16(req->length); + req->numVersions = bswap_32(req->numVersions); + req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes); +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0030-glx-Length-checking-for-non-generated-vendor-private.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0030-glx-Length-checking-for-non-generated-vendor-private.patch @@ -0,0 +1,45 @@ +From 475a39f6ac52aa2dc1babfece38d73da1a478731 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:46 -0500 +Subject: [PATCH 30/33] glx: Length-checking for non-generated vendor private + requests [CVE-2014-8098 6/8] + +Reviewed-by: Keith Packard +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/indirect_program.c | 2 ++ + glx/swap_interval.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/glx/indirect_program.c b/glx/indirect_program.c +index cda139e..5caee7b 100644 +--- a/glx/indirect_program.c ++++ b/glx/indirect_program.c +@@ -56,6 +56,8 @@ DoGetProgramString(struct __GLXclientStateRec *cl, GLbyte * pc, + __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); + ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateWithReplyReq, 8); ++ + pc += __GLX_VENDPRIV_HDR_SIZE; + if (cx != NULL) { + GLenum target; +diff --git a/glx/swap_interval.c b/glx/swap_interval.c +index 17bc992..2320550 100644 +--- a/glx/swap_interval.c ++++ b/glx/swap_interval.c +@@ -46,6 +46,8 @@ DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap) + __GLXcontext *cx; + GLint interval; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 4); ++ + cx = __glXLookupContextByTag(cl, tag); + + if ((cx == NULL) || (cx->pGlxScreen == NULL)) { +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0031-glx-Length-checking-for-non-generated-single-request.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0031-glx-Length-checking-for-non-generated-single-request.patch @@ -0,0 +1,561 @@ +From 4ab40b2b60f4f841f75250e1e60c1624d8212cd4 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:47 -0500 +Subject: [PATCH 31/33] glx: Length checking for non-generated single requests + (v2) [CVE-2014-8098 7/8] + +v2: +Fix single versus vendor-private length checking for ARB_imaging subset +extensions. (Julien Cristau) + +v3: +Fix single versus vendor-private length checking for ARB_imaging subset +extensions. (Julien Cristau) + +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Julien Cristau +Signed-off-by: Alan Coopersmith +--- + glx/indirect_texture_compression.c | 4 ++++ + glx/single2.c | 23 +++++++++++++++---- + glx/single2swap.c | 19 ++++++++++++---- + glx/singlepix.c | 44 ++++++++++++++++++++++++------------ + glx/singlepixswap.c | 34 ++++++++++++++++++++++++---- + 5 files changed, 95 insertions(+), 29 deletions(-) + +Index: xorg-server-1.15.1/glx/indirect_texture_compression.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/indirect_texture_compression.c 2014-12-04 11:56:48.021535287 -0500 ++++ xorg-server-1.15.1/glx/indirect_texture_compression.c 2014-12-04 11:56:48.017535262 -0500 +@@ -43,6 +43,8 @@ + __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); + ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + pc += __GLX_SINGLE_HDR_SIZE; + if (cx != NULL) { + const GLenum target = *(GLenum *) (pc + 0); +@@ -85,6 +87,8 @@ + __glXForceCurrent(cl, bswap_32(req->contextTag), &error); + ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + pc += __GLX_SINGLE_HDR_SIZE; + if (cx != NULL) { + const GLenum target = (GLenum) bswap_32(*(int *) (pc + 0)); +Index: xorg-server-1.15.1/glx/single2.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/single2.c 2014-12-04 11:56:48.021535287 -0500 ++++ xorg-server-1.15.1/glx/single2.c 2014-12-04 11:56:48.017535262 -0500 +@@ -45,11 +45,14 @@ + int + __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + GLsizei size; + GLenum type; + __GLXcontext *cx; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -76,10 +79,13 @@ + int + __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + GLsizei size; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -104,7 +110,7 @@ + int + __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc) + { +- ClientPtr client; ++ ClientPtr client = cl->client; + xGLXRenderModeReply reply; + __GLXcontext *cx; + GLint nitems = 0, retBytes = 0, retval, newModeCheck; +@@ -112,6 +118,8 @@ + GLenum newMode; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -188,7 +196,6 @@ + ** selection array, as per the API for glRenderMode itself. + */ + noChangeAllowed:; +- client = cl->client; + reply = (xGLXRenderModeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, +@@ -207,9 +214,12 @@ + int + __glXDisp_Flush(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + int error; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -223,10 +233,12 @@ + int + __glXDisp_Finish(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; +- ClientPtr client; + int error; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -317,7 +329,7 @@ + int + DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap) + { +- ClientPtr client; ++ ClientPtr client = cl->client; + __GLXcontext *cx; + GLenum name; + const char *string; +@@ -327,6 +339,8 @@ + char *buf = NULL, *buf1 = NULL; + GLint length = 0; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + /* If the client has the opposite byte order, swap the contextTag and + * the name. + */ +@@ -343,7 +357,6 @@ + pc += __GLX_SINGLE_HDR_SIZE; + name = *(GLenum *) (pc + 0); + string = (const char *) glGetString(name); +- client = cl->client; + + if (string == NULL) + string = ""; +Index: xorg-server-1.15.1/glx/single2swap.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/single2swap.c 2014-12-04 11:56:48.021535287 -0500 ++++ xorg-server-1.15.1/glx/single2swap.c 2014-12-04 11:56:48.017535262 -0500 +@@ -41,6 +41,7 @@ + int + __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + GLsizei size; + GLenum type; + +@@ -48,6 +49,8 @@ + __GLXcontext *cx; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -77,12 +80,15 @@ + int + __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + GLsizei size; + + __GLX_DECLARE_SWAP_VARIABLES; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -109,7 +115,7 @@ + int + __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) + { +- ClientPtr client; ++ ClientPtr client = cl->client; + __GLXcontext *cx; + xGLXRenderModeReply reply; + GLint nitems = 0, retBytes = 0, retval, newModeCheck; +@@ -120,6 +126,8 @@ + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -200,7 +208,6 @@ + ** selection array, as per the API for glRenderMode itself. + */ + noChangeAllowed:; +- client = cl->client; + reply = (xGLXRenderModeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, +@@ -224,11 +231,14 @@ + int + __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + int error; + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -243,12 +253,14 @@ + int + __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; +- ClientPtr client; + int error; + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -260,7 +272,6 @@ + cx->hasUnflushedCommands = GL_FALSE; + + /* Send empty reply packet to indicate finish is finished */ +- client = cl->client; + __GLX_BEGIN_REPLY(0); + __GLX_PUT_RETVAL(0); + __GLX_SWAP_REPLY_HEADER(); +Index: xorg-server-1.15.1/glx/singlepix.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/singlepix.c 2014-12-04 11:56:48.021535287 -0500 ++++ xorg-server-1.15.1/glx/singlepix.c 2014-12-04 11:56:48.017535262 -0500 +@@ -51,6 +51,8 @@ + int error; + char *answer, answerBuffer[200]; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 28); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -100,6 +102,8 @@ + char *answer, answerBuffer[200]; + GLint width = 0, height = 0, depth = 1; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 20); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -157,6 +161,8 @@ + GLubyte answerBuffer[200]; + char *answer; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -217,15 +223,13 @@ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + +- if (compsize < 0) ++ if ((compsize = safe_pad(compsize)) < 0) + return BadLength; +- if (compsize2 < 0) ++ if ((compsize2 = safe_pad(compsize2)) < 0) + return BadLength; +- compsize = __GLX_PAD(compsize); +- compsize2 = __GLX_PAD(compsize2); + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); +- __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1); ++ __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); + __glXClearErrorOccured(); + glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), + *(GLenum *) (pc + 8), answer, answer + compsize, NULL); +@@ -249,7 +253,8 @@ + __glXDisp_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -257,7 +262,8 @@ + __glXDisp_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -323,7 +329,8 @@ + __glXDisp_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -331,7 +338,8 @@ + __glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -390,7 +398,8 @@ + __glXDisp_GetHistogram(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -398,7 +407,8 @@ + __glXDisp_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -450,7 +460,8 @@ + __glXDisp_GetMinmax(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -458,7 +469,8 @@ + __glXDisp_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -517,7 +529,8 @@ + __glXDisp_GetColorTable(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -525,6 +538,7 @@ + __glXDisp_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } +Index: xorg-server-1.15.1/glx/singlepixswap.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/singlepixswap.c 2014-12-04 11:56:48.021535287 -0500 ++++ xorg-server-1.15.1/glx/singlepixswap.c 2014-12-04 11:56:48.017535262 -0500 +@@ -53,6 +53,8 @@ + int error; + char *answer, answerBuffer[200]; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 28); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -114,6 +116,8 @@ + char *answer, answerBuffer[200]; + GLint width = 0, height = 0, depth = 1; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 20); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -184,6 +188,8 @@ + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -251,15 +257,13 @@ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + +- if (compsize < 0) ++ if ((compsize = safe_pad(compsize)) < 0) + return BadLength; +- if (compsize2 < 0) ++ if ((compsize2 = safe_pad(compsize2)) < 0) + return BadLength; +- compsize = __GLX_PAD(compsize); +- compsize2 = __GLX_PAD(compsize2); + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); +- __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1); ++ __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); + __glXClearErrorOccured(); + glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), + *(GLenum *) (pc + 8), answer, answer + compsize, NULL); +@@ -285,7 +289,9 @@ + __glXDispSwap_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -293,7 +299,9 @@ + __glXDispSwap_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -367,7 +375,9 @@ + __glXDispSwap_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -375,7 +385,9 @@ + __glXDispSwap_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -441,7 +453,9 @@ + __glXDispSwap_GetHistogram(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -449,7 +463,9 @@ + __glXDispSwap_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -507,7 +523,9 @@ + __glXDispSwap_GetMinmax(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -515,7 +533,9 @@ + __glXDispSwap_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -581,7 +601,9 @@ + __glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -589,6 +611,8 @@ + __glXDispSwap_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0032-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0032-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch @@ -0,0 +1,913 @@ +From d303d79450436a1ef04252c2a7e36870c2506f38 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:48 -0500 +Subject: [PATCH 32/33] glx: Pass remaining request length into ->varsize (v2) + [CVE-2014-8098 8/8] + +v2: Handle more multiplies in indirect_reqsize.c (Julien Cristau) + +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +--- + glx/glxcmds.c | 7 +- + glx/glxserver.h | 2 +- + glx/indirect_reqsize.c | 142 +++++++++++++++++++------------------ + glx/indirect_reqsize.h | 181 +++++++++++++++++++++++++++++------------------- + glx/rensize.c | 27 +++++--- + 5 files changed, 205 insertions(+), 154 deletions(-) + +Index: xorg-server-1.15.1/glx/glxcmds.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/glxcmds.c 2014-12-04 11:57:06.345650678 -0500 ++++ xorg-server-1.15.1/glx/glxcmds.c 2014-12-04 11:57:06.337650627 -0500 +@@ -2057,7 +2057,8 @@ + if (entry.varsize) { + /* variable size command */ + extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, +- client->swapped); ++ client->swapped, ++ left - __GLX_RENDER_HDR_SIZE); + if (extra < 0) { + return BadLength; + } +@@ -2134,6 +2135,7 @@ + if (cl->largeCmdRequestsSoFar == 0) { + __GLXrenderSizeData entry; + int extra = 0; ++ int left = (req->length << 2) - sz_xGLXRenderLargeReq; + size_t cmdlen; + int err; + +@@ -2174,7 +2176,8 @@ + ** will be in the 1st request, so it's okay to do this. + */ + extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE, +- client->swapped); ++ client->swapped, ++ left - __GLX_RENDER_LARGE_HDR_SIZE); + if (extra < 0) { + return BadLength; + } +Index: xorg-server-1.15.1/glx/glxserver.h +=================================================================== +--- xorg-server-1.15.1.orig/glx/glxserver.h 2014-12-04 11:57:06.345650678 -0500 ++++ xorg-server-1.15.1/glx/glxserver.h 2014-12-04 11:57:06.337650627 -0500 +@@ -179,7 +179,7 @@ + /* + * Tables for computing the size of each rendering command. + */ +-typedef int (*gl_proto_size_func) (const GLbyte *, Bool); ++typedef int (*gl_proto_size_func) (const GLbyte *, Bool, int); + + typedef struct { + int bytes; +Index: xorg-server-1.15.1/glx/indirect_reqsize.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/indirect_reqsize.c 2014-12-04 11:57:06.345650678 -0500 ++++ xorg-server-1.15.1/glx/indirect_reqsize.c 2014-12-04 11:57:06.337650627 -0500 +@@ -31,24 +31,22 @@ + #include "indirect_size.h" + #include "indirect_reqsize.h" + +-#define __GLX_PAD(x) (((x) + 3) & ~3) +- + #if defined(__CYGWIN__) || defined(__MINGW32__) + #undef HAVE_ALIAS + #endif + #ifdef HAVE_ALIAS + #define ALIAS2(from,to) \ +- GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \ ++ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \ + __attribute__ ((alias( # to ))); + #define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize ) + #else + #define ALIAS(from,to) \ +- GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \ +- { return __glX ## to ## ReqSize( pc, swap ); } ++ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \ ++ { return __glX ## to ## ReqSize( pc, swap, reqlen ); } + #endif + + int +-__glXCallListsReqSize(const GLbyte * pc, Bool swap) ++__glXCallListsReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 0); + GLenum type = *(GLenum *) (pc + 4); +@@ -60,11 +58,11 @@ + } + + compsize = __glCallLists_size(type); +- return __GLX_PAD((compsize * n)); ++ return safe_pad(safe_mul(compsize, n)); + } + + int +-__glXBitmapReqSize(const GLbyte * pc, Bool swap) ++__glXBitmapReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -88,7 +86,7 @@ + } + + int +-__glXFogfvReqSize(const GLbyte * pc, Bool swap) ++__glXFogfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 0); + GLsizei compsize; +@@ -98,11 +96,11 @@ + } + + compsize = __glFogfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXLightfvReqSize(const GLbyte * pc, Bool swap) ++__glXLightfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -112,11 +110,11 @@ + } + + compsize = __glLightfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXLightModelfvReqSize(const GLbyte * pc, Bool swap) ++__glXLightModelfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 0); + GLsizei compsize; +@@ -126,11 +124,11 @@ + } + + compsize = __glLightModelfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXMaterialfvReqSize(const GLbyte * pc, Bool swap) ++__glXMaterialfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -140,11 +138,11 @@ + } + + compsize = __glMaterialfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap) ++__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -164,7 +162,7 @@ + } + + int +-__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -174,11 +172,11 @@ + } + + compsize = __glTexParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXTexImage1DReqSize(const GLbyte * pc, Bool swap) ++__glXTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -206,7 +204,7 @@ + } + + int +-__glXTexImage2DReqSize(const GLbyte * pc, Bool swap) ++__glXTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -236,7 +234,7 @@ + } + + int +-__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap) ++__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -246,11 +244,11 @@ + } + + compsize = __glTexEnvfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXTexGendvReqSize(const GLbyte * pc, Bool swap) ++__glXTexGendvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -260,11 +258,11 @@ + } + + compsize = __glTexGendv_size(pname); +- return __GLX_PAD((compsize * 8)); ++ return safe_pad(safe_mul(compsize, 8)); + } + + int +-__glXTexGenfvReqSize(const GLbyte * pc, Bool swap) ++__glXTexGenfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -274,11 +272,11 @@ + } + + compsize = __glTexGenfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap) ++__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei mapsize = *(GLsizei *) (pc + 4); + +@@ -286,11 +284,11 @@ + mapsize = bswap_32(mapsize); + } + +- return __GLX_PAD((mapsize * 4)); ++ return safe_pad(safe_mul(mapsize, 4)); + } + + int +-__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap) ++__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei mapsize = *(GLsizei *) (pc + 4); + +@@ -298,11 +296,11 @@ + mapsize = bswap_32(mapsize); + } + +- return __GLX_PAD((mapsize * 2)); ++ return safe_pad(safe_mul(mapsize, 2)); + } + + int +-__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap) ++__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -330,7 +328,7 @@ + } + + int +-__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap) ++__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 0); + +@@ -338,11 +336,11 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 4) + (n * 4)); ++ return safe_pad(safe_add(safe_mul(n, 4), safe_mul(n, 4))); + } + + int +-__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap) ++__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -370,7 +368,7 @@ + } + + int +-__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap) ++__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -400,7 +398,7 @@ + } + + int +-__glXColorTableReqSize(const GLbyte * pc, Bool swap) ++__glXColorTableReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -428,7 +426,7 @@ + } + + int +-__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -438,11 +436,11 @@ + } + + compsize = __glColorTableParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXColorSubTableReqSize(const GLbyte * pc, Bool swap) ++__glXColorSubTableReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -470,7 +468,7 @@ + } + + int +-__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap) ++__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -498,7 +496,7 @@ + } + + int +-__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap) ++__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -528,7 +526,7 @@ + } + + int +-__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -538,11 +536,11 @@ + } + + compsize = __glConvolutionParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXTexImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = *(GLint *) (pc + 8); +@@ -579,7 +577,7 @@ + } + + int +-__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = *(GLint *) (pc + 8); +@@ -613,7 +611,7 @@ + } + + int +-__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 20); + +@@ -621,11 +619,11 @@ + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 24); + +@@ -633,11 +631,11 @@ + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 28); + +@@ -645,11 +643,11 @@ + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 36); + +@@ -657,11 +655,11 @@ + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 0); + GLsizei compsize; +@@ -671,11 +669,11 @@ + } + + compsize = __glPointParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap) ++__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 0); + +@@ -683,11 +681,11 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 4)); ++ return safe_pad(safe_mul(n, 4)); + } + + int +-__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap) ++__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei len = *(GLsizei *) (pc + 8); + +@@ -695,11 +693,11 @@ + len = bswap_32(len); + } + +- return __GLX_PAD(len); ++ return safe_pad(len); + } + + int +-__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -707,11 +705,11 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 8)); ++ return safe_pad(safe_mul(n, 8)); + } + + int +-__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -719,11 +717,11 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 16)); ++ return safe_pad(safe_mul(n, 16)); + } + + int +-__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -731,11 +729,11 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 24)); ++ return safe_pad(safe_mul(n, 24)); + } + + int +-__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -743,11 +741,11 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 12)); ++ return safe_pad(safe_mul(n, 12)); + } + + int +-__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -755,11 +753,11 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 6)); ++ return safe_pad(safe_mul(n, 6)); + } + + int +-__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -767,7 +765,7 @@ + n = bswap_32(n); + } + +- return __GLX_PAD((n * 32)); ++ return safe_pad(safe_mul(n, 32)); + } + + ALIAS(Fogiv, Fogfv) +Index: xorg-server-1.15.1/glx/indirect_reqsize.h +=================================================================== +--- xorg-server-1.15.1.orig/glx/indirect_reqsize.h 2014-12-04 11:57:06.345650678 -0500 ++++ xorg-server-1.15.1/glx/indirect_reqsize.h 2014-12-04 11:57:06.337650627 -0500 +@@ -36,115 +36,156 @@ + #define PURE + #endif + +-extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap); ++extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXPolygonStippleReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexParameterivReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXPrioritizeTexturesReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexSubImage1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexSubImage2DReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXColorTableParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXColorTableParameterivReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXColorSubTableReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionFilter1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionFilter2DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionParameterivReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXSeparableFilter2DReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXTexSubImage3DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage2DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage3DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage2DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage3DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXPointParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXPointParameterivReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXProgramStringARBReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXDeleteFramebuffersReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXDeleteRenderbuffersReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs1dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs1fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs1svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs2dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs2fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs2svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs3dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs3fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs3svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4ubvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + + #undef PURE + +Index: xorg-server-1.15.1/glx/rensize.c +=================================================================== +--- xorg-server-1.15.1.orig/glx/rensize.c 2014-12-04 11:57:06.345650678 -0500 ++++ xorg-server-1.15.1/glx/rensize.c 2014-12-04 11:57:06.341650652 -0500 +@@ -44,7 +44,7 @@ + ((a & 0xff00U)<<8) | ((a & 0xffU)<<24)) + + int +-__glXMap1dReqSize(const GLbyte * pc, Bool swap) ++__glXMap1dReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint order; +@@ -61,7 +61,7 @@ + } + + int +-__glXMap1fReqSize(const GLbyte * pc, Bool swap) ++__glXMap1fReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint order; +@@ -86,7 +86,7 @@ + } + + int +-__glXMap2dReqSize(const GLbyte * pc, Bool swap) ++__glXMap2dReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint uorder, vorder; +@@ -103,7 +103,7 @@ + } + + int +-__glXMap2fReqSize(const GLbyte * pc, Bool swap) ++__glXMap2fReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint uorder, vorder; +@@ -359,13 +359,14 @@ + } + + int +-__glXDrawArraysReqSize(const GLbyte * pc, Bool swap) ++__glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc; + __GLXdispatchDrawArraysComponentHeader *compHeader; + GLint numVertexes = hdr->numVertexes; + GLint numComponents = hdr->numComponents; + GLint arrayElementSize = 0; ++ GLint x, size; + int i; + + if (swap) { +@@ -374,6 +375,13 @@ + } + + pc += sizeof(__GLXdispatchDrawArraysHeader); ++ reqlen -= sizeof(__GLXdispatchDrawArraysHeader); ++ ++ size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader), ++ numComponents); ++ if (size < 0 || reqlen < 0 || reqlen < size) ++ return -1; ++ + compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; + + for (i = 0; i < numComponents; i++) { +@@ -417,17 +425,18 @@ + return -1; + } + +- arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype)); ++ x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype))); ++ if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0) ++ return -1; + + pc += sizeof(__GLXdispatchDrawArraysComponentHeader); + } + +- return ((numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader)) + +- (numVertexes * arrayElementSize)); ++ return safe_add(size, safe_mul(numVertexes, arrayElementSize)); + } + + int +-__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap) ++__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + __GLXdispatchConvolutionFilterHeader *hdr = + (__GLXdispatchConvolutionFilterHeader *) pc; only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0033-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0033-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch @@ -0,0 +1,34 @@ +From a7c63d6599067dc8ff0d114536d2db3fadb4e195 Mon Sep 17 00:00:00 2001 +From: Robert Morell +Date: Wed, 12 Nov 2014 18:51:43 -0800 +Subject: [PATCH 33/33] glx: Fix mask truncation in __glXGetAnswerBuffer + [CVE-2014-8093 6/6] + +On a system where sizeof(unsigned) != sizeof(intptr_t), the unary +bitwise not operation will result in a mask that clears all high bits +from temp_buf in the expression: + temp_buf = (temp_buf + mask) & ~mask; + +Signed-off-by: Robert Morell +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith +--- + glx/indirect_util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glx/indirect_util.c b/glx/indirect_util.c +index de81491..9ba2815 100644 +--- a/glx/indirect_util.c ++++ b/glx/indirect_util.c +@@ -73,7 +73,7 @@ __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size, + void *local_buffer, size_t local_size, unsigned alignment) + { + void *buffer = local_buffer; +- const unsigned mask = alignment - 1; ++ const intptr_t mask = alignment - 1; + + if (local_size < required_size) { + size_t worst_case_size; +-- +1.7.9.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0034-CVE-2014-8097-additional.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0034-CVE-2014-8097-additional.patch @@ -0,0 +1,47 @@ +From b20912c3d45cbbde3c443e6c3d9e189092fe65e1 Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Tue, 9 Dec 2014 09:30:57 -0800 +Subject: dbe: Call to DDX SwapBuffers requires address of int, not unsigned + int [CVE-2014-8097 pt. 2] + +When the local types used to walk the DBE request were changed, this +changed the type of the parameter passed to the DDX SwapBuffers API, +but there wasn't a matching change in the API definition. + +At this point, with the API frozen, I just stuck a new variable in +with the correct type. Because we've already bounds-checked nStuff to +be smaller than UINT32_MAX / sizeof(DbeSwapInfoRec), we know it will +fit in a signed int without overflow. + +Signed-off-by: Keith Packard +Signed-off-by: Alan Coopersmith + +diff --git a/dbe/dbe.c b/dbe/dbe.c +index df2ad5c..e5d928d 100644 +--- a/dbe/dbe.c ++++ b/dbe/dbe.c +@@ -452,6 +452,7 @@ ProcDbeSwapBuffers(ClientPtr client) + int error; + unsigned int i, j; + unsigned int nStuff; ++ int nStuff_i; /* DDX API requires int for nStuff */ + + REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); + nStuff = stuff->n; /* use local variable for performance. */ +@@ -527,9 +528,10 @@ ProcDbeSwapBuffers(ClientPtr client) + * could deal with cross-screen synchronization. + */ + +- while (nStuff > 0) { ++ nStuff_i = nStuff; ++ while (nStuff_i > 0) { + pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow); +- error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff, swapInfo); ++ error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff_i, swapInfo); + if (error != Success) { + free(swapInfo); + return error; +-- +cgit v0.10.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0035-CVE-2014-8098-additional.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0035-CVE-2014-8098-additional.patch @@ -0,0 +1,36 @@ +From 61b17c0f10307e25e51e30e6fb1d3e3127f82d86 Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Tue, 9 Dec 2014 09:30:58 -0800 +Subject: glx: Can't mix declarations and code in X.org sources [CVE-2014-8098 + pt. 9] + +We're using compiler compatibility settings which generate warnings +when a variable is declared after the first statement. + +Signed-off-by: Keith Packard +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith + +diff --git a/glx/clientinfo.c b/glx/clientinfo.c +index c5fef30..74ad919 100644 +--- a/glx/clientinfo.c ++++ b/glx/clientinfo.c +@@ -36,13 +36,14 @@ set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req, + ClientPtr client = cl->client; + char *gl_extensions; + char *glx_extensions; ++ int size; + + REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); + + /* Verify that the size of the packet matches the size inferred from the + * sizes specified for the various fields. + */ +- int size = sz_xGLXSetClientInfoARBReq; ++ size = sz_xGLXSetClientInfoARBReq; + size = safe_add(size, safe_mul(req->numVersions, bytes_per_version)); + size = safe_add(size, safe_pad(req->numGLExtensionBytes)); + size = safe_add(size, safe_pad(req->numGLXExtensionBytes)); +-- +cgit v0.10.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0036-CVE-2014-8092-additional.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0036-CVE-2014-8092-additional.patch @@ -0,0 +1,28 @@ +From 9802a0162f738de03585ca3f3b8a8266494f7d45 Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Tue, 9 Dec 2014 09:30:59 -0800 +Subject: Missing parens in REQUEST_FIXED_SIZE macro [CVE-2014-8092 pt. 5] + +The 'n' parameter must be surrounded by parens in both places to +prevent precedence from mis-computing things. + +Signed-off-by: Keith Packard +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith + +diff --git a/include/dix.h b/include/dix.h +index 21176a8..921156b 100644 +--- a/include/dix.h ++++ b/include/dix.h +@@ -80,7 +80,7 @@ SOFTWARE. + + #define REQUEST_FIXED_SIZE(req, n)\ + if (((sizeof(req) >> 2) > client->req_len) || \ +- ((n >> 2) >= client->req_len) || \ ++ (((n) >> 2) >= client->req_len) || \ + ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len)) \ + return(BadLength) + +-- +cgit v0.10.2 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0037-CVE-2014-8092-additional-2.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0037-CVE-2014-8092-additional-2.patch @@ -0,0 +1,29 @@ +From 1559a94395258fd73e369f1a2c98a44bfe21a486 Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Tue, 9 Dec 2014 09:31:00 -0800 +Subject: dix: GetHosts bounds check using wrong pointer value [CVE-2014-8092 + pt. 6] + +GetHosts saves the pointer to allocated memory in *data, and then +wants to bounds-check writes to that region, but was mistakenly using +a bare 'data' instead of '*data'. Also, data is declared as void **, +so we need a cast to turn it into a byte pointer so we can actually do +pointer comparisons. + +Signed-off-by: Keith Packard +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith + +Index: xorg-server-1.15.1/os/access.c +=================================================================== +--- xorg-server-1.15.1.orig/os/access.c 2014-12-09 17:12:07.880851371 -0500 ++++ xorg-server-1.15.1/os/access.c 2014-12-09 17:12:07.880851371 -0500 +@@ -1335,7 +1335,7 @@ + } + for (host = validhosts; host; host = host->next) { + len = host->len; +- if ((ptr + sizeof(xHostEntry) + len) > (data + n)) ++ if ((ptr + sizeof(xHostEntry) + len) > ((unsigned char *) *data + n)) + break; + ((xHostEntry *) ptr)->family = host->family; + ((xHostEntry *) ptr)->length = len; only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2014-8xxx/0038-CVE-2014-8092-dix-allow-zero-height-putimage-requests.patch +++ xorg-server-1.15.1/debian/patches/CVE-2014-8xxx/0038-CVE-2014-8092-dix-allow-zero-height-putimage-requests.patch @@ -0,0 +1,26 @@ +From dc777c346d5d452a53b13b917c45f6a1bad2f20b Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Sat, 3 Jan 2015 08:46:45 -0800 +Subject: dix: Allow zero-height PutImage requests + +The length checking code validates PutImage height and byte width by +making sure that byte-width >= INT32_MAX / height. If height is zero, +this generates a divide by zero exception. Allow zero height requests +explicitly, bypassing the INT32_MAX check. + +Signed-off-by: Keith Packard +Reviewed-by: Alan Coopersmith + +Index: xorg-server-1.15.1/dix/dispatch.c +=================================================================== +--- xorg-server-1.15.1.orig/dix/dispatch.c 2015-02-12 08:42:03.219842220 -0500 ++++ xorg-server-1.15.1/dix/dispatch.c 2015-02-12 08:42:03.215842190 -0500 +@@ -1957,7 +1957,7 @@ + tmpImage = (char *) &stuff[1]; + lengthProto = length; + +- if (lengthProto >= (INT32_MAX / stuff->height)) ++ if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height)) + return BadLength; + + if ((bytes_to_int32(lengthProto * stuff->height) + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/CVE-2015-0255.patch +++ xorg-server-1.15.1/debian/patches/CVE-2015-0255.patch @@ -0,0 +1,173 @@ +Description: fix information leak and denial of service in XkbSetGeometry +Origin: upstream, http://cgit.freedesktop.org/xorg/xserver/commit/?id=81c90dc8f0aae3b65730409b1b615b5fa7280ebd +Origin: upstream, http://cgit.freedesktop.org/xorg/xserver/commit/?id=20079c36cf7d377938ca5478447d8b9045cb7d43 + +Index: xorg-server-1.16.0/xkb/xkb.c +=================================================================== +--- xorg-server-1.16.0.orig/xkb/xkb.c 2014-04-16 16:24:00.000000000 -0400 ++++ xorg-server-1.16.0/xkb/xkb.c 2015-02-12 08:26:28.580725260 -0500 +@@ -4957,26 +4957,29 @@ + + /***====================================================================***/ + +-static char * +-_GetCountedString(char **wire_inout, Bool swap) ++static Status ++_GetCountedString(char **wire_inout, ClientPtr client, char **str) + { +- char *wire, *str; +- CARD16 len, *plen; ++ char *wire, *next; ++ CARD16 len; + + wire = *wire_inout; +- plen = (CARD16 *) wire; +- if (swap) { +- swaps(plen); +- } +- len = *plen; +- str = malloc(len + 1); +- if (str) { +- memcpy(str, &wire[2], len); +- str[len] = '\0'; ++ len = *(CARD16 *) wire; ++ if (client->swapped) { ++ swaps(&len); + } +- wire += XkbPaddedSize(len + 2); +- *wire_inout = wire; +- return str; ++ next = wire + XkbPaddedSize(len + 2); ++ /* Check we're still within the size of the request */ ++ if (client->req_len < ++ bytes_to_int32(next - (char *) client->requestBuffer)) ++ return BadValue; ++ *str = malloc(len + 1); ++ if (!*str) ++ return BadAlloc; ++ memcpy(*str, &wire[2], len); ++ *(*str + len) = '\0'; ++ *wire_inout = next; ++ return Success; + } + + static Status +@@ -4985,25 +4988,29 @@ + { + char *wire; + xkbDoodadWireDesc *dWire; ++ xkbAnyDoodadWireDesc any; ++ xkbTextDoodadWireDesc text; + XkbDoodadPtr doodad; ++ Status status; + + dWire = (xkbDoodadWireDesc *) (*wire_inout); ++ any = dWire->any; + wire = (char *) &dWire[1]; + if (client->swapped) { +- swapl(&dWire->any.name); +- swaps(&dWire->any.top); +- swaps(&dWire->any.left); +- swaps(&dWire->any.angle); ++ swapl(&any.name); ++ swaps(&any.top); ++ swaps(&any.left); ++ swaps(&any.angle); + } + CHK_ATOM_ONLY(dWire->any.name); +- doodad = XkbAddGeomDoodad(geom, section, dWire->any.name); ++ doodad = XkbAddGeomDoodad(geom, section, any.name); + if (!doodad) + return BadAlloc; + doodad->any.type = dWire->any.type; + doodad->any.priority = dWire->any.priority; +- doodad->any.top = dWire->any.top; +- doodad->any.left = dWire->any.left; +- doodad->any.angle = dWire->any.angle; ++ doodad->any.top = any.top; ++ doodad->any.left = any.left; ++ doodad->any.angle = any.angle; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: +@@ -5026,15 +5033,22 @@ + dWire->text.colorNdx); + return BadMatch; + } ++ text = dWire->text; + if (client->swapped) { +- swaps(&dWire->text.width); +- swaps(&dWire->text.height); ++ swaps(&text.width); ++ swaps(&text.height); + } +- doodad->text.width = dWire->text.width; +- doodad->text.height = dWire->text.height; ++ doodad->text.width = text.width; ++ doodad->text.height = text.height; + doodad->text.color_ndx = dWire->text.colorNdx; +- doodad->text.text = _GetCountedString(&wire, client->swapped); +- doodad->text.font = _GetCountedString(&wire, client->swapped); ++ status = _GetCountedString(&wire, client, &doodad->text.text); ++ if (status != Success) ++ return status; ++ status = _GetCountedString(&wire, client, &doodad->text.font); ++ if (status != Success) { ++ free (doodad->text.text); ++ return status; ++ } + break; + case XkbIndicatorDoodad: + if (dWire->indicator.onColorNdx >= geom->num_colors) { +@@ -5069,7 +5083,9 @@ + } + doodad->logo.color_ndx = dWire->logo.colorNdx; + doodad->logo.shape_ndx = dWire->logo.shapeNdx; +- doodad->logo.logo_name = _GetCountedString(&wire, client->swapped); ++ status = _GetCountedString(&wire, client, &doodad->logo.logo_name); ++ if (status != Success) ++ return status; + break; + default: + client->errorValue = _XkbErrCode2(0x4F, dWire->any.type); +@@ -5301,18 +5317,20 @@ + char *wire; + + wire = (char *) &req[1]; +- geom->label_font = _GetCountedString(&wire, client->swapped); ++ status = _GetCountedString(&wire, client, &geom->label_font); ++ if (status != Success) ++ return status; + + for (i = 0; i < req->nProperties; i++) { + char *name, *val; + +- name = _GetCountedString(&wire, client->swapped); +- if (!name) +- return BadAlloc; +- val = _GetCountedString(&wire, client->swapped); +- if (!val) { ++ status = _GetCountedString(&wire, client, &name); ++ if (status != Success) ++ return status; ++ status = _GetCountedString(&wire, client, &val); ++ if (status != Success) { + free(name); +- return BadAlloc; ++ return status; + } + if (XkbAddGeomProperty(geom, name, val) == NULL) { + free(name); +@@ -5346,9 +5364,9 @@ + for (i = 0; i < req->nColors; i++) { + char *name; + +- name = _GetCountedString(&wire, client->swapped); +- if (!name) +- return BadAlloc; ++ status = _GetCountedString(&wire, client, &name); ++ if (status != Success) ++ return status; + if (!XkbAddGeomColor(geom, name, geom->num_colors)) { + free(name); + return BadAlloc; only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/drm_device_keep_trying.patch +++ xorg-server-1.15.1/debian/patches/drm_device_keep_trying.patch @@ -0,0 +1,172 @@ +From: Maarten Lankhorst +Subject: [PATCH] do not use drmGetBusid to grab the pci-id name + +The kernel returns EACCES or EAGAIN on drm open when the drm device is +currently unavailable, such as if it is in use by another process +(e.g. plymouth), or hasn't finished initializing (e.g. on a really fast +SSD). Because the probing is done before a vt switch is completed, +we have no way to ensure that we can own DRM master. This results +in failing to boot. + +Also attrib->unowned is not initialized, always initialize it to fix +a valgrind warning, and to prevent adding the same device a second time +after a vt switch. + +Fixes: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/982889 + +Signed-off-by: Bryce Harrington +--- + hw/xfree86/os-support/linux/lnx_platform.c | 29 +++++++++++++++++++++++++--- + 1 file changed, 26 insertions(+), 3 deletions(-) + +--- a/config/udev.c ++++ b/config/udev.c +@@ -98,7 +98,7 @@ + if (strncmp(sysname, "card", 4) != 0) + return; + +- LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path); ++ LogMessage(X_INFO, "config/udev: Adding drm device (%s) %s %s\n", path, sysname, syspath); + + config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest); + return; +@@ -430,11 +430,23 @@ + #ifdef CONFIG_UDEV_KMS + + static Bool ++get_pci_busid(const char *in, char *pci_str) ++{ ++ int ret, domain, bus, dev, func; ++ ret = sscanf(in, "/%04x:%02x:%02x.%d/drm/card%*d", &domain, &bus, &dev, &func); ++ if (ret != 4) ++ return FALSE; ++ sprintf(pci_str, "pci:%04x:%02x:%02x.%d", domain, bus, dev, func); ++ return TRUE; ++} ++ ++static Bool + config_udev_odev_setup_attribs(const char *path, const char *syspath, + config_odev_probe_proc_ptr probe_callback) + { + struct OdevAttributes *attribs = config_odev_allocate_attribute_list(); + int ret; ++ const char *platform; + + if (!attribs) + return FALSE; +@@ -447,6 +459,33 @@ + if (ret == FALSE) + goto fail; + ++ if (strstr(syspath, "/devices/pci")) { ++ char pci_str[17]; ++ const char *end = strstr(syspath, "/drm/card"); ++ if (strstr(syspath, "/usb")) ++ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_BUSID, ""); ++ else if (get_pci_busid(end - 13, pci_str)) ++ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_BUSID, pci_str); ++ } else if ((platform = strstr(syspath, "/devices/platform/"))) { ++ /* OMAP relies on this, modesetting doesn't use it */ ++ const char *end; ++ platform += 18; ++ end = strchr(platform, '.'); ++ if (end) { ++ char *busid; ++ ret = asprintf(&busid, "platform:%.*s:%02li", ++ (int)(end - platform), platform, strtol(end + 1, NULL, 10)); ++ if (ret >= 0) { ++ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_BUSID, busid); ++ free(busid); ++ } ++ else ++ ret = TRUE; ++ } ++ } ++ if (ret == FALSE) ++ goto fail; ++ + /* ownership of attribs is passed to probe layer */ + probe_callback(attribs); + return TRUE; +--- a/hw/xfree86/os-support/linux/lnx_platform.c ++++ b/hw/xfree86/os-support/linux/lnx_platform.c +@@ -19,44 +19,6 @@ + + #include "hotplug.h" + +-static Bool +-get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) +-{ +- drmSetVersion sv; +- char *buf; +- int fd; +- int err = 0; +- +- fd = open(path, O_RDWR, O_CLOEXEC); +- if (fd == -1) +- return FALSE; +- +- sv.drm_di_major = 1; +- sv.drm_di_minor = 4; +- sv.drm_dd_major = -1; /* Don't care */ +- sv.drm_dd_minor = -1; /* Don't care */ +- +- err = drmSetInterfaceVersion(fd, &sv); +- if (err) { +- ErrorF("setversion 1.4 failed: %s\n", strerror(-err)); +- goto out; +- } +- +- /* for a delayed probe we've already added the device */ +- if (delayed_index == -1) { +- xf86_add_platform_device(attribs); +- delayed_index = xf86_num_platform_devices - 1; +- } +- +- buf = drmGetBusid(fd); +- xf86_add_platform_device_attrib(delayed_index, +- ODEV_ATTRIB_BUSID, buf); +- drmFreeBusid(buf); +-out: +- close(fd); +- return (err == 0); +-} +- + Bool + xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid) + { +@@ -105,11 +67,6 @@ + char *dpath; + dpath = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH); + +- ret = get_drm_info(attribs, dpath, index); +- if (ret == FALSE) { +- xf86_remove_platform_device(index); +- return; +- } + ret = xf86platformAddDevice(index); + if (ret == -1) + xf86_remove_platform_device(index); +@@ -145,18 +102,10 @@ + + LogMessage(X_INFO, "xfree86: Adding drm device (%s)\n", path); + +- if (!xf86VTOwner()) { +- /* if we don't currently own the VT then don't probe the device, +- just mark it as unowned for later use */ +- attribs->unowned = TRUE; +- xf86_add_platform_device(attribs); +- return; +- } +- +- ret = get_drm_info(attribs, path, -1); +- if (ret == FALSE) +- goto out_free; +- ++ /* if we don't currently own the VT then don't probe the device, ++ just mark it as unowned for later use */ ++ attribs->unowned = !xf86VTOwner(); ++ xf86_add_platform_device(attribs); + return; + + out_free: only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/fb-24-depth.patch +++ xorg-server-1.15.1/debian/patches/fb-24-depth.patch @@ -0,0 +1,35 @@ +commit fe5018e0564118a7a8198fa286186fdb9ed818c7 +Author: Takashi Iwai +Date: Tue Aug 19 15:57:22 2014 -0500 + + fb: Fix invalid bpp for 24bit depth window + + We have a hack in fb layer for a 24bpp screen to use 32bpp images, and + fbCreateWindow() replaces its drawable.bitsPerPixel field + appropriately. But, the problem is that it always replaces when 32bpp + is passed. If the depth is 32, this results in bpp < depth, which is + actually invalid. + + Meanwhile, fbCreatePixmap() has a more check and it creates with 24bpp + only when the passed depth <= 24 for avoiding such a problem. + + This oneliner patch just adds the similar check in fbCreateWindow(). + This (hopefully) fixes the long-standing broken graphics mess of + cirrus KMS with 24bpp. + + Signed-off-by: Takashi Iwai + Reviewed-by: Keith Packard + +diff --git a/fb/fbwindow.c b/fb/fbwindow.c +index 368c4b8..c90175f 100644 +--- a/fb/fbwindow.c ++++ b/fb/fbwindow.c +@@ -33,7 +33,7 @@ fbCreateWindow(WindowPtr pWin) + { + dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin), + fbGetScreenPixmap(pWin->drawable.pScreen)); +- if (pWin->drawable.bitsPerPixel == 32) ++ if (pWin->drawable.bitsPerPixel == 32 && pWin->drawable.depth <= 24) + pWin->drawable.bitsPerPixel = + fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp; + return TRUE; only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/mi-dont-process-disabled.patch +++ xorg-server-1.15.1/debian/patches/mi-dont-process-disabled.patch @@ -0,0 +1,62 @@ +Date: Tue, 20 May 2014 14:32:59 +1000 +From: Peter Hutterer +Subject: [PATCH] mi: don't process events from disabled devices (#77884) + +Once a device is disabled, it doesn't have a sprite pointer anymore. If an +event is still in the queue and processed after DisableDevice finished, a +dereference causes a crash. Example backtrace (crash forced by injecting an +event at the right time): + +(EE) 0: /opt/xorg/bin/Xorg (OsSigHandler+0x3c) [0x48d334] +(EE) 1: /lib64/libpthread.so.0 (__restore_rt+0x0) [0x37fcc0f74f] +(EE) 2: /opt/xorg/bin/Xorg (mieqMoveToNewScreen+0x38) [0x609240] +(EE) 3: /opt/xorg/bin/Xorg (mieqProcessDeviceEvent+0xd4) [0x609389] +(EE) 4: /opt/xorg/bin/Xorg (mieqProcessInputEvents+0x206) [0x609720] +(EE) 5: /opt/xorg/bin/Xorg (ProcessInputEvents+0xd) [0x4aeb58] +(EE) 6: /opt/xorg/bin/Xorg (xf86VTSwitch+0x1a6) [0x4af457] +(EE) 7: /opt/xorg/bin/Xorg (xf86Wakeup+0x2bf) [0x4af0a7] +(EE) 8: /opt/xorg/bin/Xorg (WakeupHandler+0x83) [0x4445cb] +(EE) 9: /opt/xorg/bin/Xorg (WaitForSomething+0x3fe) [0x491bf6] +(EE) 10: /opt/xorg/bin/Xorg (Dispatch+0x97) [0x435748] +(EE) 11: /opt/xorg/bin/Xorg (dix_main+0x61d) [0x4438a9] +(EE) 12: /opt/xorg/bin/Xorg (main+0x28) [0x49ba28] +(EE) 13: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x37fc821d65] +(EE) 14: /opt/xorg/bin/Xorg (_start+0x29) [0x425e69] +(EE) 15: ? (?+0x29) [0x29] + +xf86VTSwitch() calls ProcessInputEvents() before disabling a device, and +DisableDevice() calls mieqProcessInputEvents() again when flushing touches and +button events. Between that and disabling the device (which causes new events +to be refused) there is a window where events may be triggered and enqueued. +On the next call to PIE that event is processed on a now defunct device, +causing the crash. + +The simplest fix to this is to discard events from disabled devices. We flush +the queue often enough before disabling that when we get here, we really don't +care about the events from this device. + +X.Org Bug 77884 +--- +Modified by Maarten Lankhorst to pass tests. + + mi/mieq.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/mi/mieq.c b/mi/mieq.c +index 4c07480..188a0b0 100644 +--- a/mi/mieq.c ++++ b/mi/mieq.c +@@ -515,6 +515,10 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, InternalEvent *event, ScreenPtr screen) + + verify_internal_event(event); + ++ /* refuse events from disabled devices */ ++ if (dev && !dev->enabled) ++ return 0; ++ + /* Custom event handler */ + handler = miEventQueue.handlers[event->any.type]; + +-- +1.9.0 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/os-timer-fix.patch +++ xorg-server-1.15.1/debian/patches/os-timer-fix.patch @@ -0,0 +1,78 @@ +--- orig/xorg-server-1.15.1/os/WaitFor.c 2014-04-14 04:54:50.000000000 +0200 ++++ xorg-server-1.15.1/os/WaitFor.c 2016-01-03 20:27:53.662913123 +0100 +@@ -123,7 +123,7 @@ + + static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev); + static void CheckAllTimers(void); +-static OsTimerPtr timers = NULL; ++static volatile OsTimerPtr timers = NULL; + + /***************** + * WaitForSomething: +@@ -263,11 +263,14 @@ + if ((int) (timers->expires - now) <= 0) + expired = 1; + +- while (timers && (int) (timers->expires - now) <= 0) +- DoTimer(timers, now, &timers); ++ if (expired) { ++ OsBlockSignals(); ++ while (timers && (int) (timers->expires - now) <= 0) ++ DoTimer(timers, now, &timers); ++ OsReleaseSignals(); + +- if (expired) + return 0; ++ } + } + } + else { +@@ -281,11 +284,14 @@ + if ((int) (timers->expires - now) <= 0) + expired = 1; + +- while (timers && (int) (timers->expires - now) <= 0) +- DoTimer(timers, now, &timers); +- +- if (expired) +- return 0; ++ if (expired) { ++ OsBlockSignals(); ++ while (timers && (int) (timers->expires - now) <= 0) ++ DoTimer(timers, now, &timers); ++ OsReleaseSignals(); ++ ++ return 0; ++ } + } + } + if (someReady) +@@ -408,10 +414,11 @@ + OsBlockSignals(); + *prev = timer->next; + timer->next = NULL; ++ OsReleaseSignals(); ++ + newTime = (*timer->callback) (timer, now, timer->arg); + if (newTime) + TimerSet(timer, 0, newTime, timer->callback, timer->arg); +- OsReleaseSignals(); + } + + OsTimerPtr +@@ -515,8 +522,13 @@ + { + CARD32 now = GetTimeInMillis(); + +- while (timers && (int) (timers->expires - now) <= 0) +- DoTimer(timers, now, &timers); ++ if(timers && (int) (timers->expires - now) <= 0) { ++ OsBlockSignals(); ++ while (timers && (int) (timers->expires - now) <= 0) ++ DoTimer(timers, now, &timers); ++ OsReleaseSignals(); ++ } ++ + } + + void only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/ppc64el-endian-fix.patch +++ xorg-server-1.15.1/debian/patches/ppc64el-endian-fix.patch @@ -0,0 +1,34 @@ +From adb7bc3386559dfee34b359dadcbb6796bc416e7 Mon Sep 17 00:00:00 2001 +From: Dinar Valeev +Date: Mon, 24 Feb 2014 10:36:54 +0000 +Subject: arch: Fix image and bitmap byte order for ppc64le + +So far PPC was big endian for sure. For ppc64le this is no longer +true. + +Signed-off-by: Egbert Eich +Reviewed-by: Mark Kettenis +Signed-off-by: Keith Packard +--- +diff --git a/include/servermd.h b/include/servermd.h +index 081123b..e413314 100644 +--- a/include/servermd.h ++++ b/include/servermd.h +@@ -114,8 +114,13 @@ SOFTWARE. + + #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) + +-#define IMAGE_BYTE_ORDER MSBFirst +-#define BITMAP_BIT_ORDER MSBFirst ++#if defined(__LITTLE_ENDIAN__) ++#define IMAGE_BYTE_ORDER LSBFirst ++#define BITMAP_BIT_ORDER LSBFirst ++#else ++#define IMAGE_BYTE_ORDER MSBFirst ++#define BITMAP_BIT_ORDER MSBFirst ++#endif + #define GLYPHPADBYTES 4 + + #endif /* PowerPC */ +-- +cgit v0.9.0.2-2-gbebe only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/rotation-slaved-crtc-bounds.patch +++ xorg-server-1.15.1/debian/patches/rotation-slaved-crtc-bounds.patch @@ -0,0 +1,122 @@ +From: Chris Wilson +To: xorg-devel@lists.x.org +Subject: [PATCH 2/3] randr: Consider rotation of slaved crtcs when computing bounds +Date: Wed, 23 Jul 2014 12:35:14 +0100 + +When creating a pixmap to cover a rotated slaved CRTC, we need to +consider its rotated size as that is the area that it occupies in the +framebuffer. The slave is then responsible for mapping the copy of the +framebuffer onto the rotated scanout - which can be the usual RandR +shadow composite method. + +Signed-off-by: Chris Wilson +Cc: Dave Airlie +Cc: Maarten Lankhorst +--- + randr/rrcrtc.c | 56 ++++++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 36 insertions(+), 20 deletions(-) + +--- a/randr/rrcrtc.c ++++ b/randr/rrcrtc.c +@@ -273,27 +273,43 @@ + return FALSE; + } + +-static void +-crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom) ++static int mode_height(const RRModeRec *mode, Rotation rotation) + { +- *left = crtc->x; +- *top = crtc->y; +- +- switch (crtc->rotation) { ++ switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_180: ++ return mode->mode.height; ++ case RR_Rotate_90: ++ case RR_Rotate_270: ++ return mode->mode.width; + default: +- *right = crtc->x + crtc->mode->mode.width; +- *bottom = crtc->y + crtc->mode->mode.height; +- return; ++ return 0; ++ } ++} ++ ++static int mode_width(const RRModeRec *mode, Rotation rotation) ++{ ++ switch (rotation & 0xf) { ++ case RR_Rotate_0: ++ case RR_Rotate_180: ++ return mode->mode.width; + case RR_Rotate_90: + case RR_Rotate_270: +- *right = crtc->x + crtc->mode->mode.height; +- *bottom = crtc->y + crtc->mode->mode.width; +- return; ++ return mode->mode.height; ++ default: ++ return 0; + } + } + ++static void ++crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom) ++{ ++ *left = crtc->x; ++ *top = crtc->y; ++ *right = crtc->x + mode_width(crtc->mode, crtc->rotation); ++ *bottom = crtc->y + mode_height(crtc->mode, crtc->rotation); ++} ++ + /* overlapping counts as adjacent */ + static Bool + crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b) +@@ -466,9 +482,9 @@ + if (!pScrPriv->crtcs[c]->mode) + continue; + newbox.x1 = pScrPriv->crtcs[c]->x; +- newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width; ++ newbox.x2 = pScrPriv->crtcs[c]->x + mode_width(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); + newbox.y1 = pScrPriv->crtcs[c]->y; +- newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height; ++ newbox.y2 = pScrPriv->crtcs[c]->y + mode_height(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); + } + RegionInit(&new_crtc_region, &newbox, 1); + RegionUnion(&total_region, &total_region, &new_crtc_region); +@@ -487,9 +503,9 @@ + if (!pScrPriv->crtcs[c]->mode) + continue; + newbox.x1 = pScrPriv->crtcs[c]->x; +- newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width; ++ newbox.x2 = pScrPriv->crtcs[c]->x + mode_width(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); + newbox.y1 = pScrPriv->crtcs[c]->y; +- newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height; ++ newbox.y2 = pScrPriv->crtcs[c]->y + mode_height(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); + } + RegionInit(&new_crtc_region, &newbox, 1); + RegionUnion(&total_region, &total_region, &new_crtc_region); +@@ -544,8 +560,8 @@ + int width = 0, height = 0; + + if (mode) { +- width = mode->mode.width; +- height = mode->mode.height; ++ width = mode_width(mode, rotation); ++ height = mode_height(mode, rotation); + } + ErrorF("have a master to look out for\n"); + ret = rrCheckPixmapBounding(master, crtc, +@@ -1672,8 +1688,8 @@ + changed = FALSE; + if (crtc->mode && crtc->x == pDrawable->x && + crtc->y == pDrawable->y && +- crtc->mode->mode.width == pDrawable->width && +- crtc->mode->mode.height == pDrawable->height) ++ mode_width(crtc->mode, crtc->rotation) == pDrawable->width && ++ mode_height(crtc->mode, crtc->rotation) == pDrawable->height) + size_fits = TRUE; + + /* is the pixmap already set? */ only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/xfree86_add_matchseat_key_description_to_xorg_conf_man.patch +++ xorg-server-1.15.1/debian/patches/xfree86_add_matchseat_key_description_to_xorg_conf_man.patch @@ -0,0 +1,68 @@ +From a6f5ffd5879e7fb052d343592951cc476b699bb4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?La=C3=A9rcio=20de=20Sousa?= +Date: Thu, 3 Apr 2014 11:19:15 -0300 +Subject: [PATCH] xfree86: add short description about MatchSeat key in + xorg.conf man page +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Laércio de Sousa +Reviewed-by: Dave Airlie +Signed-off-by: Peter Hutterer +--- + hw/xfree86/man/xorg.conf.man | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man +index 6d2652e..cadd87b 100644 +--- a/hw/xfree86/man/xorg.conf.man ++++ b/hw/xfree86/man/xorg.conf.man +@@ -1378,6 +1378,14 @@ for the regular text mode. + The frequency is specified in MHz. + This is rarely used. + .TP 7 ++.BI "MatchSeat " "seat\-id" ++Only apply this ++.B Device ++section if X server was started with ++.B -seat ++.I seat\-id ++option. ++.TP 7 + .BI "Option \*qModeDebug\*q \*q" boolean \*q + Enable printing of additional debugging information about modesetting to + the server log. +@@ -1900,6 +1908,14 @@ The only case where there is even a choice in this value is for depth 24, + where some hardware supports both a packed 24 bit framebuffer layout and a + sparse 32 bit framebuffer layout. + .TP 7 ++.BI "MatchSeat " "seat\-id" ++Only apply this ++.B Screen ++section if X server was started with ++.B -seat ++.I seat\-id ++option. ++.TP 7 + .B Options + Various + .B Option +@@ -2295,6 +2311,14 @@ and the first two should normally be used to indicate the core pointer + and core keyboard devices respectively. + .RE + .TP 7 ++.BI "MatchSeat " "seat\-id" ++Only apply this ++.B ServerLayout ++section if X server was started with ++.B -seat ++.I seat\-id ++option. ++.TP 7 + .B Options + In addition to the following, any option permitted in the + .B ServerFlags +-- +2.0.4 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/xfree86_add_matchseat_key_to_xorg_conf.patch +++ xorg-server-1.15.1/debian/patches/xfree86_add_matchseat_key_to_xorg_conf.patch @@ -0,0 +1,248 @@ +From 7070ebeebaca1b51f8a2801989120784a1c374ae Mon Sep 17 00:00:00 2001 +From: Oleg Samarin +Date: Thu, 3 Apr 2014 11:19:14 -0300 +Subject: [PATCH] xfree86: add new key MatchSeat to xorg.conf sections + "Device", "Screen", and "ServerLayout" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch introduces a new key MatchSeat in xorg.conf (also applies to +any .conf file in xorg.conf.d). It will allow targeting a given +"Device", "Screen", and/or "ServerLayout" section to a particular +seat only (specified by option "-seat" in X server command line), +so that other seats won't be affected. + +Without this patch, one needs to write a separate xorg.conf.custom +file and pass it to X server via "-config" option, if one wants that +these settings only apply for the right seat. However, in some cases, +this solution is undesirable or even impossible (e.g. when using GDM, +which doesn't allow X server command line customization). + +Example file (/etc/X11/xorg.conf.d/seat1.conf), which would be ignored +by X server unless it was started with "-seat seat1" option: + +Section "Device" + Identifier "card0" + Driver "nvidia" + Option "NoLogo" "True" + MatchSeat "seat1" +EndSection + +Signed-off-by: Oleg Samarin +Signed-off-by: Laércio de Sousa +Reviewed-by: Dave Airlie +Signed-off-by: Peter Hutterer +--- + hw/xfree86/common/xf86Config.c | 34 +++++++++++++++++++++++++--------- + hw/xfree86/parser/Device.c | 6 ++++++ + hw/xfree86/parser/Layout.c | 6 ++++++ + hw/xfree86/parser/Screen.c | 6 ++++++ + hw/xfree86/parser/xf86Parser.h | 3 +++ + hw/xfree86/parser/xf86tokens.h | 1 + + 6 files changed, 47 insertions(+), 9 deletions(-) + +Index: xorg-server-trusty-matchseat/hw/xfree86/common/xf86Config.c +=================================================================== +--- xorg-server-trusty-matchseat.orig/hw/xfree86/common/xf86Config.c 2014-09-11 10:50:39.823851011 -0300 ++++ xorg-server-trusty-matchseat/hw/xfree86/common/xf86Config.c 2014-09-11 10:55:16.098992439 -0300 +@@ -232,6 +232,18 @@ + return tmp_path; + } + ++#define FIND_SUITABLE(pointertype, listhead, ptr) \ ++ do { \ ++ pointertype _l, _p; \ ++ \ ++ for (_l = (listhead), _p = NULL; !_p && _l; _l = (pointertype)_l->list.next) { \ ++ if (!_l->match_seat || (SeatId && xf86nameCompare(_l->match_seat, SeatId) == 0)) \ ++ _p = _l; \ ++ } \ ++ \ ++ (ptr) = _p; \ ++ } while(0) ++ + /* + * use the datastructure that the parser provides and pick out the parts + * that we need at this point +@@ -1600,8 +1612,11 @@ + * config file, or - if it is NULL - configScreen autogenerates one for + * us */ + if (!count) { ++ XF86ConfScreenPtr screen; ++ ++ FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen); + slp[0].screen = xnfcalloc(1, sizeof(confScreenRec)); +- if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst, ++ if (!configScreen(slp[0].screen, screen, + 0, X_CONFIG)) { + free(slp[0].screen); + free(slp); +@@ -1841,7 +1856,7 @@ + * set it to NULL so that the section can be autoconfigured later */ + screenp->device = xnfcalloc(1, sizeof(GDevRec)); + if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) { +- conf_screen->scrn_device = xf86configptr->conf_device_lst; ++ FIND_SUITABLE (XF86ConfDevicePtr, xf86configptr->conf_device_lst, conf_screen->scrn_device); + xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n" + "\tUsing the first device section listed.\n", screenp->id); + } +@@ -2374,6 +2389,7 @@ + char *scanptr; + Bool singlecard = 0; + Bool implicit_layout = FALSE; ++ XF86ConfLayoutPtr layout; + + if (!autoconfig) { + char *filename, *dirname, *sysdirname; +@@ -2449,14 +2465,17 @@ + */ + + /* First check if a layout section is present, and if it is valid. */ ++ FIND_SUITABLE(XF86ConfLayoutPtr, xf86configptr->conf_layout_lst, layout); ++ if (layout == NULL || xf86ScreenName != NULL) { ++ XF86ConfScreenPtr screen; + +- if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) { + if (xf86ScreenName == NULL) { + xf86Msg(X_DEFAULT, + "No Layout section. Using the first Screen section.\n"); + } ++ FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen); + if (!configImpliedLayout(&xf86ConfigLayout, +- xf86configptr->conf_screen_lst, ++ screen, + xf86configptr)) { + xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); + return CONFIG_PARSE_ERROR; +@@ -2471,16 +2490,13 @@ + if (optlist && xf86FindOption(optlist, "defaultserverlayout")) + dfltlayout = + xf86SetStrOption(optlist, "defaultserverlayout", NULL); +- if (!configLayout +- (&xf86ConfigLayout, xf86configptr->conf_layout_lst, +- dfltlayout)) { ++ if (!configLayout(&xf86ConfigLayout, layout, dfltlayout)) { + xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); + return CONFIG_PARSE_ERROR; + } + } + else { +- if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst, +- NULL)) { ++ if (!configLayout(&xf86ConfigLayout, layout, NULL)) { + xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); + return CONFIG_PARSE_ERROR; + } +Index: xorg-server-trusty-matchseat/hw/xfree86/parser/Device.c +=================================================================== +--- xorg-server-trusty-matchseat.orig/hw/xfree86/parser/Device.c 2014-09-11 10:48:54.272129993 -0300 ++++ xorg-server-trusty-matchseat/hw/xfree86/parser/Device.c 2014-09-11 10:55:16.094992284 -0300 +@@ -72,6 +72,7 @@ + {RAMDAC, "ramdac"}, + {DACSPEED, "dacspeed"}, + {CLOCKS, "clocks"}, ++ {MATCHSEAT, "matchseat"}, + {OPTION, "option"}, + {VIDEORAM, "videoram"}, + {BIOSBASE, "biosbase"}, +@@ -217,6 +218,11 @@ + Error(NUMBER_MSG, "TextClockFreq"); + ptr->dev_textclockfreq = (int) (val.realnum * 1000.0 + 0.5); + break; ++ case MATCHSEAT: ++ if (xf86getSubToken(&(ptr->dev_comment)) != STRING) ++ Error(QUOTE_MSG, "MatchSeat"); ++ ptr->match_seat = val.str; ++ break; + case OPTION: + ptr->dev_option_lst = xf86parseOption(ptr->dev_option_lst); + break; +Index: xorg-server-trusty-matchseat/hw/xfree86/parser/Layout.c +=================================================================== +--- xorg-server-trusty-matchseat.orig/hw/xfree86/parser/Layout.c 2014-09-11 10:48:54.272129993 -0300 ++++ xorg-server-trusty-matchseat/hw/xfree86/parser/Layout.c 2014-09-11 10:55:16.094992284 -0300 +@@ -71,6 +71,7 @@ + {ENDSECTION, "endsection"}, + {SCREEN, "screen"}, + {IDENTIFIER, "identifier"}, ++ {MATCHSEAT, "matchseat"}, + {INACTIVE, "inactive"}, + {INPUTDEVICE, "inputdevice"}, + {OPTION, "option"}, +@@ -110,6 +111,11 @@ + ptr->lay_identifier = val.str; + has_ident = TRUE; + break; ++ case MATCHSEAT: ++ if (xf86getSubToken(&(ptr->lay_comment)) != STRING) ++ Error(QUOTE_MSG, "MatchSeat"); ++ ptr->match_seat = val.str; ++ break; + case INACTIVE: + { + XF86ConfInactivePtr iptr; +Index: xorg-server-trusty-matchseat/hw/xfree86/parser/Screen.c +=================================================================== +--- xorg-server-trusty-matchseat.orig/hw/xfree86/parser/Screen.c 2014-09-11 10:48:54.272129993 -0300 ++++ xorg-server-trusty-matchseat/hw/xfree86/parser/Screen.c 2014-09-11 10:55:16.094992284 -0300 +@@ -199,6 +199,7 @@ + static xf86ConfigSymTabRec ScreenTab[] = { + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, ++ {MATCHSEAT, "matchseat"}, + {OBSDRIVER, "driver"}, + {MDEVICE, "device"}, + {MONITOR, "monitor"}, +@@ -237,6 +238,11 @@ + Error(ONLY_ONE_MSG, "Identifier or Driver"); + has_ident = TRUE; + break; ++ case MATCHSEAT: ++ if (xf86getSubToken(&(ptr->scrn_comment)) != STRING) ++ Error(QUOTE_MSG, "MatchSeat"); ++ ptr->match_seat = val.str; ++ break; + case OBSDRIVER: + if (xf86getSubToken(&(ptr->scrn_comment)) != STRING) + Error(QUOTE_MSG, "Driver"); +Index: xorg-server-trusty-matchseat/hw/xfree86/parser/xf86Parser.h +=================================================================== +--- xorg-server-trusty-matchseat.orig/hw/xfree86/parser/xf86Parser.h 2014-09-11 10:48:54.272129993 -0300 ++++ xorg-server-trusty-matchseat/hw/xfree86/parser/xf86Parser.h 2014-09-11 10:55:16.094992284 -0300 +@@ -224,6 +224,7 @@ + int dev_screen; + XF86OptionPtr dev_option_lst; + char *dev_comment; ++ char *match_seat; + } XF86ConfDeviceRec, *XF86ConfDevicePtr; + + typedef struct { +@@ -275,6 +276,7 @@ + XF86OptionPtr scrn_option_lst; + char *scrn_comment; + int scrn_virtualX, scrn_virtualY; ++ char *match_seat; + } XF86ConfScreenRec, *XF86ConfScreenPtr; + + typedef struct { +@@ -366,6 +368,7 @@ + XF86ConfInactivePtr lay_inactive_lst; + XF86ConfInputrefPtr lay_input_lst; + XF86OptionPtr lay_option_lst; ++ char *match_seat; + char *lay_comment; + } XF86ConfLayoutRec, *XF86ConfLayoutPtr; + +Index: xorg-server-trusty-matchseat/hw/xfree86/parser/xf86tokens.h +=================================================================== +--- xorg-server-trusty-matchseat.orig/hw/xfree86/parser/xf86tokens.h 2014-09-11 10:48:54.272129993 -0300 ++++ xorg-server-trusty-matchseat/hw/xfree86/parser/xf86tokens.h 2014-09-11 10:55:16.094992284 -0300 +@@ -87,6 +87,7 @@ + VENDOR, + DASH, + COMMA, ++ MATCHSEAT, + OPTION, + COMMENT, + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/xfree86_allow_fallback_to_pci_bus_probe_for_non_seat0.patch +++ xorg-server-1.15.1/debian/patches/xfree86_allow_fallback_to_pci_bus_probe_for_non_seat0.patch @@ -0,0 +1,52 @@ +From 29b1484bb9555e45067669cbfe68a3c40596f4ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?La=C3=A9rcio=20de=20Sousa?= +Date: Thu, 3 Apr 2014 11:19:13 -0300 +Subject: [PATCH] xfree86: allow fallback to PCI bus probe for graphics devices + on non-seat0 X servers (#66851) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently non-seat0 X servers only probe platform bus for graphics devices, +which is OK for most KMS-compliant drivers. However, for non-KMS drivers +(like NVIDIA proprietary ones), graphics devices can't be reached +by platform bus probe, resulting in a "No devices detected" error. + +This patch allows a fallback to PCI bus probe for non-seat0 X servers +in case no platform bus graphics device is found. + +Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=66851 + +Signed-off-by: Laércio de Sousa +Reviewed-by: Hans de Goede +Reviewed-by: Dave Airlie +Signed-off-by: Peter Hutterer +--- + hw/xfree86/common/xf86Bus.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c +index 507c57d..b3b3f8c 100644 +--- a/hw/xfree86/common/xf86Bus.c ++++ b/hw/xfree86/common/xf86Bus.c +@@ -81,7 +81,7 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only) + if (drv->platformProbe != NULL) { + foundScreen = xf86platformProbeDev(drv); + } +- if (ServerIsNotSeat0()) ++ if (ServerIsNotSeat0() && foundScreen) + return foundScreen; + #endif + +@@ -201,7 +201,7 @@ xf86BusProbe(void) + { + #ifdef XSERVER_PLATFORM_BUS + xf86platformProbe(); +- if (ServerIsNotSeat0()) ++ if (ServerIsNotSeat0() && xf86_num_platform_devices > 0) + return; + #endif + #ifdef XSERVER_LIBPCIACCESS +-- +2.0.4 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/xfree86_keep_non_seat0_from_touching_vts.patch +++ xorg-server-1.15.1/debian/patches/xfree86_keep_non_seat0_from_touching_vts.patch @@ -0,0 +1,50 @@ +From 46cf2a60934076bf568062eb83121ce90b6ff596 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?La=C3=A9rcio=20de=20Sousa?= +Date: Thu, 12 Dec 2013 14:22:48 -0200 +Subject: [PATCH] xfree86: Keep a non-seat0 X server from touching VTs (#71258) + +Updated patch following Hans de Goede's advice. + +If -seat option is passed with a value different from seat0, +X server won't call xf86OpenConsole(). + +This is needed to avoid any race condition between seat0 and +non-seat0 X servers. If a non-seat0 X server opens a given VT +before a seat0 one which expects to open the same VT, one can +get an inactive systemd-logind graphical session for seat0. + +This patch was first tested in a multiseat setup with multiple +video cards and works quite well. + +I suppose it can also make things like DontVTSwitch and -sharevts +meaningless for non-seat0 seats, so it may fix bug #69477, too. + +Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=71258 + https://bugs.freedesktop.org/show_bug.cgi?id=69477 (maybe) + +See also: http://lists.x.org/archives/xorg-devel/2013-October/038391.html + https://bugzilla.redhat.com/show_bug.cgi?id=1018196 + +Signed-off-by: Hans de Goede +Reviewed-by: Hans de Goede +--- + hw/xfree86/common/xf86Init.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c +index 9c8a86a..952bf37 100644 +--- a/hw/xfree86/common/xf86Init.c ++++ b/hw/xfree86/common/xf86Init.c +@@ -544,7 +544,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) + if (NEED_IO_ENABLED(flags)) + want_hw_access = TRUE; + +- if (!(flags & HW_SKIP_CONSOLE)) ++ /* Non-seat0 X servers should not open console */ ++ if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0()) + xorgHWOpenConsole = TRUE; + } + +-- +2.0.4 + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/xi-dont-copy-too-much.patch +++ xorg-server-1.15.1/debian/patches/xi-dont-copy-too-much.patch @@ -0,0 +1,67 @@ +commit 56929f41e6c4cc1b2d72a33d14b4d993e7b613a3 +Author: Peter Hutterer +Date: Tue Apr 29 16:52:01 2014 +1000 + + Xi: don't copy a DeviceEvent into an InternalEvent + + ==26141== Invalid read of size 8 + ==26141== at 0x58FAEA: DeliverEmulatedMotionEvent (exevents.c:1484) + + An InternalEvent is bigger than a DeviceEvent, thus copying one to the other + reads past the allocated boundary. Shouldn't have any real effect since we + shouldn't access anything past the DeviceEvent boundary if the event type is + correct. + + Signed-off-by: Peter Hutterer + +diff --git a/Xi/exevents.c b/Xi/exevents.c +index 9c207eb..02530bd 100644 +--- a/Xi/exevents.c ++++ b/Xi/exevents.c +@@ -1469,7 +1469,7 @@ static void + DeliverEmulatedMotionEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, + InternalEvent *ev) + { +- InternalEvent motion; ++ DeviceEvent motion; + + if (ti->num_listeners) { + ClientPtr client; +@@ -1481,11 +1481,11 @@ DeliverEmulatedMotionEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, + ti->listeners[0].type != LISTENER_POINTER_GRAB) + return; + +- motion = *ev; +- motion.any.type = ET_TouchUpdate; +- motion.device_event.detail.button = 0; ++ motion = ev->device_event; ++ motion.type = ET_TouchUpdate; ++ motion.detail.button = 0; + +- if (!RetrieveTouchDeliveryData(dev, ti, &motion, ++ if (!RetrieveTouchDeliveryData(dev, ti, (InternalEvent*)&motion, + &ti->listeners[0], &client, &win, &grab, + &mask)) + return; +@@ -1500,18 +1500,18 @@ DeliverEmulatedMotionEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, + } + } + +- DeliverTouchEmulatedEvent(dev, ti, &motion, &ti->listeners[0], client, ++ DeliverTouchEmulatedEvent(dev, ti, (InternalEvent*)&motion, &ti->listeners[0], client, + win, grab, mask); + } + else { + InternalEvent button; + int converted; + +- converted = TouchConvertToPointerEvent(ev, &motion, &button); ++ converted = TouchConvertToPointerEvent(ev, (InternalEvent*)&motion, &button); + + BUG_WARN(converted == 0); + if (converted) +- ProcessOtherEvent(&motion, dev); ++ ProcessOtherEvent((InternalEvent*)&motion, dev); + } + } + only in patch2: unchanged: --- xorg-server-1.15.1.orig/debian/patches/xi2-resize-touch.patch +++ xorg-server-1.15.1/debian/patches/xi2-resize-touch.patch @@ -0,0 +1,34 @@ +diff --git a/dix/touch.c b/dix/touch.c +index a7ea213..1478e38 100644 +--- a/dix/touch.c ++++ b/dix/touch.c +@@ -460,12 +460,26 @@ TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev) + if (ev->flags & (TOUCH_CLIENT_ID | TOUCH_REPLAYING)) + return; + ++ if (ti->history_elements == ti->history_size - 1) { ++ DeviceEvent *hist = NULL; ++ size_t sz = ti->history_size * 2; ++ ++ if (sz < 10000) { ++ hist = realloc(ti->history, sz * sizeof(*hist)); ++ ++ if (hist) { ++ ti->history = hist; ++ ti->history_size = sz; ++ memset(&hist[sz/2], 0, sizeof(*hist)*sz/2); ++ } ++ } ++ } ++ + ti->history[ti->history_elements++] = *ev; +- /* FIXME: proper overflow fixes */ + if (ti->history_elements > ti->history_size - 1) { + ti->history_elements = ti->history_size - 1; +- DebugF("source device %d: history size %d overflowing for touch %u\n", +- ti->sourceid, ti->history_size, ti->client_id); ++ ErrorF("source device %d: history size %d overflowing for touch %u\n", ++ ti->sourceid, ti->history_size, ti->client_id); + } + } + only in patch2: unchanged: --- xorg-server-1.15.1.orig/os/WaitFor.c +++ xorg-server-1.15.1/os/WaitFor.c @@ -123,7 +123,7 @@ static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev); static void CheckAllTimers(void); -static OsTimerPtr timers = NULL; +static volatile OsTimerPtr timers = NULL; /***************** * WaitForSomething: @@ -263,11 +263,14 @@ if ((int) (timers->expires - now) <= 0) expired = 1; - while (timers && (int) (timers->expires - now) <= 0) - DoTimer(timers, now, &timers); + if (expired) { + OsBlockSignals(); + while (timers && (int) (timers->expires - now) <= 0) + DoTimer(timers, now, &timers); + OsReleaseSignals(); - if (expired) return 0; + } } } else { @@ -281,11 +284,14 @@ if ((int) (timers->expires - now) <= 0) expired = 1; - while (timers && (int) (timers->expires - now) <= 0) - DoTimer(timers, now, &timers); - - if (expired) - return 0; + if (expired) { + OsBlockSignals(); + while (timers && (int) (timers->expires - now) <= 0) + DoTimer(timers, now, &timers); + OsReleaseSignals(); + + return 0; + } } } if (someReady) @@ -408,10 +414,11 @@ OsBlockSignals(); *prev = timer->next; timer->next = NULL; + OsReleaseSignals(); + newTime = (*timer->callback) (timer, now, timer->arg); if (newTime) TimerSet(timer, 0, newTime, timer->callback, timer->arg); - OsReleaseSignals(); } OsTimerPtr @@ -515,8 +522,13 @@ { CARD32 now = GetTimeInMillis(); - while (timers && (int) (timers->expires - now) <= 0) - DoTimer(timers, now, &timers); + if(timers && (int) (timers->expires - now) <= 0) { + OsBlockSignals(); + while (timers && (int) (timers->expires - now) <= 0) + DoTimer(timers, now, &timers); + OsReleaseSignals(); + } + } void