From fb8a3c1389a012f9a99fe4be021a22ab22bebc47 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 16 Dec 2024 16:18:04 +0100 Subject: [PATCH xserver 09/13] dix: Dequeue pending events on frozen device on removal When a device is removed while still frozen, the events queued for that device remain while the device itself is freed. As a result, replaying the events will cause a use after free. To avoid the issue, make sure to dequeue and free any pending events on a frozen device when removed. CVE-2025-26600, ZDI-CAN-25871 This vulnerability was discovered by: Jan-Niklas Sohn working with Trend Micro Zero Day Initiative Signed-off-by: Olivier Fourdan Reviewed-by: Peter Hutterer (cherry picked from commit 6e0f332ba4c8b8c9a9945dc9d7989bfe06f80e14) Part-of: --- dix/devices.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/dix/devices.c b/dix/devices.c index 95190b5b7..440a00b58 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -969,6 +969,23 @@ FreeAllDeviceClasses(ClassesPtr classes) } +static void +FreePendingFrozenDeviceEvents(DeviceIntPtr dev) +{ + QdEventPtr qe, tmp; + + if (!dev->deviceGrab.sync.frozen) + return; + + /* Dequeue any frozen pending events */ + xorg_list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) { + if (qe->device == dev) { + xorg_list_del(&qe->next); + free(qe); + } + } +} + /** * Close down a device and free all resources. * Once closed down, the driver will probably not expect you that you'll ever @@ -1033,6 +1050,7 @@ CloseDevice(DeviceIntPtr dev) free(dev->last.touches[j].valuators); free(dev->last.touches); dev->config_info = NULL; + FreePendingFrozenDeviceEvents(dev); dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); free(dev); } -- 2.48.1