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