From 7f7f51e8907b14c6654944e0e321f15e256b34e7 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 20 Jan 2025 16:52:01 +0100 Subject: [PATCH xserver 10/13] sync: Do not let sync objects uninitialized When changing an alarm, the change mask values are evaluated one after the other, changing the trigger values as requested and eventually, SyncInitTrigger() is called. SyncInitTrigger() will evaluate the XSyncCACounter first and may free the existing sync object. Other changes are then evaluated and may trigger an error and an early return, not adding the new sync object. This can be used to cause a use after free when the alarm eventually triggers. To avoid the issue, delete the existing sync object as late as possible only once we are sure that no further error will cause an early exit. CVE-2025-26601, ZDI-CAN-25870 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 16a1242d0ffc7f45ed3c595ee7564b5c04287e0b) Part-of: --- Xext/sync.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index fd2ceb042..e55295904 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -329,11 +329,6 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, client->errorValue = syncObject; return rc; } - if (pSync != pTrigger->pSync) { /* new counter for trigger */ - SyncDeleteTriggerFromSyncObject(pTrigger); - pTrigger->pSync = pSync; - newSyncObject = TRUE; - } } /* if system counter, ask it what the current value is */ @@ -401,6 +396,14 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, } } + if (changes & XSyncCACounter) { + if (pSync != pTrigger->pSync) { /* new counter for trigger */ + SyncDeleteTriggerFromSyncObject(pTrigger); + pTrigger->pSync = pSync; + newSyncObject = TRUE; + } + } + /* we wait until we're sure there are no errors before registering * a new counter on a trigger */ -- 2.48.1