Peter Hutterer d887a5b
From a7bda3080d2b44eae668cdcec7a93095385b9652 Mon Sep 17 00:00:00 2001
Peter Hutterer d887a5b
From: Peter Hutterer <peter.hutterer@who-t.net>
Peter Hutterer d887a5b
Date: Tue, 28 Nov 2023 15:19:04 +1000
Peter Hutterer d887a5b
Subject: [PATCH xserver] Xi: allocate enough XkbActions for our buttons
Peter Hutterer d887a5b
Peter Hutterer d887a5b
button->xkb_acts is supposed to be an array sufficiently large for all
Peter Hutterer d887a5b
our buttons, not just a single XkbActions struct. Allocating
Peter Hutterer d887a5b
insufficient memory here means when we memcpy() later in
Peter Hutterer d887a5b
XkbSetDeviceInfo we write into memory that wasn't ours to begin with,
Peter Hutterer d887a5b
leading to the usual security ooopsiedaisies.
Peter Hutterer d887a5b
Peter Hutterer d887a5b
CVE-2023-6377, ZDI-CAN-22412, ZDI-CAN-22413
Peter Hutterer d887a5b
Peter Hutterer d887a5b
This vulnerability was discovered by:
Peter Hutterer d887a5b
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Peter Hutterer d887a5b
Peter Hutterer d887a5b
(cherry picked from commit 0c1a93d319558fe3ab2d94f51d174b4f93810afd)
Peter Hutterer d887a5b
---
Peter Hutterer d887a5b
 Xi/exevents.c | 12 ++++++------
Peter Hutterer d887a5b
 dix/devices.c | 10 ++++++++++
Peter Hutterer d887a5b
 2 files changed, 16 insertions(+), 6 deletions(-)
Peter Hutterer d887a5b
Peter Hutterer d887a5b
diff --git a/Xi/exevents.c b/Xi/exevents.c
Peter Hutterer d887a5b
index dcd4efb3bc..54ea11a938 100644
Peter Hutterer d887a5b
--- a/Xi/exevents.c
Peter Hutterer d887a5b
+++ b/Xi/exevents.c
Peter Hutterer d887a5b
@@ -611,13 +611,13 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
Peter Hutterer d887a5b
         }
Peter Hutterer d887a5b
 
Peter Hutterer d887a5b
         if (from->button->xkb_acts) {
Peter Hutterer d887a5b
-            if (!to->button->xkb_acts) {
Peter Hutterer d887a5b
-                to->button->xkb_acts = calloc(1, sizeof(XkbAction));
Peter Hutterer d887a5b
-                if (!to->button->xkb_acts)
Peter Hutterer d887a5b
-                    FatalError("[Xi] not enough memory for xkb_acts.\n");
Peter Hutterer d887a5b
-            }
Peter Hutterer d887a5b
+            size_t maxbuttons = max(to->button->numButtons, from->button->numButtons);
Peter Hutterer d887a5b
+            to->button->xkb_acts = xnfreallocarray(to->button->xkb_acts,
Peter Hutterer d887a5b
+                                                   maxbuttons,
Peter Hutterer d887a5b
+                                                   sizeof(XkbAction));
Peter Hutterer d887a5b
+            memset(to->button->xkb_acts, 0, maxbuttons * sizeof(XkbAction));
Peter Hutterer d887a5b
             memcpy(to->button->xkb_acts, from->button->xkb_acts,
Peter Hutterer d887a5b
-                   sizeof(XkbAction));
Peter Hutterer d887a5b
+                   from->button->numButtons * sizeof(XkbAction));
Peter Hutterer d887a5b
         }
Peter Hutterer d887a5b
         else {
Peter Hutterer d887a5b
             free(to->button->xkb_acts);
Peter Hutterer d887a5b
diff --git a/dix/devices.c b/dix/devices.c
Peter Hutterer d887a5b
index 5bf956ead4..15e46a9a5f 100644
Peter Hutterer d887a5b
--- a/dix/devices.c
Peter Hutterer d887a5b
+++ b/dix/devices.c
Peter Hutterer d887a5b
@@ -2525,6 +2525,8 @@ RecalculateMasterButtons(DeviceIntPtr slave)
Peter Hutterer d887a5b
 
Peter Hutterer d887a5b
     if (master->button && master->button->numButtons != maxbuttons) {
Peter Hutterer d887a5b
         int i;
Peter Hutterer d887a5b
+        int last_num_buttons = master->button->numButtons;
Peter Hutterer d887a5b
+
Peter Hutterer d887a5b
         DeviceChangedEvent event = {
Peter Hutterer d887a5b
             .header = ET_Internal,
Peter Hutterer d887a5b
             .type = ET_DeviceChanged,
Peter Hutterer d887a5b
@@ -2535,6 +2537,14 @@ RecalculateMasterButtons(DeviceIntPtr slave)
Peter Hutterer d887a5b
         };
Peter Hutterer d887a5b
 
Peter Hutterer d887a5b
         master->button->numButtons = maxbuttons;
Peter Hutterer d887a5b
+        if (last_num_buttons < maxbuttons) {
Peter Hutterer d887a5b
+            master->button->xkb_acts = xnfreallocarray(master->button->xkb_acts,
Peter Hutterer d887a5b
+                                                       maxbuttons,
Peter Hutterer d887a5b
+                                                       sizeof(XkbAction));
Peter Hutterer d887a5b
+            memset(&master->button->xkb_acts[last_num_buttons],
Peter Hutterer d887a5b
+                   0,
Peter Hutterer d887a5b
+                   (maxbuttons - last_num_buttons) * sizeof(XkbAction));
Peter Hutterer d887a5b
+        }
Peter Hutterer d887a5b
 
Peter Hutterer d887a5b
         memcpy(&event.buttons.names, master->button->labels, maxbuttons *
Peter Hutterer d887a5b
                sizeof(Atom));
Peter Hutterer d887a5b
-- 
Peter Hutterer d887a5b
2.43.0
Peter Hutterer d887a5b