From mboxrd@z Thu Jan 1 00:00:00 1970 From: Leo Famulari Subject: [PATCH 4/8] gnu: libxrandr: Fix CVE-2016-{7947,7948}. Date: Wed, 5 Oct 2016 13:55:57 -0400 Message-ID: References: Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:51871) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brqQs-0004T9-8H for guix-devel@gnu.org; Wed, 05 Oct 2016 13:56:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1brqQn-0000wl-Rr for guix-devel@gnu.org; Wed, 05 Oct 2016 13:56:41 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:39018) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brqQl-0000tb-Hl for guix-devel@gnu.org; Wed, 05 Oct 2016 13:56:37 -0400 Received: from localhost.localdomain (c-73-188-17-148.hsd1.pa.comcast.net [73.188.17.148]) by mail.messagingengine.com (Postfix) with ESMTPA id 52586F2C78 for ; Wed, 5 Oct 2016 13:56:25 -0400 (EDT) In-Reply-To: In-Reply-To: References: List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: "Guix-devel" To: guix-devel@gnu.org * gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/xorg.scm (libxrandr)[replacement]: New field. (libxrandr/fixed): New variable. --- gnu/local.mk | 1 + .../libxrandr-CVE-2016-7947-CVE-2016-7948.patch | 447 +++++++++++++++++++++ gnu/packages/xorg.scm | 8 + 3 files changed, 456 insertions(+) create mode 100644 gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch diff --git a/gnu/local.mk b/gnu/local.mk index e092c84..22d63a9 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -673,6 +673,7 @@ dist_patch_DATA = \ %D%/packages/patches/libx11-CVE-2016-7943.patch \ %D%/packages/patches/libxfixes-CVE-2016-7944.patch \ %D%/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch \ + %D%/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch \ %D%/packages/patches/libxslt-generated-ids.patch \ %D%/packages/patches/lirc-localstatedir.patch \ %D%/packages/patches/llvm-for-extempore.patch \ diff --git a/gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch b/gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch new file mode 100644 index 0000000..ece8b18 --- /dev/null +++ b/gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch @@ -0,0 +1,447 @@ +Fix CVE-2016-7947 and CVE-2016-7948. + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7947 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7948 + +Patch copied from upstream source repository: + +https://cgit.freedesktop.org/xorg/lib/libXrandr/commit/?id=a0df3e1c7728205e5c7650b2e6dce684139254a6 + +From a0df3e1c7728205e5c7650b2e6dce684139254a6 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann +Date: Sun, 25 Sep 2016 22:21:40 +0200 +Subject: [PATCH] Avoid out of boundary accesses on illegal responses + +The responses of the connected X server have to be properly checked +to avoid out of boundary accesses that could otherwise be triggered +by a malicious server. + +Signed-off-by: Tobias Stoeckmann +Reviewed-by: Matthieu Herrb +--- + src/XrrConfig.c | 32 +++++++++++++-------- + src/XrrCrtc.c | 83 ++++++++++++++++++++++++++++++++++++++++++------------- + src/XrrMonitor.c | 18 ++++++++++++ + src/XrrOutput.c | 11 ++++++++ + src/XrrProvider.c | 28 ++++++++++++++++--- + src/XrrScreen.c | 52 ++++++++++++++++++++++------------ + 6 files changed, 172 insertions(+), 52 deletions(-) + +diff --git a/src/XrrConfig.c b/src/XrrConfig.c +index 2f0282b..e68c45a 100644 +--- a/src/XrrConfig.c ++++ b/src/XrrConfig.c +@@ -29,6 +29,7 @@ + #include + #endif + ++#include + #include + #include + /* we need to be able to manipulate the Display structure on events */ +@@ -272,23 +273,30 @@ static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, + rep.rate = 0; + rep.nrateEnts = 0; + } ++ if (rep.length < INT_MAX >> 2) { ++ nbytes = (long) rep.length << 2; + +- nbytes = (long) rep.length << 2; ++ nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) + ++ ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF(CARD16) */); + +- nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) + +- ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */); ++ /* ++ * first we must compute how much space to allocate for ++ * randr library's use; we'll allocate the structures in a single ++ * allocation, on cleanlyness grounds. ++ */ + +- /* +- * first we must compute how much space to allocate for +- * randr library's use; we'll allocate the structures in a single +- * allocation, on cleanlyness grounds. +- */ ++ rbytes = sizeof (XRRScreenConfiguration) + ++ (rep.nSizes * sizeof (XRRScreenSize) + ++ rep.nrateEnts * sizeof (int)); + +- rbytes = sizeof (XRRScreenConfiguration) + +- (rep.nSizes * sizeof (XRRScreenSize) + +- rep.nrateEnts * sizeof (int)); ++ scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); ++ } else { ++ nbytes = 0; ++ nbytesRead = 0; ++ rbytes = 0; ++ scp = NULL; ++ } + +- scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); + if (scp == NULL) { + _XEatData (dpy, (unsigned long) nbytes); + return NULL; +diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c +index 5ae35c5..6665092 100644 +--- a/src/XrrCrtc.c ++++ b/src/XrrCrtc.c +@@ -24,6 +24,7 @@ + #include + #endif + ++#include + #include + #include + /* we need to be able to manipulate the Display structure on events */ +@@ -57,22 +58,33 @@ XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc) + return NULL; + } + +- nbytes = (long) rep.length << 2; ++ if (rep.length < INT_MAX >> 2) ++ { ++ nbytes = (long) rep.length << 2; + +- nbytesRead = (long) (rep.nOutput * 4 + +- rep.nPossibleOutput * 4); ++ nbytesRead = (long) (rep.nOutput * 4 + ++ rep.nPossibleOutput * 4); + +- /* +- * first we must compute how much space to allocate for +- * randr library's use; we'll allocate the structures in a single +- * allocation, on cleanlyness grounds. +- */ ++ /* ++ * first we must compute how much space to allocate for ++ * randr library's use; we'll allocate the structures in a single ++ * allocation, on cleanlyness grounds. ++ */ + +- rbytes = (sizeof (XRRCrtcInfo) + +- rep.nOutput * sizeof (RROutput) + +- rep.nPossibleOutput * sizeof (RROutput)); ++ rbytes = (sizeof (XRRCrtcInfo) + ++ rep.nOutput * sizeof (RROutput) + ++ rep.nPossibleOutput * sizeof (RROutput)); ++ ++ xci = (XRRCrtcInfo *) Xmalloc(rbytes); ++ } ++ else ++ { ++ nbytes = 0; ++ nbytesRead = 0; ++ rbytes = 0; ++ xci = NULL; ++ } + +- xci = (XRRCrtcInfo *) Xmalloc(rbytes); + if (xci == NULL) { + _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); +@@ -194,12 +206,21 @@ XRRGetCrtcGamma (Display *dpy, RRCrtc crtc) + if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) + goto out; + +- nbytes = (long) rep.length << 2; ++ if (rep.length < INT_MAX >> 2) ++ { ++ nbytes = (long) rep.length << 2; + +- /* three channels of CARD16 data */ +- nbytesRead = (rep.size * 2 * 3); ++ /* three channels of CARD16 data */ ++ nbytesRead = (rep.size * 2 * 3); + +- crtc_gamma = XRRAllocGamma (rep.size); ++ crtc_gamma = XRRAllocGamma (rep.size); ++ } ++ else ++ { ++ nbytes = 0; ++ nbytesRead = 0; ++ crtc_gamma = NULL; ++ } + + if (!crtc_gamma) + { +@@ -357,7 +378,7 @@ XRRGetCrtcTransform (Display *dpy, + xRRGetCrtcTransformReq *req; + int major_version, minor_version; + XRRCrtcTransformAttributes *attr; +- char *extra = NULL, *e; ++ char *extra = NULL, *end = NULL, *e; + int p; + + *attributes = NULL; +@@ -395,9 +416,17 @@ XRRGetCrtcTransform (Display *dpy, + else + { + int extraBytes = rep.length * 4 - CrtcTransformExtra; +- extra = Xmalloc (extraBytes); ++ if (rep.length < INT_MAX / 4 && ++ rep.length * 4 >= CrtcTransformExtra) { ++ extra = Xmalloc (extraBytes); ++ end = extra + extraBytes; ++ } else ++ extra = NULL; + if (!extra) { +- _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2)); ++ if (rep.length > (CrtcTransformExtra >> 2)) ++ _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2)); ++ else ++ _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return False; +@@ -429,22 +458,38 @@ XRRGetCrtcTransform (Display *dpy, + + e = extra; + ++ if (e + rep.pendingNbytesFilter > end) { ++ XFree (extra); ++ return False; ++ } + memcpy (attr->pendingFilter, e, rep.pendingNbytesFilter); + attr->pendingFilter[rep.pendingNbytesFilter] = '\0'; + e += (rep.pendingNbytesFilter + 3) & ~3; + for (p = 0; p < rep.pendingNparamsFilter; p++) { + INT32 f; ++ if (e + 4 > end) { ++ XFree (extra); ++ return False; ++ } + memcpy (&f, e, 4); + e += 4; + attr->pendingParams[p] = (XFixed) f; + } + attr->pendingNparams = rep.pendingNparamsFilter; + ++ if (e + rep.currentNbytesFilter > end) { ++ XFree (extra); ++ return False; ++ } + memcpy (attr->currentFilter, e, rep.currentNbytesFilter); + attr->currentFilter[rep.currentNbytesFilter] = '\0'; + e += (rep.currentNbytesFilter + 3) & ~3; + for (p = 0; p < rep.currentNparamsFilter; p++) { + INT32 f; ++ if (e + 4 > end) { ++ XFree (extra); ++ return False; ++ } + memcpy (&f, e, 4); + e += 4; + attr->currentParams[p] = (XFixed) f; +diff --git a/src/XrrMonitor.c b/src/XrrMonitor.c +index a9eaa7b..adc5330 100644 +--- a/src/XrrMonitor.c ++++ b/src/XrrMonitor.c +@@ -24,6 +24,7 @@ + #include + #endif + ++#include + #include + #include + /* we need to be able to manipulate the Display structure on events */ +@@ -65,6 +66,15 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors) + return NULL; + } + ++ if (rep.length > INT_MAX >> 2 || ++ rep.nmonitors > INT_MAX / SIZEOF(xRRMonitorInfo) || ++ rep.noutputs > INT_MAX / 4 || ++ rep.nmonitors * SIZEOF(xRRMonitorInfo) > INT_MAX - rep.noutputs * 4) { ++ _XEatData (dpy, rep.length); ++ UnlockDisplay (dpy); ++ SyncHandle (); ++ return NULL; ++ } + nbytes = (long) rep.length << 2; + nmon = rep.nmonitors; + noutput = rep.noutputs; +@@ -111,6 +121,14 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors) + mon[m].outputs = output; + buf += SIZEOF (xRRMonitorInfo); + xoutput = (CARD32 *) buf; ++ if (xmon->noutput > rep.noutputs) { ++ Xfree(buf); ++ Xfree(mon); ++ UnlockDisplay (dpy); ++ SyncHandle (); ++ return NULL; ++ } ++ rep.noutputs -= xmon->noutput; + for (o = 0; o < xmon->noutput; o++) + output[o] = xoutput[o]; + output += xmon->noutput; +diff --git a/src/XrrOutput.c b/src/XrrOutput.c +index 85f0b6e..30f3d40 100644 +--- a/src/XrrOutput.c ++++ b/src/XrrOutput.c +@@ -25,6 +25,7 @@ + #include + #endif + ++#include + #include + #include + /* we need to be able to manipulate the Display structure on events */ +@@ -60,6 +61,16 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) + return NULL; + } + ++ if (rep.length > INT_MAX >> 2 || rep.length < (OutputInfoExtra >> 2)) ++ { ++ if (rep.length > (OutputInfoExtra >> 2)) ++ _XEatDataWords (dpy, rep.length - (OutputInfoExtra >> 2)); ++ else ++ _XEatDataWords (dpy, rep.length); ++ UnlockDisplay (dpy); ++ SyncHandle (); ++ return NULL; ++ } + nbytes = ((long) (rep.length) << 2) - OutputInfoExtra; + + nbytesRead = (long) (rep.nCrtcs * 4 + +diff --git a/src/XrrProvider.c b/src/XrrProvider.c +index 9e620c7..d796cd0 100644 +--- a/src/XrrProvider.c ++++ b/src/XrrProvider.c +@@ -25,6 +25,7 @@ + #include + #endif + ++#include + #include + #include + /* we need to be able to manipulate the Display structure on events */ +@@ -59,12 +60,20 @@ XRRGetProviderResources(Display *dpy, Window window) + return NULL; + } + +- nbytes = (long) rep.length << 2; ++ if (rep.length < INT_MAX >> 2) { ++ nbytes = (long) rep.length << 2; + +- nbytesRead = (long) (rep.nProviders * 4); ++ nbytesRead = (long) (rep.nProviders * 4); + +- rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider)); +- xrpr = (XRRProviderResources *) Xmalloc(rbytes); ++ rbytes = (sizeof(XRRProviderResources) + rep.nProviders * ++ sizeof(RRProvider)); ++ xrpr = (XRRProviderResources *) Xmalloc(rbytes); ++ } else { ++ nbytes = 0; ++ nbytesRead = 0; ++ rbytes = 0; ++ xrpr = NULL; ++ } + + if (xrpr == NULL) { + _XEatDataWords (dpy, rep.length); +@@ -121,6 +130,17 @@ XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provi + return NULL; + } + ++ if (rep.length > INT_MAX >> 2 || rep.length < ProviderInfoExtra >> 2) ++ { ++ if (rep.length < ProviderInfoExtra >> 2) ++ _XEatDataWords (dpy, rep.length); ++ else ++ _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2)); ++ UnlockDisplay (dpy); ++ SyncHandle (); ++ return NULL; ++ } ++ + nbytes = ((long) rep.length << 2) - ProviderInfoExtra; + + nbytesRead = (long)(rep.nCrtcs * 4 + +diff --git a/src/XrrScreen.c b/src/XrrScreen.c +index b8ce7e5..1f7ffe6 100644 +--- a/src/XrrScreen.c ++++ b/src/XrrScreen.c +@@ -24,6 +24,7 @@ + #include + #endif + ++#include + #include + #include + /* we need to be able to manipulate the Display structure on events */ +@@ -105,27 +106,36 @@ doGetScreenResources (Display *dpy, Window window, int poll) + xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version); + } + +- nbytes = (long) rep.length << 2; ++ if (rep.length < INT_MAX >> 2) { ++ nbytes = (long) rep.length << 2; + +- nbytesRead = (long) (rep.nCrtcs * 4 + +- rep.nOutputs * 4 + +- rep.nModes * SIZEOF (xRRModeInfo) + +- ((rep.nbytesNames + 3) & ~3)); ++ nbytesRead = (long) (rep.nCrtcs * 4 + ++ rep.nOutputs * 4 + ++ rep.nModes * SIZEOF (xRRModeInfo) + ++ ((rep.nbytesNames + 3) & ~3)); + +- /* +- * first we must compute how much space to allocate for +- * randr library's use; we'll allocate the structures in a single +- * allocation, on cleanlyness grounds. +- */ ++ /* ++ * first we must compute how much space to allocate for ++ * randr library's use; we'll allocate the structures in a single ++ * allocation, on cleanlyness grounds. ++ */ ++ ++ rbytes = (sizeof (XRRScreenResources) + ++ rep.nCrtcs * sizeof (RRCrtc) + ++ rep.nOutputs * sizeof (RROutput) + ++ rep.nModes * sizeof (XRRModeInfo) + ++ rep.nbytesNames + rep.nModes); /* '\0' terminate names */ + +- rbytes = (sizeof (XRRScreenResources) + +- rep.nCrtcs * sizeof (RRCrtc) + +- rep.nOutputs * sizeof (RROutput) + +- rep.nModes * sizeof (XRRModeInfo) + +- rep.nbytesNames + rep.nModes); /* '\0' terminate names */ ++ xrsr = (XRRScreenResources *) Xmalloc(rbytes); ++ wire_names = (char *) Xmalloc (rep.nbytesNames); ++ } else { ++ nbytes = 0; ++ nbytesRead = 0; ++ rbytes = 0; ++ xrsr = NULL; ++ wire_names = NULL; ++ } + +- xrsr = (XRRScreenResources *) Xmalloc(rbytes); +- wire_names = (char *) Xmalloc (rep.nbytesNames); + if (xrsr == NULL || wire_names == NULL) { + Xfree (xrsr); + Xfree (wire_names); +@@ -174,6 +184,14 @@ doGetScreenResources (Display *dpy, Window window, int poll) + wire_name = wire_names; + for (i = 0; i < rep.nModes; i++) { + xrsr->modes[i].name = names; ++ if (xrsr->modes[i].nameLength > rep.nbytesNames) { ++ Xfree (xrsr); ++ Xfree (wire_names); ++ UnlockDisplay (dpy); ++ SyncHandle (); ++ return NULL; ++ } ++ rep.nbytesNames -= xrsr->modes[i].nameLength; + memcpy (names, wire_name, xrsr->modes[i].nameLength); + names[xrsr->modes[i].nameLength] = '\0'; + names += xrsr->modes[i].nameLength + 1; +-- +2.10.1 + diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm index ce0c4f9..b6cfbd6 100644 --- a/gnu/packages/xorg.scm +++ b/gnu/packages/xorg.scm @@ -4934,6 +4934,7 @@ new API's in libXft, or the legacy API's in libX11.") (define-public libxrandr (package (name "libxrandr") + (replacement libxrandr/fixed) (version "1.5.0") (source (origin @@ -4961,6 +4962,13 @@ new API's in libXft, or the legacy API's in libX11.") "Library for the Resize and Rotate Extension to the X11 protocol.") (license license:x11))) +(define libxrandr/fixed + (package + (inherit libxrandr) + (source (origin + (inherit (package-source libxrandr)) + (patches (search-patches + "libxrandr-CVE-2016-7947-CVE-2016-7948.patch")))))) (define-public libxvmc (package -- 2.10.1