untrusted comment: signature from openbsd 6.0 base secret key RWSho3oKSqgLQx0DKD2B091kB8ZXQ35dPjluK10DF3CA0PJYu48Y2yCd+qMAoXNVA6kGVEYH/ZkgNgvwnpmLftHPOPO532mxwAk= OpenBSD 6.0 errata 11, Oct 4, 2016: Protocol handling issues in X Window System client libraries X.Org security advisory: October 4, 2016. Fix a number of issues in the way various X client libraries handle server responses. Apply by doing: signify -Vep /etc/signify/openbsd-60-base.pub -x 011_xorg_libs.patch.sig \ -m - | (cd /usr/xenocara && patch -p0) And then rebuild and install xenocara libs: cd /usr/xenocara/lib make obj make build Index: lib/libX11/src/FontNames.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/FontNames.c,v retrieving revision 1.8 diff -u -p -u -r1.8 FontNames.c --- lib/libX11/src/FontNames.c 6 Apr 2015 20:57:59 -0000 1.8 +++ lib/libX11/src/FontNames.c 4 Oct 2016 16:11:57 -0000 @@ -66,7 +66,7 @@ int *actualCount) /* RETURN */ if (rep.nFonts) { flist = Xmalloc (rep.nFonts * sizeof(char *)); - if (rep.length < (INT_MAX >> 2)) { + if (rep.length > 0 && rep.length < (INT_MAX >> 2)) { rlen = rep.length << 2; ch = Xmalloc(rlen + 1); /* +1 to leave room for last null-terminator */ @@ -93,11 +93,22 @@ int *actualCount) /* RETURN */ if (ch + length < chend) { flist[i] = ch + 1; /* skip over length */ ch += length + 1; /* find next length ... */ - length = *(unsigned char *)ch; - *ch = '\0'; /* and replace with null-termination */ - count++; - } else - flist[i] = NULL; + if (ch <= chend) { + length = *(unsigned char *)ch; + *ch = '\0'; /* and replace with null-termination */ + count++; + } else { + Xfree(flist); + flist = NULL; + count = 0; + break; + } + } else { + Xfree(flist); + flist = NULL; + count = 0; + break; + } } } *actualCount = count; Index: lib/libX11/src/GetImage.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/GetImage.c,v retrieving revision 1.5 diff -u -p -u -r1.5 GetImage.c --- lib/libX11/src/GetImage.c 23 May 2013 22:42:07 -0000 1.5 +++ lib/libX11/src/GetImage.c 4 Oct 2016 16:11:57 -0000 @@ -59,6 +59,7 @@ XImage *XGetImage ( char *data; unsigned long nbytes; XImage *image; + int planes; LockDisplay(dpy); GetReq (GetImage, req); /* @@ -91,18 +92,28 @@ XImage *XGetImage ( return (XImage *) NULL; } _XReadPad (dpy, data, nbytes); - if (format == XYPixmap) - image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual), - Ones (plane_mask & - (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))), - format, 0, data, width, height, dpy->bitmap_pad, 0); - else /* format == ZPixmap */ - image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual), - rep.depth, ZPixmap, 0, data, width, height, - _XGetScanlinePad(dpy, (int) rep.depth), 0); + if (format == XYPixmap) { + image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual), + Ones (plane_mask & + (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))), + format, 0, data, width, height, dpy->bitmap_pad, 0); + planes = image->depth; + } else { /* format == ZPixmap */ + image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual), + rep.depth, ZPixmap, 0, data, width, height, + _XGetScanlinePad(dpy, (int) rep.depth), 0); + planes = 1; + } if (!image) Xfree(data); + if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 || + INT_MAX / image->height <= image->bytes_per_line || + INT_MAX / planes <= image->height * image->bytes_per_line || + nbytes < planes * image->height * image->bytes_per_line) { + XDestroyImage(image); + image = NULL; + } UnlockDisplay(dpy); SyncHandle(); return (image); Index: lib/libX11/src/ListExt.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/ListExt.c,v retrieving revision 1.7 diff -u -p -u -r1.7 ListExt.c --- lib/libX11/src/ListExt.c 6 Apr 2015 20:57:59 -0000 1.7 +++ lib/libX11/src/ListExt.c 4 Oct 2016 16:11:57 -0000 @@ -55,7 +55,7 @@ char **XListExtensions( if (rep.nExtensions) { list = Xmalloc (rep.nExtensions * sizeof (char *)); - if (rep.length < (INT_MAX >> 2)) { + if (rep.length > 0 && rep.length < (INT_MAX >> 2)) { rlen = rep.length << 2; ch = Xmalloc (rlen + 1); /* +1 to leave room for last null-terminator */ @@ -80,9 +80,13 @@ char **XListExtensions( if (ch + length < chend) { list[i] = ch+1; /* skip over length */ ch += length + 1; /* find next length ... */ - length = *ch; - *ch = '\0'; /* and replace with null-termination */ - count++; + if (ch <= chend) { + length = *ch; + *ch = '\0'; /* and replace with null-termination */ + count++; + } else { + list[i] = NULL; + } } else list[i] = NULL; } Index: lib/libX11/src/ModMap.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/ModMap.c,v retrieving revision 1.9 diff -u -p -u -r1.9 ModMap.c --- lib/libX11/src/ModMap.c 6 Apr 2015 20:57:59 -0000 1.9 +++ lib/libX11/src/ModMap.c 4 Oct 2016 16:11:57 -0000 @@ -42,7 +42,8 @@ XGetModifierMapping(register Display *dp GetEmptyReq(GetModifierMapping, req); (void) _XReply (dpy, (xReply *)&rep, 0, xFalse); - if (rep.length < (INT_MAX >> 2)) { + if (rep.length < (INT_MAX >> 2) && + (rep.length >> 1) == rep.numKeyPerModifier) { nbytes = (unsigned long)rep.length << 2; res = Xmalloc(sizeof (XModifierKeymap)); if (res) Index: lib/libXfixes/src/Region.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXfixes/src/Region.c,v retrieving revision 1.4 diff -u -p -u -r1.4 Region.c --- lib/libXfixes/src/Region.c 31 May 2013 14:57:04 -0000 1.4 +++ lib/libXfixes/src/Region.c 4 Oct 2016 16:11:57 -0000 @@ -23,6 +23,7 @@ #ifdef HAVE_CONFIG_H #include #endif +#include #include "Xfixesint.h" XserverRegion @@ -333,9 +334,17 @@ XFixesFetchRegionAndBounds (Display bounds->y = rep.y; bounds->width = rep.width; bounds->height = rep.height; - nbytes = (long) rep.length << 2; - nrects = rep.length >> 1; - rects = Xmalloc (nrects * sizeof (XRectangle)); + + if (rep.length < (INT_MAX >> 2)) { + nbytes = (long) rep.length << 2; + nrects = rep.length >> 1; + rects = Xmalloc (nrects * sizeof (XRectangle)); + } else { + nbytes = 0; + nrects = 0; + rects = NULL; + } + if (!rects) { _XEatDataWords(dpy, rep.length); Index: lib/libXi/src/XGMotion.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XGMotion.c,v retrieving revision 1.5 diff -u -p -u -r1.5 XGMotion.c --- lib/libXi/src/XGMotion.c 23 May 2013 22:42:10 -0000 1.5 +++ lib/libXi/src/XGMotion.c 4 Oct 2016 16:11:57 -0000 @@ -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); Index: lib/libXi/src/XGetBMap.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XGetBMap.c,v retrieving revision 1.4 diff -u -p -u -r1.4 XGetBMap.c --- lib/libXi/src/XGetBMap.c 23 May 2013 22:42:10 -0000 1.4 +++ lib/libXi/src/XGetBMap.c 4 Oct 2016 16:11:57 -0000 @@ -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); Index: lib/libXi/src/XGetDCtl.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XGetDCtl.c,v retrieving revision 1.7 diff -u -p -u -r1.7 XGetDCtl.c --- lib/libXi/src/XGetDCtl.c 9 May 2014 19:55:33 -0000 1.7 +++ lib/libXi/src/XGetDCtl.c 4 Oct 2016 16:11:57 -0000 @@ -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) Index: lib/libXi/src/XGetFCtl.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XGetFCtl.c,v retrieving revision 1.6 diff -u -p -u -r1.6 XGetFCtl.c --- lib/libXi/src/XGetFCtl.c 9 May 2014 19:55:33 -0000 1.6 +++ lib/libXi/src/XGetFCtl.c 4 Oct 2016 16:11:57 -0000 @@ -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)); } Index: lib/libXi/src/XGetKMap.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XGetKMap.c,v retrieving revision 1.4 diff -u -p -u -r1.4 XGetKMap.c --- lib/libXi/src/XGetKMap.c 23 May 2013 22:42:10 -0000 1.4 +++ lib/libXi/src/XGetKMap.c 4 Oct 2016 16:11:57 -0000 @@ -54,6 +54,7 @@ SOFTWARE. #include #endif +#include #include #include #include @@ -93,9 +94,16 @@ XGetDeviceKeyMapping(register Display * 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 Index: lib/libXi/src/XGetMMap.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XGetMMap.c,v retrieving revision 1.4 diff -u -p -u -r1.4 XGetMMap.c --- lib/libXi/src/XGetMMap.c 23 May 2013 22:42:10 -0000 1.4 +++ lib/libXi/src/XGetMMap.c 4 Oct 2016 16:11:57 -0000 @@ -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) Index: lib/libXi/src/XIQueryDevice.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XIQueryDevice.c,v retrieving revision 1.4 diff -u -p -u -r1.4 XIQueryDevice.c --- lib/libXi/src/XIQueryDevice.c 11 Jun 2012 19:24:49 -0000 1.4 +++ lib/libXi/src/XIQueryDevice.c 4 Oct 2016 16:11:57 -0000 @@ -26,6 +26,7 @@ #include #endif +#include #include #include #include @@ -43,6 +44,7 @@ XIQueryDevice(Display *dpy, int deviceid xXIQueryDeviceReq *req; xXIQueryDeviceReply reply; char *ptr; + char *end; int i; char *buf; @@ -60,14 +62,24 @@ XIQueryDevice(Display *dpy, int deviceid 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 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 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 SyncHandle(); return info; +error_loop: + while (--i >= 0) + { + Xfree(info[i].name); + Xfree(info[i].classes); + } error: UnlockDisplay(dpy); SyncHandle(); Index: lib/libXi/src/XListDev.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XListDev.c,v retrieving revision 1.7 diff -u -p -u -r1.7 XListDev.c --- lib/libXi/src/XListDev.c 9 May 2014 19:55:33 -0000 1.7 +++ lib/libXi/src/XListDev.c 4 Oct 2016 16:11:57 -0000 @@ -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 { 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 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); Index: lib/libXi/src/XOpenDev.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XOpenDev.c,v retrieving revision 1.4 diff -u -p -u -r1.4 XOpenDev.c --- lib/libXi/src/XOpenDev.c 23 May 2013 22:42:10 -0000 1.4 +++ lib/libXi/src/XOpenDev.c 4 Oct 2016 16:11:57 -0000 @@ -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 */ Index: lib/libXi/src/XQueryDv.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXi/src/XQueryDv.c,v retrieving revision 1.5 diff -u -p -u -r1.5 XQueryDv.c --- lib/libXi/src/XQueryDv.c 23 May 2013 22:42:10 -0000 1.5 +++ lib/libXi/src/XQueryDv.c 4 Oct 2016 16:11:57 -0000 @@ -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))); } Index: lib/libXrandr/src/XrrConfig.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrandr/src/XrrConfig.c,v retrieving revision 1.4 diff -u -p -u -r1.4 XrrConfig.c --- lib/libXrandr/src/XrrConfig.c 9 Mar 2013 16:34:37 -0000 1.4 +++ lib/libXrandr/src/XrrConfig.c 4 Oct 2016 16:11:58 -0000 @@ -29,6 +29,7 @@ #include #endif +#include #include #include /* we need to be able to manipulate the Display structure on events */ @@ -272,23 +273,30 @@ static XRRScreenConfiguration *_XRRGetSc rep.rate = 0; rep.nrateEnts = 0; } + if (rep.length < INT_MAX >> 2) { + nbytes = (long) rep.length << 2; - nbytes = (long) rep.length << 2; + nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) + + ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF(CARD16) */); - nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) + - ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */); + /* + * first we must compute how much space to allocate for + * randr library's use; we'll allocate the structures in a single + * allocation, on cleanlyness grounds. + */ + + rbytes = sizeof (XRRScreenConfiguration) + + (rep.nSizes * sizeof (XRRScreenSize) + + rep.nrateEnts * sizeof (int)); - /* - * first we must compute how much space to allocate for - * randr library's use; we'll allocate the structures in a single - * allocation, on cleanlyness grounds. - */ - - rbytes = sizeof (XRRScreenConfiguration) + - (rep.nSizes * sizeof (XRRScreenSize) + - rep.nrateEnts * sizeof (int)); + scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); + } else { + nbytes = 0; + nbytesRead = 0; + rbytes = 0; + scp = NULL; + } - scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); if (scp == NULL) { _XEatData (dpy, (unsigned long) nbytes); return NULL; Index: lib/libXrandr/src/XrrCrtc.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrandr/src/XrrCrtc.c,v retrieving revision 1.7 diff -u -p -u -r1.7 XrrCrtc.c --- lib/libXrandr/src/XrrCrtc.c 6 Mar 2016 13:37:21 -0000 1.7 +++ lib/libXrandr/src/XrrCrtc.c 4 Oct 2016 16:11:58 -0000 @@ -24,6 +24,7 @@ #include #endif +#include #include #include /* we need to be able to manipulate the Display structure on events */ @@ -57,22 +58,33 @@ XRRGetCrtcInfo (Display *dpy, XRRScreenR return NULL; } - nbytes = (long) rep.length << 2; + if (rep.length < INT_MAX >> 2) + { + nbytes = (long) rep.length << 2; - nbytesRead = (long) (rep.nOutput * 4 + - rep.nPossibleOutput * 4); + nbytesRead = (long) (rep.nOutput * 4 + + rep.nPossibleOutput * 4); - /* - * first we must compute how much space to allocate for - * randr library's use; we'll allocate the structures in a single - * allocation, on cleanlyness grounds. - */ + /* + * first we must compute how much space to allocate for + * randr library's use; we'll allocate the structures in a single + * allocation, on cleanlyness grounds. + */ + + rbytes = (sizeof (XRRCrtcInfo) + + rep.nOutput * sizeof (RROutput) + + rep.nPossibleOutput * sizeof (RROutput)); - rbytes = (sizeof (XRRCrtcInfo) + - rep.nOutput * sizeof (RROutput) + - rep.nPossibleOutput * sizeof (RROutput)); + xci = (XRRCrtcInfo *) Xmalloc(rbytes); + } + else + { + nbytes = 0; + nbytesRead = 0; + rbytes = 0; + xci = NULL; + } - xci = (XRRCrtcInfo *) Xmalloc(rbytes); if (xci == NULL) { _XEatDataWords (dpy, rep.length); UnlockDisplay (dpy); @@ -194,12 +206,21 @@ XRRGetCrtcGamma (Display *dpy, RRCrtc cr if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) goto out; - nbytes = (long) rep.length << 2; + if (rep.length < INT_MAX >> 2) + { + nbytes = (long) rep.length << 2; - /* three channels of CARD16 data */ - nbytesRead = (rep.size * 2 * 3); + /* three channels of CARD16 data */ + nbytesRead = (rep.size * 2 * 3); - crtc_gamma = XRRAllocGamma (rep.size); + crtc_gamma = XRRAllocGamma (rep.size); + } + else + { + nbytes = 0; + nbytesRead = 0; + crtc_gamma = NULL; + } if (!crtc_gamma) { @@ -357,7 +378,7 @@ XRRGetCrtcTransform (Display *dpy, xRRGetCrtcTransformReq *req; int major_version, minor_version; XRRCrtcTransformAttributes *attr; - char *extra = NULL, *e; + char *extra = NULL, *end = NULL, *e; int p; *attributes = NULL; @@ -395,9 +416,17 @@ XRRGetCrtcTransform (Display *dpy, else { int extraBytes = rep.length * 4 - CrtcTransformExtra; - extra = Xmalloc (extraBytes); + if (rep.length < INT_MAX / 4 && + rep.length * 4 >= CrtcTransformExtra) { + extra = Xmalloc (extraBytes); + end = extra + extraBytes; + } else + extra = NULL; if (!extra) { - _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2)); + if (rep.length > (CrtcTransformExtra >> 2)) + _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2)); + else + _XEatDataWords (dpy, rep.length); UnlockDisplay (dpy); SyncHandle (); return False; @@ -429,22 +458,38 @@ XRRGetCrtcTransform (Display *dpy, e = extra; + if (e + rep.pendingNbytesFilter > end) { + XFree (extra); + return False; + } memcpy (attr->pendingFilter, e, rep.pendingNbytesFilter); attr->pendingFilter[rep.pendingNbytesFilter] = '\0'; e += (rep.pendingNbytesFilter + 3) & ~3; for (p = 0; p < rep.pendingNparamsFilter; p++) { INT32 f; + if (e + 4 > end) { + XFree (extra); + return False; + } memcpy (&f, e, 4); e += 4; attr->pendingParams[p] = (XFixed) f; } attr->pendingNparams = rep.pendingNparamsFilter; + if (e + rep.currentNbytesFilter > end) { + XFree (extra); + return False; + } memcpy (attr->currentFilter, e, rep.currentNbytesFilter); attr->currentFilter[rep.currentNbytesFilter] = '\0'; e += (rep.currentNbytesFilter + 3) & ~3; for (p = 0; p < rep.currentNparamsFilter; p++) { INT32 f; + if (e + 4 > end) { + XFree (extra); + return False; + } memcpy (&f, e, 4); e += 4; attr->currentParams[p] = (XFixed) f; Index: lib/libXrandr/src/XrrMonitor.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrandr/src/XrrMonitor.c,v retrieving revision 1.1 diff -u -p -u -r1.1 XrrMonitor.c --- lib/libXrandr/src/XrrMonitor.c 6 Mar 2016 13:37:21 -0000 1.1 +++ lib/libXrandr/src/XrrMonitor.c 4 Oct 2016 16:11:58 -0000 @@ -24,6 +24,7 @@ #include #endif +#include #include #include /* we need to be able to manipulate the Display structure on events */ @@ -65,6 +66,15 @@ XRRGetMonitors(Display *dpy, Window wind return NULL; } + if (rep.length > INT_MAX >> 2 || + rep.nmonitors > INT_MAX / SIZEOF(xRRMonitorInfo) || + rep.noutputs > INT_MAX / 4 || + rep.nmonitors * SIZEOF(xRRMonitorInfo) > INT_MAX - rep.noutputs * 4) { + _XEatData (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; + } nbytes = (long) rep.length << 2; nmon = rep.nmonitors; noutput = rep.noutputs; @@ -111,6 +121,14 @@ XRRGetMonitors(Display *dpy, Window wind mon[m].outputs = output; buf += SIZEOF (xRRMonitorInfo); xoutput = (CARD32 *) buf; + if (xmon->noutput > rep.noutputs) { + Xfree(buf); + Xfree(mon); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; + } + rep.noutputs -= xmon->noutput; for (o = 0; o < xmon->noutput; o++) output[o] = xoutput[o]; output += xmon->noutput; Index: lib/libXrandr/src/XrrOutput.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrandr/src/XrrOutput.c,v retrieving revision 1.5 diff -u -p -u -r1.5 XrrOutput.c --- lib/libXrandr/src/XrrOutput.c 6 Mar 2016 13:37:21 -0000 1.5 +++ lib/libXrandr/src/XrrOutput.c 4 Oct 2016 16:11:58 -0000 @@ -25,6 +25,7 @@ #include #endif +#include #include #include /* we need to be able to manipulate the Display structure on events */ @@ -60,6 +61,16 @@ XRRGetOutputInfo (Display *dpy, XRRScree return NULL; } + if (rep.length > INT_MAX >> 2 || rep.length < (OutputInfoExtra >> 2)) + { + if (rep.length > (OutputInfoExtra >> 2)) + _XEatDataWords (dpy, rep.length - (OutputInfoExtra >> 2)); + else + _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; + } nbytes = ((long) (rep.length) << 2) - OutputInfoExtra; nbytesRead = (long) (rep.nCrtcs * 4 + Index: lib/libXrandr/src/XrrProvider.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrandr/src/XrrProvider.c,v retrieving revision 1.4 diff -u -p -u -r1.4 XrrProvider.c --- lib/libXrandr/src/XrrProvider.c 6 Mar 2016 13:37:21 -0000 1.4 +++ lib/libXrandr/src/XrrProvider.c 4 Oct 2016 16:11:58 -0000 @@ -25,6 +25,7 @@ #include #endif +#include #include #include /* we need to be able to manipulate the Display structure on events */ @@ -59,12 +60,20 @@ XRRGetProviderResources(Display *dpy, Wi return NULL; } - nbytes = (long) rep.length << 2; + if (rep.length < INT_MAX >> 2) { + nbytes = (long) rep.length << 2; - nbytesRead = (long) (rep.nProviders * 4); + nbytesRead = (long) (rep.nProviders * 4); - rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider)); - xrpr = (XRRProviderResources *) Xmalloc(rbytes); + rbytes = (sizeof(XRRProviderResources) + rep.nProviders * + sizeof(RRProvider)); + xrpr = (XRRProviderResources *) Xmalloc(rbytes); + } else { + nbytes = 0; + nbytesRead = 0; + rbytes = 0; + xrpr = NULL; + } if (xrpr == NULL) { _XEatDataWords (dpy, rep.length); @@ -116,6 +125,17 @@ XRRGetProviderInfo(Display *dpy, XRRScre if (!_XReply (dpy, (xReply *) &rep, ProviderInfoExtra >> 2, xFalse)) { + UnlockDisplay (dpy); + SyncHandle (); + return NULL; + } + + if (rep.length > INT_MAX >> 2 || rep.length < ProviderInfoExtra >> 2) + { + if (rep.length < ProviderInfoExtra >> 2) + _XEatDataWords (dpy, rep.length); + else + _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2)); UnlockDisplay (dpy); SyncHandle (); return NULL; Index: lib/libXrandr/src/XrrScreen.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrandr/src/XrrScreen.c,v retrieving revision 1.5 diff -u -p -u -r1.5 XrrScreen.c --- lib/libXrandr/src/XrrScreen.c 6 Mar 2016 13:37:21 -0000 1.5 +++ lib/libXrandr/src/XrrScreen.c 4 Oct 2016 16:11:58 -0000 @@ -24,6 +24,7 @@ #include #endif +#include #include #include /* we need to be able to manipulate the Display structure on events */ @@ -105,27 +106,36 @@ doGetScreenResources (Display *dpy, Wind xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version); } - nbytes = (long) rep.length << 2; + if (rep.length < INT_MAX >> 2) { + nbytes = (long) rep.length << 2; - nbytesRead = (long) (rep.nCrtcs * 4 + - rep.nOutputs * 4 + - rep.nModes * SIZEOF (xRRModeInfo) + - ((rep.nbytesNames + 3) & ~3)); - - /* - * first we must compute how much space to allocate for - * randr library's use; we'll allocate the structures in a single - * allocation, on cleanlyness grounds. - */ - - rbytes = (sizeof (XRRScreenResources) + - rep.nCrtcs * sizeof (RRCrtc) + - rep.nOutputs * sizeof (RROutput) + - rep.nModes * sizeof (XRRModeInfo) + - rep.nbytesNames + rep.nModes); /* '\0' terminate names */ + nbytesRead = (long) (rep.nCrtcs * 4 + + rep.nOutputs * 4 + + rep.nModes * SIZEOF (xRRModeInfo) + + ((rep.nbytesNames + 3) & ~3)); + + /* + * first we must compute how much space to allocate for + * randr library's use; we'll allocate the structures in a single + * allocation, on cleanlyness grounds. + */ + + rbytes = (sizeof (XRRScreenResources) + + rep.nCrtcs * sizeof (RRCrtc) + + rep.nOutputs * sizeof (RROutput) + + rep.nModes * sizeof (XRRModeInfo) + + rep.nbytesNames + rep.nModes); /* '\0' terminate names */ + + xrsr = (XRRScreenResources *) Xmalloc(rbytes); + wire_names = (char *) Xmalloc (rep.nbytesNames); + } else { + nbytes = 0; + nbytesRead = 0; + rbytes = 0; + xrsr = NULL; + wire_names = NULL; + } - xrsr = (XRRScreenResources *) Xmalloc(rbytes); - wire_names = (char *) Xmalloc (rep.nbytesNames); if (xrsr == NULL || wire_names == NULL) { if (xrsr) Xfree (xrsr); if (wire_names) Xfree (wire_names); @@ -174,6 +184,14 @@ doGetScreenResources (Display *dpy, Wind wire_name = wire_names; for (i = 0; i < rep.nModes; i++) { xrsr->modes[i].name = names; + if (xrsr->modes[i].nameLength > rep.nbytesNames) { + Xfree (xrsr); + Xfree (wire_names); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; + } + rep.nbytesNames -= xrsr->modes[i].nameLength; memcpy (names, wire_name, xrsr->modes[i].nameLength); names[xrsr->modes[i].nameLength] = '\0'; names += xrsr->modes[i].nameLength + 1; Index: lib/libXrender/src/Filter.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrender/src/Filter.c,v retrieving revision 1.5 diff -u -p -u -r1.5 Filter.c --- lib/libXrender/src/Filter.c 23 May 2013 22:42:11 -0000 1.5 +++ lib/libXrender/src/Filter.c 4 Oct 2016 16:11:58 -0000 @@ -38,7 +38,7 @@ XRenderQueryFilters (Display *dpy, Drawa char *name; char len; int i; - unsigned long nbytes, nbytesAlias, nbytesName; + unsigned long nbytes, nbytesAlias, nbytesName, reply_left; if (!RenderHasExtension (info)) return NULL; @@ -114,6 +114,7 @@ XRenderQueryFilters (Display *dpy, Drawa * Read the filter aliases */ _XRead16Pad (dpy, filters->alias, 2 * rep.numAliases); + reply_left = 8 + rep.length - 2 * rep.numAliases;; /* * Read the filter names @@ -122,9 +123,19 @@ XRenderQueryFilters (Display *dpy, Drawa { int l; _XRead (dpy, &len, 1); + reply_left--; l = len & 0xff; + if ((unsigned long)l + 1 > nbytesName) { + _XEatDataWords(dpy, reply_left); + Xfree(filters); + UnlockDisplay (dpy); + SyncHandle (); + return NULL; + } + nbytesName -= l + 1; filters->filter[i] = name; _XRead (dpy, name, l); + reply_left -= l; name[l] = '\0'; name += l + 1; } Index: lib/libXrender/src/Xrender.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXrender/src/Xrender.c,v retrieving revision 1.4 diff -u -p -u -r1.4 Xrender.c --- lib/libXrender/src/Xrender.c 23 May 2013 22:42:11 -0000 1.4 +++ lib/libXrender/src/Xrender.c 4 Oct 2016 16:11:58 -0000 @@ -533,12 +533,30 @@ XRenderQueryFormats (Display *dpy) screen->fallback = _XRenderFindFormat (xri, xScreen->fallback); screen->subpixel = SubPixelUnknown; xDepth = (xPictDepth *) (xScreen + 1); + if (screen->ndepths > rep.numDepths) { + Xfree (xri); + Xfree (xData); + _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + rep.numDepths -= screen->ndepths; for (nd = 0; nd < screen->ndepths; nd++) { depth->depth = xDepth->depth; depth->nvisuals = xDepth->nPictVisuals; depth->visuals = visual; xVisual = (xPictVisual *) (xDepth + 1); + if (depth->nvisuals > rep.numVisuals) { + Xfree (xri); + Xfree (xData); + _XEatDataWords (dpy, rep.length); + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + rep.numVisuals -= depth->nvisuals; for (nv = 0; nv < depth->nvisuals; nv++) { visual->visual = _XRenderFindVisual (dpy, xVisual->visual); Index: lib/libXtst/src/XRecord.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXtst/src/XRecord.c,v retrieving revision 1.5 diff -u -p -u -r1.5 XRecord.c --- lib/libXtst/src/XRecord.c 23 May 2013 22:42:15 -0000 1.5 +++ lib/libXtst/src/XRecord.c 4 Oct 2016 16:11:58 -0000 @@ -760,15 +760,23 @@ parse_reply_call_callback( switch (rep->category) { case XRecordFromServer: if (rep->elementHeader&XRecordFromServerTime) { + if (current_index + 4 > rep->length << 2) + return Error; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index, data->server_time); current_index += 4; } + if (current_index + 1 > rep->length << 2) + return Error; switch (reply->buf[current_index]) { case X_Reply: /* reply */ + if (current_index + 8 > rep->length << 2) + return Error; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index+4, datum_bytes); + if (datum_bytes < 0 || datum_bytes > ((INT_MAX >> 2) - 8)) + return Error; datum_bytes = (datum_bytes+8) << 2; break; default: /* error or event */ @@ -777,52 +785,73 @@ parse_reply_call_callback( break; case XRecordFromClient: if (rep->elementHeader&XRecordFromClientTime) { + if (current_index + 4 > rep->length << 2) + return Error; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index, data->server_time); current_index += 4; } if (rep->elementHeader&XRecordFromClientSequence) { + if (current_index + 4 > rep->length << 2) + return Error; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index, data->client_seq); current_index += 4; } + if (current_index + 4 > rep->length<<2) + return Error; if (reply->buf[current_index+2] == 0 && reply->buf[current_index+3] == 0) /* needn't swap 0 */ { /* BIG-REQUESTS */ + if (current_index + 8 > rep->length << 2) + return Error; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index+4, datum_bytes); } else { EXTRACT_CARD16(rep->clientSwapped, reply->buf+current_index+2, datum_bytes); } + if (datum_bytes < 0 || datum_bytes > INT_MAX >> 2) + return Error; datum_bytes <<= 2; break; case XRecordClientStarted: + if (current_index + 8 > rep->length << 2) + return Error; EXTRACT_CARD16(rep->clientSwapped, reply->buf+current_index+6, datum_bytes); datum_bytes = (datum_bytes+2) << 2; break; case XRecordClientDied: if (rep->elementHeader&XRecordFromClientSequence) { + if (current_index + 4 > rep->length << 2) + return Error; EXTRACT_CARD32(rep->clientSwapped, reply->buf+current_index, data->client_seq); current_index += 4; - } - /* fall through */ + } else if (current_index < rep->length << 2) + return Error; + datum_bytes = 0; + break; case XRecordStartOfData: case XRecordEndOfData: + if (current_index < rep->length << 2) + return Error; datum_bytes = 0; + break; } if (datum_bytes > 0) { - if (current_index + datum_bytes > rep->length << 2) + if (INT_MAX - datum_bytes < (rep->length << 2) - current_index) { fprintf(stderr, "XRecord: %lu-byte reply claims %d-byte element (seq %lu)\n", - (long)rep->length << 2, current_index + datum_bytes, + (unsigned long)rep->length << 2, current_index + datum_bytes, dpy->last_request_read); + return Error; + } /* * This assignment (and indeed the whole buffer sharing * scheme) assumes arbitrary 4-byte boundaries are @@ -869,6 +898,12 @@ XRecordEnableContext(Display *dpy, XReco /* This code should match that in XRecordEnableContextAsync */ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + + if (rep.length > INT_MAX >> 2) { UnlockDisplay(dpy); SyncHandle(); return 0; Index: lib/libXv/src/Xv.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXv/src/Xv.c,v retrieving revision 1.6 diff -u -p -u -r1.6 Xv.c --- lib/libXv/src/Xv.c 28 Sep 2013 17:51:21 -0000 1.6 +++ lib/libXv/src/Xv.c 4 Oct 2016 16:11:58 -0000 @@ -158,6 +158,7 @@ XvQueryAdaptors( size_t size; unsigned int ii, jj; char *name; + char *end; XvAdaptorInfo *pas = NULL, *pa; XvFormat *pfs, *pf; char *buffer = NULL; @@ -197,17 +198,13 @@ XvQueryAdaptors( /* GET INPUT ADAPTORS */ if (rep.num_adaptors == 0) { - /* If there's no adaptors, there's nothing more to do. */ + /* If there are no adaptors, there's nothing more to do. */ status = Success; goto out; } - if (size < (rep.num_adaptors * sz_xvAdaptorInfo)) { - /* If there's not enough data for the number of adaptors, - then we have a problem. */ - status = XvBadReply; - goto out; - } + u.buffer = buffer; + end = buffer + size; size = rep.num_adaptors * sizeof(XvAdaptorInfo); if ((pas = Xmalloc(size)) == NULL) { @@ -225,9 +222,12 @@ XvQueryAdaptors( pa++; } - u.buffer = buffer; pa = pas; for (ii = 0; ii < rep.num_adaptors; ii++) { + if (u.buffer + sz_xvAdaptorInfo > end) { + status = XvBadReply; + goto out; + } pa->type = u.pa->type; pa->base_id = u.pa->base_id; pa->num_ports = u.pa->num_ports; @@ -239,6 +239,10 @@ XvQueryAdaptors( size = u.pa->name_size; u.buffer += pad_to_int32(sz_xvAdaptorInfo); + if (u.buffer + size > end) { + status = XvBadReply; + goto out; + } if ((name = Xmalloc(size + 1)) == NULL) { status = XvBadAlloc; goto out; @@ -259,6 +263,11 @@ XvQueryAdaptors( pf = pfs; for (jj = 0; jj < pa->num_formats; jj++) { + if (u.buffer + sz_xvFormat > end) { + Xfree(pfs); + status = XvBadReply; + goto out; + } pf->depth = u.pf->depth; pf->visual_id = u.pf->visual; pf++; @@ -327,6 +336,7 @@ XvQueryEncodings( size_t size; unsigned int jj; char *name; + char *end; XvEncodingInfo *pes = NULL, *pe; char *buffer = NULL; union { @@ -364,17 +374,13 @@ XvQueryEncodings( /* GET ENCODINGS */ if (rep.num_encodings == 0) { - /* If there's no encodings, there's nothing more to do. */ + /* If there are no encodings, there's nothing more to do. */ status = Success; goto out; } - if (size < (rep.num_encodings * sz_xvEncodingInfo)) { - /* If there's not enough data for the number of adaptors, - then we have a problem. */ - status = XvBadReply; - goto out; - } + u.buffer = buffer; + end = buffer + size; size = rep.num_encodings * sizeof(XvEncodingInfo); if ((pes = Xmalloc(size)) == NULL) { @@ -391,10 +397,12 @@ XvQueryEncodings( pe++; } - u.buffer = buffer; - pe = pes; for (jj = 0; jj < rep.num_encodings; jj++) { + if (u.buffer + sz_xvEncodingInfo > end) { + status = XvBadReply; + goto out; + } pe->encoding_id = u.pe->encoding; pe->width = u.pe->width; pe->height = u.pe->height; @@ -405,6 +413,10 @@ XvQueryEncodings( size = u.pe->name_size; u.buffer += pad_to_int32(sz_xvEncodingInfo); + if (u.buffer + size > end) { + status = XvBadReply; + goto out; + } if ((name = Xmalloc(size + 1)) == NULL) { status = XvBadAlloc; goto out; Index: lib/libXvMC/src/XvMC.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXvMC/src/XvMC.c,v retrieving revision 1.6 diff -u -p -u -r1.6 XvMC.c --- lib/libXvMC/src/XvMC.c 6 Apr 2015 13:33:24 -0000 1.6 +++ lib/libXvMC/src/XvMC.c 4 Oct 2016 16:11:58 -0000 @@ -576,9 +576,9 @@ Status XvMCGetDRInfo(Display *dpy, XvPor if (*name && *busID && tmpBuf) { _XRead(dpy, tmpBuf, realSize); strncpy(*name,tmpBuf,rep.nameLen); - (*name)[rep.nameLen - 1] = '\0'; + (*name)[rep.nameLen == 0 ? 0 : rep.nameLen - 1] = '\0'; strncpy(*busID,tmpBuf+rep.nameLen,rep.busIDLen); - (*busID)[rep.busIDLen - 1] = '\0'; + (*busID)[rep.busIDLen == 0 ? 0 : rep.busIDLen - 1] = '\0'; XFree(tmpBuf); } else { XFree(*name);