Blame SOURCES/xorg-CVE-2024-21886-1.patch

2d42f4
From 4e0e99ef60f07757756913221847a26c71afc3e8 Mon Sep 17 00:00:00 2001
2d42f4
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
2d42f4
Date: Fri, 22 Dec 2023 18:28:31 +0100
2d42f4
Subject: [PATCH] Xi: do not keep linked list pointer during recursion
2d42f4
2d42f4
The `DisableDevice()` function is called whenever an enabled device
2d42f4
is disabled and it moves the device from the `inputInfo.devices` linked
2d42f4
list to the `inputInfo.off_devices` linked list.
2d42f4
2d42f4
However, its link/unlink operation has an issue during the recursive
2d42f4
call to `DisableDevice()` due to the `prev` pointer pointing to a
2d42f4
removed device.
2d42f4
2d42f4
This issue leads to a length mismatch between the total number of
2d42f4
devices and the number of device in the list, leading to a heap
2d42f4
overflow and, possibly, to local privilege escalation.
2d42f4
2d42f4
Simplify the code that checked whether the device passed to
2d42f4
`DisableDevice()` was in `inputInfo.devices` or not and find the
2d42f4
previous device after the recursion.
2d42f4
2d42f4
CVE-2024-21886, ZDI-CAN-22840
2d42f4
2d42f4
This vulnerability was discovered by:
2d42f4
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
2d42f4
---
2d42f4
 dix/devices.c | 15 ++++++++++++---
2d42f4
 1 file changed, 12 insertions(+), 3 deletions(-)
2d42f4
2d42f4
diff --git a/dix/devices.c b/dix/devices.c
2d42f4
index 3f3224d62..3a64d8702 100644
2d42f4
--- a/dix/devices.c
2d42f4
+++ b/dix/devices.c
2d42f4
@@ -451,14 +451,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
2d42f4
 {
2d42f4
     DeviceIntPtr *prev, other;
2d42f4
     BOOL enabled;
2d42f4
+    BOOL dev_in_devices_list = FALSE;
2d42f4
     int flags[MAXDEVICES] = { 0 };
2d42f4
 
2d42f4
     if (!dev->enabled)
2d42f4
         return TRUE;
2d42f4
 
2d42f4
-    for (prev = &inputInfo.devices;
2d42f4
-         *prev && (*prev != dev); prev = &(*prev)->next);
2d42f4
-    if (*prev != dev)
2d42f4
+    for (other = inputInfo.devices; other; other = other->next) {
2d42f4
+        if (other == dev) {
2d42f4
+            dev_in_devices_list = TRUE;
2d42f4
+            break;
2d42f4
+        }
2d42f4
+    }
2d42f4
+
2d42f4
+    if (!dev_in_devices_list)
2d42f4
         return FALSE;
2d42f4
 
2d42f4
     TouchEndPhysicallyActiveTouches(dev);
2d42f4
@@ -509,6 +515,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
2d42f4
     LeaveWindow(dev);
2d42f4
     SetFocusOut(dev);
2d42f4
 
2d42f4
+    for (prev = &inputInfo.devices;
2d42f4
+         *prev && (*prev != dev); prev = &(*prev)->next);
2d42f4
+
2d42f4
     *prev = dev->next;
2d42f4
     dev->next = inputInfo.off_devices;
2d42f4
     inputInfo.off_devices = dev;
2d42f4
-- 
2d42f4
2.43.0
2d42f4