untrusted comment: verify with openbsd-78-base.pub RWS3/nvFmk4SWUGAPi9jlrMZl51fTk23JGGoQkgOGsJNwk+N6BKgKSjHP/jeUOxVey2JTQ/5zZQIsQs5hfadMJQ4eEYTrfJWfwA= OpenBSD 7.8 errata 028, April 14, 2026: Multiple vulnerabilites in the X server sync and Xkb extensions. CVE-2026-33999 CVE-2026-34000 CVE-2026-34001 CVE-2026-34002 CVE-2026-34003 Apply by doing: signify -Vep /etc/signify/openbsd-78-base.pub -x 028_xserver.patch.sig \ -m - | (cd /usr/xenocara && patch -p0) And then rebuild and install the X server: cd /usr/xenocara/xserver make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper build Index: xserver/miext/sync/misync.c =================================================================== RCS file: /cvs/xenocara/xserver/miext/sync/misync.c,v diff -u -p -r1.6 misync.c --- xserver/miext/sync/misync.c 12 Dec 2019 06:05:20 -0000 1.6 +++ xserver/miext/sync/misync.c 13 Apr 2026 12:45:41 -0000 @@ -131,16 +131,22 @@ miSyncDestroyFence(SyncFence * pFence) void miSyncTriggerFence(SyncFence * pFence) { - SyncTriggerList *ptl, *pNext; + SyncTriggerList *ptl; + Bool triggered; pFence->funcs.SetTriggered(pFence); /* run through triggers to see if any fired */ - for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) { - pNext = ptl->next; - if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, 0)) - (*ptl->pTrigger->TriggerFired) (ptl->pTrigger); - } + do { + triggered = FALSE; + for (ptl = pFence->sync.pTriglist; ptl; ptl = ptl->next) { + if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, 0)) { + (*ptl->pTrigger->TriggerFired) (ptl->pTrigger); + triggered = TRUE; + break; + } + } + } while (triggered); } SyncScreenFuncsPtr Index: xserver/xkb/xkb.c =================================================================== RCS file: /cvs/xenocara/xserver/xkb/xkb.c,v diff -u -p -r1.26.4.1 xkb.c --- xserver/xkb/xkb.c 28 Oct 2025 13:26:59 -0000 1.26.4.1 +++ xserver/xkb/xkb.c 13 Apr 2026 12:45:41 -0000 @@ -1639,6 +1639,10 @@ CheckKeyTypes(ClientPtr client, for (i = 0; i < req->nTypes; i++) { unsigned width; + if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) { + *nMapsRtrn = _XkbErrCode3(0x0b, req->nTypes, i); + return 0; + } if (client->swapped && doswap) { swaps(&wire->virtualMods); } @@ -1664,7 +1668,18 @@ CheckKeyTypes(ClientPtr client, xkbModsWireDesc *preWire; mapWire = (xkbKTSetMapEntryWireDesc *) &wire[1]; + if (!_XkbCheckRequestBounds(client, req, mapWire, + &mapWire[wire->nMapEntries])) { + *nMapsRtrn = _XkbErrCode3(0x0c, i, wire->nMapEntries); + return 0; + } preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries]; + if (wire->preserve && + !_XkbCheckRequestBounds(client, req, preWire, + &preWire[wire->nMapEntries])) { + *nMapsRtrn = _XkbErrCode3(0x0d, i, wire->nMapEntries); + return 0; + } for (n = 0; n < wire->nMapEntries; n++) { if (client->swapped && doswap) { swaps(&mapWire[n].virtualMods); @@ -1737,6 +1752,11 @@ CheckKeySyms(ClientPtr client, KeySym *pSyms; register unsigned nG; + /* Check we received enough data to read the next xkbSymMapWireDesc */ + if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) { + *errorRtrn = _XkbErrCode3(0x18, i + req->firstKeySym, i); + return 0; + } if (client->swapped && doswap) { swaps(&wire->nSyms); } @@ -1775,6 +1795,12 @@ CheckKeySyms(ClientPtr client, return 0; } pSyms = (KeySym *) &wire[1]; + if (wire->nSyms != 0) { + if (!_XkbCheckRequestBounds(client, req, pSyms, &pSyms[wire->nSyms])) { + *errorRtrn = _XkbErrCode3(0x19, i + req->firstKeySym, wire->nSyms); + return 0; + } + } wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; } @@ -1798,11 +1824,12 @@ CheckKeySyms(ClientPtr client, } static int -CheckKeyActions(XkbDescPtr xkb, - xkbSetMapReq * req, - int nTypes, - CARD8 *mapWidths, - CARD16 *symsPerKey, CARD8 **wireRtrn, int *nActsRtrn) +CheckKeyActions(ClientPtr client, + XkbDescPtr xkb, + xkbSetMapReq * req, + int nTypes, + CARD8 *mapWidths, + CARD16 *symsPerKey, CARD8 **wireRtrn, int *nActsRtrn) { int nActs; CARD8 *wire = *wireRtrn; @@ -1813,6 +1840,11 @@ CheckKeyActions(XkbDescPtr xkb, CHK_REQ_KEY_RANGE2(0x21, req->firstKeyAct, req->nKeyActs, req, (*nActsRtrn), 0); for (nActs = i = 0; i < req->nKeyActs; i++) { + /* Check we received enough data to read the next byte on the wire */ + if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) { + *nActsRtrn = _XkbErrCode3(0x24, i + req->firstKeyAct, i); + return 0; + } if (wire[0] != 0) { if (wire[0] == symsPerKey[i + req->firstKeyAct]) nActs += wire[0]; @@ -1831,7 +1863,8 @@ CheckKeyActions(XkbDescPtr xkb, } static int -CheckKeyBehaviors(XkbDescPtr xkb, +CheckKeyBehaviors(ClientPtr client, + XkbDescPtr xkb, xkbSetMapReq * req, xkbBehaviorWireDesc ** wireRtrn, int *errorRtrn) { @@ -1857,6 +1890,11 @@ CheckKeyBehaviors(XkbDescPtr xkb, } for (i = 0; i < req->totalKeyBehaviors; i++, wire++) { + /* Check we received enough data to read the next behavior */ + if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) { + *errorRtrn = _XkbErrCode3(0x36, first, i); + return 0; + } if ((wire->key < first) || (wire->key > last)) { *errorRtrn = _XkbErrCode4(0x33, first, last, wire->key); return 0; @@ -1882,7 +1920,8 @@ CheckKeyBehaviors(XkbDescPtr xkb, } static int -CheckVirtualMods(XkbDescRec * xkb, +CheckVirtualMods(ClientPtr client, + XkbDescRec * xkb, xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn) { register CARD8 *wire = *wireRtrn; @@ -1894,12 +1933,18 @@ CheckVirtualMods(XkbDescRec * xkb, if (req->virtualMods & bit) nMods++; } + /* Check we received enough data for the number of virtual mods expected */ + if (!_XkbCheckRequestBounds(client, req, wire, wire + XkbPaddedSize(nMods))) { + *errorRtrn = _XkbErrCode3(0x37, nMods, i); + return 0; + } *wireRtrn = (wire + XkbPaddedSize(nMods)); return 1; } static int -CheckKeyExplicit(XkbDescPtr xkb, +CheckKeyExplicit(ClientPtr client, + XkbDescPtr xkb, xkbSetMapReq * req, CARD8 **wireRtrn, int *errorRtrn) { register CARD8 *wire = *wireRtrn; @@ -1925,6 +1970,11 @@ CheckKeyExplicit(XkbDescPtr xkb, } start = wire; for (i = 0; i < req->totalKeyExplicit; i++, wire += 2) { + /* Check we received enough data to read the next two bytes */ + if (!_XkbCheckRequestBounds(client, req, wire, wire + 2)) { + *errorRtrn = _XkbErrCode4(0x54, first, last, i); + return 0; + } if ((wire[0] < first) || (wire[0] > last)) { *errorRtrn = _XkbErrCode4(0x53, first, last, wire[0]); return 0; @@ -1940,8 +1990,8 @@ CheckKeyExplicit(XkbDescPtr xkb, } static int -CheckModifierMap(XkbDescPtr xkb, xkbSetMapReq * req, CARD8 **wireRtrn, - int *errRtrn) +CheckModifierMap(ClientPtr client, XkbDescPtr xkb, xkbSetMapReq * req, + CARD8 **wireRtrn, int *errRtrn) { register CARD8 *wire = *wireRtrn; CARD8 *start; @@ -1965,6 +2015,10 @@ CheckModifierMap(XkbDescPtr xkb, xkbSetM } start = wire; for (i = 0; i < req->totalModMapKeys; i++, wire += 2) { + if (!_XkbCheckRequestBounds(client, req, wire, wire + 2)) { + *errRtrn = _XkbErrCode3(0x64, req->totalModMapKeys, i); + return 0; + } if ((wire[0] < first) || (wire[0] > last)) { *errRtrn = _XkbErrCode4(0x63, first, last, wire[0]); return 0; @@ -1976,7 +2030,8 @@ CheckModifierMap(XkbDescPtr xkb, xkbSetM } static int -CheckVirtualModMap(XkbDescPtr xkb, +CheckVirtualModMap(ClientPtr client, + XkbDescPtr xkb, xkbSetMapReq * req, xkbVModMapWireDesc ** wireRtrn, int *errRtrn) { @@ -2000,6 +2055,11 @@ CheckVirtualModMap(XkbDescPtr xkb, return 0; } for (i = 0; i < req->totalVModMapKeys; i++, wire++) { + /* Check we received enough data to read the next virtual mod map key */ + if (!_XkbCheckRequestBounds(client, req, wire, wire + 1)) { + *errRtrn = _XkbErrCode3(0x74, first, i); + return 0; + } if ((wire->key < first) || (wire->key > last)) { *errRtrn = _XkbErrCode4(0x73, first, last, wire->key); return 0; @@ -2544,7 +2604,7 @@ _XkbSetMapChecks(ClientPtr client, Devic } if ((req->present & XkbKeyActionsMask) && - (!CheckKeyActions(xkb, req, nTypes, mapWidths, symsPerKey, + (!CheckKeyActions(client, xkb, req, nTypes, mapWidths, symsPerKey, (CARD8 **) &values, &nActions))) { client->errorValue = nActions; return BadValue; @@ -2552,29 +2612,29 @@ _XkbSetMapChecks(ClientPtr client, Devic if ((req->present & XkbKeyBehaviorsMask) && (!CheckKeyBehaviors - (xkb, req, (xkbBehaviorWireDesc **) &values, &error))) { + (client, xkb, req, (xkbBehaviorWireDesc **) &values, &error))) { client->errorValue = error; return BadValue; } if ((req->present & XkbVirtualModsMask) && - (!CheckVirtualMods(xkb, req, (CARD8 **) &values, &error))) { + (!CheckVirtualMods(client, xkb, req, (CARD8 **) &values, &error))) { client->errorValue = error; return BadValue; } if ((req->present & XkbExplicitComponentsMask) && - (!CheckKeyExplicit(xkb, req, (CARD8 **) &values, &error))) { + (!CheckKeyExplicit(client, xkb, req, (CARD8 **) &values, &error))) { client->errorValue = error; return BadValue; } if ((req->present & XkbModifierMapMask) && - (!CheckModifierMap(xkb, req, (CARD8 **) &values, &error))) { + (!CheckModifierMap(client, xkb, req, (CARD8 **) &values, &error))) { client->errorValue = error; return BadValue; } if ((req->present & XkbVirtualModMapMask) && (!CheckVirtualModMap - (xkb, req, (xkbVModMapWireDesc **) &values, &error))) { + (client, xkb, req, (xkbVModMapWireDesc **) &values, &error))) { client->errorValue = error; return BadValue; } @@ -3004,7 +3064,7 @@ _XkbSetCompatMap(ClientPtr client, Devic return BadAlloc; } } - else if (req->truncateSI) { + else if (req->truncateSI || req->firstSI + req->nSI > compat->num_si) { compat->num_si = req->firstSI + req->nSI; } sym = &compat->sym_interpret[req->firstSI]; @@ -5603,7 +5663,7 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSe } for (i = 0; i < req->nKeyAliases; i++) { - if (!_XkbCheckRequestBounds(client, req, wire, wire + XkbKeyNameLength)) + if (!_XkbCheckRequestBounds(client, req, wire, wire + 2 * XkbKeyNameLength)) return BadLength; if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL)