From 54c3d9fad0f2f97835da9d275b53255f4963029f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 20 Apr 2026 11:18:13 +1000 Subject: [PATCH] xkb: clamp nMaps to mapWidths buffer size in CheckKeyTypes CheckKeyTypes computes nMaps = firstType + nTypes from client-controlled request fields when XkbSetMapResizeTypes is set. This value is used to index mapWidths[], a stack-allocated CARD8 array of XkbMaxLegalKeyCode + 1 (256) elements. No upper bound is enforced on nMaps. An attacker can first send SetMap(firstType=0, nTypes=255, ResizeTypes) to set the server's num_types to 255, then send SetMap(firstType=255, nTypes=10, ResizeTypes). The firstType > num_types check passes because 255 > 255 is false (the check uses > rather than >=). nMaps is then computed as 265, and the loop writes mapWidths[255..264], overflowing 9 bytes past the stack buffer into adjacent stack variables (symsPerKey[]). Fix by rejecting requests where firstType + nTypes would exceed the mapWidths buffer size (XkbMaxLegalKeyCode + 1). This vulnerability was discovered by: Anonymous working with TrendAI Zero Day Initiative ZDI-CAN-30161 Assisted-by: Claude:claude-opus-4-6 (cherry picked from commit 867b59b33bee669cb412f1314e47c52eacf6e00b) Part-of: --- xkb/xkb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xkb/xkb.c b/xkb/xkb.c index 2b5027104..fad39f9a9 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -1617,6 +1617,11 @@ CheckKeyTypes(ClientPtr client, *nMapsRtrn = _XkbErrCode4(0x02, req->firstType, req->nTypes, 4); return 0; } + if (nMaps > XkbMaxLegalKeyCode + 1) { + *nMapsRtrn = _XkbErrCode4(0x02, req->firstType, req->nTypes, + XkbMaxLegalKeyCode + 1); + return 0; + } } else if (req->present & XkbKeyTypesMask) { nMaps = xkb->map->num_types;