xorg-x11-server-Xwayland/0006-Xi-Fix-barrier-device-search.patch

119 lines
3.5 KiB
Diff

From e70ec8fd0f4a94a9132caaff2beadf411964ab06 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 16 Dec 2024 11:25:11 +0100
Subject: [PATCH xserver 06/13] Xi: Fix barrier device search
The function GetBarrierDevice() would search for the pointer device
based on its device id and return the matching value, or supposedly NULL
if no match was found.
Unfortunately, as written, it would return the last element of the list
if no matching device id was found which can lead to out of bounds
memory access.
Fix the search function to return NULL if not matching device is found,
and adjust the callers to handle the case where the device cannot be
found.
CVE-2025-26598, ZDI-CAN-25740
This vulnerability was discovered by:
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit bba9df1a9d57234c76c0b93f88dacb143d01bca2)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1831>
---
Xi/xibarriers.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 1926762ad..cb336f22b 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -129,14 +129,15 @@ static void FreePointerBarrierClient(struct PointerBarrierClient *c)
static struct PointerBarrierDevice *GetBarrierDevice(struct PointerBarrierClient *c, int deviceid)
{
- struct PointerBarrierDevice *pbd = NULL;
+ struct PointerBarrierDevice *p, *pbd = NULL;
- xorg_list_for_each_entry(pbd, &c->per_device, entry) {
- if (pbd->deviceid == deviceid)
+ xorg_list_for_each_entry(p, &c->per_device, entry) {
+ if (p->deviceid == deviceid) {
+ pbd = p;
break;
+ }
}
- BUG_WARN(!pbd);
return pbd;
}
@@ -337,6 +338,9 @@ barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
double distance;
pbd = GetBarrierDevice(c, dev->id);
+ if (!pbd)
+ continue;
+
if (pbd->seen)
continue;
@@ -445,6 +449,9 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
nearest = &c->barrier;
pbd = GetBarrierDevice(c, master->id);
+ if (!pbd)
+ continue;
+
new_sequence = !pbd->hit;
pbd->seen = TRUE;
@@ -485,6 +492,9 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
int flags = 0;
pbd = GetBarrierDevice(c, master->id);
+ if (!pbd)
+ continue;
+
pbd->seen = FALSE;
if (!pbd->hit)
continue;
@@ -679,6 +689,9 @@ BarrierFreeBarrier(void *data, XID id)
continue;
pbd = GetBarrierDevice(c, dev->id);
+ if (!pbd)
+ continue;
+
if (!pbd->hit)
continue;
@@ -738,6 +751,8 @@ static void remove_master_func(void *res, XID id, void *devid)
barrier = container_of(b, struct PointerBarrierClient, barrier);
pbd = GetBarrierDevice(barrier, *deviceid);
+ if (!pbd)
+ return;
if (pbd->hit) {
BarrierEvent ev = {
@@ -903,6 +918,10 @@ ProcXIBarrierReleasePointer(ClientPtr client)
barrier = container_of(b, struct PointerBarrierClient, barrier);
pbd = GetBarrierDevice(barrier, dev->id);
+ if (!pbd) {
+ client->errorValue = dev->id;
+ return BadDevice;
+ }
if (pbd->barrier_event_id == event_id)
pbd->release_event_id = event_id;
--
2.48.1