diff --git a/gnu/local.mk b/gnu/local.mk index 915c5e7e20..116c9ab589 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -668,7 +668,6 @@ dist_patch_DATA = \ %D%/packages/patches/libwmf-CVE-2015-0848+CVE-2015-4588.patch \ %D%/packages/patches/libwmf-CVE-2015-4695.patch \ %D%/packages/patches/libwmf-CVE-2015-4696.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/libxrender-CVE-2016-7949.patch \ %D%/packages/patches/libxrender-CVE-2016-7950.patch \ diff --git a/gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch b/gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch deleted file mode 100644 index ca899e34c0..0000000000 --- a/gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch +++ /dev/null @@ -1,420 +0,0 @@ -Fix CVE-2016-7945: - -https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7945 - -Patch copied from upstream source repository: - -https://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=19a9cd607de73947fcfb104682f203ffe4e1f4e5 - -From 19a9cd607de73947fcfb104682f203ffe4e1f4e5 Mon Sep 17 00:00:00 2001 -From: Tobias Stoeckmann -Date: Sun, 25 Sep 2016 22:31:34 +0200 -Subject: [PATCH] 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 -Reviewed-by: Matthieu Herrb ---- - src/XGMotion.c | 3 ++- - src/XGetBMap.c | 3 ++- - src/XGetDCtl.c | 6 ++++-- - src/XGetFCtl.c | 7 ++++++- - src/XGetKMap.c | 14 +++++++++++--- - src/XGetMMap.c | 11 +++++++++-- - src/XIQueryDevice.c | 36 ++++++++++++++++++++++++++++++++++-- - src/XListDev.c | 21 +++++++++++++++------ - src/XOpenDev.c | 13 ++++++++++--- - src/XQueryDv.c | 8 ++++++-- - 10 files changed, 99 insertions(+), 23 deletions(-) - -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 - #endif - -+#include - #include - #include - #include -@@ -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 - #endif - -+#include - #include - #include - #include -@@ -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 - #endif - -+#include - #include - #include - #include -@@ -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 - #endif - -+#include - #include - #include - #include -@@ -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))); - } --- -2.10.1 - diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm index 02382586fc..a4472f1cc9 100644 --- a/gnu/packages/xorg.scm +++ b/gnu/packages/xorg.scm @@ -4912,8 +4912,7 @@ (define-public libxfont (define-public libxi (package (name "libxi") - (replacement libxi/fixed) - (version "1.7.6") + (version "1.7.7") (source (origin (method url-fetch) @@ -4923,7 +4922,7 @@ (define-public libxi ".tar.bz2")) (sha256 (base32 - "1b5p0l19ynmd6blnqr205wyngh6fagl35nqb4v05dw60rr9aachz")))) + "0c70n4aq0ba628wr88ih4740nci9d9f6y3v96sx376vvlm7q6vwr")))) (build-system gnu-build-system) (propagated-inputs `(("inputproto" ,inputproto) @@ -4939,14 +4938,6 @@ (define-public libxi (description "Library for the XInput Extension to the X11 protocol.") (license license:x11))) -(define libxi/fixed - (package - (inherit libxi) - (source (origin - (inherit (package-source libxi)) - (patches (search-patches - "libxi-CVE-2016-7945-CVE-2016-7946.patch")))))) - (define-public libxrandr (package (name "libxrandr")