diff options
author | Leonardo Arena <rnalrd@alpinelinux.org> | 2016-10-20 10:03:01 +0000 |
---|---|---|
committer | Leonardo Arena <rnalrd@alpinelinux.org> | 2016-10-20 10:07:10 +0000 |
commit | b0140e4401ffc6200ed5a33ebe5e45d4ceac66fd (patch) | |
tree | ad7935f2049e53b54d21857cd6951456f26aa97f | |
parent | cb627c977abbd0298bd4dddb278243f001aebb0d (diff) | |
download | aports-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/APKBUILD | 25 | ||||
-rw-r--r-- | main/libxi/CVE-2016-7945-7946.patch | 400 |
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 + |