From 933231c9ba54bd2c00a05cd74406011031315a46 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Fri, 24 May 2013 09:14:10 +0000 Subject: main/libxrandr: fix CVE-2013-1986 ref #1931 fixes #1959 (cherry picked from commit 0df792b849962f1e9302b2405f6d846e414e27bc) --- main/libxrandr/APKBUILD | 35 ++++++-- main/libxrandr/CVE-2013-1986-1.patch | 158 +++++++++++++++++++++++++++++++++++ main/libxrandr/CVE-2013-1986-2.patch | 60 +++++++++++++ main/libxrandr/CVE-2013-1986-3.patch | 81 ++++++++++++++++++ main/libxrandr/CVE-2013-1986-4.patch | 48 +++++++++++ 5 files changed, 375 insertions(+), 7 deletions(-) create mode 100644 main/libxrandr/CVE-2013-1986-1.patch create mode 100644 main/libxrandr/CVE-2013-1986-2.patch create mode 100644 main/libxrandr/CVE-2013-1986-3.patch create mode 100644 main/libxrandr/CVE-2013-1986-4.patch diff --git a/main/libxrandr/APKBUILD b/main/libxrandr/APKBUILD index 94bca423db..713a803241 100644 --- a/main/libxrandr/APKBUILD +++ b/main/libxrandr/APKBUILD @@ -1,20 +1,37 @@ # Maintainer: Natanael Copa pkgname=libxrandr pkgver=1.3.2 -pkgrel=0 +pkgrel=1 pkgdesc="X11 RandR extension library" url="http://xorg.freedesktop.org/" arch="all" license="custom" subpackages="$pkgname-dev $pkgname-doc" depends= -makedepends="pkgconfig libxext-dev libxrender-dev randrproto libx11-dev" -source="http://xorg.freedesktop.org/releases/individual/lib/libXrandr-$pkgver.tar.bz2" - depends_dev="xproto randrproto libx11-dev libxext-dev libxrender-dev" +makedepends="$depends_dev libtool autoconf automake util-macros" +source="http://xorg.freedesktop.org/releases/individual/lib/libXrandr-$pkgver.tar.bz2 + CVE-2013-1986-1.patch + CVE-2013-1986-2.patch + CVE-2013-1986-3.patch + CVE-2013-1986-4.patch + " + + +_builddir="$srcdir"/libXrandr-$pkgver +prepare() { + cd "$_builddir" + for i in $source; do + case $i in + *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;; + esac + done + libtoolize --force && aclocal && autoheader && autoconf \ + && automake --add-missing +} build() { - cd "$srcdir"/libXrandr-$pkgver + cd "$_builddir" ./configure --prefix=/usr \ --sysconfdir=/etc \ || return 1 @@ -22,9 +39,13 @@ build() { } package() { - cd "$srcdir"/libXrandr-$pkgver + cd "$_builddir" make DESTDIR="$pkgdir" install || return 1 rm "$pkgdir"/usr/lib/*.la || return 1 install -Dm644 COPYING "$pkgdir"/usr/share/licenses/$pkgname/COPYING } -md5sums="92473da2fccf5fac665be4fa4f2037fa libXrandr-1.3.2.tar.bz2" +md5sums="92473da2fccf5fac665be4fa4f2037fa libXrandr-1.3.2.tar.bz2 +d5ef9db626af5fe41f2dc2bd707f0e6d CVE-2013-1986-1.patch +9ecaa507114e318be01e9b8d480ce91b CVE-2013-1986-2.patch +a5b4094938415ac7e21e7a73b8f3e130 CVE-2013-1986-3.patch +03ee896864d2e5818de89f93e23070be CVE-2013-1986-4.patch" diff --git a/main/libxrandr/CVE-2013-1986-1.patch b/main/libxrandr/CVE-2013-1986-1.patch new file mode 100644 index 0000000000..f338d53af0 --- /dev/null +++ b/main/libxrandr/CVE-2013-1986-1.patch @@ -0,0 +1,158 @@ +From e3c51160c87bc8cfe43f944df641bc1e627797ec Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 3 May 2013 23:29:22 -0700 +Subject: [PATCH] Use _XEatDataWords to avoid overflow of rep.length bit shifting + +rep.length is a CARD32, so rep.length << 2 could overflow in 32-bit builds + +Signed-off-by: Alan Coopersmith +Signed-off-by: Julien Cristau +--- + configure.ac | 6 ++++++ + src/Xrandrint.h | 13 +++++++++++++ + src/XrrCrtc.c | 6 +++--- + src/XrrOutput.c | 2 +- + src/XrrProperty.c | 9 ++++----- + src/XrrScreen.c | 2 +- + 6 files changed, 28 insertions(+), 10 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 8c74adb..46401ef 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -56,6 +56,12 @@ AC_SUBST(RANDR_VERSION) + # Obtain compiler/linker options for depedencies + PKG_CHECK_MODULES(RANDR, x11 randrproto >= $RANDR_VERSION xext xextproto xrender renderproto) + ++# Check for _XEatDataWords function that may be patched into older Xlib release ++SAVE_LIBS="$LIBS" ++LIBS="$RANDR_LIBS" ++AC_CHECK_FUNCS([_XEatDataWords]) ++LIBS="$SAVE_LIBS" ++ + AC_CONFIG_FILES([Makefile + src/Makefile + man/Makefile +diff --git a/src/Xrandrint.h b/src/Xrandrint.h +index 7fb5831..791b36b 100644 +--- a/src/Xrandrint.h ++++ b/src/Xrandrint.h +@@ -42,6 +42,19 @@ extern char XRRExtensionName[]; + + XExtDisplayInfo *XRRFindDisplay (Display *dpy); + ++#ifndef HAVE__XEATDATAWORDS ++#include /* for LONG64 on 64-bit platforms */ ++#include ++ ++static inline void _XEatDataWords(Display *dpy, unsigned long n) ++{ ++# ifndef LONG64 ++ if (n >= (ULONG_MAX >> 2)) ++ _XIOError(dpy); ++# endif ++ _XEatData (dpy, n << 2); ++} ++#endif + + /* deliberately opaque internal data structure; can be extended, + but not reordered */ +diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c +index 697987a..d3c748b 100644 +--- a/src/XrrCrtc.c ++++ b/src/XrrCrtc.c +@@ -74,7 +74,7 @@ XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc) + + xci = (XRRCrtcInfo *) Xmalloc(rbytes); + if (xci == NULL) { +- _XEatData (dpy, (unsigned long) nbytes); ++ _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; +@@ -203,7 +203,7 @@ XRRGetCrtcGamma (Display *dpy, RRCrtc crtc) + + if (!crtc_gamma) + { +- _XEatData (dpy, (unsigned long) nbytes); ++ _XEatDataWords (dpy, rep.length); + goto out; + } + _XRead16 (dpy, crtc_gamma->red, rep.size * 2); +@@ -397,7 +397,7 @@ XRRGetCrtcTransform (Display *dpy, + int extraBytes = rep.length * 4 - CrtcTransformExtra; + extra = Xmalloc (extraBytes); + if (!extra) { +- _XEatData (dpy, extraBytes); ++ _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2)); + UnlockDisplay (dpy); + SyncHandle (); + return False; +diff --git a/src/XrrOutput.c b/src/XrrOutput.c +index 18863bd..487d38a 100644 +--- a/src/XrrOutput.c ++++ b/src/XrrOutput.c +@@ -81,7 +81,7 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) + + xoi = (XRROutputInfo *) Xmalloc(rbytes); + if (xoi == NULL) { +- _XEatData (dpy, (unsigned long) nbytes); ++ _XEatDataWords (dpy, rep.length - (OutputInfoExtra >> 2)); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; +diff --git a/src/XrrProperty.c b/src/XrrProperty.c +index 1a125b2..afa9d24 100644 +--- a/src/XrrProperty.c ++++ b/src/XrrProperty.c +@@ -62,7 +62,7 @@ XRRListOutputProperties (Display *dpy, RROutput output, int *nprop) + + props = (Atom *) Xmalloc (rbytes); + if (props == NULL) { +- _XEatData (dpy, nbytes); ++ _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + *nprop = 0; +@@ -107,7 +107,7 @@ XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property) + + prop_info = (XRRPropertyInfo *) Xmalloc (rbytes); + if (prop_info == NULL) { +- _XEatData (dpy, nbytes); ++ _XEatDataWords(dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; +@@ -313,14 +313,13 @@ XRRGetOutputProperty (Display *dpy, RROutput output, + * This part of the code should never be reached. If it is, + * the server sent back a property with an invalid format. + */ +- nbytes = rep.length << 2; +- _XEatData(dpy, (unsigned long) nbytes); ++ _XEatDataWords(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + return(BadImplementation); + } + if (! *prop) { +- _XEatData(dpy, (unsigned long) nbytes); ++ _XEatDataWords(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + return(BadAlloc); +diff --git a/src/XrrScreen.c b/src/XrrScreen.c +index 54bc2ca..c4e9eb5 100644 +--- a/src/XrrScreen.c ++++ b/src/XrrScreen.c +@@ -129,7 +129,7 @@ doGetScreenResources (Display *dpy, Window window, int poll) + if (xrsr == NULL || wire_names == NULL) { + if (xrsr) Xfree (xrsr); + if (wire_names) Xfree (wire_names); +- _XEatData (dpy, (unsigned long) nbytes); ++ _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; +-- +1.7.2.5 + diff --git a/main/libxrandr/CVE-2013-1986-2.patch b/main/libxrandr/CVE-2013-1986-2.patch new file mode 100644 index 0000000000..1f728b74c1 --- /dev/null +++ b/main/libxrandr/CVE-2013-1986-2.patch @@ -0,0 +1,60 @@ +From 30f848810239641ba6399f4f379ff1325359ce26 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 12 Apr 2013 21:44:59 -0700 +Subject: [PATCH] integer overflow in XRRQueryOutputProperty() [CVE-2013-1986 1/4] + +rep.length is a CARD32, while rbytes was a signed int, so + rbytes = sizeof (XRRPropertyInfo) + rep.length * sizeof (long); +could result in integer overflow, leading to an undersized malloc +and reading data off the connection and writing it past the end of +the allocated buffer. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Signed-off-by: Julien Cristau +--- + src/XrrProperty.c | 13 +++++++++---- + 1 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/src/XrrProperty.c b/src/XrrProperty.c +index afa9d24..603da9a 100644 +--- a/src/XrrProperty.c ++++ b/src/XrrProperty.c +@@ -31,6 +31,7 @@ + #include + #include + #include "Xrandrint.h" ++#include + + Atom * + XRRListOutputProperties (Display *dpy, RROutput output, int *nprop) +@@ -84,7 +85,7 @@ XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property) + XExtDisplayInfo *info = XRRFindDisplay(dpy); + xRRQueryOutputPropertyReply rep; + xRRQueryOutputPropertyReq *req; +- int rbytes, nbytes; ++ unsigned int rbytes, nbytes; + XRRPropertyInfo *prop_info; + + RRCheckExtension (dpy, info, NULL); +@@ -102,10 +103,14 @@ XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property) + return NULL; + } + +- rbytes = sizeof (XRRPropertyInfo) + rep.length * sizeof (long); +- nbytes = rep.length << 2; ++ if (rep.length < ((INT_MAX / sizeof(long)) - sizeof (XRRPropertyInfo))) { ++ rbytes = sizeof (XRRPropertyInfo) + (rep.length * sizeof (long)); ++ nbytes = rep.length << 2; ++ ++ prop_info = Xmalloc (rbytes); ++ } else ++ prop_info = NULL; + +- prop_info = (XRRPropertyInfo *) Xmalloc (rbytes); + if (prop_info == NULL) { + _XEatDataWords(dpy, rep.length); + UnlockDisplay (dpy); +-- +1.7.2.5 + diff --git a/main/libxrandr/CVE-2013-1986-3.patch b/main/libxrandr/CVE-2013-1986-3.patch new file mode 100644 index 0000000000..3a6ed0353e --- /dev/null +++ b/main/libxrandr/CVE-2013-1986-3.patch @@ -0,0 +1,81 @@ +From d4946df6b4c2352b91786253d9bbfb098f59a821 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 4 May 2013 21:37:49 -0700 +Subject: [PATCH] integer overflow in XRRGetOutputProperty() [CVE-2013-1986 3/4] + +If the reported number of properties is too large, the calculations +to allocate memory for them may overflow, leaving us returning less +memory to the caller than implied by the value written to *nitems. + +(Same as reported against libX11 XGetWindowProperty by Ilja Van Sprundel) + +Signed-off-by: Alan Coopersmith +Signed-off-by: Julien Cristau +--- + src/XrrProperty.c | 22 ++++++++++++++-------- + 1 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/src/XrrProperty.c b/src/XrrProperty.c +index 603da9a..0c30d43 100644 +--- a/src/XrrProperty.c ++++ b/src/XrrProperty.c +@@ -257,7 +257,7 @@ XRRGetOutputProperty (Display *dpy, RROutput output, + XExtDisplayInfo *info = XRRFindDisplay(dpy); + xRRGetOutputPropertyReply rep; + xRRGetOutputPropertyReq *req; +- long nbytes, rbytes; ++ unsigned long nbytes, rbytes; + + RRCheckExtension (dpy, info, 1); + +@@ -282,34 +282,40 @@ XRRGetOutputProperty (Display *dpy, RROutput output, + + *prop = (unsigned char *) NULL; + if (rep.propertyType != None) { ++ int format = rep.format; ++ ++ /* ++ * Protect against both integer overflow and just plain oversized ++ * memory allocation - no server should ever return this many props. ++ */ ++ if (rep.nItems >= (INT_MAX >> 4)) ++ format = -1; /* fall through to default error case */ ++ + /* + * One extra byte is malloced than is needed to contain the property + * data, but this last byte is null terminated and convenient for + * returning string properties, so the client doesn't then have to + * recopy the string to make it null terminated. + */ +- switch (rep.format) { ++ switch (format) { + case 8: + nbytes = rep.nItems; + rbytes = rep.nItems + 1; +- if (rbytes > 0 && +- (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes))) ++ if (rbytes > 0 && (*prop = Xmalloc (rbytes))) + _XReadPad (dpy, (char *) *prop, nbytes); + break; + + case 16: + nbytes = rep.nItems << 1; + rbytes = rep.nItems * sizeof (short) + 1; +- if (rbytes > 0 && +- (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes))) ++ if (rbytes > 0 && (*prop = Xmalloc (rbytes))) + _XRead16Pad (dpy, (short *) *prop, nbytes); + break; + + case 32: + nbytes = rep.nItems << 2; + rbytes = rep.nItems * sizeof (long) + 1; +- if (rbytes > 0 && +- (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes))) ++ if (rbytes > 0 && (*prop = Xmalloc (rbytes))) + _XRead32 (dpy, (long *) *prop, nbytes); + break; + +-- +1.7.2.5 + diff --git a/main/libxrandr/CVE-2013-1986-4.patch b/main/libxrandr/CVE-2013-1986-4.patch new file mode 100644 index 0000000000..1583c84a72 --- /dev/null +++ b/main/libxrandr/CVE-2013-1986-4.patch @@ -0,0 +1,48 @@ +From 2ee6511dfc3c3cd766021d26554643bd984b18ac Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 4 May 2013 21:47:50 -0700 +Subject: [PATCH] Make XRRGet*Property() always initialize returned values + +Avoids memory corruption and other errors when callers access them +without checking to see if the calls returned an error value. + +Callers are still required to check for errors, this just reduces the +damage when they don't. + +(Same as reported against libX11 XGetWindowProperty by Ilja Van Sprundel) + +Signed-off-by: Alan Coopersmith +Signed-off-by: Julien Cristau +--- + src/XrrProperty.c | 8 +++++++- + 1 files changed, 7 insertions(+), 1 deletions(-) + +diff --git a/src/XrrProperty.c b/src/XrrProperty.c +index 0c30d43..5864651 100644 +--- a/src/XrrProperty.c ++++ b/src/XrrProperty.c +@@ -259,6 +259,13 @@ XRRGetOutputProperty (Display *dpy, RROutput output, + xRRGetOutputPropertyReq *req; + unsigned long nbytes, rbytes; + ++ /* Always initialize return values, in case callers fail to initialize ++ them and fail to check the return code for an error. */ ++ *actual_type = None; ++ *actual_format = 0; ++ *nitems = *bytes_after = 0L; ++ *prop = (unsigned char *) NULL; ++ + RRCheckExtension (dpy, info, 1); + + LockDisplay (dpy); +@@ -280,7 +287,6 @@ XRRGetOutputProperty (Display *dpy, RROutput output, + return ((xError *)&rep)->errorCode; + } + +- *prop = (unsigned char *) NULL; + if (rep.propertyType != None) { + int format = rep.format; + +-- +1.7.2.5 + -- cgit v1.2.3