xkb: Fix out-of-bounds array access in _CheckSetShapes()

The primaryNdx and approxNdx fields in the shape wire description are
attacker-controlled CARD8 values from the client request. They are used
to index into the shape->outlines[] array, but were only checked against
XkbNoShape (0xff) and never validated against the actual number of
outlines (shapeWire->nOutlines).

Assisted-by: Claude:claude-claude-opus-4-6
(cherry picked from commit 86a321ad98)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2224>
This commit is contained in:
Peter Hutterer 2026-04-18 07:34:51 +10:00 committed by Alan Coopersmith
parent c9cd39f9b7
commit 39befa04f9

View file

@ -5563,10 +5563,22 @@ _CheckSetShapes(XkbGeometryPtr geom,
ol->num_points = olWire->nPoints;
olWire = (xkbOutlineWireDesc *)ptWire;
}
if (shapeWire->primaryNdx != XkbNoShape)
if (shapeWire->primaryNdx != XkbNoShape) {
if (shapeWire->primaryNdx >= shapeWire->nOutlines) {
client->errorValue = _XkbErrCode3(0x08, shapeWire->primaryNdx,
shapeWire->nOutlines);
return BadValue;
}
shape->primary = &shape->outlines[shapeWire->primaryNdx];
if (shapeWire->approxNdx != XkbNoShape)
}
if (shapeWire->approxNdx != XkbNoShape) {
if (shapeWire->approxNdx >= shapeWire->nOutlines) {
client->errorValue = _XkbErrCode3(0x08, shapeWire->approxNdx,
shapeWire->nOutlines);
return BadValue;
}
shape->approx = &shape->outlines[shapeWire->approxNdx];
}
shapeWire = (xkbShapeWireDesc *) olWire;
}
wire = (char *) shapeWire;