Blame SOURCES/xorg-CVE-2024-21885.patch

2d42f4
From a483b5c7724469309e3df427730cbb8b805b9c9f Mon Sep 17 00:00:00 2001
2d42f4
From: Peter Hutterer <peter.hutterer@who-t.net>
2d42f4
Date: Thu, 4 Jan 2024 10:01:24 +1000
2d42f4
Subject: [PATCH xserver] Xi: flush hierarchy events after adding/removing
2d42f4
 master devices
2d42f4
2d42f4
The `XISendDeviceHierarchyEvent()` function allocates space to store up
2d42f4
to `MAXDEVICES` (256) `xXIHierarchyInfo` structures in `info`.
2d42f4
2d42f4
If a device with a given ID was removed and a new device with the same
2d42f4
ID added both in the same operation, the single device ID will lead to
2d42f4
two info structures being written to `info`.
2d42f4
2d42f4
Since this case can occur for every device ID at once, a total of two
2d42f4
times `MAXDEVICES` info structures might be written to the allocation.
2d42f4
2d42f4
To avoid it, once one add/remove master is processed, send out the
2d42f4
device hierarchy event for the current state and continue. That event
2d42f4
thus only ever has exactly one of either added/removed in it (and
2d42f4
optionally slave attached/detached).
2d42f4
2d42f4
CVE-2024-21885, ZDI-CAN-22744
2d42f4
2d42f4
This vulnerability was discovered by:
2d42f4
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
2d42f4
---
2d42f4
 Xi/xichangehierarchy.c | 30 ++++++++++++++++++++++++------
2d42f4
 1 file changed, 24 insertions(+), 6 deletions(-)
2d42f4
2d42f4
diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
2d42f4
index 01eb7a8af4..67eedddec6 100644
2d42f4
--- a/Xi/xichangehierarchy.c
2d42f4
+++ b/Xi/xichangehierarchy.c
2d42f4
@@ -340,6 +340,11 @@ ProcXIChangeHierarchy(ClientPtr client)
2d42f4
     size_t len;			/* length of data remaining in request */
2d42f4
     int rc = Success;
2d42f4
     int flags[MAXDEVICES] = { 0 };
2d42f4
+    enum {
2d42f4
+        NO_CHANGE,
2d42f4
+        FLUSH,
2d42f4
+        CHANGED,
2d42f4
+    } changes = NO_CHANGE;
2d42f4
 
2d42f4
     REQUEST(xXIChangeHierarchyReq);
2d42f4
     REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
2d42f4
@@ -389,8 +394,9 @@ ProcXIChangeHierarchy(ClientPtr client)
2d42f4
             rc = add_master(client, c, flags);
2d42f4
             if (rc != Success)
2d42f4
                 goto unwind;
2d42f4
-        }
2d42f4
+            changes = FLUSH;
2d42f4
             break;
2d42f4
+        }
2d42f4
         case XIRemoveMaster:
2d42f4
         {
2d42f4
             xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
2d42f4
@@ -399,8 +405,9 @@ ProcXIChangeHierarchy(ClientPtr client)
2d42f4
             rc = remove_master(client, r, flags);
2d42f4
             if (rc != Success)
2d42f4
                 goto unwind;
2d42f4
-        }
2d42f4
+            changes = FLUSH;
2d42f4
             break;
2d42f4
+        }
2d42f4
         case XIDetachSlave:
2d42f4
         {
2d42f4
             xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
2d42f4
@@ -409,8 +416,9 @@ ProcXIChangeHierarchy(ClientPtr client)
2d42f4
             rc = detach_slave(client, c, flags);
2d42f4
             if (rc != Success)
2d42f4
                 goto unwind;
2d42f4
-        }
2d42f4
+            changes = CHANGED;
2d42f4
             break;
2d42f4
+        }
2d42f4
         case XIAttachSlave:
2d42f4
         {
2d42f4
             xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
2d42f4
@@ -495,16 +503,25 @@ ProcXIChangeHierarchy(ClientPtr client)
2d42f4
             rc = attach_slave(client, c, flags);
2d42f4
             if (rc != Success)
2d42f4
                 goto unwind;
2d42f4
+            changes = CHANGED;
2d42f4
+            break;
2d42f4
         }
2d42f4
+        default:
2d42f4
             break;
2d42f4
         }
2d42f4
 
2d42f4
+        if (changes == FLUSH) {
2d42f4
+            XISendDeviceHierarchyEvent(flags);
2d42f4
+            memset(flags, 0, sizeof(flags));
2d42f4
+            changes = NO_CHANGE;
2d42f4
+        }
2d42f4
+
2d42f4
         len -= any->length * 4;
2d42f4
         any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
2d42f4
     }
2d42f4
 
2d42f4
  unwind:
2d42f4
-
2d42f4
-    XISendDeviceHierarchyEvent(flags);
2d42f4
+    if (changes != NO_CHANGE)
2d42f4
+        XISendDeviceHierarchyEvent(flags);
2d42f4
     return rc;
2d42f4
 }
2d42f4
-- 
2d42f4
2.43.0
2d42f4