Your message dated Sat, 09 Dec 2017 10:47:53 +0000 with message-id <1512816473.1994.32.camel@adam-barratt.org.uk> and subject line Closing bugs for updates included in jessie point release has caused the Debian Bug report #852966, regarding jessie-pu: package libxi/2:1.7.4-1+deb8u1 to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact owner@bugs.debian.org immediately.) -- 852966: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852966 Debian Bug Tracking System Contact owner@bugs.debian.org with problems
--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: jessie-pu: package libxi/2:1.7.4-1+deb8u1
- From: Julien Cristau <jcristau@debian.org>
- Date: Sat, 28 Jan 2017 16:23:59 +0100
- Message-id: <20170128152359.nzdzmtd2vl6bvtca@betterave.cristau.org>
Package: release.debian.org Severity: normal Tags: jessie User: release.debian.org@packages.debian.org Usertags: pu I think this is the last one for this round. It's also the one I'm least confident about. But it's been in sid and wheezy-lts for a while, and a couple of issues have already been found and fixed, so maybe it's ok. Cheers, Julien diff -u libxi-1.7.4/debian/changelog libxi-1.7.4/debian/changelog --- libxi-1.7.4/debian/changelog +++ libxi-1.7.4/debian/changelog @@ -1,3 +1,11 @@ +libxi (2:1.7.4-1+deb8u1) jessie; urgency=medium + + * Insufficient validation of data from the X server can cause out of + boundary memory access or endless loops. Addresses CVE-2016-7945 and + CVE-2016-7946. + + -- Julien Cristau <jcristau@debian.org> Sat, 28 Jan 2017 16:17:42 +0100 + libxi (2:1.7.4-1) unstable; urgency=low * New upstream release. only in patch2: unchanged: --- libxi-1.7.4.orig/man/XListInputDevices.txt +++ libxi-1.7.4/man/XListInputDevices.txt @@ -220,5 +220,13 @@ Floating. If the device is a master device, attached specifies the device ID of the master device this device is paired with. - To free the XDeviceInfo array created by XListInputDevices, use - XFreeDeviceList. +RETURN VALUE +------------ + + XListInputDevices returns a pointer to an array of XDeviceInfo + structs and sets ndevices_return to the number of elements in + that array. To free the XDeviceInfo array created by + XListInputDevices, use XFreeDeviceList. + + On error, XListInputDevices returns NULL and ndevices_return is + left unmodified. only in patch2: unchanged: --- libxi-1.7.4.orig/src/XGMotion.c +++ libxi-1.7.4/src/XGMotion.c @@ -114,7 +114,8 @@ } /* 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); only in patch2: unchanged: --- libxi-1.7.4.orig/src/XGetBMap.c +++ libxi-1.7.4/src/XGetBMap.c @@ -92,7 +92,8 @@ 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); only in patch2: unchanged: --- libxi-1.7.4.orig/src/XGetDCtl.c +++ libxi-1.7.4/src/XGetDCtl.c @@ -93,7 +93,8 @@ 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 @@ 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) only in patch2: unchanged: --- libxi-1.7.4.orig/src/XGetFCtl.c +++ libxi-1.7.4/src/XGetFCtl.c @@ -73,6 +73,7 @@ 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 @@ 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 @@ case StringFeedbackClass: { xStringFeedbackState *strf = (xStringFeedbackState *) f; + if ((char *)f + sizeof(*strf) > end) + goto out; size += sizeof(XStringFeedbackState) + (strf->num_syms_supported * sizeof(KeySym)); } only in patch2: unchanged: --- libxi-1.7.4.orig/src/XGetKMap.c +++ libxi-1.7.4/src/XGetKMap.c @@ -54,6 +54,7 @@ #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 @@ 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 only in patch2: unchanged: --- libxi-1.7.4.orig/src/XGetMMap.c +++ libxi-1.7.4/src/XGetMMap.c @@ -53,6 +53,7 @@ #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 @@ 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) only in patch2: unchanged: --- libxi-1.7.4.orig/src/XIQueryDevice.c +++ libxi-1.7.4/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,8 +44,9 @@ xXIQueryDeviceReq *req; xXIQueryDeviceReply reply; char *ptr; + char *end; int i; - char *buf; + char *buf = NULL; XExtDisplayInfo *extinfo = XInput_find_display(dpy); @@ -60,14 +62,25 @@ if (!_XReply(dpy, (xReply*) &reply, 0, xFalse)) goto error; - *ndevices_return = reply.num_devices; - info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo)); - if (!info) + if (reply.length < INT_MAX / 4) + { + *ndevices_return = reply.num_devices; + info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo)); + buf = Xmalloc(reply.length * 4); + } + else + { + *ndevices_return = 0; + info = NULL; + buf = NULL; + } + + if (!info || !buf) 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 +92,9 @@ 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 +103,23 @@ 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,7 +130,15 @@ SyncHandle(); return info; +error_loop: + while (--i >= 0) + { + Xfree(info[i].name); + Xfree(info[i].classes); + } error: + Xfree(info); + Xfree(buf); UnlockDisplay(dpy); SyncHandle(); *ndevices_return = -1; only in patch2: unchanged: --- libxi-1.7.4.orig/src/XListDev.c +++ libxi-1.7.4/src/XListDev.c @@ -73,35 +73,42 @@ return ((base_size + padsize - 1)/padsize) * padsize; } -static size_t -SizeClassInfo(xAnyClassPtr *any, int num_classes) +static int +SizeClassInfo(xAnyClassPtr *any, size_t len, int num_classes, size_t *size) { - int size = 0; int j; + size_t sz = 0; + for (j = 0; j < num_classes; j++) { switch ((*any)->class) { case KeyClass: - size += pad_to_xid(sizeof(XKeyInfo)); + sz += pad_to_xid(sizeof(XKeyInfo)); break; case ButtonClass: - size += pad_to_xid(sizeof(XButtonInfo)); + sz += pad_to_xid(sizeof(XButtonInfo)); break; case ValuatorClass: { xValuatorInfoPtr v; + if (len < sizeof(v)) + return 1; v = (xValuatorInfoPtr) *any; - size += pad_to_xid(sizeof(XValuatorInfo) + + sz += pad_to_xid(sizeof(XValuatorInfo) + (v->num_axes * sizeof(XAxisInfo))); break; } default: break; } + if ((*any)->length > len) + return 1; *any = (xAnyClassPtr) ((char *)(*any) + (*any)->length); } - return size; + *size = sz; + + return 0; } static void @@ -168,9 +175,9 @@ XDeviceInfo * XListInputDevices( register Display *dpy, - int *ndevices) + int *ndevices_return) { - size_t size; + size_t s, size; xListInputDevicesReq *req; xListInputDevicesReply rep; xDeviceInfo *list, *slist = NULL; @@ -178,10 +185,12 @@ XDeviceInfo *clist = NULL; xAnyClassPtr any, sav_any; XAnyClassPtr Any; + char *end = NULL; unsigned char *nptr, *Nptr; int i; unsigned long rlen; XExtDisplayInfo *info = XInput_find_display(dpy); + int ndevices; LockDisplay(dpy); if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1) @@ -197,8 +206,8 @@ return (XDeviceInfo *) NULL; } - if ((*ndevices = rep.ndevices)) { /* at least 1 input device */ - size = *ndevices * sizeof(XDeviceInfo); + if ((ndevices = rep.ndevices)) { /* at least 1 input device */ + size = ndevices * sizeof(XDeviceInfo); if (rep.length < (INT_MAX >> 2)) { rlen = rep.length << 2; /* multiply length by 4 */ slist = list = Xmalloc(rlen); @@ -211,18 +220,21 @@ } _XRead(dpy, (char *)list, rlen); - any = (xAnyClassPtr) ((char *)list + (*ndevices * sizeof(xDeviceInfo))); + any = (xAnyClassPtr) ((char *)list + (ndevices * sizeof(xDeviceInfo))); sav_any = any; - for (i = 0; i < *ndevices; i++, list++) { - size += SizeClassInfo(&any, (int)list->num_classes); + end = (char *)list + rlen; + for (i = 0; i < ndevices; i++, list++) { + if(SizeClassInfo(&any, end - (char *)any, (int)list->num_classes, &s)) + goto out; + size += s; } - Nptr = ((unsigned char *)list) + rlen + 1; - for (i = 0, nptr = (unsigned char *)any; i < *ndevices; i++) { + 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); @@ -234,10 +246,10 @@ } sclist = clist; Any = (XAnyClassPtr) ((char *)clist + - (*ndevices * sizeof(XDeviceInfo))); + (ndevices * sizeof(XDeviceInfo))); list = slist; any = sav_any; - for (i = 0; i < *ndevices; i++, list++, clist++) { + for (i = 0; i < ndevices; i++, list++, clist++) { clist->type = list->type; clist->id = list->id; clist->use = list->use; @@ -250,7 +262,7 @@ clist = sclist; nptr = (unsigned char *)any; Nptr = (unsigned char *)Any; - for (i = 0; i < *ndevices; i++, clist++) { + for (i = 0; i < ndevices; i++, clist++) { clist->name = (char *)Nptr; memcpy(Nptr, nptr + 1, *nptr); Nptr += (*nptr); @@ -259,6 +271,8 @@ } } + *ndevices_return = ndevices; + out: XFree((char *)slist); UnlockDisplay(dpy); only in patch2: unchanged: --- libxi-1.7.4.orig/src/XOpenDev.c +++ libxi-1.7.4/src/XOpenDev.c @@ -53,6 +53,7 @@ #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 @@ 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 */ only in patch2: unchanged: --- libxi-1.7.4.orig/src/XQueryDv.c +++ libxi-1.7.4/src/XQueryDv.c @@ -73,7 +73,7 @@ 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 @@ 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 @@ _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 @@ case ValuatorClass: { xValuatorState *v = (xValuatorState *) any; + if ((char *)any + sizeof(xValuatorState) > end) + goto out; size += (sizeof(XValuatorState) + (v->num_valuators * sizeof(int))); }Attachment: signature.asc
Description: PGP signature
--- End Message ---
--- Begin Message ---
- To: 815728-done@bugs.debian.org, 840643-done@bugs.debian.org, 852849-done@bugs.debian.org, 852947-done@bugs.debian.org, 852949-done@bugs.debian.org, 852952-done@bugs.debian.org, 852958-done@bugs.debian.org, 852961-done@bugs.debian.org, 852965-done@bugs.debian.org, 852966-done@bugs.debian.org, 856240-done@bugs.debian.org, 861541-done@bugs.debian.org, 862363-done@bugs.debian.org, 862961-done@bugs.debian.org, 863093-done@bugs.debian.org, 867817-done@bugs.debian.org, 868337-done@bugs.debian.org, 869991-done@bugs.debian.org, 870178-done@bugs.debian.org, 870376-done@bugs.debian.org, 872056-done@bugs.debian.org, 872442-done@bugs.debian.org, 873053-done@bugs.debian.org, 873310-done@bugs.debian.org, 873466-done@bugs.debian.org, 873481-done@bugs.debian.org, 873877-done@bugs.debian.org, 876019-done@bugs.debian.org, 876313-done@bugs.debian.org, 876630-done@bugs.debian.org, 876638-done@bugs.debian.org, 877045-done@bugs.debian.org, 879630-done@bugs.debian.org, 880123-done@bugs.debian.org, 880630-done@bugs.debian.org, 880861-done@bugs.debian.org, 880895-done@bugs.debian.org, 881306-done@bugs.debian.org, 882061-done@bugs.debian.org, 882132-done@bugs.debian.org, 882242-done@bugs.debian.org, 882503-done@bugs.debian.org, 882802-done@bugs.debian.org, 882960-done@bugs.debian.org, 882961-done@bugs.debian.org, 883177-done@bugs.debian.org, 883292-done@bugs.debian.org
- Subject: Closing bugs for updates included in jessie point release
- From: "Adam D. Barratt" <adam@adam-barratt.org.uk>
- Date: Sat, 09 Dec 2017 10:47:53 +0000
- Message-id: <1512816473.1994.32.camel@adam-barratt.org.uk>
Version: 8.10 Hi, Each of the updates referenced in these bugs was included in this morning's jessie point release. Thanks! Regards, Adam
--- End Message ---