Blame SOURCES/0001-Xi-allocate-enough-XkbActions-for-our-buttons.patch

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