From e6d9eccdf7eeb94ed8fdd2cd4e7ebd51ed7fb04a Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Fri, 24 May 2013 09:55:00 +0000 Subject: main/libxt: fix CVE-2013-2002,CVE-2013-2005 ref #1931 --- ...eturn-values-of-XGetWindowProperty-CVE-20.patch | 175 +++++++++++++++++++++ ...-length-in-_XtResourceConfigurationEH-CVE.patch | 78 +++++++++ main/libxt/APKBUILD | 37 ++++- 3 files changed, 282 insertions(+), 8 deletions(-) create mode 100644 main/libxt/0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch create mode 100644 main/libxt/0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch diff --git a/main/libxt/0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch b/main/libxt/0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch new file mode 100644 index 000000000..f61180225 --- /dev/null +++ b/main/libxt/0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch @@ -0,0 +1,175 @@ +From eae57493feec958bcf733ad0d334715107029f8b Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 9 Mar 2013 11:29:21 -0800 +Subject: [PATCH 1/2] Unchecked return values of XGetWindowProperty + [CVE-2013-2005] + +Multiple functions in Selection.c assumed that XGetWindowProperty() would +always set the pointer to the property, but before libX11 1.6, it could +fail to do so in some cases, leading to libXt freeing or operating on an +uninitialized pointer value, so libXt should always initialize the pointers +and check for failure itself. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +--- + src/Selection.c | 84 ++++++++++++++++++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 37 deletions(-) + +diff --git a/src/Selection.c b/src/Selection.c +index f35cb44..4f59d70 100644 +--- a/src/Selection.c ++++ b/src/Selection.c +@@ -839,14 +839,16 @@ static void HandleSelectionEvents( + IndirectPair *p; + int format; + unsigned long bytesafter, length; +- unsigned char *value; ++ unsigned char *value = NULL; + ev.property = event->xselectionrequest.property; + StartProtectedSection(ev.display, ev.requestor); +- (void) XGetWindowProperty(ev.display, ev.requestor, ++ if (XGetWindowProperty(ev.display, ev.requestor, + event->xselectionrequest.property, 0L, 1000000, + False,(Atom)AnyPropertyType, &target, &format, &length, +- &bytesafter, &value); +- count = BYTELENGTH(length, format) / sizeof(IndirectPair); ++ &bytesafter, &value) == Success) ++ count = BYTELENGTH(length, format) / sizeof(IndirectPair); ++ else ++ count = 0; + for (p = (IndirectPair *)value; count; p++, count--) { + EndProtectedSection(ctx->dpy); + if (!GetConversion(ctx, (XSelectionRequestEvent*)event, +@@ -1053,9 +1055,10 @@ static Boolean IsINCRtype( + + if (prop == None) return False; + +- (void)XGetWindowProperty(XtDisplay(info->widget), window, prop, 0L, 0L, +- False, info->ctx->prop_list->incr_atom, +- &type, &format, &length, &bytesafter, &value); ++ if (XGetWindowProperty(XtDisplay(info->widget), window, prop, 0L, 0L, ++ False, info->ctx->prop_list->incr_atom, &type, ++ &format, &length, &bytesafter, &value) != Success) ++ return False; + + return (type == info->ctx->prop_list->incr_atom); + } +@@ -1069,7 +1072,6 @@ static void ReqCleanup( + { + CallBackInfo info = (CallBackInfo)closure; + unsigned long bytesafter, length; +- char *value; + int format; + Atom target; + +@@ -1093,17 +1095,19 @@ static void ReqCleanup( + (ev->xproperty.state == PropertyNewValue) && + (ev->xproperty.atom == info->property)) { + XPropertyEvent *event = (XPropertyEvent *) ev; +- (void) XGetWindowProperty(event->display, XtWindow(widget), +- event->atom, 0L, 1000000, True, AnyPropertyType, +- &target, &format, &length, &bytesafter, +- (unsigned char **) &value); +- XFree(value); +- if (length == 0) { +- XtRemoveEventHandler(widget, (EventMask) PropertyChangeMask, FALSE, +- ReqCleanup, (XtPointer) info ); +- FreeSelectionProperty(XtDisplay(widget), info->property); +- XtFree(info->value); /* requestor never got this, so free now */ +- FreeInfo(info); ++ char *value = NULL; ++ if (XGetWindowProperty(event->display, XtWindow(widget), ++ event->atom, 0L, 1000000, True, AnyPropertyType, ++ &target, &format, &length, &bytesafter, ++ (unsigned char **) &value) == Success) { ++ XFree(value); ++ if (length == 0) { ++ XtRemoveEventHandler(widget, (EventMask) PropertyChangeMask, ++ FALSE, ReqCleanup, (XtPointer) info ); ++ FreeSelectionProperty(XtDisplay(widget), info->property); ++ XtFree(info->value); /* requestor never got this, so free now */ ++ FreeInfo(info); ++ } + } + } + } +@@ -1121,20 +1125,23 @@ static void ReqTimedOut( + unsigned long bytesafter; + unsigned long proplength; + Atom type; +- IndirectPair *pairs; + XtPointer *c; + int i; + + if (*info->target == info->ctx->prop_list->indirect_atom) { +- (void) XGetWindowProperty(XtDisplay(info->widget), +- XtWindow(info->widget), info->property, 0L, +- 10000000, True, AnyPropertyType, &type, &format, +- &proplength, &bytesafter, (unsigned char **) &pairs); +- XFree((char*)pairs); +- for (proplength = proplength / IndirectPairWordSize, i = 0, c = info->req_closure; +- proplength; proplength--, c++, i++) +- (*info->callbacks[i])(info->widget, *c, +- &info->ctx->selection, &resulttype, value, &length, &format); ++ IndirectPair *pairs = NULL; ++ if (XGetWindowProperty(XtDisplay(info->widget), XtWindow(info->widget), ++ info->property, 0L, 10000000, True, ++ AnyPropertyType, &type, &format, &proplength, ++ &bytesafter, (unsigned char **) &pairs) ++ == Success) { ++ XFree(pairs); ++ for (proplength = proplength / IndirectPairWordSize, i = 0, ++ c = info->req_closure; ++ proplength; proplength--, c++, i++) ++ (*info->callbacks[i])(info->widget, *c, &info->ctx->selection, ++ &resulttype, value, &length, &format); ++ } + } else { + (*info->callbacks[0])(info->widget, *info->req_closure, + &info->ctx->selection, &resulttype, value, &length, &format); +@@ -1280,12 +1287,13 @@ Boolean HandleNormal( + unsigned long length; + int format; + Atom type; +- unsigned char *value; ++ unsigned char *value = NULL; + int number = info->current; + +- (void) XGetWindowProperty(dpy, XtWindow(widget), property, 0L, +- 10000000, False, AnyPropertyType, +- &type, &format, &length, &bytesafter, &value); ++ if (XGetWindowProperty(dpy, XtWindow(widget), property, 0L, 10000000, ++ False, AnyPropertyType, &type, &format, &length, ++ &bytesafter, &value) != Success) ++ return FALSE; + + if (type == info->ctx->prop_list->incr_atom) { + unsigned long size = IncrPropSize(widget, value, format, length); +@@ -1370,7 +1378,6 @@ static void HandleSelectionReplies( + Display *dpy = event->display; + CallBackInfo info = (CallBackInfo) closure; + Select ctx = info->ctx; +- IndirectPair *pairs, *p; + unsigned long bytesafter; + unsigned long length; + int format; +@@ -1385,9 +1392,12 @@ static void HandleSelectionReplies( + XtRemoveEventHandler(widget, (EventMask)0, TRUE, + HandleSelectionReplies, (XtPointer) info ); + if (event->target == ctx->prop_list->indirect_atom) { +- (void) XGetWindowProperty(dpy, XtWindow(widget), info->property, 0L, +- 10000000, True, AnyPropertyType, &type, &format, +- &length, &bytesafter, (unsigned char **) &pairs); ++ IndirectPair *pairs = NULL, *p; ++ if (XGetWindowProperty(dpy, XtWindow(widget), info->property, 0L, ++ 10000000, True, AnyPropertyType, &type, &format, ++ &length, &bytesafter, (unsigned char **) &pairs) ++ != Success) ++ length = 0; + for (length = length / IndirectPairWordSize, p = pairs, + c = info->req_closure; + length; length--, p++, c++, info->current++) { +-- +1.8.2.3 + diff --git a/main/libxt/0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch b/main/libxt/0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch new file mode 100644 index 000000000..05c77504e --- /dev/null +++ b/main/libxt/0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch @@ -0,0 +1,78 @@ +From 9264a21b688891dbdcee630ff72cf39aa75fc4e1 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 9 Mar 2013 11:44:14 -0800 +Subject: [PATCH 2/2] unvalidated length in _XtResourceConfigurationEH + [CVE-2013-2002] + +The RCM_DATA property is expected to be in the format: + resource_length, resource, value + +If the property contains a resource_length thats results in a pointer +outside the property string, memory corruption can occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +--- + src/ResConfig.c | 41 ++++++++++++++++++++++++++--------------- + 1 file changed, 26 insertions(+), 15 deletions(-) + +diff --git a/src/ResConfig.c b/src/ResConfig.c +index 68da536..1f3edbe 100644 +--- a/src/ResConfig.c ++++ b/src/ResConfig.c +@@ -971,26 +971,37 @@ _XtResourceConfigurationEH ( + * resource and value fields. + */ + if (data) { ++ char *data_end = data + nitems; ++ char *data_value; ++ + resource_len = Strtoul ((void *)data, &data_ptr, 10); +- data_ptr++; + +- data_ptr[resource_len] = '\0'; ++ if (data_ptr != (char *) data) { ++ data_ptr++; ++ data_value = data_ptr + resource_len; ++ } else /* strtoul failed to convert a number */ ++ data_ptr = data_value = NULL; ++ ++ if (data_value > data_ptr && data_value < data_end) { ++ *data_value++ = '\0'; + +- resource = XtNewString (data_ptr); +- value = XtNewString (&data_ptr[resource_len + 1]); ++ resource = XtNewString (data_ptr); ++ value = XtNewString (data_value); + #ifdef DEBUG +- fprintf (stderr, "resource_len=%d\n",resource_len); +- fprintf (stderr, "resource = %s\t value = %s\n", +- resource, value); ++ fprintf (stderr, "resource_len=%d\n" ++ resource_len); ++ fprintf (stderr, "resource = %s\t value = %s\n", ++ resource, value); + #endif +- /* +- * descend the application widget tree and +- * apply the value to the appropriate widgets +- */ +- _search_widget_tree (w, resource, value); +- +- XtFree (resource); +- XtFree (value); ++ /* ++ * descend the application widget tree and ++ * apply the value to the appropriate widgets ++ */ ++ _search_widget_tree (w, resource, value); ++ ++ XtFree (resource); ++ XtFree (value); ++ } + } + } + +-- +1.8.2.3 + diff --git a/main/libxt/APKBUILD b/main/libxt/APKBUILD index 3e5c6686e..c2b318a96 100644 --- a/main/libxt/APKBUILD +++ b/main/libxt/APKBUILD @@ -1,29 +1,50 @@ # Maintainer: Natanael Copa pkgname=libxt pkgver=1.1.3 -pkgrel=0 +pkgrel=1 pkgdesc="X11 toolkit intrinsics library" url="http://xorg.freedesktop.org/" arch="all" license="custom" subpackages="$pkgname-dev $pkgname-doc" depends= -makedepends="pkgconfig libsm-dev libice-dev libx11-dev e2fsprogs-dev" -source="http://xorg.freedesktop.org/releases/individual/lib/libXt-$pkgver.tar.bz2" - depends_dev="xproto libx11-dev libsm-dev" +makedepends="$depends_dev libice-dev e2fsprogs-dev" +source="http://xorg.freedesktop.org/releases/individual/lib/libXt-$pkgver.tar.bz2 + 0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch + 0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch + " + +_builddir="$srcdir"/libXt-$pkgver +prepare() { + cd "$_builddir" + for i in $source; do + case $i in + *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;; + esac + done +} + build () { - cd "$srcdir"/libXt-$pkgver + cd "$_builddir" ./configure --prefix=/usr \ --sysconfdir=/etc \ - --disable-install-makestrs + || return 1 make || return 1 } package() { - cd "$srcdir"/libXt-$pkgver + cd "$_builddir" make -j1 DESTDIR="$pkgdir" install || return 1 rm "$pkgdir"/usr/lib/*.la || return 1 } -md5sums="a6f137ae100e74ebe3b71eb4a38c40b3 libXt-1.1.3.tar.bz2" +md5sums="a6f137ae100e74ebe3b71eb4a38c40b3 libXt-1.1.3.tar.bz2 +ddbc29bbc588eaeb01c01a94ddf8cdb8 0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch +4ffbba851dcb9031ec620e48d0acffe9 0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch" +sha256sums="8db593c3fc5ffc4e9cd854ba50af1eac9b90d66521ba17802b8f1e0d2d7f05bd libXt-1.1.3.tar.bz2 +84d0bc18fb74b4bbde40ec19e7745db1fc8cdc131a2578361005b289fa6dcb09 0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch +758c710f423e22d17b8938574bebf8dc5c8193ef8296f8c8fb974229f886420c 0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch" +sha512sums="26d81ddb00f2d231afe37f0d55be9aaf95f0926086751d1816d02d15244e8ac7dc61e4e96e6ac33b2d22455aa7992c7b86e5bc9eada4ebcecaf6909dc0939416 libXt-1.1.3.tar.bz2 +b1e7040636ff0ab4d67c522c46aa72d134ca47bfb8553288a28e6e69e1aafcb9bce41e4a55b2356d7145fdacef72c5018ff96923bf46d7c21e15bf30d23d40e3 0001-Unchecked-return-values-of-XGetWindowProperty-CVE-20.patch +e43430f8b904bce0a6e171a6e24f7dc85bcfa9741d742c00d7f616744ae629b7ea3bdb32dd2b4c8f006880657f6ffc809966b69ce24bdf2343ecedf4fe579b1c 0002-unvalidated-length-in-_XtResourceConfigurationEH-CVE.patch" -- cgit v1.2.3