Xext/panoramiX.c | 3 Xext/saver.c | 2 Xext/shm.c | 1 Xext/xres.c | 4 - Xext/xvdisp.c | 4 - Xi/xibarriers.c | 12 +++ Xi/xichangehierarchy.c | 6 - dbe/dbe.c | 5 + debian/changelog | 26 ++++++++ dix/dispatch.c | 7 +- hw/dmx/dmxpict.c | 2 hw/xfree86/common/xf86DGA.c | 81 ++++++++++++++------------ hw/xfree86/common/xf86vmode.c | 129 ++++++++++++++++++++++-------------------- hw/xfree86/dri/xf86dri.c | 1 os/io.c | 5 + pseudoramiX/pseudoramiX.c | 3 render/render.c | 7 ++ xfixes/cursor.c | 5 + xfixes/region.c | 3 xfixes/saveset.c | 1 xfixes/xfixes.c | 1 xkb/xkbtext.c | 42 ++++++------- 22 files changed, 221 insertions(+), 129 deletions(-)
New commits: commit fe4b80e8d0993e2e89e4b5bddab9d1d35fadd254 Author: Julien Cristau <[email protected]> Date: Fri Oct 13 12:01:00 2017 +0200 Changelog update diff --git a/debian/changelog b/debian/changelog index 80ad59d..867cbf7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,29 @@ +xorg-server (2:1.16.4-1+deb8u2) UNRELEASED; urgency=high + + * render: Fix out of boundary heap access + * Xext/shm: Validate shmseg resource id (CVE-2017-13721) + * xkb: Escape non-printable characters correctly. + * xkb: Handle xkb formated string output safely (CVE-2017-13723) + * os: Make sure big requests have sufficient length. + * Unvalidated lengths in + - XFree86-VidModeExtension (CVE-2017-12180) + - XFree86-DGA (CVE-2017-12181) + - XFree86-DRI (CVE-2017-12182) + - XFIXES (CVE-2017-12183) + - XINERAMA (CVE-2017-12184) + - MIT-SCREEN-SAVER (CVE-2017-12185) + - X-Resource (CVE-2017-12186) + - RENDER (CVE-2017-12187) + * Xi: Test exact size of XIBarrierReleasePointer + * Xi: integer overflow and unvalidated length in + (S)ProcXIBarrierReleasePointer (CVE-2017-12179) + * Xi: Silence some tautological warnings + * Xi: fix wrong extra length check in ProcXIChangeHierarchy (CVE-2017-12178) + * dbe: Unvalidated variable-length request in ProcDbeGetVisualInfo (CVE-2017-12177) + * Unvalidated extra length in ProcEstablishConnection (CVE-2017-12176) + + -- Julien Cristau <[email protected]> Fri, 13 Oct 2017 11:55:04 +0200 + xorg-server (2:1.16.4-1+deb8u1) jessie-security; urgency=medium * CVE-2017-10971 CVE-2017-10972 commit 542ccdcf2b9dd696004bab2e3644d07461835602 Author: Michal Srb <[email protected]> Date: Thu Jul 27 11:54:26 2017 +0200 xkb: Escape non-printable characters correctly. XkbStringText escapes non-printable characters using octal numbers. Such escape sequence would be at most 5 characters long ("\0123"), so it reserves 5 bytes in the buffer. Due to char->unsigned int conversion, it would print much longer string for negative numbers. Reviewed-by: Keith Packard <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit eaf1f72ed8994b708d94ec2de7b1a99f5c4a39b8) (cherry picked from commit 3094c4c6d879215923f2183ecd048b4f5429b182) diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c index 9f2c5d3..74d2235 100644 --- a/xkb/xkbtext.c +++ b/xkb/xkbtext.c @@ -603,7 +603,7 @@ XkbStringText(char *str, unsigned format) } else { *out++ = '0'; - sprintf(out, "%o", *in); + sprintf(out, "%o", (unsigned char) *in); while (*out != '\0') out++; } commit 1caf94cc4c7ac51a925f11c1d9de7eeb8c6e4b4e Author: Nathan Kidd <[email protected]> Date: Fri Jan 9 10:15:46 2015 -0500 Unvalidated extra length in ProcEstablishConnection (CVE-2017-12176) Reviewed-by: Julien Cristau <[email protected]> Signed-off-by: Nathan Kidd <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit b747da5e25be944337a9cd1415506fc06b70aa81) (cherry picked from commit 95f605b42d8bbb6bea2834a1abfc205981c5b803) diff --git a/dix/dispatch.c b/dix/dispatch.c index 4e24e62..e50a021 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -3614,7 +3614,12 @@ ProcEstablishConnection(ClientPtr client) prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq); auth_proto = (char *) prefix + sz_xConnClientPrefix; auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); - if ((prefix->majorVersion != X_PROTOCOL) || + + if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix + + pad_to_int32(prefix->nbytesAuthProto) + + pad_to_int32(prefix->nbytesAuthString)) + reason = "Bad length"; + else if ((prefix->majorVersion != X_PROTOCOL) || (prefix->minorVersion != X_PROTOCOL_REVISION)) reason = "Protocol version mismatch"; else commit 49afe4200aa94bc54d90ef14cf2867691adbc0b1 Author: Nathan Kidd <[email protected]> Date: Fri Jan 9 10:09:14 2015 -0500 dbe: Unvalidated variable-length request in ProcDbeGetVisualInfo (CVE-2017-12177) v2: Protect against integer overflow (Alan Coopersmith) Reviewed-by: Alan Coopersmith <[email protected]> Reviewed-by: Jeremy Huddleston Sequoia <[email protected]> Reviewed-by: Julien Cristau <[email protected]> Signed-off-by: Nathan Kidd <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit 4ca68b878e851e2136c234f40a25008297d8d831) (cherry picked from commit cc41e5b581d287c56f8d7113a97a4882dcfdd696) diff --git a/dbe/dbe.c b/dbe/dbe.c index fc3d475..542d087 100644 --- a/dbe/dbe.c +++ b/dbe/dbe.c @@ -575,6 +575,9 @@ ProcDbeGetVisualInfo(ClientPtr client) XdbeScreenVisualInfo *pScrVisInfo; REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); + if (stuff->n > UINT32_MAX / sizeof(CARD32)) + return BadLength; + REQUEST_FIXED_SIZE(xDbeGetVisualInfoReq, stuff->n * sizeof(CARD32)); if (stuff->n > UINT32_MAX / sizeof(DrawablePtr)) return BadAlloc; @@ -926,7 +929,7 @@ SProcDbeSwapBuffers(ClientPtr client) swapl(&stuff->n); if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) - return BadAlloc; + return BadLength; REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); if (stuff->n != 0) { commit bdb178fb6cee19e13405a00e7f601eb734981bc2 Author: Nathan Kidd <[email protected]> Date: Wed Dec 24 16:22:18 2014 -0500 Xi: fix wrong extra length check in ProcXIChangeHierarchy (CVE-2017-12178) Reviewed-by: Alan Coopersmith <[email protected]> Reviewed-by: Jeremy Huddleston Sequoia <[email protected]> Reviewed-by: Julien Cristau <[email protected]> Signed-off-by: Nathan Kidd <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit 859b08d523307eebde7724fd1a0789c44813e821) (cherry picked from commit 6c15122163a2d2615db7e998e8d436815a08dec6) diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index 8d5b577..0f96c91 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -421,7 +421,7 @@ ProcXIChangeHierarchy(ClientPtr client) if (!stuff->num_changes) return rc; - len = ((size_t)stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo); + len = ((size_t)stuff->length << 2) - sizeof(xXIChangeHierarchyReq); any = (xXIAnyHierarchyChangeInfo *) &stuff[1]; while (stuff->num_changes--) { commit 7a7b8c97240112c0b7b279018908410d854b6ccc Author: Jeremy Huddleston Sequoia <[email protected]> Date: Thu Oct 15 22:28:49 2015 -0700 Xi: Silence some tautological warnings xichangehierarchy.c:424:23: warning: comparison of constant 536870911 with expression of type 'uint16_t' (aka 'unsigned short') is always false [-Wtautological-constant-out-of-range-compare,Semantic Issue] if (stuff->length > (INT_MAX >> 2)) ~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~ xichangehierarchy.c:438:26: warning: comparison of constant 536870911 with expression of type 'uint16_t' (aka 'unsigned short') is always false [-Wtautological-constant-out-of-range-compare,Semantic Issue] if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2))) ~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~ Signed-off-by: Jeremy Huddleston Sequoia <[email protected]> Reviewed-by: Peter Hutterer <[email protected]> Signed-off-by: Peter Hutterer <[email protected]> (cherry picked from commit ee06f674bbcd796324d6daf69bfb5d8856e94008) diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index 2732445..8d5b577 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -421,9 +421,7 @@ ProcXIChangeHierarchy(ClientPtr client) if (!stuff->num_changes) return rc; - if (stuff->length > (INT_MAX >> 2)) - return BadAlloc; - len = (stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo); + len = ((size_t)stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo); any = (xXIAnyHierarchyChangeInfo *) &stuff[1]; while (stuff->num_changes--) { @@ -435,7 +433,7 @@ ProcXIChangeHierarchy(ClientPtr client) SWAPIF(swaps(&any->type)); SWAPIF(swaps(&any->length)); - if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2))) + if (len < ((size_t)any->length << 2)) return BadLength; #define CHANGE_SIZE_MATCH(type) \ commit 70bd4d33207372778ed3a2718ab1ea644b4c5adf Author: Nathan Kidd <[email protected]> Date: Fri Jan 9 10:04:41 2015 -0500 Xi: integer overflow and unvalidated length in (S)ProcXIBarrierReleasePointer [jcristau: originally this patch fixed the same issue as commit 211e05ac85 "Xi: Test exact size of XIBarrierReleasePointer", with the addition of these checks] This addresses CVE-2017-12179 Reviewed-by: Alan Coopersmith <[email protected]> Reviewed-by: Jeremy Huddleston Sequoia <[email protected]> Reviewed-by: Julien Cristau <[email protected]> Signed-off-by: Jeremy Huddleston Sequoia <[email protected]> Signed-off-by: Nathan Kidd <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit d088e3c1286b548a58e62afdc70bb40981cdb9e8) (cherry picked from commit c77cd08efcf386bcc5d8dfbd0427134b2b2d0888) diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c index 0bc5761..b0a4a92 100644 --- a/Xi/xibarriers.c +++ b/Xi/xibarriers.c @@ -834,6 +834,8 @@ SProcXIBarrierReleasePointer(ClientPtr client) REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq); swapl(&stuff->num_barriers); + if (stuff->num_barriers > UINT32_MAX / sizeof(xXIBarrierReleasePointerInfo)) + return BadLength; REQUEST_FIXED_SIZE(xXIBarrierReleasePointerReq, stuff->num_barriers * sizeof(xXIBarrierReleasePointerInfo)); info = (xXIBarrierReleasePointerInfo*) &stuff[1]; @@ -856,6 +858,9 @@ ProcXIBarrierReleasePointer(ClientPtr client) xXIBarrierReleasePointerInfo *info; REQUEST(xXIBarrierReleasePointerReq); + REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq); + if (stuff->num_barriers > UINT32_MAX / sizeof(xXIBarrierReleasePointerInfo)) + return BadLength; REQUEST_FIXED_SIZE(xXIBarrierReleasePointerReq, stuff->num_barriers * sizeof(xXIBarrierReleasePointerInfo)); info = (xXIBarrierReleasePointerInfo*) &stuff[1]; commit 9a2e0fc2018f708b1879f84eaa49476dbebb3f2d Author: Nathan Kidd <[email protected]> Date: Sun Dec 21 01:10:03 2014 -0500 hw/xfree86: unvalidated lengths This addresses: CVE-2017-12180 in XFree86-VidModeExtension CVE-2017-12181 in XFree86-DGA CVE-2017-12182 in XFree86-DRI Reviewed-by: Jeremy Huddleston Sequoia <[email protected]> Reviewed-by: Julien Cristau <[email protected]> Signed-off-by: Nathan Kidd <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit 1b1d4c04695dced2463404174b50b3581dbd857b) (cherry picked from commit d264da92f7f8129b8aad4f0114a6467fc38fc896) diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c index b9e1e3f..81ca776 100644 --- a/hw/xfree86/common/xf86DGA.c +++ b/hw/xfree86/common/xf86DGA.c @@ -1272,13 +1272,14 @@ ProcXDGAOpenFramebuffer(ClientPtr client) char *deviceName; int nameSize; + REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (!DGAAvailable(stuff->screen)) return DGAErrorBase + XF86DGANoDirectVideoMode; - REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1305,14 +1306,14 @@ ProcXDGACloseFramebuffer(ClientPtr client) { REQUEST(xXDGACloseFramebufferReq); + REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (!DGAAvailable(stuff->screen)) return DGAErrorBase + XF86DGANoDirectVideoMode; - REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq); - DGACloseFramebuffer(stuff->screen); return Success; @@ -1328,10 +1329,11 @@ ProcXDGAQueryModes(ClientPtr client) xXDGAModeInfo info; XDGAModePtr mode; + REQUEST_SIZE_MATCH(xXDGAQueryModesReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; - REQUEST_SIZE_MATCH(xXDGAQueryModesReq); rep.type = X_Reply; rep.length = 0; rep.number = 0; @@ -1443,11 +1445,12 @@ ProcXDGASetMode(ClientPtr client) ClientPtr owner; int size; + REQUEST_SIZE_MATCH(xXDGASetModeReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; owner = DGA_GETCLIENT(stuff->screen); - REQUEST_SIZE_MATCH(xXDGASetModeReq); rep.type = X_Reply; rep.length = 0; rep.offset = 0; @@ -1533,14 +1536,14 @@ ProcXDGASetViewport(ClientPtr client) { REQUEST(xXDGASetViewportReq); + REQUEST_SIZE_MATCH(xXDGASetViewportReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGASetViewportReq); - DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags); return Success; @@ -1554,14 +1557,14 @@ ProcXDGAInstallColormap(ClientPtr client) REQUEST(xXDGAInstallColormapReq); + REQUEST_SIZE_MATCH(xXDGAInstallColormapReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGAInstallColormapReq); - rc = dixLookupResourceByType((void **) &cmap, stuff->cmap, RT_COLORMAP, client, DixInstallAccess); if (rc != Success) @@ -1575,14 +1578,14 @@ ProcXDGASelectInput(ClientPtr client) { REQUEST(xXDGASelectInputReq); + REQUEST_SIZE_MATCH(xXDGASelectInputReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGASelectInputReq); - if (DGA_GETCLIENT(stuff->screen) == client) DGASelectInput(stuff->screen, client, stuff->mask); @@ -1594,14 +1597,14 @@ ProcXDGAFillRectangle(ClientPtr client) { REQUEST(xXDGAFillRectangleReq); + REQUEST_SIZE_MATCH(xXDGAFillRectangleReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGAFillRectangleReq); - if (Success != DGAFillRect(stuff->screen, stuff->x, stuff->y, stuff->width, stuff->height, stuff->color)) return BadMatch; @@ -1614,14 +1617,14 @@ ProcXDGACopyArea(ClientPtr client) { REQUEST(xXDGACopyAreaReq); + REQUEST_SIZE_MATCH(xXDGACopyAreaReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGACopyAreaReq); - if (Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy, stuff->width, stuff->height, stuff->dstx, stuff->dsty)) @@ -1635,14 +1638,14 @@ ProcXDGACopyTransparentArea(ClientPtr client) { REQUEST(xXDGACopyTransparentAreaReq); + REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq); - if (Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy, stuff->width, stuff->height, stuff->dstx, stuff->dsty, stuff->key)) @@ -1657,13 +1660,14 @@ ProcXDGAGetViewportStatus(ClientPtr client) REQUEST(xXDGAGetViewportStatusReq); xXDGAGetViewportStatusReply rep; + REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1680,13 +1684,14 @@ ProcXDGASync(ClientPtr client) REQUEST(xXDGASyncReq); xXDGASyncReply rep; + REQUEST_SIZE_MATCH(xXDGASyncReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGASyncReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1725,13 +1730,14 @@ ProcXDGAChangePixmapMode(ClientPtr client) xXDGAChangePixmapModeReply rep; int x, y; + REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1755,14 +1761,14 @@ ProcXDGACreateColormap(ClientPtr client) REQUEST(xXDGACreateColormapReq); int result; + REQUEST_SIZE_MATCH(xXDGACreateColormapReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXDGACreateColormapReq); - if (!stuff->mode) return BadValue; @@ -1791,10 +1797,11 @@ ProcXF86DGAGetVideoLL(ClientPtr client) int num, offset, flags; char *name; + REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; - REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1831,9 +1838,10 @@ ProcXF86DGADirectVideo(ClientPtr client) REQUEST(xXF86DGADirectVideoReq); + REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; - REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq); if (!DGAAvailable(stuff->screen)) return DGAErrorBase + XF86DGANoDirectVideoMode; @@ -1889,10 +1897,11 @@ ProcXF86DGAGetViewPortSize(ClientPtr client) REQUEST(xXF86DGAGetViewPortSizeReq); xXF86DGAGetViewPortSizeReply rep; + REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; - REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1917,14 +1926,14 @@ ProcXF86DGASetViewPort(ClientPtr client) { REQUEST(xXF86DGASetViewPortReq); + REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq); - if (!DGAAvailable(stuff->screen)) return DGAErrorBase + XF86DGANoDirectVideoMode; @@ -1944,10 +1953,11 @@ ProcXF86DGAGetVidPage(ClientPtr client) REQUEST(xXF86DGAGetVidPageReq); xXF86DGAGetVidPageReply rep; + REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; - REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -1962,11 +1972,11 @@ ProcXF86DGASetVidPage(ClientPtr client) { REQUEST(xXF86DGASetVidPageReq); + REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; - REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq); - /* silently fail */ return Success; @@ -1980,14 +1990,14 @@ ProcXF86DGAInstallColormap(ClientPtr client) REQUEST(xXF86DGAInstallColormapReq); + REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq); - if (!DGAActive(stuff->screen)) return DGAErrorBase + XF86DGADirectNotActivated; @@ -2008,10 +2018,11 @@ ProcXF86DGAQueryDirectVideo(ClientPtr client) REQUEST(xXF86DGAQueryDirectVideoReq); xXF86DGAQueryDirectVideoReply rep; + REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; - REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; @@ -2030,14 +2041,14 @@ ProcXF86DGAViewPortChanged(ClientPtr client) REQUEST(xXF86DGAViewPortChangedReq); xXF86DGAViewPortChangedReply rep; + REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq); + if (stuff->screen >= screenInfo.numScreens) return BadValue; if (DGA_GETCLIENT(stuff->screen) != client) return DGAErrorBase + XF86DGADirectNotActivated; - REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq); - if (!DGAActive(stuff->screen)) return DGAErrorBase + XF86DGADirectNotActivated; diff --git a/hw/xfree86/common/xf86vmode.c b/hw/xfree86/common/xf86vmode.c index 2b07833..63df14f 100644 --- a/hw/xfree86/common/xf86vmode.c +++ b/hw/xfree86/common/xf86vmode.c @@ -532,6 +532,20 @@ ProcXF86VidModeAddModeLine(ClientPtr client) DEBUG_P("XF86VidModeAddModeline"); ver = ClientMajorVersion(client); + + if (ver < 2) { + REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq)); + } + else { + REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq)); + } + if (ver < 2) { /* convert from old format */ stuff = &newstuff; @@ -581,18 +595,6 @@ ProcXF86VidModeAddModeLine(ClientPtr client) (unsigned long) stuff->after_flags); } - if (ver < 2) { - REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq)); - } - else { - REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq)); - } if (len != stuff->privsize) return BadLength; @@ -695,6 +697,20 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client) DEBUG_P("XF86VidModeDeleteModeline"); ver = ClientMajorVersion(client); + + if (ver < 2) { + REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq)); + } + else { + REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq)); + } + if (ver < 2) { /* convert from old format */ stuff = &newstuff; @@ -725,18 +741,6 @@ ProcXF86VidModeDeleteModeLine(ClientPtr client) (unsigned long) stuff->flags); } - if (ver < 2) { - REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq)); - } - else { - REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq)); - } if (len != stuff->privsize) { if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) { ErrorF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, " @@ -820,6 +824,20 @@ ProcXF86VidModeModModeLine(ClientPtr client) DEBUG_P("XF86VidModeModModeline"); ver = ClientMajorVersion(client); + + if (ver < 2) { + REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq)); + } + else { + REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86VidModeModModeLineReq)); + } + if (ver < 2) { /* convert from old format */ stuff = &newstuff; @@ -846,18 +864,6 @@ ProcXF86VidModeModModeLine(ClientPtr client) stuff->vtotal, (unsigned long) stuff->flags); } - if (ver < 2) { - REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq)); - } - else { - REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86VidModeModModeLineReq)); - } if (len != stuff->privsize) return BadLength; @@ -949,6 +955,19 @@ ProcXF86VidModeValidateModeLine(ClientPtr client) DEBUG_P("XF86VidModeValidateModeline"); ver = ClientMajorVersion(client); + + if (ver < 2) { + REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq); + len = client->req_len - + bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq)); + } + else { + REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq)); + } + if (ver < 2) { /* convert from old format */ stuff = &newstuff; @@ -979,17 +998,6 @@ ProcXF86VidModeValidateModeLine(ClientPtr client) (unsigned long) stuff->flags); } - if (ver < 2) { - REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq); - len = client->req_len - - bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq)); - } - else { - REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq)); - } if (len != stuff->privsize) return BadLength; @@ -1087,6 +1095,20 @@ ProcXF86VidModeSwitchToMode(ClientPtr client) DEBUG_P("XF86VidModeSwitchToMode"); ver = ClientMajorVersion(client); + + if (ver < 2) { + REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq)); + } + else { + REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq); + len = + client->req_len - + bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq)); + } + if (ver < 2) { /* convert from old format */ stuff = &newstuff; @@ -1117,18 +1139,6 @@ ProcXF86VidModeSwitchToMode(ClientPtr client) (unsigned long) stuff->flags); } - if (ver < 2) { - REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq)); - } - else { - REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq); - len = - client->req_len - - bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq)); - } if (len != stuff->privsize) return BadLength; @@ -1470,6 +1480,7 @@ ProcXF86VidModeSetGammaRamp(ClientPtr client) int length; REQUEST(xXF86VidModeSetGammaRampReq); + REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq); if (stuff->screen >= screenInfo.numScreens) return BadValue; diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c index 086e833..49bd6d2 100644 --- a/hw/xfree86/dri/xf86dri.c +++ b/hw/xfree86/dri/xf86dri.c @@ -570,6 +570,7 @@ static int SProcXF86DRIQueryDirectRenderingCapable(register ClientPtr client) { REQUEST(xXF86DRIQueryDirectRenderingCapableReq); + REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); swaps(&stuff->length); swapl(&stuff->screen); return ProcXF86DRIQueryDirectRenderingCapable(client); commit 0beb544b29c6e94fa1cf105c42fec4f786900efa Author: Nathan Kidd <[email protected]> Date: Fri Jan 9 11:43:05 2015 -0500 xfixes: unvalidated lengths (CVE-2017-12183) v2: Use before swap (Jeremy Huddleston Sequoia) v3: Fix wrong XFixesCopyRegion checks (Alan Coopersmith) Reviewed-by: Alan Coopersmith <[email protected]> Reviewed-by: Jeremy Huddleston Sequoia <[email protected]> Reviewed-by: Julien Cristau <[email protected]> Signed-off-by: Jeremy Huddleston Sequoia <[email protected]> Signed-off-by: Nathan Kidd <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit 55caa8b08c84af2b50fbc936cf334a5a93dd7db5) (cherry picked from commit 61502107a30d64f991784648c3228ebc6694a032) diff --git a/xfixes/cursor.c b/xfixes/cursor.c index 31a408f..26b2053 100644 --- a/xfixes/cursor.c +++ b/xfixes/cursor.c @@ -280,6 +280,7 @@ int SProcXFixesSelectCursorInput(ClientPtr client) { REQUEST(xXFixesSelectCursorInputReq); + REQUEST_SIZE_MATCH(xXFixesSelectCursorInputReq); swaps(&stuff->length); swapl(&stuff->window); @@ -415,7 +416,7 @@ ProcXFixesSetCursorName(ClientPtr client) REQUEST(xXFixesSetCursorNameReq); Atom atom; - REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); + REQUEST_FIXED_SIZE(xXFixesSetCursorNameReq, stuff->nbytes); VERIFY_CURSOR(pCursor, stuff->cursor, client, DixSetAttrAccess); tchar = (char *) &stuff[1]; atom = MakeAtom(tchar, stuff->nbytes, TRUE); @@ -1010,6 +1011,8 @@ SProcXFixesCreatePointerBarrier(ClientPtr client) int i; CARD16 *in_devices = (CARD16 *) &stuff[1]; + REQUEST_AT_LEAST_SIZE(xXFixesCreatePointerBarrierReq); + swaps(&stuff->length); swaps(&stuff->num_devices); REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices)); diff --git a/xfixes/region.c b/xfixes/region.c index f9de525..899c8c2 100644 --- a/xfixes/region.c +++ b/xfixes/region.c @@ -374,6 +374,7 @@ ProcXFixesCopyRegion(ClientPtr client) RegionPtr pSource, pDestination; REQUEST(xXFixesCopyRegionReq); + REQUEST_SIZE_MATCH(xXFixesCopyRegionReq); VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); @@ -390,7 +391,7 @@ SProcXFixesCopyRegion(ClientPtr client) REQUEST(xXFixesCopyRegionReq); swaps(&stuff->length); - REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq); + REQUEST_SIZE_MATCH(xXFixesCopyRegionReq); swapl(&stuff->source); swapl(&stuff->destination); return (*ProcXFixesVector[stuff->xfixesReqType]) (client); diff --git a/xfixes/saveset.c b/xfixes/saveset.c index eb3f658..aa365cf 100644 --- a/xfixes/saveset.c +++ b/xfixes/saveset.c @@ -62,6 +62,7 @@ int SProcXFixesChangeSaveSet(ClientPtr client) { REQUEST(xXFixesChangeSaveSetReq); + REQUEST_SIZE_MATCH(xXFixesChangeSaveSetReq); swaps(&stuff->length); swapl(&stuff->window); diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c index 3307f87..1c254e0 100644 --- a/xfixes/xfixes.c +++ b/xfixes/xfixes.c @@ -160,6 +160,7 @@ static int SProcXFixesQueryVersion(ClientPtr client) { REQUEST(xXFixesQueryVersionReq); + REQUEST_SIZE_MATCH(xXFixesQueryVersionReq); swaps(&stuff->length); swapl(&stuff->majorVersion); commit 3dc11889861ef45bbf73deb8ed93e55195b82c07 Author: Nathan Kidd <[email protected]> Date: Fri Jan 9 09:57:23 2015 -0500 Unvalidated lengths v2: Add overflow check and remove unnecessary check (Julien Cristau) This addresses: CVE-2017-12184 in XINERAMA CVE-2017-12185 in MIT-SCREEN-SAVER CVE-2017-12186 in X-Resource CVE-2017-12187 in RENDER Reviewed-by: Jeremy Huddleston Sequoia <[email protected]> Reviewed-by: Julien Cristau <[email protected]> Signed-off-by: Nathan Kidd <[email protected]> Signed-off-by: Julien Cristau <[email protected]> (cherry picked from commit cad5a1050b7184d828aef9c1dd151c3ab649d37e)

