Index: xkb.c =================================================================== RCS file: /cvsroot/xsrc/external/mit/xorg-server/dist/xkb/xkb.c,v retrieving revision 1.4.2.1 diff -p -u -r1.4.2.1 xkb.c --- xkb.c 6 Dec 2020 10:18:02 -0000 1.4.2.1 +++ xkb.c 15 Jul 2022 09:29:17 -0000 @@ -5151,7 +5151,7 @@ _GetCountedString(char **wire_inout, Cli } static Status -_CheckSetDoodad(char **wire_inout, +_CheckSetDoodad(char **wire_inout, xkbSetGeometryReq *req, XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) { char *wire; @@ -5162,6 +5162,9 @@ _CheckSetDoodad(char **wire_inout, Status status; dWire = (xkbDoodadWireDesc *) (*wire_inout); + if (!_XkbCheckRequestBounds(client, req, dWire, dWire + 1)) + return BadLength; + any = dWire->any; wire = (char *) &dWire[1]; if (client->swapped) { @@ -5264,7 +5267,7 @@ _CheckSetDoodad(char **wire_inout, } static Status -_CheckSetOverlay(char **wire_inout, +_CheckSetOverlay(char **wire_inout, xkbSetGeometryReq *req, XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) { register int r; @@ -5275,6 +5278,9 @@ _CheckSetOverlay(char **wire_inout, wire = *wire_inout; olWire = (xkbOverlayWireDesc *) wire; + if (!_XkbCheckRequestBounds(client, req, olWire, olWire + 1)) + return BadLength; + if (client->swapped) { swapl(&olWire->name); } @@ -5286,6 +5292,9 @@ _CheckSetOverlay(char **wire_inout, xkbOverlayKeyWireDesc *kWire; XkbOverlayRowPtr row; + if (!_XkbCheckRequestBounds(client, req, rWire, rWire + 1)) + return BadLength; + if (rWire->rowUnder > section->num_rows) { client->errorValue = _XkbErrCode4(0x20, r, section->num_rows, rWire->rowUnder); @@ -5294,6 +5303,9 @@ _CheckSetOverlay(char **wire_inout, row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys); kWire = (xkbOverlayKeyWireDesc *) &rWire[1]; for (k = 0; k < rWire->nKeys; k++, kWire++) { + if (!_XkbCheckRequestBounds(client, req, kWire, kWire + 1)) + return BadLength; + if (XkbAddGeomOverlayKey(ol, row, (char *) kWire->over, (char *) kWire->under) == NULL) { @@ -5327,6 +5339,9 @@ _CheckSetSections(XkbGeometryPtr geom, register int r; xkbRowWireDesc *rWire; + if (!_XkbCheckRequestBounds(client, req, sWire, sWire + 1)) + return BadLength; + if (client->swapped) { swapl(&sWire->name); swaps(&sWire->top); @@ -5352,6 +5367,9 @@ _CheckSetSections(XkbGeometryPtr geom, XkbRowPtr row; xkbKeyWireDesc *kWire; + if (!_XkbCheckRequestBounds(client, req, rWire, rWire + 1)) + return BadLength; + if (client->swapped) { swaps(&rWire->top); swaps(&rWire->left); @@ -5363,16 +5381,19 @@ _CheckSetSections(XkbGeometryPtr geom, row->left = rWire->left; row->vertical = rWire->vertical; kWire = (xkbKeyWireDesc *) &rWire[1]; - for (k = 0; k < rWire->nKeys; k++) { + for (k = 0; k < rWire->nKeys; k++, kWire++) { XkbKeyPtr key; + if (!_XkbCheckRequestBounds(client, req, kWire, kWire + 1)) + return BadLength; + key = XkbAddGeomKey(row); if (!key) return BadAlloc; - memcpy(key->name.name, kWire[k].name, XkbKeyNameLength); - key->gap = kWire[k].gap; - key->shape_ndx = kWire[k].shapeNdx; - key->color_ndx = kWire[k].colorNdx; + memcpy(key->name.name, kWire->name, XkbKeyNameLength); + key->gap = kWire->gap; + key->shape_ndx = kWire->shapeNdx; + key->color_ndx = kWire->colorNdx; if (key->shape_ndx >= geom->num_shapes) { client->errorValue = _XkbErrCode3(0x10, key->shape_ndx, geom->num_shapes); @@ -5384,14 +5405,14 @@ _CheckSetSections(XkbGeometryPtr geom, return BadMatch; } } - rWire = (xkbRowWireDesc *) &kWire[rWire->nKeys]; + rWire = (xkbRowWireDesc *)kWire; } wire = (char *) rWire; if (sWire->nDoodads > 0) { register int d; for (d = 0; d < sWire->nDoodads; d++) { - status = _CheckSetDoodad(&wire, geom, section, client); + status = _CheckSetDoodad(&wire, req, geom, section, client); if (status != Success) return status; } @@ -5400,7 +5421,7 @@ _CheckSetSections(XkbGeometryPtr geom, register int o; for (o = 0; o < sWire->nOverlays; o++) { - status = _CheckSetOverlay(&wire, geom, section, client); + status = _CheckSetOverlay(&wire, req, geom, section, client); if (status != Success) return status; } @@ -5434,6 +5455,9 @@ _CheckSetShapes(XkbGeometryPtr geom, xkbOutlineWireDesc *olWire; XkbOutlinePtr ol; + if (!_XkbCheckRequestBounds(client, req, shapeWire, shapeWire + 1)) + return BadLength; + shape = XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines); if (!shape) @@ -5444,21 +5468,27 @@ _CheckSetShapes(XkbGeometryPtr geom, XkbPointPtr pt; xkbPointWireDesc *ptWire; + if (!_XkbCheckRequestBounds(client, req, olWire, olWire + 1)) + return BadLength; + ol = XkbAddGeomOutline(shape, olWire->nPoints); if (!ol) return BadAlloc; ol->corner_radius = olWire->cornerRadius; ptWire = (xkbPointWireDesc *) &olWire[1]; - for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) { - pt->x = ptWire[p].x; - pt->y = ptWire[p].y; + for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++, ptWire++) { + if (!_XkbCheckRequestBounds(client, req, ptWire, ptWire + 1)) + return BadLength; + + pt->x = ptWire->x; + pt->y = ptWire->y; if (client->swapped) { swaps(&pt->x); swaps(&pt->y); } } ol->num_points = olWire->nPoints; - olWire = (xkbOutlineWireDesc *) (&ptWire[olWire->nPoints]); + olWire = (xkbOutlineWireDesc *)ptWire; } if (shapeWire->primaryNdx != XkbNoShape) shape->primary = &shape->outlines[shapeWire->primaryNdx]; @@ -5555,12 +5585,15 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSe return status; for (i = 0; i < req->nDoodads; i++) { - status = _CheckSetDoodad(&wire, geom, NULL, client); + status = _CheckSetDoodad(&wire, req, geom, NULL, client); if (status != Success) return status; } for (i = 0; i < req->nKeyAliases; i++) { + if (!_XkbCheckRequestBounds(client, req, wire, wire + XkbKeyNameLength)) + return BadLength; + if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL) return BadAlloc; wire += 2 * XkbKeyNameLength; @@ -6545,7 +6578,8 @@ ProcXkbGetDeviceInfo(ClientPtr client) static char * CheckSetDeviceIndicators(char *wire, DeviceIntPtr dev, - int num, int *status_rtrn, ClientPtr client) + int num, int *status_rtrn, ClientPtr client, + xkbSetDeviceInfoReq * stuff) { xkbDeviceLedsWireDesc *ledWire; int i; @@ -6553,6 +6587,11 @@ CheckSetDeviceIndicators(char *wire, ledWire = (xkbDeviceLedsWireDesc *) wire; for (i = 0; i < num; i++) { + if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) { + *status_rtrn = BadLength; + return (char *) ledWire; + } + if (client->swapped) { swaps(&ledWire->ledClass); swaps(&ledWire->ledID); @@ -6580,6 +6619,11 @@ CheckSetDeviceIndicators(char *wire, atomWire = (CARD32 *) &ledWire[1]; if (nNames > 0) { for (n = 0; n < nNames; n++) { + if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) { + *status_rtrn = BadLength; + return (char *) atomWire; + } + if (client->swapped) { swapl(atomWire); } @@ -6591,6 +6635,10 @@ CheckSetDeviceIndicators(char *wire, mapWire = (xkbIndicatorMapWireDesc *) atomWire; if (nMaps > 0) { for (n = 0; n < nMaps; n++) { + if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) { + *status_rtrn = BadLength; + return (char *) mapWire; + } if (client->swapped) { swaps(&mapWire->virtualMods); swapl(&mapWire->ctrls); @@ -6642,11 +6690,6 @@ SetDeviceIndicators(char *wire, xkbIndicatorMapWireDesc *mapWire; XkbSrvLedInfoPtr sli; - if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) { - *status_rtrn = BadLength; - return (char *) ledWire; - } - namec = mapc = statec = 0; sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, XkbXI_IndicatorMapsMask); @@ -6665,10 +6708,6 @@ SetDeviceIndicators(char *wire, memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { if (ledWire->namesPresent & bit) { - if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) { - *status_rtrn = BadLength; - return (char *) atomWire; - } sli->names[n] = (Atom) *atomWire; if (sli->names[n] == None) ledWire->namesPresent &= ~bit; @@ -6686,10 +6725,6 @@ SetDeviceIndicators(char *wire, if (ledWire->mapsPresent) { for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { if (ledWire->mapsPresent & bit) { - if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) { - *status_rtrn = BadLength; - return (char *) mapWire; - } sli->maps[n].flags = mapWire->flags; sli->maps[n].which_groups = mapWire->whichGroups; sli->maps[n].groups = mapWire->groups; @@ -6725,13 +6760,17 @@ SetDeviceIndicators(char *wire, } static int -_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, +_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, xkbSetDeviceInfoReq * stuff) { char *wire; wire = (char *) &stuff[1]; if (stuff->change & XkbXI_ButtonActionsMask) { + int sz = stuff->nBtns * SIZEOF(xkbActionWireDesc); + if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz)) + return BadLength; + if (!dev->button) { client->errorValue = _XkbErrCode2(XkbErr_BadClass, ButtonClass); return XkbKeyboardErrorCode; @@ -6742,13 +6781,13 @@ _XkbSetDeviceInfo(ClientPtr client, Devi dev->button->numButtons); return BadMatch; } - wire += (stuff->nBtns * SIZEOF(xkbActionWireDesc)); + wire += sz; } if (stuff->change & XkbXI_IndicatorsMask) { int status = Success; wire = CheckSetDeviceIndicators(wire, dev, stuff->nDeviceLedFBs, - &status, client); + &status, client, stuff); if (status != Success) return status; } @@ -6759,8 +6798,8 @@ _XkbSetDeviceInfo(ClientPtr client, Devi } static int -_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, - xkbSetDeviceInfoReq * stuff) +_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, + xkbSetDeviceInfoReq * stuff) { char *wire; xkbExtensionDeviceNotify ed; @@ -6784,8 +6823,6 @@ _XkbSetDeviceInfoCheck(ClientPtr client, if (stuff->firstBtn + stuff->nBtns > nBtns) return BadValue; sz = stuff->nBtns * SIZEOF(xkbActionWireDesc); - if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz)) - return BadLength; memcpy((char *) &acts[stuff->firstBtn], (char *) wire, sz); wire += sz; ed.reason |= XkbXI_ButtonActionsMask;