Fedora Account System
Red Hat Associate
Red Hat Customer
CheckKeySyms() in xkb/xkb.c populates a symsPerKey[] validation array with new key widths for keys in the SetMap request range, then continues filling entries for keys beyond the range. However, the second loop starts at index i = nKeySyms (the first loop's counter) rather than i = firstKeySym + nKeySyms. When firstKeySym is large and nKeySyms is small, the second loop overwrites symsPerKey[target] with the old width from the existing map. CheckKeyActions() then validates the wire action count against the stale old width and accepts it. In _XkbSetMap(), SetKeySyms() widens the key (resizing actions to nGroups * newWidth), but SetKeyActions() then resizes again to the old count. A subsequent XkbGetMap request reads XkbKeyNumActions() entries (derived from the new wider key_sym_map.width) from the shorter action allocation, causing an out-of-bounds heap read. The overread bytes are copied into the GetMap reply and sent back to the requesting client, producing a bounded heap information disclosure. Fixed in: xorg-server-21.1.25 and xwayland-24.1.14 * Patch From 2d6e9cd5f0e79115e1c0573f9473a8e8fa7dd12a Mon Sep 17 00:00:00 2001 From: Peter Hutterer <peter.hutterer> Date: Thu, 3 Sep 2026 14:55:27 +1000 Subject: [PATCH xserver] xkb: fix CheckKeySyms overwriting request-range symsPerKey entries CheckKeySyms() has two loops: the first processes keys in the SetMap request range, the second fills in any missing keys from the existing map. The indexing between the two was inconsistent: the first loop uses a zero-based index + req->firstKeySym, the second loop used it just as zero-based index. Example: req->firstKeySym = 50 req->nKeySyms = 10 i goes from 0 to 10, loop 1 checks [50, 60), changes the width but finishes with i at 10. loop 2 then runs over [10, 255(, copying the old keymap width The second loop overwrites the new widths with the width of the existing keymap. The subsequent SetKeySyms worked on the new width and may write fewer actions than the map width. A subsequent XkbGetMap request would then read XkbKeyNumActions() entries (derived from the new wider key_sym_map.width) from the shorter action allocation, causing an out-of-bounds heap read. The overread bytes would be copied into the GetMap reply and sent back to the client, producing a bounded heap information disclosure. This vulnerability was discovered by: WONJOON HWANG (@joon1337) working with TrendAI Zero Day Initiative ZDI-CAN-32408 CVE-2026-93524 Assisted-by: Claude:claude-opus-4-6 #+begin_src diff --- xkb/xkb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xkb/xkb.c b/xkb/xkb.c index cbbbc5055e3c..9ed01552e12b 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -1808,16 +1808,17 @@ CheckKeySyms(ClientPtr client, if (!_XkbCheckRequestBounds(client, req, pSyms, &pSyms[wire->nSyms])) { ,*errorRtrn = _XkbErrCode3(0x19, i + req->firstKeySym, wire->nSyms); return 0; } } wire = (xkbSymMapWireDesc *) &pSyms[wire->nSyms]; } + i = req->firstKeySym + req->nKeySyms; map = &xkb->map->key_sym_map[i]; for (; i <= (unsigned) xkb->max_key_code; i++, map++) { register int g, nG, w; nG = XkbKeyNumGroups(xkb, i); for (w = g = 0; g < nG; g++) { if (map->kt_index[g] >= (unsigned) nTypes) { ,*errorRtrn = _XkbErrCode4(0x18, i, g, map->kt_index[g]); -- 2.55.0 #+end_src