Bug 2545908 (CVE-2026-93520) - CVE-2026-93520 xorg-x11-server: xorg-x11-server: arbitrary code execution via out-of-bounds write in XKB keycode handling
Summary: CVE-2026-93520 xorg-x11-server: xorg-x11-server: arbitrary code execution via...
Keywords:
Status: NEW
Alias: CVE-2026-93520
Deadline: 2026-10-07
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-10-05 13:02 UTC by OSIDB Bzimport
Modified: 2026-10-09 11:00 UTC (History)
3 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-10-05 13:02:52 UTC
This is caused by an incomplete fix regression from commit a3171732d.
     XkbAllocNames() still uses max_key_code+1 for the names->keys allocation
     size, while memset in the ChangeKeycodeRange path uses MAP_LENGTH which
     can be larger. This causes a heap out-of-bounds write when the keycode
     range is changed to a value where MAP_LENGTH exceeds max_key_code+1.

     An authenticated X client can trigger this by sending XKB requests that
     change the keycode range.

     The heap out-of-bounds write can lead to arbitrary code execution or denial
     of service.

     Fixed in: xorg-server-21.1.25 and xwayland-24.1.14
     Fix: https://gitlab.freedesktop.org/xorg/xserver/-/commit/TBD
     Found by: Anonymous working with TrendAI Zero Day Initiative.
               (ZDI-CAN-31941)


* Patch
From 58e2874f69ef83323cdd18a4004535e06a8947bb Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer>
Date: Wed, 26 Aug 2026 17:04:03 +1000
Subject: [PATCH xserver] xkb: allocate names->keys to MAP_LENGTH in
 XkbAllocNames

Commit a3171732d ("xkb: Always use MAP_LENGTH keymap size") converted
most XKB allocation functions to use MAP_LENGTH (256) instead of
max_key_code + 1. It also removed the per-array reallocarray() calls in
XkbChangeKeycodeRange(), replacing them with a memset up to MAP_LENGTH.
However, XkbAllocNames() was missed and still allocates names->keys to
max_key_code + 1.

When a keycodes component with max_key_code < 255 is loaded (e.g.
sun(type6) with max_key_code=132) and then a SetMap request extends
maxKeyCode to 255, XkbChangeKeycodeRange() memsets names->keys from
max_key_code to MAP_LENGTH-1, writing past the undersized allocation.

Fix by allocating names->keys to MAP_LENGTH, consistent with all other
keymap arrays after a3171732d.

This vulnerability was discovered by:
  Anonymous working with TrendAI Zero Day Initiative

ZDI-CAN-31941

CVE-2026-93520

Fixes: a3171732da50 ("xkb: Always use MAP_LENGTH keymap size")

Assisted-by: Claude:claude-opus-4-6
#+begin_src diff
---
 xkb/XKBAlloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xkb/XKBAlloc.c b/xkb/XKBAlloc.c
index dced42eebd2c..314a858ddb09 100644
--- a/xkb/XKBAlloc.c
+++ b/xkb/XKBAlloc.c
@@ -143,17 +143,17 @@ XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases)
             }
         }
     }
     if ((which & XkbKeyNamesMask) && (names->keys == NULL)) {
         if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
             (!XkbIsLegalKeycode(xkb->max_key_code)) ||
             (xkb->max_key_code < xkb->min_key_code))
             return BadValue;
-        names->keys = calloc((xkb->max_key_code + 1), sizeof(XkbKeyNameRec));
+        names->keys = calloc(MAP_LENGTH, sizeof(XkbKeyNameRec));
         if (names->keys == NULL)
             return BadAlloc;
     }
     if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
         if (names->key_aliases == NULL) {
             names->key_aliases = calloc(nTotalAliases, sizeof(XkbKeyAliasRec));
         }
         else if (nTotalAliases > names->num_key_aliases) {
-- 
2.55.0
#+end_src


Note You need to log in before you can comment on or make changes to this bug.