aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonardo Arena <rnalrd@alpinelinux.org>2016-10-20 10:03:01 +0000
committerLeonardo Arena <rnalrd@alpinelinux.org>2016-10-20 10:07:10 +0000
commitb0140e4401ffc6200ed5a33ebe5e45d4ceac66fd (patch)
treead7935f2049e53b54d21857cd6951456f26aa97f
parentcb627c977abbd0298bd4dddb278243f001aebb0d (diff)
downloadaports-b0140e4401ffc6200ed5a33ebe5e45d4ceac66fd.tar.bz2
aports-b0140e4401ffc6200ed5a33ebe5e45d4ceac66fd.tar.xz
main/libxi: security fixes (CVE-2016-7945, CVE-2016-7946)
Fixes #6305 (cherry picked from commit ffaa32a96062a37c4b3aff0dc2b6e37661dab85a)
-rw-r--r--main/libxi/APKBUILD25
-rw-r--r--main/libxi/CVE-2016-7945-7946.patch400
2 files changed, 415 insertions, 10 deletions
diff --git a/main/libxi/APKBUILD b/main/libxi/APKBUILD
index c970020e50..293a1d8f49 100644
--- a/main/libxi/APKBUILD
+++ b/main/libxi/APKBUILD
@@ -1,7 +1,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=libxi
pkgver=1.7.4
-pkgrel=0
+pkgrel=1
pkgdesc="X11 Input extension library"
url="http://xorg.freedesktop.org"
arch="all"
@@ -9,13 +9,15 @@ license="custom"
subpackages="$pkgname-dev $pkgname-doc"
depends=
depends_dev="inputproto libx11-dev libxext-dev libxfixes-dev"
-makedepends="
- $depends_dev
- pkgconfig
- xextproto
- xproto
+makedepends="$depends_dev pkgconfig xextproto xproto"
+source="http://xorg.freedesktop.org/releases/individual/lib/libXi-$pkgver.tar.bz2
+ CVE-2016-7945-7946.patch
"
-source="http://xorg.freedesktop.org/releases/individual/lib/libXi-$pkgver.tar.bz2"
+
+# secfixes:
+# 1.7.4-r1:
+# - CVE-2016-7945
+# - CVE-2016-7946
_builddir="$srcdir"/libXi-$pkgver
prepare() {
@@ -45,6 +47,9 @@ package() {
rm "$pkgdir"/usr/lib/*.la || return 1
install -Dm644 COPYING "$pkgdir"/usr/share/licenses/$pkgname/COPYING
}
-md5sums="9c4a69c34b19ec1e4212e849549544cb libXi-1.7.4.tar.bz2"
-sha256sums="2cffc2686618dc1803725636cd92b36342c512dc60a7a35cba34bf7192a42244 libXi-1.7.4.tar.bz2"
-sha512sums="17182e580bdf6d65c743ceef4f652f7c7975761f288dfd6f2961c2fed23931569f7cf7cac745bb252fe0a6c3be2739ba6f6533b895519800e382a48f2e5297f0 libXi-1.7.4.tar.bz2"
+md5sums="9c4a69c34b19ec1e4212e849549544cb libXi-1.7.4.tar.bz2
+3f23ae121a1a185b30829e73f90aa066 CVE-2016-7945-7946.patch"
+sha256sums="2cffc2686618dc1803725636cd92b36342c512dc60a7a35cba34bf7192a42244 libXi-1.7.4.tar.bz2
+6af5945a5a759530a50e39869de76f50f9ff0866d80c48c231d1b39df895eb02 CVE-2016-7945-7946.patch"
+sha512sums="17182e580bdf6d65c743ceef4f652f7c7975761f288dfd6f2961c2fed23931569f7cf7cac745bb252fe0a6c3be2739ba6f6533b895519800e382a48f2e5297f0 libXi-1.7.4.tar.bz2
+6471798bbbd56123d523c90d2a5174e59dfd7189de19913097a716adc77eff16e681c892833b712bd39c0fc99289d11749f8f5378dd97061c90a5150f0cfee63 CVE-2016-7945-7946.patch"
diff --git a/main/libxi/CVE-2016-7945-7946.patch b/main/libxi/CVE-2016-7945-7946.patch
new file mode 100644
index 0000000000..25cd059c94
--- /dev/null
+++ b/main/libxi/CVE-2016-7945-7946.patch
@@ -0,0 +1,400 @@
+From 19a9cd607de73947fcfb104682f203ffe4e1f4e5 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 22:31:34 +0200
+Subject: Properly validate server responses.
+
+By validating length fields from server responses, out of boundary
+accesses and endless loops can be mitigated.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+
+diff --git a/src/XGMotion.c b/src/XGMotion.c
+index 7785843..9433e29 100644
+--- a/src/XGMotion.c
++++ b/src/XGMotion.c
+@@ -114,7 +114,8 @@ XGetDeviceMotionEvents(
+ }
+ /* rep.axes is a CARD8, so assume max number of axes for bounds check */
+ if (rep.nEvents <
+- (INT_MAX / (sizeof(XDeviceTimeCoord) + (UCHAR_MAX * sizeof(int))))) {
++ (INT_MAX / (sizeof(XDeviceTimeCoord) + (UCHAR_MAX * sizeof(int)))) &&
++ rep.nEvents * (rep.axes + 1) <= rep.length) {
+ size_t bsize = rep.nEvents *
+ (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int)));
+ bufp = Xmalloc(bsize);
+diff --git a/src/XGetBMap.c b/src/XGetBMap.c
+index 002daba..13bb8c6 100644
+--- a/src/XGetBMap.c
++++ b/src/XGetBMap.c
+@@ -92,7 +92,8 @@ XGetDeviceButtonMapping(
+
+ status = _XReply(dpy, (xReply *) & rep, 0, xFalse);
+ if (status == 1) {
+- if (rep.length <= (sizeof(mapping) >> 2)) {
++ if (rep.length <= (sizeof(mapping) >> 2) &&
++ rep.nElts <= (rep.length << 2)) {
+ unsigned long nbytes = rep.length << 2;
+ _XRead(dpy, (char *)mapping, nbytes);
+
+diff --git a/src/XGetDCtl.c b/src/XGetDCtl.c
+index c5d3b53..7f6b396 100644
+--- a/src/XGetDCtl.c
++++ b/src/XGetDCtl.c
+@@ -93,7 +93,8 @@ XGetDeviceControl(
+ if (rep.length > 0) {
+ unsigned long nbytes;
+ size_t size = 0;
+- if (rep.length < (INT_MAX >> 2)) {
++ if (rep.length < (INT_MAX >> 2) &&
++ (rep.length << 2) >= sizeof(xDeviceState)) {
+ nbytes = (unsigned long) rep.length << 2;
+ d = Xmalloc(nbytes);
+ }
+@@ -117,7 +118,8 @@ XGetDeviceControl(
+ size_t val_size;
+
+ r = (xDeviceResolutionState *) d;
+- if (r->num_valuators >= (INT_MAX / (3 * sizeof(int))))
++ if (sizeof(xDeviceResolutionState) > nbytes ||
++ r->num_valuators >= (INT_MAX / (3 * sizeof(int))))
+ goto out;
+ val_size = 3 * sizeof(int) * r->num_valuators;
+ if ((sizeof(xDeviceResolutionState) + val_size) > nbytes)
+diff --git a/src/XGetFCtl.c b/src/XGetFCtl.c
+index 7fd6d0e..82dcc64 100644
+--- a/src/XGetFCtl.c
++++ b/src/XGetFCtl.c
+@@ -73,6 +73,7 @@ XGetFeedbackControl(
+ XFeedbackState *Sav = NULL;
+ xFeedbackState *f = NULL;
+ xFeedbackState *sav = NULL;
++ char *end = NULL;
+ xGetFeedbackControlReq *req;
+ xGetFeedbackControlReply rep;
+ XExtDisplayInfo *info = XInput_find_display(dpy);
+@@ -105,10 +106,12 @@ XGetFeedbackControl(
+ goto out;
+ }
+ sav = f;
++ end = (char *)f + nbytes;
+ _XRead(dpy, (char *)f, nbytes);
+
+ for (i = 0; i < *num_feedbacks; i++) {
+- if (f->length > nbytes)
++ if ((char *)f + sizeof(*f) > end ||
++ f->length == 0 || f->length > nbytes)
+ goto out;
+ nbytes -= f->length;
+
+@@ -125,6 +128,8 @@ XGetFeedbackControl(
+ case StringFeedbackClass:
+ {
+ xStringFeedbackState *strf = (xStringFeedbackState *) f;
++ if ((char *)f + sizeof(*strf) > end)
++ goto out;
+ size += sizeof(XStringFeedbackState) +
+ (strf->num_syms_supported * sizeof(KeySym));
+ }
+diff --git a/src/XGetKMap.c b/src/XGetKMap.c
+index 0540ce4..008a72b 100644
+--- a/src/XGetKMap.c
++++ b/src/XGetKMap.c
+@@ -54,6 +54,7 @@ SOFTWARE.
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <X11/extensions/XI.h>
+ #include <X11/extensions/XIproto.h>
+ #include <X11/Xlibint.h>
+@@ -93,9 +94,16 @@ XGetDeviceKeyMapping(register Display * dpy, XDevice * dev,
+ return (KeySym *) NULL;
+ }
+ if (rep.length > 0) {
+- *syms_per_code = rep.keySymsPerKeyCode;
+- nbytes = (long)rep.length << 2;
+- mapping = (KeySym *) Xmalloc((unsigned)nbytes);
++ if (rep.length < INT_MAX >> 2 &&
++ rep.length == rep.keySymsPerKeyCode * keycount) {
++ *syms_per_code = rep.keySymsPerKeyCode;
++ nbytes = (long)rep.length << 2;
++ mapping = (KeySym *) Xmalloc((unsigned)nbytes);
++ } else {
++ *syms_per_code = 0;
++ nbytes = 0;
++ mapping = NULL;
++ }
+ if (mapping)
+ _XRead(dpy, (char *)mapping, nbytes);
+ else
+diff --git a/src/XGetMMap.c b/src/XGetMMap.c
+index 246698c..33c114f 100644
+--- a/src/XGetMMap.c
++++ b/src/XGetMMap.c
+@@ -53,6 +53,7 @@ SOFTWARE.
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <X11/extensions/XI.h>
+ #include <X11/extensions/XIproto.h>
+ #include <X11/Xlibint.h>
+@@ -85,8 +86,14 @@ XGetDeviceModifierMapping(
+ SyncHandle();
+ return (XModifierKeymap *) NULL;
+ }
+- nbytes = (unsigned long)rep.length << 2;
+- res = (XModifierKeymap *) Xmalloc(sizeof(XModifierKeymap));
++ if (rep.length < (INT_MAX >> 2) &&
++ rep.numKeyPerModifier == rep.length >> 1) {
++ nbytes = (unsigned long)rep.length << 2;
++ res = (XModifierKeymap *) Xmalloc(sizeof(XModifierKeymap));
++ } else {
++ nbytes = 0;
++ res = NULL;
++ }
+ if (res) {
+ res->modifiermap = (KeyCode *) Xmalloc(nbytes);
+ if (res->modifiermap)
+diff --git a/src/XIQueryDevice.c b/src/XIQueryDevice.c
+index fb8504f..a457cd6 100644
+--- a/src/XIQueryDevice.c
++++ b/src/XIQueryDevice.c
+@@ -26,6 +26,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdint.h>
+ #include <X11/Xlibint.h>
+ #include <X11/extensions/XI2proto.h>
+@@ -43,6 +44,7 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ xXIQueryDeviceReq *req;
+ xXIQueryDeviceReply reply;
+ char *ptr;
++ char *end;
+ int i;
+ char *buf;
+
+@@ -60,14 +62,24 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ if (!_XReply(dpy, (xReply*) &reply, 0, xFalse))
+ goto error;
+
+- *ndevices_return = reply.num_devices;
+- info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo));
++ if (reply.length < INT_MAX / 4)
++ {
++ *ndevices_return = reply.num_devices;
++ info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo));
++ }
++ else
++ {
++ *ndevices_return = 0;
++ info = NULL;
++ }
++
+ if (!info)
+ goto error;
+
+ buf = Xmalloc(reply.length * 4);
+ _XRead(dpy, buf, reply.length * 4);
+ ptr = buf;
++ end = buf + reply.length * 4;
+
+ /* info is a null-terminated array */
+ info[reply.num_devices].name = NULL;
+@@ -79,6 +91,9 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ XIDeviceInfo *lib = &info[i];
+ xXIDeviceInfo *wire = (xXIDeviceInfo*)ptr;
+
++ if (ptr + sizeof(xXIDeviceInfo) > end)
++ goto error_loop;
++
+ lib->deviceid = wire->deviceid;
+ lib->use = wire->use;
+ lib->attachment = wire->attachment;
+@@ -87,12 +102,23 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+
+ ptr += sizeof(xXIDeviceInfo);
+
++ if (ptr + wire->name_len > end)
++ goto error_loop;
++
+ lib->name = Xcalloc(wire->name_len + 1, 1);
++ if (lib->name == NULL)
++ goto error_loop;
+ strncpy(lib->name, ptr, wire->name_len);
++ lib->name[wire->name_len] = '\0';
+ ptr += ((wire->name_len + 3)/4) * 4;
+
+ sz = size_classes((xXIAnyInfo*)ptr, nclasses);
+ lib->classes = Xmalloc(sz);
++ if (lib->classes == NULL)
++ {
++ Xfree(lib->name);
++ goto error_loop;
++ }
+ ptr += copy_classes(lib, (xXIAnyInfo*)ptr, &nclasses);
+ /* We skip over unused classes */
+ lib->num_classes = nclasses;
+@@ -103,6 +129,12 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ SyncHandle();
+ return info;
+
++error_loop:
++ while (--i >= 0)
++ {
++ Xfree(info[i].name);
++ Xfree(info[i].classes);
++ }
+ error:
+ UnlockDisplay(dpy);
+ error_unlocked:
+diff --git a/src/XListDev.c b/src/XListDev.c
+index b85ff3c..f850cd0 100644
+--- a/src/XListDev.c
++++ b/src/XListDev.c
+@@ -74,7 +74,7 @@ static int pad_to_xid(int base_size)
+ }
+
+ static size_t
+-SizeClassInfo(xAnyClassPtr *any, int num_classes)
++SizeClassInfo(xAnyClassPtr *any, size_t len, int num_classes)
+ {
+ int size = 0;
+ int j;
+@@ -90,6 +90,8 @@ SizeClassInfo(xAnyClassPtr *any, int num_classes)
+ {
+ xValuatorInfoPtr v;
+
++ if (len < sizeof(v))
++ return 0;
+ v = (xValuatorInfoPtr) *any;
+ size += pad_to_xid(sizeof(XValuatorInfo) +
+ (v->num_axes * sizeof(XAxisInfo)));
+@@ -98,6 +100,8 @@ SizeClassInfo(xAnyClassPtr *any, int num_classes)
+ default:
+ break;
+ }
++ if ((*any)->length > len)
++ return 0;
+ *any = (xAnyClassPtr) ((char *)(*any) + (*any)->length);
+ }
+
+@@ -170,7 +174,7 @@ XListInputDevices(
+ register Display *dpy,
+ int *ndevices)
+ {
+- size_t size;
++ size_t s, size;
+ xListInputDevicesReq *req;
+ xListInputDevicesReply rep;
+ xDeviceInfo *list, *slist = NULL;
+@@ -178,6 +182,7 @@ XListInputDevices(
+ XDeviceInfo *clist = NULL;
+ xAnyClassPtr any, sav_any;
+ XAnyClassPtr Any;
++ char *end = NULL;
+ unsigned char *nptr, *Nptr;
+ int i;
+ unsigned long rlen;
+@@ -213,16 +218,20 @@ XListInputDevices(
+
+ any = (xAnyClassPtr) ((char *)list + (*ndevices * sizeof(xDeviceInfo)));
+ sav_any = any;
++ end = (char *)list + rlen;
+ for (i = 0; i < *ndevices; i++, list++) {
+- size += SizeClassInfo(&any, (int)list->num_classes);
++ s = SizeClassInfo(&any, end - (char *)any, (int)list->num_classes);
++ if (!s)
++ goto out;
++ size += s;
+ }
+
+- Nptr = ((unsigned char *)list) + rlen + 1;
++ Nptr = ((unsigned char *)list) + rlen;
+ for (i = 0, nptr = (unsigned char *)any; i < *ndevices; i++) {
++ if (nptr >= Nptr)
++ goto out;
+ size += *nptr + 1;
+ nptr += (*nptr + 1);
+- if (nptr > Nptr)
+- goto out;
+ }
+
+ clist = (XDeviceInfoPtr) Xmalloc(size);
+diff --git a/src/XOpenDev.c b/src/XOpenDev.c
+index 029dec2..4b3c460 100644
+--- a/src/XOpenDev.c
++++ b/src/XOpenDev.c
+@@ -53,6 +53,7 @@ SOFTWARE.
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <X11/extensions/XI.h>
+ #include <X11/extensions/XIproto.h>
+ #include <X11/Xlibint.h>
+@@ -86,9 +87,15 @@ XOpenDevice(
+ return (XDevice *) NULL;
+ }
+
+- rlen = rep.length << 2;
+- dev = (XDevice *) Xmalloc(sizeof(XDevice) + rep.num_classes *
+- sizeof(XInputClassInfo));
++ if (rep.length < INT_MAX >> 2 &&
++ (rep.length << 2) >= rep.num_classes * sizeof(xInputClassInfo)) {
++ rlen = rep.length << 2;
++ dev = (XDevice *) Xmalloc(sizeof(XDevice) + rep.num_classes *
++ sizeof(XInputClassInfo));
++ } else {
++ rlen = 0;
++ dev = NULL;
++ }
+ if (dev) {
+ int dlen; /* data length */
+
+diff --git a/src/XQueryDv.c b/src/XQueryDv.c
+index de1c0e5..7ee2272 100644
+--- a/src/XQueryDv.c
++++ b/src/XQueryDv.c
+@@ -73,7 +73,7 @@ XQueryDeviceState(
+ xQueryDeviceStateReply rep;
+ XDeviceState *state = NULL;
+ XInputClass *any, *Any;
+- char *data = NULL;
++ char *data = NULL, *end = NULL;
+ XExtDisplayInfo *info = XInput_find_display(dpy);
+
+ LockDisplay(dpy);
+@@ -92,6 +92,7 @@ XQueryDeviceState(
+ if (rep.length < (INT_MAX >> 2)) {
+ rlen = (unsigned long) rep.length << 2;
+ data = Xmalloc(rlen);
++ end = data + rlen;
+ }
+ if (!data) {
+ _XEatDataWords(dpy, rep.length);
+@@ -100,7 +101,8 @@ XQueryDeviceState(
+ _XRead(dpy, data, rlen);
+
+ for (i = 0, any = (XInputClass *) data; i < (int)rep.num_classes; i++) {
+- if (any->length > rlen)
++ if ((char *)any + sizeof(XInputClass) > end ||
++ any->length == 0 || any->length > rlen)
+ goto out;
+ rlen -= any->length;
+
+@@ -114,6 +116,8 @@ XQueryDeviceState(
+ case ValuatorClass:
+ {
+ xValuatorState *v = (xValuatorState *) any;
++ if ((char *)any + sizeof(xValuatorState) > end)
++ goto out;
+ size += (sizeof(XValuatorState) +
+ (v->num_valuators * sizeof(int)));
+ }
+--
+cgit v0.10.2
+