untrusted comment: verify with openbsd-66-base.pub RWSvK/c+cFe24BNfAOGjpMiaLiZGR4q5dLhWXj9LcrSL5nIsr0aeGijbm6x5uAXrjMRrzEkk/ja+deScrKB/pyW6+oAWb2ALTws= OpenBSD 6.6 errata 041, August 25, 2020: Various X server extensions had deficient input validation. Apply by doing: signify -Vep /etc/signify/openbsd-66-base.pub -x 041_xserverlen.patch.sig \ -m - | (cd /usr/xenocara && patch -p0) And then compile and rebuild the X server cd /usr/xenocara/xserver make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper build Index: xserver/Xi/xichangehierarchy.c =================================================================== RCS file: /cvs/xenocara/xserver/Xi/xichangehierarchy.c,v retrieving revision 1.12 diff -u -p -u -p -r1.12 xichangehierarchy.c --- xserver/Xi/xichangehierarchy.c 27 Jul 2019 07:57:08 -0000 1.12 +++ xserver/Xi/xichangehierarchy.c 20 Aug 2020 18:05:26 -0000 @@ -423,7 +423,7 @@ ProcXIChangeHierarchy(ClientPtr client) if (!stuff->num_changes) return rc; - len = ((size_t)stuff->length << 2) - sizeof(xXIChangeHierarchyReq); + len = ((size_t)client->req_len << 2) - sizeof(xXIChangeHierarchyReq); any = (xXIAnyHierarchyChangeInfo *) &stuff[1]; while (stuff->num_changes--) { Index: xserver/record/record.c =================================================================== RCS file: /cvs/xenocara/xserver/record/record.c,v retrieving revision 1.18 diff -u -p -u -p -r1.18 record.c --- xserver/record/record.c 27 Jul 2019 07:57:25 -0000 1.18 +++ xserver/record/record.c 20 Aug 2020 18:05:27 -0000 @@ -2499,7 +2499,7 @@ SProcRecordQueryVersion(ClientPtr client } /* SProcRecordQueryVersion */ static int _X_COLD -SwapCreateRegister(xRecordRegisterClientsReq * stuff) +SwapCreateRegister(ClientPtr client, xRecordRegisterClientsReq * stuff) { int i; XID *pClientID; @@ -2509,13 +2509,13 @@ SwapCreateRegister(xRecordRegisterClient swapl(&stuff->nRanges); pClientID = (XID *) &stuff[1]; if (stuff->nClients > - stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq)) + client->req_len - bytes_to_int32(sz_xRecordRegisterClientsReq)) return BadLength; for (i = 0; i < stuff->nClients; i++, pClientID++) { swapl(pClientID); } if (stuff->nRanges > - stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq) + client->req_len - bytes_to_int32(sz_xRecordRegisterClientsReq) - stuff->nClients) return BadLength; RecordSwapRanges((xRecordRange *) pClientID, stuff->nRanges); @@ -2530,7 +2530,7 @@ SProcRecordCreateContext(ClientPtr clien swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq); - if ((status = SwapCreateRegister((void *) stuff)) != Success) + if ((status = SwapCreateRegister(client, (void *) stuff)) != Success) return status; return ProcRecordCreateContext(client); } /* SProcRecordCreateContext */ @@ -2543,7 +2543,7 @@ SProcRecordRegisterClients(ClientPtr cli swaps(&stuff->length); REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq); - if ((status = SwapCreateRegister((void *) stuff)) != Success) + if ((status = SwapCreateRegister(client, (void *) stuff)) != Success) return status; return ProcRecordRegisterClients(client); } /* SProcRecordRegisterClients */ Index: xserver/xkb/xkb.c =================================================================== RCS file: /cvs/xenocara/xserver/xkb/xkb.c,v retrieving revision 1.16 diff -u -p -u -p -r1.16 xkb.c --- xserver/xkb/xkb.c 27 Jul 2019 07:57:26 -0000 1.16 +++ xserver/xkb/xkb.c 20 Aug 2020 18:05:28 -0000 @@ -152,6 +152,19 @@ static RESTYPE RT_XKBCLIENT; #define CHK_REQ_KEY_RANGE(err,first,num,r) \ CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue) +static Bool +_XkbCheckRequestBounds(ClientPtr client, void *stuff, void *from, void *to) { + char *cstuff = (char *)stuff; + char *cfrom = (char *)from; + char *cto = (char *)to; + + return cfrom < cto && + cfrom >= cstuff && + cfrom < cstuff + ((size_t)client->req_len << 2) && + cto >= cstuff && + cto <= cstuff + ((size_t)client->req_len << 2); +} + /***====================================================================***/ int @@ -4036,6 +4049,8 @@ _XkbSetNamesCheck(ClientPtr client, Devi client->errorValue = _XkbErrCode2(0x04, stuff->firstType); return BadAccess; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nTypes)) + return BadLength; old = tmp; tmp = _XkbCheckAtoms(tmp, stuff->nTypes, client->swapped, &bad); if (!tmp) { @@ -4065,6 +4080,8 @@ _XkbSetNamesCheck(ClientPtr client, Devi } width = (CARD8 *) tmp; tmp = (CARD32 *) (((char *) tmp) + XkbPaddedSize(stuff->nKTLevels)); + if (!_XkbCheckRequestBounds(client, stuff, width, tmp)) + return BadLength; type = &xkb->map->types[stuff->firstKTLevel]; for (i = 0; i < stuff->nKTLevels; i++, type++) { if (width[i] == 0) @@ -4074,6 +4091,8 @@ _XkbSetNamesCheck(ClientPtr client, Devi type->num_levels, width[i]); return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + width[i])) + return BadLength; tmp = _XkbCheckAtoms(tmp, width[i], client->swapped, &bad); if (!tmp) { client->errorValue = bad; @@ -4086,6 +4105,9 @@ _XkbSetNamesCheck(ClientPtr client, Devi client->errorValue = 0x08; return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + Ones(stuff->indicators))) + return BadLength; tmp = _XkbCheckMaskedAtoms(tmp, XkbNumIndicators, stuff->indicators, client->swapped, &bad); if (!tmp) { @@ -4098,6 +4120,9 @@ _XkbSetNamesCheck(ClientPtr client, Devi client->errorValue = 0x09; return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + Ones(stuff->virtualMods))) + return BadLength; tmp = _XkbCheckMaskedAtoms(tmp, XkbNumVirtualMods, (CARD32) stuff->virtualMods, client->swapped, &bad); @@ -4111,6 +4136,9 @@ _XkbSetNamesCheck(ClientPtr client, Devi client->errorValue = 0x0a; return BadMatch; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + Ones(stuff->groupNames))) + return BadLength; tmp = _XkbCheckMaskedAtoms(tmp, XkbNumKbdGroups, (CARD32) stuff->groupNames, client->swapped, &bad); @@ -4132,9 +4160,14 @@ _XkbSetNamesCheck(ClientPtr client, Devi stuff->nKeys); return BadValue; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + stuff->nKeys)) + return BadLength; tmp += stuff->nKeys; } if ((stuff->which & XkbKeyAliasesMask) && (stuff->nKeyAliases > 0)) { + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + (stuff->nKeyAliases * 2))) + return BadLength; tmp += stuff->nKeyAliases * 2; } if (stuff->which & XkbRGNamesMask) { @@ -4142,6 +4175,9 @@ _XkbSetNamesCheck(ClientPtr client, Devi client->errorValue = _XkbErrCode2(0x0d, stuff->nRadioGroups); return BadValue; } + if (!_XkbCheckRequestBounds(client, stuff, tmp, + tmp + stuff->nRadioGroups)) + return BadLength; tmp = _XkbCheckAtoms(tmp, stuff->nRadioGroups, client->swapped, &bad); if (!tmp) { client->errorValue = bad; @@ -4335,6 +4371,8 @@ ProcXkbSetNames(ClientPtr client) /* check device-independent stuff */ tmp = (CARD32 *) &stuff[1]; + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbKeycodesNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4342,6 +4380,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbGeometryNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4349,6 +4389,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbSymbolsNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4356,6 +4398,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbPhysSymbolsNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4363,6 +4407,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbTypesNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { @@ -4370,6 +4416,8 @@ ProcXkbSetNames(ClientPtr client) return BadAtom; } } + if (!_XkbCheckRequestBounds(client, stuff, tmp, tmp + 1)) + return BadLength; if (stuff->which & XkbCompatNameMask) { tmp = _XkbCheckAtoms(tmp, 1, client->swapped, &bad); if (!tmp) { Index: xserver/xkb/xkbSwap.c =================================================================== RCS file: /cvs/xenocara/xserver/xkb/xkbSwap.c,v retrieving revision 1.7 diff -u -p -u -p -r1.7 xkbSwap.c --- xserver/xkb/xkbSwap.c 27 Jul 2019 07:57:26 -0000 1.7 +++ xserver/xkb/xkbSwap.c 20 Aug 2020 18:05:28 -0000 @@ -76,7 +76,7 @@ SProcXkbSelectEvents(ClientPtr client) register unsigned bit, ndx, maskLeft, dataLeft, size; from.c8 = (CARD8 *) &stuff[1]; - dataLeft = (stuff->length * 4) - SIZEOF(xkbSelectEventsReq); + dataLeft = (client->req_len * 4) - SIZEOF(xkbSelectEventsReq); maskLeft = (stuff->affectWhich & (~XkbMapNotifyMask)); for (ndx = 0, bit = 1; (maskLeft != 0); ndx++, bit <<= 1) { if (((bit & maskLeft) == 0) || (ndx == XkbMapNotify))