Blame SOURCES/xorg-CVE-2023-6377.patch

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